ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

nitschej's profile - activity

2013-07-31 22:14:06 -0500 received badge  Famous Question (source)
2013-07-31 22:14:06 -0500 received badge  Notable Question (source)
2013-07-31 22:14:06 -0500 received badge  Popular Question (source)
2013-01-13 09:44:37 -0500 received badge  Taxonomist
2012-11-15 12:57:43 -0500 received badge  Famous Question (source)
2012-10-29 07:58:57 -0500 received badge  Famous Question (source)
2012-10-29 07:58:57 -0500 received badge  Notable Question (source)
2012-09-09 07:31:01 -0500 received badge  Notable Question (source)
2012-09-09 07:31:01 -0500 received badge  Popular Question (source)
2012-08-15 18:24:50 -0500 received badge  Famous Question (source)
2012-07-28 07:08:38 -0500 received badge  Popular Question (source)
2012-06-08 00:54:03 -0500 marked best answer How to spawn multiple nodes in same C++ process

Hello there,

I want to spawn multiple nodes within the same C++ process. To this end I used boost/thread. All seems to work, except that always one of the nodes is not showing up in 'rosnode list'. This is the code that runs the threads and creates the nodes:

static boost::mutex mutex;
static boost::once_flag cv_thread_flag = BOOST_ONCE_INIT;

void worker0(int argc, char* argv[]) {
    mutex.lock();
    ros::init(argc, argv, "optical_flow_visualization0");
    optical_flow_analyser::visualize::of_visualize vis("asdf", 0);
    mutex.unlock();
    ros::spin();
}

void worker1(int argc, char* argv[]) {
    mutex.lock();
    ros::init(argc, argv, "optical_flow_visualization1");
    optical_flow_analyser::visualize::of_visualize vis("asdf", 1);
    mutex.unlock();
    ros::spin();
}

int main(int argc, char* argv[]) {
    boost::call_once(cv_thread_flag, &cv::startWindowThread);
    boost::thread worker_thread_0(worker0, argc, argv);
    boost::thread worker_thread_1(worker1, argc, argv);
    worker_thread_0.join();
    worker_thread_1.join();
    return 0;
}

Sample output of 'rosnode list':

% rosnode list
/gazebo
/optical_flow_visualization1
(...)

The internal workings of the node consist of subscribing to some image_transport topics and displaying them with cv::imshow() in the callback function. As stated above this does indeed work as it should, but the fact that only one of the nodes is found by rosnode tells me that I might be doing something wrong here.

So I wonder: Is this a sane way of spawning multiple nodes? If not: how should I do it instead?

The background of this is that I want to process multiple camera streams from Gazebo, and I'd like to have it so, that I can flexibly spawn processing nodes, depending on how many camera streams there are.

2012-06-06 04:00:15 -0500 received badge  Good Question (source)
2012-03-28 06:34:33 -0500 received badge  Notable Question (source)
2012-02-21 12:45:43 -0500 received badge  Nice Question (source)
2011-12-08 01:26:59 -0500 received badge  Popular Question (source)
2011-11-03 00:29:57 -0500 asked a question Disable Gazebo texture blurring?

Gazebo is blurring textures at a certain distance from the camera. The transition from unblurred to blurred is actually quite hard and interferes with optical flow calculation.

Is there a way to disable this without recompiling Gazebo? I can actually live with all textures, even the very near ones, being blurred, as long as there is no visible transition.

2011-10-30 23:50:33 -0500 commented answer Gazebo camera timestamp issue
Ok, I'll try that. Btw. I wonder, doesn't lexical_cast actually use the ostream operator?
2011-10-26 19:14:05 -0500 commented answer Gazebo camera timestamp issue
I didn't know about that operator until now. But I checked it and it does not normalize the output stream.
2011-10-25 22:19:34 -0500 asked a question Gazebo camera timestamp issue

If I use a gazebo camera like this:

<sensor:camera name="camera1_sensor">
  <imageSize>160 160</imageSize>
  <controller:gazebo_ros_camera name="controller-cam1" plugin="libgazebo_ros_camera.so">
    <updateRate>20.0</updateRate>
    <imageTopicName>/gazebo/cam1</imageTopicName>
    <cameraInfoTopicName>/gazebo/cam1/info</cameraInfoTopicName>
  </controller:gazebo_ros_camera>
</sensor:camera>

The timestamps for full second N is actually output as N-1 + 1000000000ns. This leads to weird behavior, for example when using

boost::lexical_cast<std::string>(image_message1->header.stamp)

in a C++ application, as it produces the string "{N-1}.10" instead of the expected "{N}.00".
I assume that it is probably wrong to blindly use the lexical_cast on every datatype that comes along. And actually this is not a big issue, if you finally realize that it works that way.
But I wonder if this is the correct behavior/usage of ROS::Time? Can I expect other components that output ROS::Time tho behave in the same way and should I do it the same if I ever was to create a ROS::Time object?

