Gazebo | Ignition | Community
Ask Your Question
2

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

http://gazebosim.org/tutorials?tut=gazebojs_install&cat=gazebojs

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.

visibility.cpp:

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());
  node->Init();

  // gztopic echo /gazebo/default/visual shows this 
  gazebo::transport::PublisherPtr pub =
      node->Advertise<gazebo::msgs::Visual>("~/visual");

  std::cout << "waiting for connection" << std::endl;
  pub->WaitForConnection();

  double transparency = 1.0;
  bool visible = true;

  gazebo::msgs::Visual msg; 
  msg.set_parent_name(parent_name);
  msg.set_name(name);
  std::cout << "parent " << parent_name << ", name " << name << std::endl;

  while (true)
  {
    msg.set_transparency(transparency);
    msg.set_visible(visible);
    //std::cout << "transparency " << transparency << std::endl;
    pub->Publish(msg);

    visible = !visible;
    transparency = 1.0 - transparency;

    sleep(2.0);
  }

  gazebo::shutdown();

  return 0;
}
edit retag flag offensive close merge delete

4 Answers

Sort by ยป oldest newest most voted
1

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

Comments

Is GazeboJS the quickest way to do that as described on http://gazebosim.org/tutorials?tut=gazebojs_pubsub&cat=gazebojs ?(python would be nice, I did see http://answers.gazebosim.org/question/19/publish-a-topic/ 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
1

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

Comments

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, https://bitbucket.org/osrf/gazebo/raw/default/examples/stand_alone/publisher can probably be adapted.

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

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

AchmadFathoni gravatar image

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

exodia_randomizer.hh

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

#ifndef GAZEBO_PLUGINS_RANDOMPLUGIN_HH_
#define GAZEBO_PLUGINS_RANDOMPLUGIN_HH_

#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{
        public:
            exodiaRandomSpawn();
            void Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf);
        private:       
            //ROS
            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;
    };
}

#endif

exodia_randomizer.cpp

/**
 * @file exodiaRandomSpawn.cpp
 * @author Achmad Fathoni (fathoni.id@gmail.com)
 * @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(
            "/toggle_invisible", 
            &exodiaRandomSpawn::toggleInvisibleCb, 
            this
        );
        node->Init();
        visPub = node->Advertise<msgs::Visual>("~/visual");
        visMsg.set_visible(true);
    }

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

        visMsg.set_visible(req.visible);

        for(auto link : parent->GetLinks()){
            std::string link_name = 
                parent->GetName()+"::"+link->GetName();
            ROS_INFO("%s", link_name.c_str());
            visMsg.set_parent_name(link_name);
            visMsg.set_parent_id(parent->GetId());
            visMsg.set_name(link_name+"::visual");
            visMsg.set_id(link->GetId());
            visPub->Publish(visMsg);
        }


        return true;
    };

    GZ_REGISTER_MODEL_PLUGIN(exodiaRandomSpawn)
}

toggleinvisible.srv

bool visible
----
edit flag offensive delete link more
0

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

Stats

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

Seen: 2,137 times

Last updated: Dec 20 '18