Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Calling gazebo service set_model_state in C++ Code

Hi,

I'm trying to set the state of a robot in simulation. In a terminal, this works:

rosservice call /gazebo/set_model_state '{model_state: { model_name: my_robot, pose: { position: { x: 0.0, y: 0.0 ,z: 0.1 }, orientation: {x: 0.0, y: 0.0, z: 0.0, w: 0.0 } }, twist: { linear: {x: 0.0 , y: 0 ,z: 0 } , angular: { x: 0.0 , y: 0 , z: 0.0 } } , reference_frame: world } }'

Now I want to do the same in C++ Code. Can someone give me a hint, how I can achieve this?

Thanks in advance!

Calling gazebo service set_model_state in C++ Code

Hi,

I'm trying to set the state of a robot in simulation. In a terminal, this works:

rosservice call /gazebo/set_model_state '{model_state: { model_name: my_robot, pose: { position: { x: 0.0, y: 0.0 ,z: 0.1 }, orientation: {x: 0.0, y: 0.0, z: 0.0, w: 0.0 } }, twist: { linear: {x: 0.0 , y: 0 ,z: 0 } , angular: { x: 0.0 , y: 0 , z: 0.0 } } , reference_frame: world } }'

Now I want to do the same in C++ Code. Can someone give me a hint, how I can achieve this?

Thanks in advance!

Next try: Adding the line

ros::ServiceClient client = n.serviceClient<gazebo::ModelState>("/gazebo/SetModelState");

or

ros::ServiceClient client = n.serviceClient<gazebo::ModelState>("/gazebo/set_model_state");

results in the following errors when compiling (I hope this is readable):

Description Resource Path Location Type /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp_traits/include/ros/service_traits.h instantiated from ‘const char* ros::service_traits::md5sum() [with M = gazebo::ModelState_<std::allocator<void> >]’ RL-RelWithDebInfo@RL 79 C/C++ Problem

Description Resource Path Location Type /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp_traits/include/ros/service_traits.h error: ‘__s_getServerMD5Sum’ is not a member of ‘gazebo::ModelState_<std::allocator<void> >’ RL-RelWithDebInfo@RL 47 C/C++ Problem

Description Resource Path Location Type /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp/include/ros/node_handle.h instantiated from ‘ros::ServiceClient ros::NodeHandle::serviceClient(const std::string&, bool, const ros::M_string&) [with Service = gazebo::ModelState_<std::allocator<void> >]’ RL-RelWithDebInfo@RL 1062 C/C++ Problem

Description Resource Path Location Type /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp/include/ros/service_client_options.h instantiated from ‘void ros::ServiceClientOptions::init(const std::string&, bool, const ros::M_string&) [with Service = gazebo::ModelState_<std::allocator<void> >]’ RL-RelWithDebInfo@RL 93 C/C++ Problem

Calling gazebo service set_model_state in C++ Code

Hi,

I'm trying to set the state of a robot in simulation. In a terminal, this works:

rosservice call /gazebo/set_model_state '{model_state: { model_name: my_robot, pose: { position: { x: 0.0, y: 0.0 ,z: 0.1 }, orientation: {x: 0.0, y: 0.0, z: 0.0, w: 0.0 } }, twist: { linear: {x: 0.0 , y: 0 ,z: 0 } , angular: { x: 0.0 , y: 0 , z: 0.0 } } , reference_frame: world } }'

Now I want to do the same in C++ Code. Can someone give me a hint, how I can achieve this?

Thanks in advance!


Next try: Adding the line

ros::ServiceClient client = n.serviceClient<gazebo::ModelState>("/gazebo/SetModelState");

or

ros::ServiceClient client = n.serviceClient<gazebo::ModelState>("/gazebo/set_model_state");

results in the following errors when compiling (I hope this is readable):

Description Resource Path Location Type /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp_traits/include/ros/service_traits.h instantiated from ‘const char* ros::service_traits::md5sum() [with M = gazebo::ModelState_<std::allocator<void> >]’ RL-RelWithDebInfo@RL 79 C/C++ Problem

Description Resource Path Location Type /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp_traits/include/ros/service_traits.h error: ‘__s_getServerMD5Sum’ is not a member of ‘gazebo::ModelState_<std::allocator<void> >’ RL-RelWithDebInfo@RL 47 C/C++ Problem

