Closed weseu closed 4 years ago
Apologies for the delay in responding. I was very carefully researching the options available for control of these options for the SR305. I believe that C++ is going to be the best method to do so.
Scripting for motion_range can be found here:
https://github.com/IntelRealSense/librealsense/issues/3185
An example of C++ code for changing gain and exposure manually is here:
https://github.com/IntelRealSense/librealsense/issues/2024#issuecomment-404067092
Hi @MartyG-RealSense , I am just curious about how to set the value by using ddynamic_reconfigure methods. Because I am trying to write a node can loop the value in a range(for example: motion range 0~60) when run the rs_camera.launch, should I write a register to save the value(EX: registerEnumVariable) and then publish it ? I followed the base_realsense_node.cpp in Line 383 to 486, which is under realsense-ros. Or even I don't need to do this...
By the way, I didn't know how to write the code like this
rs2::pipeline p; auto profile = p.start(); auto dev = profile.get_device(); auto sensor = dev.query_sensors().front(); sensor.set_option(RS2_OPTION_MOTION_RANGE, ...); sensor.set_option(RS2_OPTION_CONFIDENCE_THRESHOLD, ...); sensor.set_option(RS2_OPTION_FILTER_OPTION, ...);
Could you please tell me how should I do(like which workspace should I under, which headfile should I include, or any sample code I could follow)? thank you.
Hi @drfg0119
If you are using an SR305 like @weseu then this is a difficult question to advise on in regard to using ROS and dynamic reconfigure. This is because I do not know whether SR305 is compatible with the ROS wrapper, even though the SR305 is basically an SR300 inside its casing. SR300 is compatible but I do not have official information about whether SR305 is compatible.
To achieve what you would like to do with ROS, I suspect that you would have to do two things, if you have an SR305 and it can be used as an SR300 with the ROS wrapper:
https://github.com/IntelRealSense/librealsense/tree/v1.12.1
http://wiki.ros.org/realsense_camera#SR300_Dynamically_Reconfigurable_Parameters
I would recommend waiting for confirmation from @doronhi the RealSense ROS developer about whether the above plan is correct though, so that you do not waste your time. I apologise that I could not provide more certainty in my advice on this particular case.
Hi @MartyG-RealSense , haha OK that's fine, thank you, but I can run the rqt_reconfigure to set values in the "coded-light sensor" node dynamically, so I thought that is available for me to write a node to control SR305.
But, could you please help me to understand the code written by @dorodnic here ? I want to know how should I do(like which workspace should I under, which headfile should I include, or any sample code I could follow) to write it?
Thank you for your attention.
rs2::pipeline p; auto profile = p.start(); auto dev = profile.get_device(); auto sensor = dev.query_sensors().front(); sensor.set_option(RS2_OPTION_MOTION_RANGE, ...); sensor.set_option(RS2_OPTION_CONFIDENCE_THRESHOLD, ...); sensor.set_option(RS2_OPTION_FILTER_OPTION, ...);
@drfg0119 The code example by Dorodnic is in a programming language called C++. To create a C++ program, it is recommended that compiler software such as Microsoft Visual Studio is used. A free version of Visual Studio is Visual Studio Community.
https://visualstudio.microsoft.com/vs/community/
The link below has some guidance about integrating Librealsense into a project that you have created yourself.
https://github.com/IntelRealSense/librealsense/issues/4277
There is also a 'getting started' project for beginners.
https://github.com/zivsha/librealsense/tree/getting_started_example/examples/getting-started
Once you have a 'development environment' set up in a program such as Visual Studio then you will be in a position to use scripting code such as the sample that Dorodnic provided.
The basics of the structure of Dorodnic's sample is that the first few lines set up a 'pipeline' for the camera's processes to work within and then tell Librealsense how to find your camera with a device 'profile'. The last few lines - set.option commands - configure a particular aspect of the camera's functions, such as its motion range value.
Hi @MartyG-RealSense , I have written a node named controller like this, because I didn't know how to deal with the protected member in class options
which is under rs_option.hpp, so I used inheritance to make a new class called controller
, but when I found there is error when it run into the function defined myself like ctr.get_MvR(option)
, then I check the function step by step, I found bug is error::handle(e)
in my hpp file. Is there any idea could suggest? I'll appreciate.
#include </opt/ros/melodic/include/ros/ros.h>
#include </home/nvidia/catkin_ws/src/ddynamic_reconfigure/include/ddynamic_reconfigure/ddynamic_reconfigure.h>
#include <string>
#include <map>
#include <iostream>
#include <fstream>
#include "/home/nvidia/librealsense/include/librealsense2/h/rs_option.h"
#include "/home/nvidia/librealsense/include/librealsense2/h/rs_types.h"
#include <algorithm>
#include <cctype>
#include <mutex>
#include "controller.hpp"
using namespace ddynamic_reconfigure;
int main(int argc, char **argv)
{
ROS_INFO("Spinning node");
ros::init(argc, argv, "controller");
ros::NodeHandle nh;
ddynamic_reconfigure::DDynamicReconfigure ddynrec;
rs2::controller ctr; // like rs2::options sensor
rs2_option option = static_cast<rs2_option>(16); //no.16 is RS2_OPTION_MOTION_RANGE
const auto sensor_option_value = ctr.get_MvR(option); // like sensor.get_option(option)
auto option_value = int(sensor_option_value);
ros::Rate loop_rate(10);
int c = 0;
while (ros::ok())
{
c++;
option_value = 0;
if(!(c%10))
{
option_value+=5;
if(option_value > 60)
option_value = 0;
}
ctr.set_MvR(option, option_value); // like sensor.set_option(option, option_value);
ddynrec.registerVariable<int>(
ctr.get_MvR_name(option), int(option_value),
[option, ctr](int new_value) { ctr.set_MvR(option, new_value); },
ctr.get_MvR_description(option));
loop_rate.sleep();
}
ROS_INFO("Spinning node shutdown...");
return 0;
}
Here is the controller.hpp written myself, it's copy from rs_option.hpp
#include "/usr/local/include/librealsense2/hpp/rs_options.hpp"
#include "/usr/local/include/librealsense2/hpp/rs_types.hpp"
namespace rs2
{
class controller : public options
{
public:
const char* get_MvR_description(rs2_option option) const
{
rs2_error* e = nullptr;
auto res = rs2_get_option_description(_ctr, option, &e);
error::handle(e);
return res;
}
const char* get_MvR_name(rs2_option option) const
{
rs2_error* e = nullptr;
auto res = rs2_get_option_name(_ctr, option, &e);
error::handle(e);
return res;
}
const char* get_MvR_value_description(rs2_option option, float val) const
{
rs2_error* e = nullptr;
auto res = rs2_get_option_value_description(_ctr, option, val, &e);
error::handle(e);
return res;
}
float get_MvR(rs2_option option) const
{
rs2_error* e = nullptr;
auto res = rs2_get_option(_ctr, option, &e);
error::handle(e);
return res;
}
void set_MvR(rs2_option option, float value) const
{
rs2_error* e = nullptr;
rs2_set_option(_ctr, option, value, &e);
error::handle(e);
}
std::vector<rs2_option> get_supported_MvR()
{
std::vector<rs2_option> res;
rs2_error* e = nullptr;
std::shared_ptr<rs2_options_list> options_list(
rs2_get_options_list(_ctr, &e),
rs2_delete_options_list);
for (auto opt = 0; opt < rs2_get_options_list_size(options_list.get(), &e);opt++)
{
res.push_back(rs2_get_option_from_list(options_list.get(), opt, &e));
}
return res;
}
explicit controller(rs2_options* o = nullptr) : _ctr(o)
{
}
controller& operator=(const controller& other)
{
_ctr = other._ctr;
return *this;
}
controller(const cpntroller& other) : _ctr(other._ctr) {}
virtual ~controller() = default;
template<class T>
controller& operator=(const T& dev)
{
_ctr = (rs2_options*)(dev.get());
return *this;
}
rs2_options* _ctr;
};
}
I set the print for finding the bug, here is in cpp.
Here is under hpp.
Here is the result.
Please help me, thank you!
I do not have experience of writing ROS node scripts unfortunately, so are unable to debug them.
Is your include for controller.hpp meant to be expressed as #include "controller.hpp" or should it be #include
Are they different !!? I dont know haha, I'm just new in programming sorry...
But I try to change "" to <>, the comment said it "no such file or directory".
Ok, looking at your other scripts, using " " seems to be valid too. As I said, my programming knowledge is still developing. :)
Since you did not specify a folder path in #include "controller.hpp" , is the file controller.hpp located in the same folder as the node script that is including it?
Oh yes, I put the .hpp and .cpp under same folder! Thank you haha
You are very welcome! Is your problem solved now, please?
Not yet, that is not the problem haha...
If there is a bug in the node script then I do not have the programming knowledge to advise on that, sadly. I will refer the problem to an Intel support manager for advice. I apologise for the delay that this will cause to your project in the meantime.
Don't mind it, thank you for your attention.
hey I solved the problem, because I didn't add this after main code haha.
But I need to face another problem now haha, the "e.get_failed_function()" throw the info(said "rs2_get_option"),and "e.get_failed_args()" also throw the info(said "option:nullptr, option:Filter Option"), finally the "e.what()" throw the info(said "null pointer passed for argument"option"."). Totally, the full sentence is RealSense error calling rs2_get_option(option:nullptr, option:Filter Option): null pointer passed for argument "options". is there any idea could help me? thanks.
Great news that you solved your original problem!
Regarding the new problem, there was someone who created a workaround for a similar error. The workaround made the program keep trying until it worked.
https://github.com/IntelRealSense/librealsense/issues/3892#issuecomment-488828666
catch (const rs2::error & e) { std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << std::endl; }
but there isn't the same function, should I follow their solution? And then I change my code, I realize that there is an class called sensor could do the same thing I want, so I delete my controller.hpp haha, but I am confused that still has same problem said: RealSense error calling rs2_get_option(option:nullptr, option:Filter Option): null pointer passed for argument "options". did I use the wrong way...?
here is my code. thanks
#include </opt/ros/melodic/include/ros/ros.h>
#include </home/nvidia/catkin_ws/src/ddynamic_reconfigure/include/ddynamic_reconfigure/ddynamic_reconfigure.h>
#include </home/nvidia/librealsense/include/librealsense2/rs.hpp>
#include <vector>
#include <utility>
#include <map>
#include <iomanip>
#include <iostream>
using namespace ddynamic_reconfigure;
int main(int argc, char **argv) try
{
ROS_INFO("Spinning node");
printf("c1\n");
ros::init(argc, argv, "controller");
printf("c2\n");
ros::NodeHandle nh;
printf("c3\n");
ddynamic_reconfigure::DDynamicReconfigure ddynrec;
printf("c4\n");
//rs2::controller ctr;
rs2::sensor sensor;
printf("c5\n");
rs2_option option;
printf("c6\n");
option = static_cast<rs2_option>(16);
printf("c7\n");
const auto sensor_option_value = sensor.get_option(option);
printf("c8\n");
auto option_value = int(sensor_option_value);
ros::Rate loop_rate(10);
int c = 0;
while (ros::ok())
{
c++;
option_value = 0;
if(!(c%10))
{
option_value+=5;
if(option_value > 60)
option_value = 0;
}
sensor.set_option(option, option_value);
ddynrec.registerVariable<int>(
sensor.get_option_name(option), option_value,
[option, sensor](int new_value) { sensor.set_option(option, new_value); },
sensor.get_option_description(option));
ddynrec.publishServicesTopics();
loop_rate.sleep();
}
ROS_INFO("Spinning node shutdown...");
return EXIT_SUCCESS;
}
catch (const rs2::error & e)
{
std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << std::endl;
return EXIT_FAILURE;
}
catch (const std::exception& e)
{
std::cerr << e.what() <<std::endl;
return EXIT_FAILURE;
}
And then there is an compile warning, is it OK...???
and this is the error
Oh, you already put in error catch code before the link I gave you. Sorry about that.
@doronhi sorry to bother you. Can you check the code above when you get an opportunity please to see why @drfg0119 might be getting null pointer errors. Thanks!
Hi @MartyG-RealSense and @doronhi , here the code is my latest version, I face the problem that I couldn't run the rs_camera.launch with my node together. Could you please help me..? Thanks!
#include "ros/ros.h"
#include </home/nvidia/catkin_ws/src/ddynamic_reconfigure/include/ddynamic_reconfigure/ddynamic_reconfigure.h>
#include </home/nvidia/librealsense/include/librealsense2/rs.hpp>
#include <vector>
#include <utility>
#include <map>
#include <iomanip>
#include <iostream>
#include <algorithm>
static rs2::device get_a_realsense_device()
{
rs2::context ctx;
rs2::device_list devices = ctx.query_devices();
rs2::device selected_device;
selected_device = devices[0]; //SR300
return selected_device;
}
static rs2::sensor get_a_sensor_from_a_device(const rs2::device& dev)
{
std::vector<rs2::sensor> sensors = dev.query_sensors();
return sensors[0]; //Coded-Light Depth Sensor
}
int main(int argc, char **argv) try
{
ROS_INFO("Spinning node");
ros::init(argc, argv, "controller");
ros::NodeHandle nh;
printf("c1\n");
rs2::device dev = get_a_realsense_device();
printf("c2\n");
rs2::sensor sensor;
printf("c3\n");
sensor = get_a_sensor_from_a_device(dev);
printf("c4\n");
rs2_option option;
printf("c5\n");
option = static_cast<rs2_option>(15); //Motion Range
printf("c6\n");
std::cout << option << std::endl;
float sensor_option_value = sensor.get_option(option);
printf("c7\n");
// printf("%d\n", sensor_option_value);
auto option_value = int(sensor_option_value);
ros::Rate loop_rate(1000);
int c = 0;
option_value = 0;
while (ros::ok())
{
c++;
if(c!=0)
{
option_value+=5;
printf("%d\n",option_value);
if(option_value > 60)
option_value = 0;
}
printf("ya1\n");
sensor.set_option(option, option_value);
printf("%d\n",option_value);
printf("c8\n");
ros::spinOnce();
loop_rate.sleep();
}
ROS_INFO("Spinning node shutdown...");
return EXIT_SUCCESS;
}
catch (const rs2::error & e)
{
std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << std::endl;
return EXIT_FAILURE;
}
catch (const std::exception& e)
{
std::cerr << e.what() <<std::endl;
return EXIT_FAILURE;
}
Hi, I am just thinking how to fix the device-conflicting problem, I have 2 idea like:
But I don't know how to do it, or maybe I am wrong. Could you please help me? Thanks!
The "failed to set power state" error sounds like more power demand is being put on the computer's USB ports by the camera than it can cope with. This error has sometimes been seen in setups where more than one camera has been added to the same computer, and small computing boards such as Raspberry Pi may be more liable than full PCs to encounter this error.
In situations where there is a single camera attached and insufficient power for the camera to be detected reliably, a typical solution would be to attach the camera to a mains electricity powered USB 3 hub instead of attaching the camera directly to the computer. With a powered hub, the camera no longer has to take its power from the computer. A hub can supply 12 watts of power, which is more than enough for the average 2 watt power demand of a single camera.
Could you please provide details please of what kind of computer / computing device you are using, and which operating system you are using (Windows, Linux, etc). Thanks!
Required Info | |
---|---|
Camera Model | { SR305 } |
Firmware Version | 3.27.3.0 |
Operating System & Version | Linux (Ubuntu 18.04) |
Kernel Version (Linux Only) | (Jetpack 4.2.2) |
Platform | NVIDIA Jetson TX2 |
SDK Version | { RealsenseViewer 2.32.1 } |
Language | {ROS(Melodic) / C++ } |
Segment | {Robot } |
But I only connect with one cam.. I am only allowed to run rs_camera.launch or my-node one by one. If I run both of them at the same time, this is the result.. failed to set power state
If your launch file and node are both using the default configuration of SR305 instead of a custom configuration, each one might try to open 2 streams (the default SR305 configuration) and overwhelm the computing board with power demand, similar to the SR305 case in the link below.
https://github.com/IntelRealSense/librealsense/issues/5782#issuecomment-582077781
Yes, I launch nodes both using the default configuration of SR305, but I only want to open "one" stream, that shouldn't be a conflicting issue here... Thank you for your attention.
BTW, I'm trying another way to write my auto&dynamic-setting-parameter-controller haha, I want to focus on how to write a client node because there is a service called "set_parameters" under ddynamic_reconfigure project.
Is there any method could help me? I have no idea about where the Config in librealsense is, I want to find them then I can use the parameter.
If there is any idea could provide, please help me. Thanks
I apologise for the delay in responding further, as I was researching your wish to write a C++ node that could access dynamic reconfigure, and set_parameters in particular,
I first found a beginners tutorial for creating a C++ ROS node that uses dynamic reconfigure.
http://wiki.ros.org/dynamic_reconfigure/Tutorials/SettingUpDynamicReconfigureForANode%28cpp%29
The link below is an interesting looking reference regarding use of set_parameters in a ROS dynamic reconfigure node:
i hope that the above information will provide some useful insights.
Hi, I'm really appreciate for your attention.
I want to know how to get the Config(EX: dynamic_tutorials::TutorialsConfig config
) there were parameters already declared in there.
The Config I want to find is under coded_light_depth_sensor under realsense2_camera .
Thank you, but I've already know how beginners tutorial declare their service, because they define their own parameters, but I don't know how did realsense2_camera work, would you please help me? Thanks
I did not have much luck finding a C++ RealSense node script that refers to "Coded-Light Depth Sensor" except for the one in the link below.
Here also found one haha. https://github.com/IntelRealSense/librealsense/blob/master/src/ivcam/sr300.h#L303
Sorry, I didn't describe my problem clearly.
The reason why I want to find "Config" under coded_light_depth_sensor is I want to write a method that could help me to find the definition(EX: value range, value maximum and minimum...) of the parameter(EX: motion_range).
Then, I can use the declared parameter do everything I want.
Just like the following code: https://github.com/WelinLee/ROS_dynamic_reconfig/blob/master/ros_dynamic_test/src/dyn_client.cpp#L25
then I want to do a comparison between this one: https://github.com/pal-robotics/ddynamic_reconfigure/blob/kinetic-devel/test/test_ddynamic_reconfigure.cpp#L43
Thank you.
I must emphasise that I do not have any experience of programming ROS node scripts, so I can only answer on this subject with what I can find on the internet that others have written. With very specific questions like this one about SR300, dynamic reconfigure and motion range parameters, there is no information that I can find that I can use to offer a suggestion.
I still also do not know if realsense2_camera is capable of providing a minimum and maximum value for motion_range like the order realsense_camera module can.
The only option available to me is to tag @doronhi again. I do apologise.
Thank you, I'll keep going and wait for your supports. HaHa
@drfg0119 I apologise that you did not receive a further response. Do you still require assistance with this case please? thanks for your patience!
Yes @MartyG-RealSense , thank for your attention, I have a last question !! I am curious about that could I set the value like gain or offset on IR camera(not the RGB) of SR305 ? I didn't find them under the coded-light depth sensor, but I thought there might be a code I could tune the value. Could you please help me ? Thank you very much.
It's a difficult question. The original realsense_camera ROS module for SR300 and Librealsense1 had support for changing values like gain by using dynamic reconfigure.
http://wiki.ros.org/realsense_camera#SR300_Dynamically_Reconfigurable_Parameters
However, I do not have any documentation that these features are still supported in the current realsense2_camera ROS module for Librealsense2.
If you are using ROS Kinetic then there is the possibility that you might be able to use librealsense1 and realsense_camera to achieve access to these SR300 functions, if those old programs are able to recognise an SR305 as an SR300.
@doronhi can you provide guidance about what SR300-specific features could be accessed with an SR305 and realsense2_camera, please?
Hi, I haven't got an access to an SR305 for the last few weeks. Hopefully next week. I see reference to SR305 in the code so, In the meanwhile, could you tell me if you tried using realsense2_camera wrapper with SR305? Didn't it work? Could you add the log (from the screen)? If it works you should have all the options available with rqt_reconfigure. Which one didn't you see there?
Hi @doronhi ,
I see reference to SR305 in the code so, In the meanwhile, could you tell me if you tried using realsense2_camera wrapper with SR305? Didn't it work? Could you add the log (from the screen)?
I've already solved the programming problem, thanks for your following.
If it works you should have all the options available with rqt_reconfigure. Which one didn't you see there?
However, I am just curious about that is there a option named Gain (like UVC image gain applied on RGB camera) is under IR camera? Thank you.
I'm glad you solved it. Closing the ticket now, then.
There is a "Gain" option for IR camera. You can check it out if you run rosrun rqt_reconfigure rqt_reconfigure
. It's under camera->stereo_module->gain. Make sure to unmark "camera->stereo_module->enable_auto_exposure" for your gain modifications to apply. Watch the effects on the "infra1/image_rect_raw" topic using rqt_image_view
(or some other ROS viewer).
When I open "rs_camera.launch",I want to use another c++ code to dynamic Adjustment it's motion_range , gain....and so on.
Maybe I can use the ddynamic_reconfigure package,but I don't know how to do......
can you help me....give me some direction......