Gazebo | Ignition | Community
Ask Your Question
3

How to add a dynamic visual marker in gazebo?

asked 2013-06-28 11:04:16 -0500

rsquare gravatar image

I have a regular robot model in gazebo and i'd like to display some forces applied on a link for visualization and validation purposes. What would be the best way to do this?

I'm looking for something that would allow me to display a vector (coming from a ros topic) without interacting with the rest of the sim. Do I have to use a cylinder object? if so, how do I modify it dynamically?

I run gazebo 1.5 distributed with Ros-groovy in linux 12.04 lts.

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
1

answered 2017-01-31 10:36:03 -0500

nkoenig gravatar image

Visual markers have been added to gazebo8. Use gz marker -h for help.

edit flag offensive delete link more

Comments

Is there are way to update the markers efficiently? I need a marker that visualizes a vector every OnUpdate loop and it seems that node.Request("/marker", markerMsg); is super slow.

cosmictrex gravatar imagecosmictrex ( 2020-06-26 03:06:54 -0500 )edit

@cosmictrex Hi, did you find a solution to your problem?

rfn123 gravatar imagerfn123 ( 2020-12-21 06:01:02 -0500 )edit

@nkoenig Is there a way to make these visual markers appear in camera images?

ashwin5059198 gravatar imageashwin5059198 ( 2021-06-15 03:49:56 -0500 )edit
9

answered 2013-06-29 11:12:32 -0500

ffurrer gravatar image

You could add a visual plugin for that: briefly described here:

Add something like this in your model.sdf:

<link name="some_link">
    <visual name="some_visual">
        <plugin name="some_visual_plugin" filename="some_visual_plugin.so"/>
        <pose>0 0 0 0 0 0</pose>
        <geometry>
            <!-- your geometry -->
        </geometry>
    </visual>
    <....>
</link>

And then to add you would write a plugin as:

in some gazebo_visual_plugin.h:

#ifndef SOME_VISUAL_PLUGIN_H
#define SOME_VISUAL_PLUGIN_H

#include "gazebo/physics/physics.hh"
#include "gazebo/transport/TransportTypes.hh"
#include "gazebo/msgs/MessageTypes.hh"

#include "gazebo/common/Time.hh"
#include "gazebo/common/Plugin.hh"
#include "gazebo/common/Events.hh"

#include "gazebo/rendering/DynamicLines.hh"
#include "gazebo/rendering/RenderTypes.hh"
#include "gazebo/rendering/Visual.hh"
#include "gazebo/rendering/Scene.hh"

#include <ros/callback_queue.h>
#include <ros/advertise_options.h>
#include <ros/ros.h>

#include <geometry_msgs/Point.h>
// if you want some positions of the model use this....
#include <gazebo_msgs/ModelStates.h>

#include <boost/thread.hpp>
#include <boost/bind.hpp>


namespace gazebo
{
  namespace rendering
  {
    class SomeVisualPlugin : public VisualPlugin
    {
      public:
        /// \brief Constructor
        SomeVisualPlugin();

        /// \brief Destructor
        virtual ~SomeVisualPlugin();

        /// \brief Load the visual force plugin tags
        /// \param node XML config node
        void Load( VisualPtr _parent, sdf::ElementPtr _sdf );


      protected: 
        /// \brief Update the visual plugin
        virtual void UpdateChild();


      private:
        /// \brief pointer to ros node
        ros::NodeHandle* rosnode_;

        /// \brief store model name
        std::string model_name_;

        /// \brief topic name
        std::string topic_name_;

        // /// \brief The visual pointer used to visualize the force.
        VisualPtr visual_;

        // /// \brief The scene pointer.
        ScenePtr scene_;

        /// \brief For example a line to visualize the force
        DynamicLines *line;

        /// \brief for setting ROS name space
        std::string visual_namespace_;

        /// \Subscribe to some force
        ros::Subscriber force_sub_;

        /// \brief Visualize the force
        void VisualizeForceOnLink(const geometry_msgs::PointConstPtr &force_ms);

        // Pointer to the update event connection
        event::ConnectionPtr update_connection_;
    };
  }
}