Description Resource Path Location Type /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp/include/ros/node_handle.h instantiated from ‘ros::ServiceClient ros::NodeHandle::serviceClient(const std::string&, bool, const ros::M_string&) [with Service = gazebo::ModelState_<std::allocator<void> >]’ RL-RelWithDebInfo@RL 1062 C/C++ Problem

Description Resource Path Location Type /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp/include/ros/service_client_options.h instantiated from ‘void ros::ServiceClientOptions::init(const std::string&, bool, const ros::M_string&) [with Service = gazebo::ModelState_<std::allocator<void> >]’ RL-RelWithDebInfo@RL 93 C/C++ Problem


Edit2: I installed "gazebo_msgs", added it to the manifest and included "gazebo_msgs/ModelState.h". If I add the line

ros::ServiceClient client = n.serviceClient<gazebo_msgs::SetModelState>("/gazebo/SetModelState");

I get the error, that 'SetModelState' is not a member of 'gazebo_msgs' and that there's no matching function for call to ‘ros::NodeHandle::serviceClient(const char [22])’. I'm using diamondback, but this page http://www.ros.org/wiki/gazebo_msgs only talk about electric. Is this a problem? Doing this works:

gazebo_msgs::ModelState my_model_state;

and according to this docu http://ros.org/doc/electric/api/gazebo_msgs/html/index-msg.html, I thought

  ros::ServiceClient client = n.serviceClient<gazebo_msgs::ModelState>("/gazebo/SetModelState");

should work, but I get errors:

/opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp_traits/include/ros/service_traits.h instantiated from ‘const char* ros::service_traits::md5sum() [with M = gazebo_msgs::ModelState_<std::allocator<void> >]’

/opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp_traits/include/ros/service_traits.h error: ‘__s_getServerMD5Sum’ is not a member of ‘gazebo_msgs::ModelState_<std::allocator<void> >’

/opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp/include/ros/node_handle.h instantiated from ‘ros::ServiceClient ros::NodeHandle::serviceClient(const std::string&, bool, const ros::M_string&) [with Service = gazebo_msgs::ModelState_<std::allocator<void> >]’

/opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp/include/ros/service_client_options.h instantiated from ‘void ros::ServiceClientOptions::init(const std::string&, bool, const ros::M_string&) [with Service = gazebo_msgs::ModelState_<std::allocator<void> >]’

Calling gazebo service set_model_state in C++ Code

Hi,

I'm trying to set the state of a robot in simulation. In a terminal, this works:

rosservice call /gazebo/set_model_state '{model_state: { model_name: my_robot, pose: { position: { x: 0.0, y: 0.0 ,z: 0.1 }, orientation: {x: 0.0, y: 0.0, z: 0.0, w: 0.0 } }, twist: { linear: {x: 0.0 , y: 0 ,z: 0 } , angular: { x: 0.0 , y: 0 , z: 0.0 } } , reference_frame: world } }'

Now I want to do the same in C++ Code. Can someone give me a hint, how I can achieve this?

Thanks in advance!


Next try: Adding the lineIt works, thanks for your help!!

If someone runs into to same problem, here is the complete solution: First, how to do it in general (I know that there are tutorials, maybe this helps anyway); then I will post the concrete code.

Search with 'rostopic list' the service you want to call, you see the service names. With 'rosservice type name_of_service' you get the message_type. In message_type, you need to replace "/" by "::" for the usage below. In your code, you can write

ros::NodeHandle n;
ros::ServiceClient client = n.serviceClient<gazebo::ModelState>("/gazebo/SetModelState");
n.serviceClient<message_type>("name_of_service");

orNow you need to create a message of the message type, i.e.

message_type my_message;

(still with "::" instead of "/" in message_type) To find out what the service wants as input and returns as output, search for the file short_message_type.srv, where short_message_type.srv is the part after the most right "::", see concrete example at the buttom. [Probably this is also possible with a ros command in terminal.] In this file, you find names and types of the arguments of the service. You need to put the input arguments in my_message.request. So if there is a input argument of type double named 'number', you need to set something like my_message.request.number=42. Now you can call the service with

client.call(my_message);

After that, you will find in my_message.response what the service has returned (output arguments).

For my problem (under diamondback), the complete code is:

