Gazebo | Ignition | Community
Ask Your Question

Toggle visibility of a link?

asked 2014-12-05 11:47:11 -0500

updated 2015-01-06 17:34:30 -0500

Ideally I could publish a message from ROS that would set the transparency of a specified link to any value.

Would I have to write a custom plugin?

Pursuing the gazebojs approach:

This is using Gazebo 2.2.3

I've gone through

One note is that npm install installs node_modules to the current directory, I moved it to a better location and the require below is the relative path to it::

  var gazebojs = require('./npm/node_modules/gazebojs')
  var gazebo = new gazebojs.Gazebo()
  msg = { "parent_name" : "sensor_head", "name" : "sensor_head_rotation_link", "visible":false };
  gazebo.publish('gazebo.msgs.Visual', '~/Visual', msg);

But the link stays visible. Am I missing something else required to turn the visibility off? I assume leaving out all the optional fields except 'visible' in the protobuf is fine.

If I put garbage into the parent_name or name fields there are no errors. Am I using those fields incorrectly? In the World tab I see Model | sensor_head | sensor_head_rotation_link, the Property for clicking on that shows the name as sensor_head::sensor_head_rotation_link

(I have it correct above but if the msg has a problem it mostly results in an error that crashes node like::

  terminate called after throwing an instance of 'j2pb_error'
    what():  Unknown field: visibility
    Aborted (core dumped)


Pursuing the C++ Approach:

If I use the following code, launch gazebo and create a box called unitbox1, running ./visibility unit_box_1 link still doesn't produce any visual changes.


int main(int argn, char** argv)
  gazebo::setupClient(argn, argv);

  std::string name = "sensor_head_rotation_link";
  std::string parent_name = "sensor_head";

  if (argn >= 3)
    parent_name = argv[1];
    name = argv[2];

  gazebo::transport::NodePtr node(new gazebo::transport::Node());

  // gztopic echo /gazebo/default/visual shows this 
  gazebo::transport::PublisherPtr pub =

  std::cout << "waiting for connection" << std::endl;

  double transparency = 1.0;
  bool visible = true;

  gazebo::msgs::Visual msg; 
  std::cout << "parent " << parent_name << ", name " << name << std::endl;

  while (true)
    //std::cout << "transparency " << transparency << std::endl;

    visible = !visible;
    transparency = 1.0 - transparency;



  return 0;
edit retag flag offensive close merge delete

4 Answers

Sort by ยป oldest newest most voted

answered 2014-12-05 16:35:23 -0500

nkoenig gravatar image

You can use Gazebo's transport mechanism to publish a visual message to toggle visibility.

Topic: ~/visual

Message Type: gazebo::msgs::Visual

edit flag offensive delete link more


Is GazeboJS the quickest way to do that as described on ?(python would be nice, I did see but it looks inferior)

Lucas Walter gravatar imageLucas Walter ( 2014-12-05 16:56:08 -0500 )edit

gazebojs would work, or you'd can use the gazebo transport mechansim in a C program.

nkoenig gravatar imagenkoenig ( 2014-12-08 09:39:50 -0500 )edit

I've updated the question above with problems encountered in the gazebojs appraoch.

Lucas Walter gravatar imageLucas Walter ( 2014-12-19 14:52:08 -0500 )edit

The field is called visible, not visibility. See the visual.proto API here

scpeters gravatar imagescpeters ( 2014-12-30 13:13:54 -0500 )edit

Yes, as already noted the wrong field name crashes it, the correct name doesn't crash but didn't produce a visual change.

Lucas Walter gravatar imageLucas Walter ( 2014-12-30 18:01:09 -0500 )edit

I tried out the publishing to ~/visual in a C++ program and could not get a a change to visibility with either visible or transparency. The code is in the updated description above.

Lucas Walter gravatar imageLucas Walter ( 2015-01-06 17:38:09 -0500 )edit

answered 2014-12-30 18:22:08 -0500

scpeters gravatar image

Try setting the transparency field to 0.0 to make it not visible or 1.0 to make it visible. I have used this successfully before (see DRCVehiclePlugin). Note that I did set both the name and parent name.

edit flag offensive delete link more


Have you tried the GazeboJS method? Transparency doesn't work for me either.

Lucas Walter gravatar imageLucas Walter ( 2015-01-06 15:16:19 -0500 )edit

If C/C++ is the only method that works I'll try that out, can probably be adapted.

Lucas Walter gravatar imageLucas Walter ( 2015-01-06 15:16:40 -0500 )edit

answered 2018-12-18 17:53:54 -0500

AchmadFathoni gravatar image

updated 2018-12-20 08:27:25 -0500


 * @file RandomSpawn.hh
 * @author Achmad Fathoni (
 * @brief Spawn model at random pose inside box
 * @version 0.1
 * @date 2018-11-20
 * @copyright Copyright (c) 2018


#include "gazebo/gazebo.hh"
#include "gazebo/physics/physics.hh"

#include <chrono>
#include <random>
#include <thread>

#include "ros/ros.h"

#include <std_srvs/Empty.h>
#include <exodia_gazebo/toggleInvisible.h>

namespace gazebo{
    class GAZEBO_VISIBLE exodiaRandomSpawn : public ModelPlugin{
            void Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf);
            ros::NodeHandle n;

            ros::ServiceServer toggleInvisible;
            bool toggleInvisibleCb(
                exodia_gazebo::toggleInvisible::Request &req,
                exodia_gazebo::toggleInvisible::Response &res
            physics::ModelPtr parent;

            transport::PublisherPtr visPub;
            transport::NodePtr node;
            msgs::Visual visMsg;



 * @file exodiaRandomSpawn.cpp
 * @author Achmad Fathoni (
 * @brief 
 * @version 0.1
 * @date 2018-12-20
 * @copyright Copyright (c) 2018
#include "gazebo_plugins/exodiaRandomSpawn.hh"

namespace gazebo{
    exodiaRandomSpawn::exodiaRandomSpawn():node(new transport::Node())
        ROS_INFO("Activate invisiblitiy");

    void exodiaRandomSpawn::Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf){
        parent = _parent;
        ROS_INFO("Activate invisiblitiy");
        toggleInvisible = n.advertiseService(
        visPub = node->Advertise<msgs::Visual>("~/visual");

    bool exodiaRandomSpawn::toggleInvisibleCb(
        exodia_gazebo::toggleInvisible::Request &req,
        exodia_gazebo::toggleInvisible::Response &res


        for(auto link : parent->GetLinks()){
            std::string link_name = 
            ROS_INFO("%s", link_name.c_str());

        return true;



bool visible
edit flag offensive delete link more

answered 2016-07-01 07:05:00 -0500

MhAyman gravatar image

updated 2016-07-01 07:05:52 -0500

this answer might be a bit late, but in case anyone else had the same problem with the 'gazebojs' approach,

var gazebojs = require('./npm/node_modules/gazebojs')
  var gazebo = new gazebojs.Gazebo()
  msg = { "parent_name" : "sensor_head", "name" : "sensor_head_rotation_link", "visible":false };
  gazebo.publish('gazebo.msgs.Visual', '~/Visual', msg);

this script wont work unless it is run from the terminal, Or if you did insert a timeout for example to make it looks like this

var gazebojs = require("gazebojs");
var gazebo = new gazebojs.Gazebo();
setTimeout(()=> {
    gazebo.publish("gazebo.msgs.WorldControl", "~/world_control", { reset: { all: true } });
}, 1000);

This script would work just fine.

this is currently a problem with gazebojs, and it hasn't been solved yet.

edit flag offensive delete link more
Login/Signup to Answer

Question Tools

1 follower


Asked: 2014-12-05 11:47:11 -0500

Seen: 2,137 times

Last updated: Dec 20 '18