2011-09-08 19:55:34 -0500 marked best answer Teleporting robot via 'rosservice call /gazebo/set_model_state' produces weird behaviour

Trying with the pioneer2dx_camera.world confirms that there is a bug with setting pose of nested models in diamondback and electric. The problem is due to a bug in the recursive updates in Entity.cc. Ticketed.

Current work around is to combine nested models into a single model. For example, pioneer2dx_camera.world becomes:

<?xml version="1.0"?>

<gazebo:world 
  xmlns:xi="http://www.w3.org/2001/XInclude"
  xmlns:gazebo="http://playerstage.sourceforge.net/gazebo/xmlschema/#gz" 
  xmlns:model="http://playerstage.sourceforge.net/gazebo/xmlschema/#model" 
  xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor" 
  xmlns:window="http://playerstage.sourceforge.net/gazebo/xmlschema/#window" 
  xmlns:param="http://playerstage.sourceforge.net/gazebo/xmlschema/#param" 
  xmlns:body="http://playerstage.sourceforge.net/gazebo/xmlschema/#body" 
  xmlns:geom="http://playerstage.sourceforge.net/gazebo/xmlschema/#geom" 
  xmlns:joint="http://playerstage.sourceforge.net/gazebo/xmlschema/#joint" 
  xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface" 
  xmlns:ui="http://playerstage.sourceforge.net/gazebo/xmlschema/#ui"
  xmlns:rendering="http://playerstage.sourceforge.net/gazebo/xmlschema/#rendering" 
  xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"
  xmlns:physics="http://playerstage.sourceforge.net/gazebo/xmlschema/#physics" >

  <verbosity>5</verbosity>

  <physics:ode>
    <stepTime>0.001</stepTime>
    <gravity>0 0 0</gravity>
    <cfm>0.0000000001</cfm>
    <erp>0.2</erp>

    <stepType>quick</stepType>
    <stepIters>100</stepIters>
    <stepW>1.3</stepW>
    <contactMaxCorrectingVel>100.0</contactMaxCorrectingVel>
    <contactSurfaceLayer>0.00</contactSurfaceLayer>
  </physics:ode>

  <rendering:gui>
    <type>fltk</type>
    <size>800 600</size>
    <updateRate>20</updateRate>
    <pos>0 0</pos>

    <frames>
      <row height="100%">
        <camera width="100%">
          <xyz>0.35 -0.5 0.43</xyz>
          <rpy>0 14 111.5</rpy>
        </camera>
      </row>
    </frames>
  </rendering:gui>

  <rendering:ogre>
    <ambient>0.5 0.5 0.5 1.0</ambient>
  </rendering:ogre>

   <!-- Ground Plane -->
  <model:physical name="plane1_model">
    <xyz>0 0 0</xyz>
    <rpy>0 0 0</rpy>
    <static>true</static>

    <body:plane name="plane1_body">
      <geom:plane name="plane1_geom">
        <normal>0 0 1</normal>
        <size>2000 2000</size>
        <segments>10 10</segments>
        <uvTile>100 100</uvTile>
        <material>Gazebo/Grey</material>
      </geom:plane>
    </body:plane>
  </model:physical>

  <model:physical name="cylinder1_model">
    <xyz>1 -1.5 0.5</xyz>
    <rpy>0.0 0.0 0.0</rpy>

    <body:cylinder name="cylinder1_body">
      <massMatrix>true</massMatrix> 
      <mass>1.0</mass>
      <ixx>0.01</ixx>
      <ixy>0.00</ixy>
      <ixz>0.00</ixz>
      <iyy>0.01</iyy>
      <iyz>0.00</iyz>
      <izz>0.01</izz>
      <cx>0.0</cx>
      <cy>0.0</cy>
      <cz>0.0</cz>
      <geom:cylinder name="cylinder1_geom">
        <size>0.5 1</size>
        <visual>
          <mesh>unit_cylinder</mesh>
          <material>Gazebo/RustyBarrel</material>
        </visual>
      </geom:cylinder>
    </body:cylinder>
  </model:physical>

  <model:physical name="pioneer2dx_model1">
    <xyz>0 0 0.148</xyz>
    <rpy>0.0 0.0 0.0</rpy>

  <body:box name="sonyvid30_body">
    <xyz>0.15 0.0 0.09</xyz>
    <rpy>0.0 0.0 0.0</rpy>

    <massMatrix>true</massMatrix> 
    <mass>0.1</mass>
    <ixx>0.01</ixx>
    <ixy>0.00</ixy>
    <ixz>0.00</ixz>
    <iyy>0.01</iyy>
    <iyz>0.00</iyz>
    <izz>0.01</izz>
    <cx>0.0</cx>
    <cy ...
(more)
2011-09-07 21:15:54 -0500 commented question Teleporting robot via 'rosservice call /gazebo/set_model_state' produces weird behaviour
No, visually it looks ok when paused. Parent and child model appear at the right spot instantly. But when unpausing again the behavior is all the same.
2011-09-07 19:41:42 -0500 commented answer Teleporting robot via 'rosservice call /gazebo/set_model_state' produces weird behaviour
Yes, all packages are up to date. Gazebo package version is 1.2.8-s1312465587~natty. As mentioned it only works if it is a compound model, try "rosrun gazebo gazebo `rospack find gazebo`/gazebo/share/gazebo/worlds/pioneer2dx_camera.world" instead. But don't forget to disable gravity.
2011-09-06 21:36:59 -0500 received badge  Editor (source)
2011-09-06 21:32:58 -0500 asked a question Teleporting robot via 'rosservice call /gazebo/set_model_state' produces weird behaviour

The problem appears with:

  • zero gravity worlds (<gravity>0 0 0</gravity>) OR models with gravity disabled (<enableGravity>false</enableGravity>)
  • AND models that use <attach> and <include> to include additional models (for example a pioneer2dx with attached sonyvid30)

What to do to make it happen: teleport your robot into some location above the ground, for example run

rosservice call /gazebo/set_model_state '{model_state: { model_name: pioneer2dx_model1, pose: { position: { x: 0, y: 0, z: .6 }, orientation: {x: 0, y: 0, z: 0, w: 0 } }, twist: { linear: {x: 0 , y: 0 ,z: 0 } , angular: { x: 0 , y: 0 , z: 0 } } }}'

What I would expect to happen: The robot appears in the specified location, peacefully floating there.

What actually happens: The robot does indeed appear in the specified location. But it is usually rotating wildly, sometimes also drifting away from its position

A good example is the pioneer2dx_camera.world which I think lives somewhere in most Gazebo installations. Just change the <gravity> specification to zero and try the rosservice call above.

The question is now: Is this a bug? Are there other workarounds known than to not use <attach> and <include> on models?

Edit: I actually use the Diamondback Ubuntu packages. So maybe this isn't relevant for newer versions.

An example, from the pioneer2dx_camera.world file, which shows the behavior :

<model:physical name="pioneer2dx_model1">
  <xyz>0 0 0.145</xyz>
  <rpy>0.0 0.0 0.0</rpy>
  <model:physical name="sonyvid30_model">
    <xyz>0.15 0 0.09</xyz>
    <attach>
      <parentBody>chassis_body</parentBody>
      <myBody>sonyvid30_body</myBody>
    </attach>
    <include embedded="true">
      <xi:include href="../models/sonyvid30.model" />
    </include>
  </model:physical>
  <include embedded="true">
    <xi:include href="../models/pioneer2dx.model" />
  </include>
</model:physical>

An example which does not show the behavior :

<model:physical name="pioneer2dx_model1">
  <xyz>1 1 0.145</xyz>
  <rpy>0.0 0.0 0.0</rpy>
  <include embedded="true">
    <xi:include href="../models/pioneer2dx.model" />
  </include>
</model:physical>

Any other models, that do not use the <attach>...</attach> + <include>...</include> tags are not affected, though I did not test all too many models. This is probably what you meant by "links".

Actually, when watching the "teleport operation" from a distance I can see what probably causes the spinning: The main body, for example the pioneer2dx_model1, appears at the new position instantly, but the attached body, for example the sonyvid30_model seems to remain at the old position for a very short time and then follows main body like it was attached with a rubber band or something the like. The ensuing impact then makes the robot spin and/or drift.

2011-08-31 20:58:45 -0500 received badge  Student (source)
2011-08-25 22:21:00 -0500 received badge  Supporter (source)
2011-08-25 22:20:38 -0500 marked best answer How to spawn multiple nodes in same C++ process

I think you don't need multiple nodes for your application. The main thing ros::init does is set the name and register the remappings.

You just need multiple topic descriptions and that works without a problem (you can remap topic names independent of the node name if you want).

2011-08-25 22:20:36 -0500 marked best answer How to spawn multiple nodes in same C++ process

I am surprised this seemed to work at all. I would not expect a single process to provide more than one node.

I recommend implementing each thread as a nodelet. They are well-supported and the nodelet manager can dynamically load additional threads for the process when needed.

Many camera drivers provide device nodelets, allowing you to display shared copies of the images published. The image pipeline also provides nodelets for similar reasons.