ros::init(argc, argv, "my_node");
ros::NodeHandle n;
geometry_msgs::Pose start_pose;
start_pose.position.x = 0.0;
start_pose.position.y = 0.0;
start_pose.position.z = 0.1;
start_pose.orientation.x = 0.0;
start_pose.orientation.y = 0.0;
start_pose.orientation.z = 0.0;
start_pose.orientation.w = 0.0;

geometry_msgs::Twist start_twist;
start_twist.linear.x = 0.0;
start_twist.linear.y = 0.0;
start_twist.linear.z = 0.0;
start_twist.angular.x = 0.0;
start_twist.angular.y = 0.0;
start_twist.angular.z = 0.0;

gazebo::ModelState modelstate;
modelstate.model_name = (std::string) "my_robot";
modelstate.reference_frame = (std::string) "world";
modelstate.pose = start_pose;
modelstate.twist = start_twist;

ros::ServiceClient client = n.serviceClient<gazebo::ModelState>("/gazebo/set_model_state");
n.serviceClient<gazebo::SetModelState>("/gazebo/set_model_state");
gazebo::SetModelState setmodelstate;
setmodelstate.request.model_state = modelstate;
client.call(setmodelstate);

results in the following errors when compiling (I hope this is readable):

Description Resource Path Location Type /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp_traits/include/ros/service_traits.h instantiated from ‘const char* ros::service_traits::md5sum() [with M = gazebo::ModelState_<std::allocator<void> >]’ RL-RelWithDebInfo@RL 79 C/C++ Problem

Description Resource Path Location Type /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp_traits/include/ros/service_traits.h error: ‘__s_getServerMD5Sum’ is not a member of ‘gazebo::ModelState_<std::allocator<void> >’ RL-RelWithDebInfo@RL 47 C/C++ Problem

Description Resource Path Location Type /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp/include/ros/node_handle.h instantiated from ‘ros::ServiceClient ros::NodeHandle::serviceClient(const std::string&, bool, const ros::M_string&) [with Service = gazebo::ModelState_<std::allocator<void> >]’ RL-RelWithDebInfo@RL 1062 C/C++ Problem

Description Resource Path Location Type /opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp/include/ros/service_client_options.h instantiated from ‘void ros::ServiceClientOptions::init(const std::string&, bool, const ros::M_string&) [with Service = gazebo::ModelState_<std::allocator<void> >]’ RL-RelWithDebInfo@RL 93 C/C++ Problem


Edit2: I installed "gazebo_msgs", added it to the manifest and included "gazebo_msgs/ModelState.h". If I add the line

ros::ServiceClient client = n.serviceClient<gazebo_msgs::SetModelState>("/gazebo/SetModelState");

I get the error, that 'SetModelState' is not a member of 'gazebo_msgs' and that there's no matching function for call to ‘ros::NodeHandle::serviceClient(const char [22])’. I'm using diamondback, but this page http://www.ros.org/wiki/gazebo_msgs only talk about electric. Is this a problem? Doing this works:

gazebo_msgs::ModelState my_model_state;

and according to this docu http://ros.org/doc/electric/api/gazebo_msgs/html/index-msg.html, I thought

  ros::ServiceClient client = n.serviceClient<gazebo_msgs::ModelState>("/gazebo/SetModelState");

should work, but I get errors:

/opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp_traits/include/ros/service_traits.h instantiated from ‘const char* ros::service_traits::md5sum() [with M = gazebo_msgs::ModelState_<std::allocator<void> >]’

/opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp_traits/include/ros/service_traits.h error: ‘__s_getServerMD5Sum’ is not a member of ‘gazebo_msgs::ModelState_<std::allocator<void> >’

/opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp/include/ros/node_handle.h instantiated from ‘ros::ServiceClient ros::NodeHandle::serviceClient(const std::string&, bool, const ros::M_string&) [with Service = gazebo_msgs::ModelState_<std::allocator<void> >]’

/opt/ros/diamondback/stacks/ros_comm/clients/cpp/roscpp/include/ros/service_client_options.h instantiated from ‘void ros::ServiceClientOptions::init(const std::string&, bool, const ros::M_string&) [with Service = gazebo_msgs::ModelState_<std::allocator<void> >]’

Calling gazebo service set_model_state in C++ Code

Hi,

I'm trying to set the state of a robot in simulation. In a terminal, this works:

