Gazebo | Ignition | Community
Ask Your Question
0

How to modify a model plugin to publish data to a rostopic or ros node?

asked 2019-10-07 04:46:14 -0600

zaccer gravatar image

updated 2019-10-08 00:34:41 -0600

I am trying to work with gazebo_motor_model.cpp. I need to visual some data that is calculated inside the plugin such a force, drag_torque etc. Is there a way i can publish this data to a topic or node so that i can visualize it using rqt.

P.S. - I am working on ROS kinetic with gazebo 7

Adding the .cpp file for reference. C:\fakepath\gazebo_motor_model.cpp

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted
1

answered 2019-10-07 05:24:46 -0600

kumpakri gravatar image

updated 2019-10-07 07:39:10 -0600

Sure, just initialize the ROS node inside the load function

if (!ros::isInitialized())
    {
        int argc = 0;
        char **argv = NULL;

        ros::init(argc, argv, node_name,
            ros::init_options::NoSigintHandler);
    }

    // Create ROS node.
    this->rosNode.reset(new ros::NodeHandle( node_name ));

and create a publisher

this->rosPub = this->rosNode->advertise<std_msgs::Float64>(topic_name,1);

Then you can access the class variable this->rosPub from within the plugin and send the messages.


EDIT

Include ROS at the top of the header file gazebo_motor_model.h:

#include "ros/ros.h"

Declare the class variables inside the header file

namespace gazebo {
    ...
    class GazeboMotorModel : public MotorModel, public ModelPlugin {
         ...
         private: std::unique_ptr<ros::NodeHandle> rosNode;
         private: ros::Publisher rosPub;

initialize the ROS node inside the Load function of the plugin inside the gazebo_motor_model.cpp file

if (!ros::isInitialized())
    {
        int argc = 0;
        char **argv = NULL;

        ros::init(argc, argv, "my_ros_node",
            ros::init_options::NoSigintHandler);
    }

    // Create ROS node.
    this->rosNode.reset(new ros::NodeHandle( "my_ros_node" ));

initialize the ros publisher right under the ROS node initialization

this->rosPub = this->rosNode->advertise<std_msgs::Float64>("my_ros_topic",1);

note that the message type (here std_msgs::Float64) must be edited to match your topics message type.

Now you can send the message anywhere in your update function

  std_msgs::Float64 msg;
  msg.data = 15.3;
  this->rosPub.publish(msg);
edit flag offensive delete link more

Comments

does the node need to be initialized in a separate script or in the same plugin file? Is there some example I can take reference of?

zaccer gravatar imagezaccer ( 2019-10-07 05:52:03 -0600 )edit

You do it inside the plugin from which you want to get the information out to ROS.

kumpakri gravatar imagekumpakri ( 2019-10-07 06:32:04 -0600 )edit

After implementing the code, i tried to compile it but got the error ‘ros’ has not been declared if (!ros::isInitialized()) ^ . Any suggestions?

zaccer gravatar imagezaccer ( 2019-10-07 06:42:51 -0600 )edit

The gazebo plugins typically have a source code .cpp inside the /src folder and the header file .h or .hh of the same name inside the /include folder. You need to tell the interpreter to look into the ROS library. That is typically done inside the header file. The class variables (rosNode and rosPub in the example) are also typically declared in the header file. See the new edit in my answer.

kumpakri gravatar imagekumpakri ( 2019-10-07 07:09:30 -0600 )edit

private: std::unique_ptr<ros::nodehandle> rosNode; private: ros::Publisher rosPub; Do I need to modify the ros.h file to include the above class.

And how would i use the this->rospub class to publish lets say force inside UpdateForcesAndMoments function.

I should have mentioned, I am relatively new to ROS hence the struggle with such basic stuff.

zaccer gravatar imagezaccer ( 2019-10-07 07:18:55 -0600 )edit

See if the current edit has all the answers you need. I think I addressed them all. Point to me what stays unclear still.

kumpakri gravatar imagekumpakri ( 2019-10-07 07:23:17 -0600 )edit

Your source code is named gazebo_motor_model.cpp so your header file inside the /include folder is named gazebo_motor_model.h. That is the header file you need to modify with the three lines I showed you above.

kumpakri gravatar imagekumpakri ( 2019-10-07 07:37:03 -0600 )edit

When you look inside the Gazebo 7 API documentation (Physics --> Joint --> GetVelocity()) You can see it returns a scalar number in double format, so, actually, the example with Float64 message type could be used if you are creating your own topic to publish to.

In that case also include the message type somewhere in your code (you can do it in source code or header file alike)

#include <std_msgs/Float64.h>
kumpakri gravatar imagekumpakri ( 2019-10-07 07:46:28 -0600 )edit

Thanks a lot for the detailed explanation.

zaccer gravatar imagezaccer ( 2019-10-07 23:33:40 -0600 )edit

I implemented the code in the gazebo_motor_model.cpp, i was able to compile it without any error. but neither the node name nor the topic comes up during rosnode list and rostopic list.I am editing my question to include my modified gazebo_motor_model.cpp file. Please tell me where i might be making mistake.

zaccer gravatar imagezaccer ( 2019-10-08 00:22:12 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2019-10-07 04:46:14 -0600

Seen: 994 times

Last updated: Oct 08 '19