The Generic YARP Module is a component model to easily develop software modules for robotics leveraging the YARP ecosystem (http://github.com/robotology/YARP).
It is developed under the European Project WALK-MAN: http://www.walk-man.eu/.
This is a simple tutorial about the use of a generic software architecture to implement a task that will be run on a robot.
Using the Generic YARP Module ( GYM from here on ) makes it standard and simpler writing a task; it also provides some built-in features that will be described in this tutorial.
The goal of this tutorial is to understand how to use the GYM. For further details about the implementation of the GYM please refer to the Doxygen documentation.
The GYM tutorial assumes some basic knowledge about:
- C++: the GYM supports only C++ language and it uses some features (like smart pointers ) from C++ 11.
- YARP (Yet Another Robot Platform): GYM is a piece of software built upon YARP. It can be seen as a "middleware" between YARP and the code of your module.
GYM is composed by two main components:
- a template class called generic_module / control_module derived from YARP RFModule that represents a low-rate thread used to supervise the life cycle of an internal control thread(described below).
- a class called generic_thread / control_thread derived from YARP RateThread that represents an high-rate control thread.
The generic module/thread are used for general purpose modules (e.g. perception modules); the control module/thread instead are used to control the robot.
In order to use the GYM you simply have to inherit from this two classes: in the image below you can see an overview of the GYM design when we define two classes called MyModule and MyThread respectively derived from generic_module (with MyThread class as template argument) and generic_thread.
As you can see MyModule inherits from generic_module a YARP Resource Finder , a YARP Param Helper and three YARP ports:
- A switch port(input) used to send commands related to the life cycle of the internal control thread:
- start: creates the control thread and starts it.
- stop: stops the control thread and kills it (delete all its resources).
- pause: suspends the control thread.
- resume: resumes the control thread.
- quit: same as stop; moreover it closes the module itself.
- A status port(output) that gives information about the control thread: alive or not alive.
- An rpc port(input/output) opened when the control thread starts and used for the communication with the Param Helper:
- help: help.
- save_params: saves the actual parameters configuration.
- set/get [param]: online sets/gets the value of the parameter passed as argument.
- [custom commands]: possibly you can define your own Param Helper commands in MyModule.
When using the GYM there are few constraints to keep in mind:
-
Constraint # 1 Only generic_thread / control_thread derived classes can be passed as a template argument of a generic_module / control_module.
-
Constraint # 2 You have to specify two mandatory parameters for the Resource Finder(as command line args or inside the .ini configuration file):
- thread_period: the period of the internal control thread in milliseconds (as an int).
- robot_name: the name of the robot (as a string).
Here you can find a simple example about the usage of the GYM.
GYM is a github repo, repo, and the tutorial example is inside the examples folder.
The tutorial example consists in a simple task implementation: control the position of the left arm joints in real-time.
Open 7 terminal:
On terminal # 1 start YARP name server
~$ yarpserver --write
On terminal # 2 start gazebo
~$ gazebo
Inside gazebo load the coman model you prefer.
On terminal # 3 run generic_tutorial executable
~$ generic_tutorial --from tutorial_configuration.ini
As you can see from the output of this terminal, the generic_tutorial founds the .ini file that you have specified through the resource finder command line param --from. Moreover it opens the switch and status ports specified in the image above.
Now the module is started, but for the moment the internal thread does not exist. We can monitor the life-cycle of the internal thread through the module status port:
on terminal # 4 monitor the status of the module in terms of the life-cycle of its internal control thread
~$ yarp read ... /generic_tutorial/module/status:o
On terminal # 5 start the internal control thread through the switch interface
~$ yarp write ... /generic_tutorial/switch:i
~$ >> start
Give the start command to the module make the internal thread starts, you can verify it looking at the output of terminal # 4. From terminal # 3 output you can see the initialization values of our parameters and all the yarp log messages about new open ports and devices.
The robot left arm is still idle: to make it move to the initial configuration give the "test_cmd"command to the generic_module command port:
on terminal # 6
~$ yarp write ... /generic_tutorial/command:i
~$ >> test_cmd
The robot left arm is moving to the configuration specified in the .ini file.
How to modify the position of the left arm joints in real-time? Let's use the Param Helper through the rpc port of the module:
on terminal # 7
~$ yarp rpc /generic_tutorial/rpc
~$ >> help
..... help output .....
~$ >> get left_arm
..... output of the left_arm actual joint configuration .....
~$ >> set left_arm -90 0 0 0 0 0 0
In this way we set the new configuration for the left arm joints.
To make the robot move to new configuration give the "test_cmd" command on terminal # 6
~$ >> test_cmd
While moving to a new configuration you can pause/resume the control thread using the switch interface on terminal # 5. You can also stop the module or quit it.
If you like the new parameters configuration, you can easily save it using the "save_params <filename[.ini]>" rpc command:
on terminal # 7
~$ >> save_params new_configuration.ini
If you want now you can repeat the test starting the generic_tutorial with this different initial configuration:
~$ generic_tutorial --from new_configuration.ini
To Install the Generic YARP Module library, it is recommended to use the robotology superbuild http://www.github.com/robotology-playground/robotology-superbuild
GYM will install two bash scripts that can generate a GYM skeleton for a generic or control module/thread:
- generate_GYM_generic_skeleton.sh <module_prefix> : will generate a skeleton for the generic module/thread.
- generate_GYM_control_skeleton.sh <module_prefix> : will generate a skeleton for the control module/thread.
This is an example on how to generate the generic GYM skeleton:
mkdir GYM_skeleton_example
cd GYM_skeleton_example
generate_GYM_generic_skeleton.sh GYM_skeleton_example
You will see this in your GYM_skeleton_example folder:
.
├── app
│ ├── CMakeLists.txt
│ └── conf
│ └── GYM_skeleton_example_initial_config.ini
├── CMakeLists.txt
├── include
│ ├── GYM_skeleton_example_constants.h
│ ├── GYM_skeleton_example_module.hpp
│ └── GYM_skeleton_example_thread.h
├── README.md
└── src
├── GYM_skeleton_example_main.cpp
└── GYM_skeleton_example_thread.cpp
4 directories, 9 files
The skeleton is ready for you, you just need to modify the empty GYM_skeleton_example_thread.cpp functions like: custom_init() , run() , etc.