rosservice call /gazebo/set_model_state '{model_state: { model_name: my_robot, pose: { position: { x: 0.0, y: 0.0 ,z: 0.1 }, orientation: {x: 0.0, y: 0.0, z: 0.0, w: 0.0 } }, twist: { linear: {x: 0.0 , y: 0 ,z: 0 } , angular: { x: 0.0 , y: 0 , z: 0.0 } } , reference_frame: world } }'

Now I want to do the same in C++ Code. Can someone give me a hint, how I can achieve this?

Thanks in advance!


It works, thanks for your help!!

If someone runs into to same problem, here is the complete solution: First, how to do it in general (I know that there are tutorials, maybe this helps anyway); then I will post the concrete code.

Search with 'rostopic list' the service you want to call, you see the service names. With 'rosservice type name_of_service' you get the message_type. In message_type, you need to replace "/" by "::" for the usage below. In your code, you can write

ros::NodeHandle n;
ros::ServiceClient client = n.serviceClient<message_type>("name_of_service");

Now you need to create a message of the message type, i.e.

message_type my_message;

(still with "::" instead of "/" in message_type) To find out what the service wants as input and returns as output, search for the file short_message_type.srv, where short_message_type.srv is the part after the most right "::", see concrete example at the buttom. [Probably this is also possible with a ros command in terminal.] In this file, you find names and types of the arguments of the service. You need to put the input arguments in my_message.request. So if there is a input argument of type double named 'number', you need to set something like my_message.request.number=42. Now you can call the service with

client.call(my_message);

After that, you will find in my_message.response what the service has returned (output arguments).

For my problem (under diamondback), the complete code is:

ros::init(argc, argv, "my_node");
ros::NodeHandle n;
geometry_msgs::Pose start_pose;
start_pose.position.x = 0.0;
start_pose.position.y = 0.0;
start_pose.position.z = 0.1;
start_pose.orientation.x = 0.0;
start_pose.orientation.y = 0.0;
start_pose.orientation.z = 0.0;
start_pose.orientation.w = 0.0;

geometry_msgs::Twist start_twist;
start_twist.linear.x = 0.0;
start_twist.linear.y = 0.0;
start_twist.linear.z = 0.0;
start_twist.angular.x = 0.0;
start_twist.angular.y = 0.0;
start_twist.angular.z = 0.0;

gazebo::ModelState modelstate;
modelstate.model_name = (std::string) "my_robot";
modelstate.reference_frame = (std::string) "world";
modelstate.pose = start_pose;
modelstate.twist = start_twist;

ros::ServiceClient client = n.serviceClient<gazebo::SetModelState>("/gazebo/set_model_state");
gazebo::SetModelState setmodelstate;
setmodelstate.request.model_state = modelstate;
client.call(setmodelstate);

Calling gazebo service set_model_state in C++ Code

Hi,

I'm trying to set the state of a robot in simulation. In a terminal, this works:

rosservice call /gazebo/set_model_state '{model_state: { model_name: my_robot, pose: { position: { x: 0.0, y: 0.0 ,z: 0.1 }, orientation: {x: 0.0, y: 0.0, z: 0.0, w: 0.0 } }, twist: { linear: {x: 0.0 , y: 0 ,z: 0 } , angular: { x: 0.0 , y: 0 , z: 0.0 } } , reference_frame: world } }'

Now I want to do the same in C++ Code. Can someone give me a hint, how I can achieve this?

Thanks in advance!


It works, thanks for your help!!

If someone runs into to same problem, here is the complete solution: First, how to do it in general (I know that there are tutorials, maybe this helps anyway); then I will post the concrete code.

Search with 'rostopic list' the service you want to call, you see the service names. With 'rosservice type name_of_service' you get the message_type. In message_type, you need to replace "/" by "::" for the usage below. In your code, you can write

ros::NodeHandle n;
ros::ServiceClient client = n.serviceClient<message_type>("name_of_service");

Now you need to create a message of the message type, i.e.

message_type my_message;

(still with "::" instead of "/" in message_type) To find out what the service wants as input and returns as output, search for the file short_message_type.srv, where short_message_type.srv is the part after the most right "::", see concrete example at the buttom. [Probably this is also possible with a ros command in terminal.] In this file, you find names and types of the arguments of the service. You need to put the input arguments in my_message.request. So if there is a input argument of type double named 'number', you need to set something like my_message.request.number=42. Now you can call the service with

