robotology / wb-toolbox

Simulink toolbox to rapidly prototype robot controllers
https://robotology.github.io/wb-toolbox/
GNU Lesser General Public License v2.1
23 stars 16 forks source link

How to use multiple robot model with the same model name #193

Open lrapetti opened 4 years ago

lrapetti commented 4 years ago

Let's consider the case in which we want to use different robots, the urdf file name is set trough the Configuration block RobotName property. The urdf is then found inside the other blocks using yarp resource finder, which means in general we can et properly a `YARP_ROBOT_NAME so that the model is found.

e.g.

YARP_ROBOT_NAME=iCubGenova02
WBTConfigRobot_2.RobotName=model.urdf
$ yarp resource --find model.urdf
..
"/Users/..../robotology-superbuild/build/install/share/iCub/robots/iCubGenova02/model.urdf"

Now let's consider the case we want to use different robots with the same urdf file name model.urdf. We can set only a single env variable YARP_ROBOT_NAME, so we cannot use the two different robot models.

The workaround I have found is to define a RobotName with the model name path before and to add a path to the YARP_DATA_DIRS as follow:

YARP_DATA_DIRS=${YARP_DATA_DIRS}:/Users/..../robotology-superbuild/build/install/share/iCub/robots
WBTConfigRobot_1.RobotName=iCubGenova02/model.urdf
WBTConfigRobot_2.RobotName=iCubGenova04/model.urdf

I am wondering if there is a smarter way to do so, or if it make sense to add YARP_ROBOT_NAME to the WBToolbox config block.

DanielePucci commented 4 years ago

CC @diegoferigo

diegoferigo commented 4 years ago

Thanks for reporting @lrapetti. Currently the toolbox does not support directly setting the YARP_ROBOT_NAME environment variable as you found out.

In general, I don't like much to rely on YARP's ResourceFinder to find files in the operating system. It was historically done this way and we never changed since. There are some limitations and I think your use-case is one of them. The ResourceFinder uses this single-robot logic, maybe because it was designed with the usage on the real robot's workstations or laptop where experiments are executed targeting a single robot.

I fear that keeping the ResourceFinder as backend to find files, the best we can find are kind of cleaner workarounds, not really solutions. Do you only need to find the urdf file, or also other configuration that use the robot-specific folder? A workaround could be renaming one of the two files with something unique and save the symlink outside the inactive robot folder (one of the two, have a look to the documentation for specific searched folders).

For what regards the config block, is not straightforward. There's no standard library to set environment variables in a multiplatform application, and if we want to go towards this way, we have to develop one (it wouldn't be difficult but requires some testing). I thought that the ResourceFinder had APIs to change during runtime the robot folder but I was wrong, it can only read the active one. Unfortunately from this side the APIs are rather limited and even if we would get the path from the config block, it seems that we should anyway pass through the environment variable. @traversaro

traversaro commented 4 years ago

Related discussion on the YARP side: https://github.com/robotology/yarp/issues/593 .

There's no standard library to set environment variables in a multiplatform application, and if we want to go towards this way, we have to develop one (it wouldn't be difficult but requires some testing).

As long as we depend on YARP, there is https://www.yarp.it/classyarp_1_1os_1_1NetworkBase.html#aaa7fbc0bb3fe0d3b4f36f0f01f902b31 . On the MATLAB side, there is https://www.mathworks.com/help/matlab/ref/setenv.html that if I remember correctly in the past we used exactly to set the YARP_ROBOT_NAME . If we have a use case for which the env variable does not work fine (for example in the case of multithreading) I guess that a method such as ResourceFinder::setRobotName that overrides the value passed by YARP_ROBOT_NAME is probably a YARP modification that it could make sense to propose.

traversaro commented 4 years ago

As long as we depend on YARP, there is https://www.yarp.it/classyarp_1_1os_1_1NetworkBase.html#aaa7fbc0bb3fe0d3b4f36f0f01f902b31 . On the MATLAB side, there is https://www.mathworks.com/help/matlab/ref/setenv.html that if I remember correctly in the past we used exactly to set the YARP_ROBOT_NAME .

On this, the putenv/_putenv functions are also available on both *nix and on Windows.

diegoferigo commented 4 years ago

Good call, using NetworkBase::setEnvironment might speed up the implementation. At this point I think this is the fastest solution that could also help cleaning up the .m files of our controllers. The manually exported variable could be substituted by this new option of the config block. @gabrielenava do you see any problem from your side?

The changes are not straightforward but are not complicated:

  1. Modify the mask to add an optional new field.
  2. Update the +WBToolbox/Configuration class that stores the data of the config block.
  3. Update the helpers ConfigurationToMask.m and MaskToConfiguration.m.
  4. Update all the S-Functions of blocks with the new parameter (it can be done with just one for prototyping and then extend it to all the others).
  5. Extend the base::Configuration class to store the optional robot name.
  6. Parse the new parameter from the base::WBBlock base class. They are passed to the singleton that stores them here.
  7. Update base::WholeBodySingleton, in particular base::WholeBodySingleton::fillConfiguration and base::WholeBodySingleton::storeConfiguration.
  8. Get the robot name if it exists and export the variable before that ResourceFinder is used.

@lrapetti Would you like to help contributing with this modification? I'd be happy to guide you in the process if necessary.

lrapetti commented 4 years ago

Thanks @diegoferigo and @traversaro for the suggestions.

I can have a look and try to take care of the proposed steps, this modification should do it for my use case.

If we have a use case for which the env variable does not work fine (for example in the case of multithreading) I guess that a method such as ResourceFinder::setRobotName that overrides the value passed by YARP_ROBOT_NAME is probably a YARP modification that it could make sense to propose.

In the long run anyway I think this functionality might be interesting to have for multi-robots use case.

diegoferigo commented 4 years ago

Great, thanks @lrapetti! Let me know if you need anything.

In the long run anyway I think this functionality might be interesting to have for multi-robots use case.

I agree. In this specific case, changing the logic of wb-toolbox would be straightforward after the steps above will be implemented. It only affects the last step.

gabrielenava commented 4 years ago

@gabrielenava do you see any problem from your side?

from what I understood, if you are going to add a new option in the config block I guess we need to update all controllers configuration files, but the update should be easy. We can coordinate on this.

diegoferigo commented 4 years ago

Yes. I just want to double check if from matlab you use the YARP_ROBOT_NAME to get other files part of the YARP context of the robot beyond passing it to wb-toolbox.

gabrielenava commented 4 years ago

Yes. I just want to double check if from matlab you use the YARP_ROBOT_NAME to get other files part of the YARP context of the robot beyond passing it to wb-toolbox.

Not other files part of the YARP context. It is used only to locate the folder that contains the gains and other parameters for the selected robot. The associated code is here. Probably we need some modifications in this initialisation file, but this shouldn't be a blocking problem.