Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try to run two parallel simulations of a gz-sim-yarp-plugins-enabled robot #147

Closed
traversaro opened this issue Apr 5, 2024 · 8 comments · Fixed by #153
Closed

Try to run two parallel simulations of a gz-sim-yarp-plugins-enabled robot #147

traversaro opened this issue Apr 5, 2024 · 8 comments · Fixed by #153
Assignees

Comments

@traversaro
Copy link
Member

We can use the existing test infrastructure, and we should use a model without any nws as otherwise launching two different nws with the same ports will fail.

@xela-95
Copy link
Member

xela-95 commented Apr 11, 2024

Potential refactoring of singletons

While thinking on how to implement this issue, I continue to stumble upon the fact that I don't like the singletons we have for every plugin.

I try to explain the main points I have in mind:

  • The job of the singleton classes is the same for each plugin, resulting in a code duplication. The responsibility of these singletons is to contain a map of the sensor data structure, that in our code call with <sensor-type>Data, e.g.

    struct ForceTorqueData
    {
    std::mutex m_mutex;
    std::array<double, 6> m_data;
    std::string sensorScopedName;
    double simTime;
    };
    containing data specific to the sensor. But the singleton class itself is just a singleton thread-safe structure

  • The DeviceRegistry class is another a singleton class, this time containing a map of PolyDriver*. Here are contained pointers to every Driver class instantiated through gz-sim-yarp-plugins. Note that each Driver class has a member of <sensor-type>Data that is bound in the open method:

    m_sensorData
    = ::gzyarp::ForceTorqueDataSingleton::getHandler()->getSensor(sensorScopedName);
    , hence it can access the data of the sensor.

  • Until now the IDs of the singleton maps are:

    • for plugin singleton classes usually are the sensor scoped name (e.g. for a FT sensor it has the form of: model/force_torque_model/joint/joint_12/sensor/force_torque_sensor)
    • for the DeviceRegistry singleton class the Id is the same of the plugin singletons to which is appended the yarpDeviceName configuration parameter, which has to be unique for each Yarp device (e.g. for the FT sensor above it could be model/force_torque_model/joint/joint_12/sensor/force_torque_sensor/forcetorque_plugin_device).

    To address the current issue I want to add to the DeviceRegistry key also the memory address of the PolyDriver instance, resulting in something like 0x5f4e865a8df8/model/force_torque_model/joint/joint_12/sensor/force_torque_sensor/forcetorque_plugin_device, but in principle this Id could be used also as key in the map of the plugin singleton class.

This suspect of useless code duplication made me think to potential alternatives involving different levels of code refactoring:

  • refactor all the plugin singleton classes to a single class, but maintain a separation between DeviceRegistry and this other singleton;
  • maintain only DeviceRegistry class and refactor the plugins code to access plugin data from the Driver instance obtained from it. I think that we need at least one singleton class to have a DB of all the Drivers.

@traversaro what do you think about it? Do you have any other solutions in mind?

@traversaro
Copy link
Member Author

  • To address the current issue I want to add to the DeviceRegistry key also the memory address of the PolyDriver instance, resulting in something like 0x5f4e865a8df8/model/force_torque_model/joint/joint_12/sensor/force_torque_sensor/forcetorque_plugin_device, but in principle this Id could be used also as key in the map of the plugin singleton class.

How does the robotinterface plugin work in this case? If you use the PolyDriver pointer instead of the gz::sim::Server pointer, you can't use it to filter the devices that belong to a given gz server.

@xela-95
Copy link
Member

xela-95 commented Apr 11, 2024

  • To address the current issue I want to add to the DeviceRegistry key also the memory address of the PolyDriver instance, resulting in something like 0x5f4e865a8df8/model/force_torque_model/joint/joint_12/sensor/force_torque_sensor/forcetorque_plugin_device, but in principle this Id could be used also as key in the map of the plugin singleton class.

How does the robotinterface plugin work in this case? If you use the PolyDriver pointer instead of the gz::sim::Server pointer, you can't use it to filter the devices that belong to a given gz server.

Yes you're right, I got confused, it is the address of the server (or any other unique property of it) that has to be used to filter the plugins.

@xela-95
Copy link
Member

xela-95 commented Apr 15, 2024

I'm trying to find a way to get the pointer to the actual gz::sim::Server running a world, but until now I didn't found a viable option.

I report here some questions I found related to launching parallel Gazebo (classic) simulations:

@xela-95
Copy link
Member

xela-95 commented Apr 15, 2024

As an additional experiment I tried to launch from two terminals the same single pendulum world.

The result, as shown in the recording, is that by default the two Gazebo GUIs that open are simulating the same world. If I pause one simulations also the other pauses, so they're completely linked.

2024-04-15_14-48-46.mp4

@traversaro
Copy link
Member Author

I'm trying to find a way to get the pointer to the actual gz::sim::Server running a world, but until now I didn't found a viable option.

Probably we can use a pointer to another structure that is unique for every server, for example gz::sim::EntityComponentManager ? Note that then we will get the dual problem of getting the gz::sim::EntityComponentManager pointer given the gz::sim::Server pointer, however they may be workaround for this (see gazebosim/gz-sim#248).

@traversaro
Copy link
Member Author

By the way, apparently there is a test that tries to run two parallel servers, see https://github.com/gazebosim/gz-sim/blob/gz-sim8/test/integration/multiple_servers.cc .

@xela-95
Copy link
Member

xela-95 commented Apr 15, 2024

By the way, apparently there is a test that tries to run two parallel servers, see https://github.com/gazebosim/gz-sim/blob/gz-sim8/test/integration/multiple_servers.cc .

Yep and that is also similar to the test I've implemented in https://github.com/robotology/gz-sim-yarp-plugins/blob/f0d224658bd884cd8836a9eda798092ba7eea778/tests/controlboard/ControlBoardOnMultipleGazeboInstances.cc

This can be a sign that this could be accomplished.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants