There are magnificent tutorials about how to create plugins for Gazebo in the GazeboSim webpage. There are even some tutorials about how to create plugins for Gazebo + ROS. Those tutorials show that there are several types of plugins (world, model, sensor, system, visual), and indicate how to create a plugin for a world type plugin.
Recently I need to create a plugin for a light detector. Reading the tutorials, I missed a concrete example about how to create a sensor plugin. Hence, I had to investigate a little bit about it. The result is the content of this post.
How to: light sensor plugin in Gazebo
Following the indications provided at the answers forum of Gazebo, I decided to build a very simple light detector sensor based on a camera. Instead of using a raytracing algorithm from lights, the idea is to use a camera to capture an image, then use the image to calculate the illuminance of the image, and then publish that illuminance value through a ROS topic.
Since the plugin is for its use with ROS, the whole plugin should be compilable using a ROS environment. Hence, be sure that you have installed the following packages in your Linux system:
- ros-<your_ros_version>-<your_gazebo_version>-ros. (in my case it is ros-jade-gazebo6-ros)
- ros-<your_ros_version>-<your_gazebo_version>-plugins (in my case it is ros-jade-gazebo6-plugins)
This tutorial, has two parts: on the first one we will explain how to create the plugin, and on the second, how to test that it works
Creating the plugin
Creating a ROS package for the plugin
First thing, is to create the package in our catkin workspace that will allow us to compile the plugin without a problem.
cd ~/catkin_ws/src catkin_create_pkg gazebo_light_sensor_plugin gazebo_ros gazebo_plugins roscpp
Creating the plugin code
For this purpose, since we are using a camera to capture the light, we are going to create a plugin class that inherits from the CameraPlugin. The code that follows has been created taking as guideline the code of the authentic gazebo ROS camera plugin.
Create a file called light_sensor_plugin.h inside the include directory of your package, including the following code:
#ifndef GAZEBO_ROS_LIGHT_SENSOR_HH
#define GAZEBO_ROS_LIGHT_SENSOR_HH
#include <string>
// library for processing camera data for gazebo / ros conversions
#include <gazebo/plugins/CameraPlugin.hh>
#include <gazebo_plugins/gazebo_ros_camera_utils.h>
namespace gazebo
{
class GazeboRosLight : public CameraPlugin, GazeboRosCameraUtils
{
/// \brief Constructor
/// \param parent The parent entity, must be a Model or a Sensor
public: GazeboRosLight();
/// \brief Destructor
public: ~GazeboRosLight();
/// \brief Load the plugin
/// \param take in SDF root element
public: void Load(sensors::SensorPtr _parent, sdf::ElementPtr _sdf);
/// \brief Update the controller
protected: virtual void OnNewFrame(const unsigned char *_image,
unsigned int _width, unsigned int _height,
unsigned int _depth, const std::string &_format);
ros::NodeHandle _nh;
ros::Publisher _sensorPublisher;
double _fov;
double _range;
};
}
#endif
As you can see, the code includes a node handler to connect to the roscore. It also defines a publisher that will publish messages containing the illuminance value. Two parameters have been defined: fov (field of view) and range. At present only fov is used to indicate the amount of pixels around the center of the image that will be taken into account to calculate the illuminance.
Next step is to create a file named light_sensor_plugin.cpp containing the following code in the src directory of your package:
#include <gazebo/common/Plugin.hh>
#include <ros/ros.h>
#include "gazebo_light_sensor_plugin/light_sensor_plugin.h"
#include "gazebo_plugins/gazebo_ros_camera.h"
#include <string>
#include <gazebo/sensors/Sensor.hh>
#include <gazebo/sensors/CameraSensor.hh>
#include <gazebo/sensors/SensorTypes.hh>
#include <sensor_msgs/Illuminance.h>
namespace gazebo
{
// Register this plugin with the simulator
GZ_REGISTER_SENSOR_PLUGIN(GazeboRosLight)
////////////////////////////////////////////////////////////////////////////////
// Constructor
GazeboRosLight::GazeboRosLight():
_nh("light_sensor_plugin"),
_fov(6),
_range(10)
{
_sensorPublisher = _nh.advertise<sensor_msgs::Illuminance>("lightSensor", 1);
}
////////////////////////////////////////////////////////////////////////////////
// Destructor
GazeboRosLight::~GazeboRosLight()
{
ROS_DEBUG_STREAM_NAMED("camera","Unloaded");
}
void GazeboRosLight::Load(sensors::SensorPtr _parent, sdf::ElementPtr _sdf)
{
// Make sure the ROS node for Gazebo has already been initialized
if (!ros::isInitialized())
{
ROS_FATAL_STREAM("A ROS node for Gazebo has not been initialized, unable to load plugin. "
<< "Load the Gazebo system plugin 'libgazebo_ros_api_plugin.so' in the gazebo_ros package)");
return;
}
CameraPlugin::Load(_parent, _sdf);
// copying from CameraPlugin into GazeboRosCameraUtils
this->parentSensor_ = this->parentSensor;
this->width_ = this->width;
this->height_ = this->height;
this->depth_ = this->depth;
this->format_ = this->format;
this->camera_ = this->camera;
GazeboRosCameraUtils::Load(_parent, _sdf);
}
////////////////////////////////////////////////////////////////////////////////
// Update the controller
void GazeboRosLight::OnNewFrame(const unsigned char *_image,
unsigned int _width, unsigned int _height, unsigned int _depth,
const std::string &_format)
{
static int seq=0;
this->sensor_update_time_ = this->parentSensor_->GetLastUpdateTime();
if (!this->parentSensor->IsActive())
{
if ((*this->image_connect_count_) > 0)
// do this first so there's chance for sensor to run once after activated
this->parentSensor->SetActive(true);
}
else
{
if ((*this->image_connect_count_) > 0)
{
common::Time cur_time = this->world_->GetSimTime();
if (cur_time - this->last_update_time_ >= this->update_period_)
{
this->PutCameraData(_image);
this->PublishCameraInfo();
this->last_update_time_ = cur_time;
sensor_msgs::Illuminance msg;
msg.header.stamp = ros::Time::now();
msg.header.frame_id = "";
msg.header.seq = seq;
int startingPix = _width * ( (int)(_height/2) - (int)( _fov/2)) - (int)(_fov/2);
double illum = 0;
for (int i=0; i<_fov ; ++i)
{
int index = startingPix + i*_width;
for (int j=0; j<_fov ; ++j)
illum += _image[index+j];
}
msg.illuminance = illum/(_fov*_fov);
msg.variance = 0.0;
_sensorPublisher.publish(msg);
seq++;
}
}
}
}
}
That is the code that calculates the illuminance in a very simple way. Basically, it just adds the values of all the pixels in the fov of the camera and then divides by the total number of pixels.
Create a proper CMakeLists.txt
Substitute the code of the automatically created CMakeLists.txt by the code below:
cmake_minimum_required(VERSION 2.8.3)
project(gazebo_light_sensor_plugin)
find_package(catkin REQUIRED COMPONENTS
gazebo_plugins
gazebo_ros
roscpp
)
find_package (gazebo REQUIRED)
catkin_package(
INCLUDE_DIRS include
CATKIN_DEPENDS gazebo_plugins gazebo_ros roscpp
)
###########
## Build ##
###########
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
link_directories(${GAZEBO_LIBRARY_DIRS})
include_directories(include)
include_directories( ${catkin_INCLUDE_DIRS}
${Boost_INCLUDE_DIR}
${GAZEBO_INCLUDE_DIRS}
)
add_library(${PROJECT_NAME} src/light_sensor_plugin.cpp)
## Specify libraries to link a library or executable target against
target_link_libraries( ${PROJECT_NAME} ${catkin_LIBRARIES} ${GAZEBO_LIBRARIES} CameraPlugin )
Update the package.xml and compile
Now you need to include the following line in your package.xml, between the tags <export></export>
<gazebo_ros plugin_path="${prefix}/lib" gazebo_media_path="${prefix}" />
Now you are ready to compile the plugin. Compilation should generate the library containing the plugin inside your building directory.
> roscd > cd .. > catkin_make
Testing the Plugin
Let’s create a world file containing the plugin and launch it to see how it works
Create a world file
You need a world file that includes the plugin. Here it is an example. Create a worlds directory inside your plugin package, and save the following code in a file entitled light.world. This world file just loads the camera with its plugin so it may be a bit ugly but enough for your tests. Feel free to add more elements and models in the world file (like for example, in the picture at the top of this post).
<?xml version="1.0" ?> <sdf version="1.4"> <world name="default"> <include> <uri>model://ground_plane</uri> </include> <include> <uri>model://sun</uri> </include> <!-- reference to your plugin --> <model name='camera'> <pose>0 -1 0.05 0 -0 0</pose> <link name='link'> <inertial> <mass>0.1</mass> <inertia> <ixx>1</ixx> <ixy>0</ixy> <ixz>0</ixz> <iyy>1</iyy> <iyz>0</iyz> <izz>1</izz> </inertia> </inertial> <collision name='collision'> <geometry> <box> <size>0.1 0.1 0.1</size> </box> </geometry> <max_contacts>10</max_contacts> <surface> <contact> <ode/> </contact> <bounce/> <friction> <ode/> </friction> </surface> </collision> <visual name='visual'> <geometry> <box> <size>0.1 0.1 0.1</size> </box> </geometry> </visual> <sensor name='camera' type='camera'> <camera name='__default__'> <horizontal_fov>1.047</horizontal_fov> <image> <width>320</width> <height>240</height> </image> <clip> <near>0.1</near> <far>100</far> </clip> </camera> <plugin name="gazebo_light_sensor_plugin" filename="libgazebo_light_sensor_plugin.so"> <cameraName>camera</cameraName> <alwaysOn>true</alwaysOn> <updateRate>10</updateRate> <imageTopicName>rgb/image_raw</imageTopicName> <depthImageTopicName>depth/image_raw</depthImageTopicName> <pointCloudTopicName>depth/points</pointCloudTopicName> <cameraInfoTopicName>rgb/camera_info</cameraInfoTopicName> <depthImageCameraInfoTopicName>depth/camera_info</depthImageCameraInfoTopicName> <frameName>camera_depth_optical_frame</frameName> <baseline>0.1</baseline> <distortion_k1>0.0</distortion_k1> <distortion_k2>0.0</distortion_k2> <distortion_k3>0.0</distortion_k3> <distortion_t1>0.0</distortion_t1> <distortion_t2>0.0</distortion_t2> <pointCloudCutoff>0.4</pointCloudCutoff> <robotNamespace>/</robotNamespace> </plugin> </sensor> <self_collide>0</self_collide> <kinematic>0</kinematic> <gravity>1</gravity> </link> </model> </world> </sdf>
Create a launch file
Now the final step, to create a launch that will upload everything for you. Save the following code as main.launch inside the launch directory of you package.
<launch> <!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched --> <include file="$(find gazebo_ros)/launch/empty_world.launch"> <arg name="verbose" value="true"/> <arg name="world_name" value="$(find gazebo_light_sensor_plugin)/worlds/light.world"/> <!-- more default parameters can be changed here --> </include> </launch>
Ready to run!
Now launch the world. Be sure that a roscore is running or your machine, and that the GAZEBO_PLUGIN_PATH environment var includes the path to the new plugin.
Now execute the following command:
roslaunch gazebo_light_sensor_plugin main.launch
You can see what the camera is observing by running the following command:
rosrun image_view image_view image:=/camera/rgb/image_raw
After running that command, a small window will appear in your screen showing what the camera is capturing. Of course, since your world is completely empty, you will only see something like as ugly as this:
Try to add some stuff in front of the camera and see how it is actually working.
Now it is time to check the value of illuminance by watching the published topic (/light_sensor_plugin/lightSensor). Just type the following and you are done:
rostopic echo /light_sensor_plugin/lightSensor
You should see the topic messages been published in your screen, something like this:
Conclusion
Now you have a plugin for your Gazebo simulations that can measure (very roughly) the light detected. It can be improved in many ways, but it serves as a starting point for understanding the complex world of plugins within Gazebo.
You can use it in you desktop Gazebo or even inside the ROS Development Studio. It is also independent of the ROS version you are using (just install the proper packages).
Hi users:
First of all thanks for the tutorial.
When I launch .launch file terminal says:
gzserver: symbol lookup error: /home/alcor/catkin_ws/devel/lib/libgazebo_light_sensor_plugin.so: undefined symbol: _ZN6gazebo20GazeboRosCameraUtilsC2Ev
[gazebo-2] process has died [pid 3163, exit code 255, cmd /home/alcor/catkin_ws/src/gazebo_light_sensor_plugin/scripts/run_gazebo /home/alcor/catkin_ws/src/gazebo_light_sensor_plugin/worlds/light.world __name:=gazebo __log:=/root/.ros/log/251944be-636a-11e5-af06-fcaa14787194/gazebo-2.log].
log file: /root/.ros/log/251944be-636a-11e5-af06-fcaa14787194/gazebo-2*.log
What am I doing wrong? or why does it happen?
Thanks a lot
Hi Alvaro, sorry for answering you so late.
Please follow the tutorial again with the updated code, since there were some errors in the code of the post that are now solved. Let me know if it works for you.
Does this package need to depend on `gazebo_plugins` also?
You are right Steve. Added to the post, thanks!
gzserver: symbol lookup error: /home/alcor/catkin_ws/devel/lib/libgazebo_light_sensor_plugin.so: undefined symbol: _ZN6gazebo20GazeboRosCameraUtilsC2Ev
[gazebo-2] process has died [pid 3163, exit code 255, cmd /home/david/catkin_ws/src/gazebo_light_sensor_plugin/scripts/run_gazebo /home/david/catkin_ws/src/gazebo_light_sensor_plugin/worlds/light.world __name:=gazebo __log:=/root/.ros/log/251944be-636a-11e5-af06-fcaa14787194/gazebo-2.log].
log file: /root/.ros/log/251944be-636a-11e5-af06-fcaa14787194/gazebo-2*.log
i have same error…
what should i do?
Hi Davidkim,
I have detected some errors in the code posted here. I have just updated the code and included extra information. Please follow again the tutorial and let me know if the error is solved.
i put light_sensor_plugin.h file in catkin_ws/src/gazebo_light_sensor_plugin/include/gazebo_light_sensor_plugin but when i catkin_make at catkin_ws. it said “cant find light_sensor_plugin.h”
so i tried put it in catkin_ws/src/gazebo_light_sensor_plugin/include again it said same..
i checked CMakelist.txt but it looks right because it wrote “include_directories(include)”
i cant find what is wrong.
Hi David,
the “light_sensor_plugin.h” file should be put inside “catkin_ws/src/gazebo_light_sensor_plugin/include/gazebo_light_sensor_plugin/” directory.
Now, once you have it there, check that your CMakeLists.txt contains this:
catkin_package(
INCLUDE_DIRS include
CATKIN_DEPENDS gazebo_plugins gazebo_ros roscpp
)
I think is that what you are missing.
Yeah, it is working now and i saw some messages from “rostopic ehco /camera/rgb/image_raw”
but 14.04 indigo version dont allow to use “rosrun image_view image_view image:=/camera/rgb/image_raw”
so…
i tried to see it on rviz but i cant see anything when i choose topic “camera/rgb/image_raw”
i cant see it on rviz?
Davidkim,
you should be able to use rosrun image_view image_view in Indigo without a problem, as well as rviz to display the camera.
Once launched the simulation, type the following:
> rostopic echo -n1 /camera/rgb/image_raw
A list of data should appear on the screen if everything goes ok. If that is correct, then you can use the rosrun image_view or rviz to watch the image
Thanks a lot for this tutorial. After three days for googling this is finally what worked.
Thank you Shikher for you support comments. Liked your page and projects about programming and robots. Would you mind to write a blog post for our blog sharing your experience with Gazebo, why you need it, how are you handling it, etc?
Sure. Will do it this weekend.
Hi, first thanks for this tutorial.
I faced a problem when using the roslaunch command :
“Invalid tag: gazebo_light_sensor_plugin
ROS path [0]=/opt/ros/kinetic/share/ros
ROS path [1]=/opt/ros/kinetic/share.
Arg xml is
The traceback for the exception was written to the log file”
I am pretty sure I followed all the previous steps carefully !
I then tried to launch gazebo manually using the command
“gazebo –verbose src/gazebo_light_sensor_plugin/worlds/light.world”
but received the error
“[FATAL] [1488156372.811166473]: You must call ros::init() before creating the first NodeHandle
Couldn’t find an AF_INET address for []
Couldn’t find an AF_INET address for []
[ERROR] [1488156372.834977386]: [registerPublisher] Failed to contact master at [:0]. Retrying…”
after regular connection to the gazebo master
I really do not know what to do now, thanks for your help.
Nevermind, problem solved, just got confused and sourced the wrong file, now it works perfectly !
Hi, first of all many thanks for the tutorial, it was really helpful for me.
I am rather new in ROS, and I am trying to use a depth camera plugin. This plugin is defined in the same way you describe in the tutorial, meaning that it is defined as a ROS package and have the proper CMakeLists.txt and package.xml files. I am wondering now how to use this plugin with a robot I have defined in another package.
I hope you can help me with this issue, thanks in advance.
I’m not sure if you solved this already
but, once you make your plugin, it becomes a binary file.
If it’s a ros package, then that file should be under
/{path to your catkin_ws}/devel/
By this, you can use that plugin from where ever you want. Just declare the plugin just like how this tutorial has, under the element.
Note: Make sure your plugin path is specified in the GAZEBO_PLUGIN_PATH variable.
does it work with indigo+gazebo7? Does it raise compatible problems due to API change?
Hi, first of all many thanks for the tutorial, it was really helpful for me.
I’m trying to create a sonar sensor plugin, in the first steps I utilized the files that already exist in the gazebo on the sonar sensor. However I do not know how to create the file URCMakeList.txt, I tried to change a few things, but an error occurs, so I would like to know how you created this file.
I hope you can help me, thanks in advance.
Hi Larissa,
we just took the default CMakeLists.txt that is generated automatically when you create a package with catkin_create_pkg and then modified accordingly with what we needed.
What I suggest you is that you have a look a the docs about CMakeLists.txt in the ROS wiki, here: http://wiki.ros.org/catkin/CMakeLists.txt
Then, also have a look at the plugins repository of Gazebo (here https://github.com/ros-simulation/gazebo_ros_pkgs) and check what other CMakeLists.txt contain.
Hello! Thanks a lot for the tutorial 🙂
I have a couple of questions with your code.
First, judging by the ‘for’ cycles, for me its no clear that you are adding all the pixels in the fov. I don’t understand what is happening with the StartingPix and the index variables. Can you please explain that to me? It would be very helpful.
Second, I strongly believe that the final result of ‘illuminance’ is not in ‘lux’ unit. This because the average of the pixel intensity is very different to a luminous flux incident on a surface. So I think that the final result should be called ‘Average pixel intensity’. If I’m wrong, can you please explain to me how did you manage to convert RGB values to lux units?
Much thanks for your work, it’s being very helpful, greetings!
Adding a little bit more:
It’s important to distinguish between the ‘Illuminance’ and the ‘Average pixel intensity’ results. This because, with the current code, if you put two boxes – one box at a time- in the same exact spot, with the same simulated lights, but one box black and the other box white, the current ‘Illuminance’ result will change. This is wrong, since the light in the fov haven’t changed. But if you specify that the result of the code is ‘Average pixel intensity’ then it makes sense.
Hi, thanks for this well-written tutorial.
Secondly, is it possible to do this in python?
Not that I’m aware
Hi, thanks for the tutorial. I am finding some problems when compiling the code with catkin_make. It says the following:
/home/mateo/catkin_ws/src/gazebo_light_sensor_plugin/src/light_sensor_plugin.cpp:67:54: error: ‘class gazebo::sensors::Sensor’ has no member named ‘GetLastUpdateTime’
this->sensor_update_time_ = this->parentSensor_->GetLastUpdateTime();
^
/home/mateo/catkin_ws/src/gazebo_light_sensor_plugin/src/light_sensor_plugin.cpp:79:47: error: ‘class gazebo::physics::World’ has no member named ‘GetSimTime’
common::Time cur_time = this->world_->GetSimTime();
^
gazebo_light_sensor_plugin/CMakeFiles/gazebo_light_sensor_plugin.dir/build.make:62: recipe for target ‘gazebo_light_sensor_plugin/CMakeFiles/gazebo_light_sensor_plugin.dir/src/light_sensor_plugin.cpp.o’ failed
Any idea on why is this happening?
You maybe use gazebo9.plaese change GetLastUpdateTime()to LastUpdateTime().And GetSimTime()to SimTime()
Hello. Is there any way to write gazebo plugins in python?
Not at present
Hi, thank you so much for the tutorial. It was a nice way to know more about the plugins.
I just have a comment, nothing big.
I was getting a warning about the GetLastUpdateTime function.
I’m not sure since which version but this seems to have been replaced by LastUpdateTime function.
Still works with the old one but I didn’t want the warning to come up each time I catkin_make it.
Yes you may be right. I did not check for the new version…
Take into account that I wrote that post for Gazebo 4 and now we are already at Gazebo 10!
The Gazebo guys usually change some things from version to version, and then the put as deprecated the old version. Deprecated means, the function is still there but it will be no longer available in future versions so you better migrate.
You can try to change by the new function and see if it works
There’s a bunch of html code in here and i’m not 100% sure i can cleanly decode it, would it be possible to paste the code in without the > etc?
Code cleared. Thanks for letting us know
Hi,
I am able to get the plugin to work, however it only actively publishes the illuminance while “rosrun image_view image_view image:=…” is running. Is it supposed to be like this?
Thanks.
Yes that is correct. This means that it will only publish when there is another program listening to the topic. That saves CPU
An outstanding share! I have just forwarded this onto a coworker who has been conducting a little homework on this.
And he actually bought me dinner because I found it for him…
lol. So allow me to reword this…. Thank YOU for the meal!!
But yeah, thanx for spending the time to discuss
this topic here on your internet site.
Thanks , I’ve recently been looking for info about this topic for
a while and yours is the best I’ve discovered so far.
However, what about the conclusion? Are you positive concerning the source?
you’re actually a excellent webmaster. The site loading pace is incredible.
It sort of feels that you’re doing any distinctive
trick. Also, The contents are masterwork. you’ve done a excellent activity in this matter!
When discussing responsive website design composition, most originators and
developers consider websites on cell phones, tablets,
and cell PCs. On a typical cell phone with a 3-by-four numeric
keypad, as an example, where no less than three letters are assigned to a number, you usually should punch via every key a
number of occasions to get one phrase on the display screen. For passable end result, feel free
to intake no less than one teaspoon of bee pollen each day.
Nowadays, individuals carry a digital camera, or a minimum of a
VGA phone, to take footage. Make your computer faster with
more reminiscence and take management of your
computer. They take up much less room on the countertop or
in the cabinet once they do get put away. Women get easily attracted in the direction of men who’re protecting and highly effective.
Who doesn’t like LED lights on their drum pads of their darkish studio at night?
How much space do you may have in your studio?
This design is incredible! You certainly know how to keep a reader entertained.
Between your wit and your videos, I was almost moved to
start my own blog (well, almost…HaHa!) Great job. I really loved
what you had to say, and more than that, how you presented it.
Too cool!
Hello, is there a chance that you could make an update for the tutorial, I’m triying to execute with Ubuntu 18.04, ROS melodic and gazebo9. It give me erros related to the code itself so my guess is that the syntaxis have changed.
Hey Jesus Yepez,
The syntaxis has changed a little. Briefly the functions you get the errors should be replaced with the same name but removing the “Get” at the beginning of the function name.
Have a look at this commit to see what changes. Note that I put a preprocessor directive to make the code compatible with ROS kinetic and melodic (I am using both).
I forgot to put the link haha
https://gitlab.com/monte-carlo-robots/brainiac/brainiac_simulator/-/commit/04e04ff5cf037386a8e6e0a81102796d94b8c1e7
Hi, first of all thank you for this tutorial. I followed your steps to build a personalized plugin to drive my robot with 3 wheel. I wrote the code and built successfully using catkin_make. When I tried to include the plugin into my robot model and then run a launch file that spawns the robot, I get an error message saying that This program was compiled against version 3.4.0 of the Protocol Buffer runtime library, which is not compatible with the installed version (3.6.1).
To make sure that this error is made by the added plugin , when I comment out the implementation of the plugin in the xacro file I no longer get this error.
Could you please help me with this ?
The Error message is: [libprotobuf FATAL google/protobuf/stubs/common.cc:79] This program was compiled against version 3.4.0 of the Protocol Buffer runtime library, which is not compatible with the installed version (3.6.1). Contact the program author for an update. If you compiled the program yourself, make sure that your headers are from the same version of Protocol Buffers as your link-time library. (Version verification failed in “google/protobuf/any.pb.cc”.)
terminate called after throwing an instance of ‘google::protobuf::FatalException’
what(): This program was compiled against version 3.4.0 of the Protocol Buffer runtime library, which is not compatible with the installed version (3.6.1). Contact the program author for an update. If you compiled the program yourself, make sure that your headers are from the same version of Protocol Buffers as your link-time library. (Version verification failed in “google/protobuf/any.pb.cc”.)
Note: I am using Gazebo11 and ros noetic (ubuntu 20.04)