Gazebo | Ignition | Community
Ask Your Question

Inserting camera model programmatically

asked 2014-12-12 13:22:44 -0600

NickDP gravatar image

updated 2014-12-15 12:32:45 -0600

I want to be able to record a simulation in Gazebo. For this I use a camera model, as discussed in this question.

The following camera model works fine if I insert it from the Gazebo GUI or if I include it in a .world file. (The model is taken from the above question, with the only notable difference that I moved <save> element into the <camera> element, which appears to be necessary):

<?xml version="1.0" ?>
<sdf version="1.5">
  <model name="camera">
    <pose>4 -4 4 0 0.5 2.4</pose>
    <link name="link">
      <pose>0.05 0.05 0.05 0 0 0</pose>
      <visual name="visual">
            <size>0.1 0.1 0.1</size>
      <sensor name="camera" type="camera">
          <save enabled="true">

The problem

Now I want to be able to insert the model programmatically, when using Gazebo as a library.

I have created a minimum working example here: Pastebin

When I run this MWE I get a segmentation fault (after inserting the model, in the while loop where I wait for the model to show up). If I remove the <sensor> element, inserting the model is successful.

What am I doing wrong?

Thanks for your help.


Below is the backtrace from running the MWE:

Starting program: /home/nicolas/GazeboAgentCameraExample/build/main 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/".
[New Thread 0x7fffdd4c4700 (LWP 13481)]
[New Thread 0x7fffdccc3700 (LWP 13482)]
[New Thread 0x7fffdc4c2700 (LWP 13483)]
[New Thread 0x7fffdb3d3700 (LWP 13484)]
[New Thread 0x7fffd8dc4700 (LWP 13485)]
[New Thread 0x7fffd0a10700 (LWP 13486)]
[New Thread 0x7fffcbfff700 (LWP 13487)]
[New Thread 0x7fffcb7fe700 (LWP 13488)]
[New Thread 0x7fffcaffd700 (LWP 13489)]
Gazebo server setup successful
[New Thread 0x7fffca3c4700 (LWP 13490)]
[New Thread 0x7fffc9bc2700 (LWP 13492)]
[New Thread 0x7fffc9fc3700 (LWP 13491)]
[New Thread 0x7fffc97c1700 (LWP 13493)]
[New Thread 0x7fffc8fc0700 (LWP 13495)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffc97c1700 (LWP 13493)]
0x00007ffff1f93fa9 in gazebo::sensors::SensorFactory::NewSensor(std::string const&) () from /usr/lib/x86_64-linux-gnu/
(gdb) thread apply all bt

Thread 15 (Thread 0x7fffc8fc0700 (LWP 13495)):
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x00007ffff7b53efb in ?? () from /usr/lib/x86_64-linux-gnu/
#2  0x00007ffff7b4aec7 in gazebo::physics::World::LogWorker() () from /usr/lib/x86_64-linux-gnu/
#3  0x00007ffff4c45a4a in ?? () from /usr/lib/x86_64-linux-gnu/
#4  0x00007ffff7151182 in start_thread (arg=0x7fffc8fc0700) at pthread_create.c:312
#5  0x00007ffff6963efd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

Thread 14 (Thread 0x7fffc97c1700 (LWP 13493)):
#0  0x00007ffff1f93fa9 in gazebo::sensors::SensorFactory::NewSensor(std::string const&) () from /usr/lib/x86_64-linux-gnu/
#1  0x00007ffff1f96e67 in ...
edit retag flag offensive close merge delete


Can you get a backtrace from the segmentation fault? Let me know if you need more explanation than that link.

scpeters gravatar imagescpeters ( 2014-12-14 04:27:56 -0600 )edit

I edited the question to include the backtrace. Can you conclude anything from it?

NickDP gravatar imageNickDP ( 2014-12-15 11:26:27 -0600 )edit

I don't see the seg-fault in that portion of the backtrace. Can you try thread apply all bt and also paste the gdb error (ie. Program received signal SIGABRT, Aborted.)?

scpeters gravatar imagescpeters ( 2014-12-15 12:19:07 -0600 )edit

sorry about that. Hopefully now you can find what you're looking for.

NickDP gravatar imageNickDP ( 2014-12-15 12:34:57 -0600 )edit

Thanks, I'll take a look.

scpeters gravatar imagescpeters ( 2014-12-15 12:46:03 -0600 )edit

You might be missing some of the calls from Server::Run, such as sensors::run_once(true), and sensors::run_threads()

scpeters gravatar imagescpeters ( 2014-12-15 12:55:47 -0600 )edit

Interesting, do I have to call these myself? I would have expected setupServer() to take care of this kind of thing. If I add these two commands to my main after loading the world, I the model is loaded, i.e. I can see the box in the world. However, I can't see the camera visualization and there are no frames saved to /tmp/gazebo_frames.

NickDP gravatar imageNickDP ( 2014-12-15 13:20:16 -0600 )edit is our reference implementation; if it makes those calls, I would expect your program to need to do it as well. I cc'd some of my colleagues who may be able to provide more assistance.

scpeters gravatar imagescpeters ( 2014-12-15 14:00:53 -0600 )edit

1 Answer

Sort by ยป oldest newest most voted

answered 2014-12-16 09:56:54 -0600

nkoenig gravatar image

The following is a modified version of your code that should work. The key bit is running a sensor update loop. Sensors that rely on the rendering engine must be run in the main thread. This is a requirement of opengl.

I've create this issue to make it easier to use sensors and create a better example.

#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/sensors/sensors.hh>
#include <gazebo/common/common.hh>
#include <iostream>

int main(int _argc, char **_argv)
  // setup Gazebo server
    std::cout << "Gazebo server setup successful\n";
    std::cout << "Gazebo server setup failed!\n";

  gazebo::physics::WorldPtr world = gazebo::loadWorld("worlds/");

  // Start the Gazebo GUI
  system("gzclient &");

  std::string cameraString =
    "<?xml version='1.0' ?>"
       "<sdf version='1.5'>"
          "<model name='camera'>"
            "<pose>4 -4 4 0 0.5 2.4</pose>"
            "<link name=link>"
               "<visual name='visual'>"
                      "<size>0.1 0.1 0.1</size>"
                "<sensor name='camera' type='camera'>"
                      "<save enabled='true'>"

  // insert the camera
  int modelCountBefore = world->GetModelCount();
  int retry=0;
  while (world->GetModelCount() == modelCountBefore)
    if (retry>1000)

  if(world->GetModelCount() == modelCountBefore+1)
    std::cout << "Successfully inserted model.\n";
    std::cout << "Failed inserting model\n";


edit flag offensive delete link more


With this addition the example code works. However, in my actual application I still can't get it to work. I wrote a library that runs the Gazebo server and allows me to insert and manipulate models. In my main I have an instance of that class and go through some sample poses etc. So I can't have my main be stuck in this while loop. Am I understanding correctly that there is no way to move the sensor update into my library, for example in a callback to Events::ConnectWorldUpdateBegin?

NickDP gravatar imageNickDP ( 2014-12-16 13:24:50 -0600 )edit

Question Tools



Asked: 2014-12-12 13:22:44 -0600

Seen: 913 times

Last updated: Dec 16 '14