#endif

and the gazebo_visual_plugin.cpp:

#include <test_pkg/gazebo_visual_plugin.h>

namespace gazebo
{
  namespace rendering
  {

    ////////////////////////////////////////////////////////////////////////////////
    // Constructor
    SomeVisualPlugin::SomeVisualPlugin(): 
      line(NULL),
    {

    }

    ////////////////////////////////////////////////////////////////////////////////
    // Destructor
    SomeVisualPlugin::~SomeVisualPlugin()
    {
      // Finalize the visualizer
      this->rosnode_->shutdown();
      delete this->rosnode_;
    }

    ////////////////////////////////////////////////////////////////////////////////
    // Load the plugin
    void SomeVisualPlugin::Load( VisualPtr _parent, sdf::ElementPtr _sdf )
    {
      this->visual_ = _parent;

      this->visual_namespace_ = "visual/";

      // start ros node
      if (!ros::isInitialized())
      {
        int argc = 0;
        char** argv = NULL;
        ros::init(argc,argv,"gazebo_visual",ros::init_options::NoSigintHandler|ros::init_options::AnonymousName);
      }

      this->rosnode_ = new ros::NodeHandle(this->visited_visual_namespace_);
      this->force_sub_ = this->rosnode_->subscribe("/some_force", 1000, &SomeVisualPlugin::VisualizeForceOnLink, this);

      // Listen to the update event. This event is broadcast every
      // simulation iteration.
      this->update_connection_ = event::Events::ConnectRender(
          boost::bind(&SomeVisualPlugin::UpdateChild, this));
    }

    //////////////////////////////////////////////////////////////////////////////////
    // Update the visualizer
    void SomeVisualPlugin::UpdateChild()
    {
      ros::spinOnce();
    }

    //////////////////////////////////////////////////////////////////////////////////
    // VisualizeForceOnLink
    void SomeVisualPlugin::VisualizeForceOnLink(const geometry_msgs::PointConstPtr &force_msg)
    {
      this->line = this->visual_->CreateDynamicLine(RENDERING_LINE_STRIP);

      //TODO: Get the current link position
      link_pose = CurrentLinkPose();
      //TODO: Get the current end position
      endpoint = CalculateEndpointOfForceVector(link_pose, force_msg);

      // Add two points to a connecting line strip from link_pose to endpoint
      this->line->AddPoint(
        math::Vector3(
          link_pose.position.x,
          link_pose.position.y,
          link_pose.position.z
          )
        );
      this->line->AddPoint(math::Vector3(endpoint.x, endpoint.y, endpoint.z));
      // set the Material of the line, in this case to purple
      this->line->setMaterial("Gazebo/Purple")
      this->line->setVisibilityFlags(GZ_VISIBILITY_GUI);
      this->visual_->SetVisible(true);
    }

    // Register this plugin within the simulator
    GZ_REGISTER_VISUAL_PLUGIN(SomeVisualPlugin)
  }
}

Didn't ... (more)

edit flag offensive delete link more

Comments

1

Thanks a lot! I had no idea there existed a DynamicLines class! I'll work on it and let you know how it goes.

rsquare gravatar imagersquare ( 2013-07-02 10:50:09 -0500 )edit

Thanks for this answer. May end up using this Template!

josephcoombe gravatar imagejosephcoombe ( 2018-05-03 08:32:42 -0500 )edit

Does it have to be done from a visual plugin? I have a plugin that gives me a ModelPtr, and the plugin computes and applies forces to it with AddForceAtRelativePosition. I would like to print those forces with DynamicLines, but I just don't manage to do it from that plugin... Even link->GetChild() only seems to give me the collision but not the visual...

jonesv gravatar imagejonesv ( 2021-03-04 17:00:53 -0500 )edit

I want to do the same thing actually. But I think it cannot be done. Because there are two different plugin, model plugin and visual plugin.

ismilesj gravatar imageismilesj ( 2021-09-08 10:08:14 -0500 )edit

Question Tools

7 followers

Stats

Asked: 2013-06-28 11:04:16 -0500

Seen: 14,948 times

Last updated: Jan 31 '17