client.call(my_message);

After that, you will find in my_message.response what the service has returned (output arguments).

For my problem (under diamondback), the complete code is:

ros::init(argc, argv, "my_node");
ros::NodeHandle n;
geometry_msgs::Pose start_pose;
start_pose.position.x = 0.0;
start_pose.position.y = 0.0;
start_pose.position.z = 0.1;
start_pose.orientation.x = 0.0;
start_pose.orientation.y = 0.0;
start_pose.orientation.z = 0.0;
start_pose.orientation.w = 0.0;

geometry_msgs::Twist start_twist;
start_twist.linear.x = 0.0;
start_twist.linear.y = 0.0;
start_twist.linear.z = 0.0;
start_twist.angular.x = 0.0;
start_twist.angular.y = 0.0;
start_twist.angular.z = 0.0;

gazebo::ModelState modelstate;
modelstate.model_name = (std::string) "my_robot";
modelstate.reference_frame = (std::string) "world";
modelstate.pose = start_pose;
modelstate.twist = start_twist;

ros::ServiceClient client = n.serviceClient<gazebo::SetModelState>("/gazebo/set_model_state");
gazebo::SetModelState setmodelstate;
setmodelstate.request.model_state = modelstate;
client.call(setmodelstate);

Calling gazebo service set_model_state in C++ Code

Hi,

I'm trying to set the state of a robot in simulation. In a terminal, this works:

rosservice call /gazebo/set_model_state '{model_state: { model_name: my_robot, pose: { position: { x: 0.0, y: 0.0 ,z: 0.1 }, orientation: {x: 0.0, y: 0.0, z: 0.0, w: 0.0 } }, twist: { linear: {x: 0.0 , y: 0 ,z: 0 } , angular: { x: 0.0 , y: 0 , z: 0.0 } } , reference_frame: world } }'

Now I want to do the same in C++ Code. Can someone give me a hint, how I can achieve this?

Thanks in advance!


It works, thanks for your help!!

If someone runs into to same problem, here is the complete solution: First, how to do it in general (I know that there are tutorials, maybe this helps anyway); then I will post the concrete code.

Search with 'rostopic list' the service you want to call, you see the service names. With 'rosservice type name_of_service' you get the message_type. In message_type, you need to replace "/" by "::" for the usage below. In your code, you can write

ros::NodeHandle n;
ros::ServiceClient client = n.serviceClient<message_type>("name_of_service");

Now you need to create a message of the message type, i.e.

message_type my_message;

(still with "::" instead of "/" in message_type) To find out what the service wants as input and returns as output, search for the file short_message_type.srv, where short_message_type.srv is the part after the most right "::", see concrete example at the buttom. [Probably this is also possible with a ros command in terminal.] In this file, you find names and types of the arguments of the service. You need to put the input arguments in my_message.request. So if there is a input argument of type double named 'number', you need to set something like my_message.request.number=42. Now you can call the service with

client.call(my_message);

After that, you will find in my_message.response what the service has returned (output arguments).

For my problem (under diamondback), the complete code is:

ros::init(argc, argv, "my_node");
ros::NodeHandle n;
geometry_msgs::Pose start_pose;
start_pose.position.x = 0.0;
start_pose.position.y = 0.0;
start_pose.position.z = 0.1;
start_pose.orientation.x = 0.0;
start_pose.orientation.y = 0.0;
start_pose.orientation.z = 0.0;
start_pose.orientation.w = 0.0;

geometry_msgs::Twist start_twist;
start_twist.linear.x = 0.0;
start_twist.linear.y = 0.0;
start_twist.linear.z = 0.0;
start_twist.angular.x = 0.0;
start_twist.angular.y = 0.0;
start_twist.angular.z = 0.0;

gazebo::ModelState modelstate;
modelstate.model_name = (std::string) "my_robot";
modelstate.reference_frame = (std::string) "world";
modelstate.pose = start_pose;
modelstate.twist = start_twist;

ros::ServiceClient client = n.serviceClient<gazebo::SetModelState>("/gazebo/set_model_state");
gazebo::SetModelState setmodelstate;
setmodelstate.request.model_state = modelstate;
client.call(setmodelstate);