How to create Webots components - cyberbotics/AROSYS GitHub Wiki
Naming convention
It is important to be consistent with the name used for new components. It should always start with ComponentWebots
then add a clear name designing the function such as ComponentWebotsRGBCamera
. For systems, we recommend to use SystemWebots
following by the task done and the robot used such as SystemWebotsPathFollowingRobotino3
. A better convention would be to create name like this : System
+ Task
+ Robot
+ Simulator/RealWorld
since the system is created for one particular application and robots/simulators can be easily replaced.
Type of component
ComponentWebotsSensors
To explain the steps involved in the realization of a new sensor component for Webots, the ComponentWebotsLidar
will be used as an example.
1. Model composition
Step 1: Create a component
This step is carried out just like any other component.
- Open
SmartMDSD Toolchain v3.12
. - On the top right, there is an white rectangle with the letter C inside. Click on it and the Project explorer on the left will change.
- Select
File
>New
>Component Project (Tier 3)
. - Choose a name for the component respecting the convention. Here type
ComponentWebotsLidar
and click onNext
button. - Choose to add some SmartMDSD Model Types. The default checked box are sufficient for this example, so click on
Next
button. - Include in the component the communication objects you need. Select
CommBasicObjects
. Don't worry if you miss a communication object, you can still add it after. - Then, click on
Finish
button. The interface will change and open the model tab.
Step 2: Create the component model
When creating a component model, you have to find which inputs/outputs need to be implemented to stay consistent with all existing components. The aim is to match one of them with modifications to realize the same task. For this example, the SmartGazeboBaseServer
or SmartPioneerBaseServer
integrates directly the laser acquisition and transmission for ComponentLaserObstacleAvoid
. The ComponentWebotsLidar
's goal is to extract these functions and create a new component model.
This file is accessible from the Project explorer on the left. Open the model folder and unfold the file icon called ComponentWebotsLidar.component
. Double-click on the file to edit the Model
. Use the Palette on the right for the following instructions.
Note : If the Palette panel is not visible, there is a small triangle to open it in the top right corner of the window's tab.
- If you miss some communication objects when creating the component, click on
ImportDomainModels
and drag them into the window. Then, check the elements needed and click onOK
button. - Click on
Activity
from sub-menuActivity Tools
and drag it into the component box. Rename it as LaserTask by double-clicking on the activity or using theProperties
tab. - Click on
PeriodicTimer
from sub-menuActivity Tools
and drag it into the activity box. - Click on
InputPort
from sub-menuComponent Tools
and drag it into the component box. Select the right service for the input port which isForking Service Definition BaseStateService
. It serves to adjust the calculation coming from the lidar by setting its pose according to the robot. - Click on
OutputPort
from sub-menuComponent Tools
and drag it into the component box. Select the right service for the output port which isForking Service Definition LaserService
and then the activityLaserTask
to link them together. It serves to transmit lidar data to other components. - Click on
MandatoryInputLink
from sub-menuComponent Tools
and reliesLaserTask
's activity to the input portBaseStateServiceIn
. Go in theProperties
tab and checkOptional
option. - Save the file. The result is shown in the following figure.
2. Code implementation
Step 1: Generate the code
Search for the component you created and select it.
- Make a right-click on it and select
Build Configurations > Clean All
and click onOK
button. - Make a right-click on it and select
Run Code-Generation
. - Make a right-click on it and select
Build Configurations > Build Selected
and click onOK
button. - Normally it should build successfully since the code generated is the one from SmartSoft.
Step 2: Implementation
The code implementation is quite generic but requires adaptations for each case depending on the sensor being implemented. Some files are not modified at all, such as CompHandler.*
, SmartStateChangeHandler.*
and startstop-hooks.sh
.
-
CMakeLists.txt
You can copy all the code from here. -
ComponentWebotsLidarCore.hh
You can imitate the code from here. It serves to declare amutex
variable which serve to block the modifications of variables accessible everywhere in the component. The second variablewebotsRobot
serves to connect to the Webots robot to access at all parameters, values and functions. -
ComponentWebotsLidarCore.cc
You can copy the code from here which starts after the message printed. This portion of code serves to check if a robot's name is defined in order to connect the right robot to the right controller when it creates the robot's instance. -
LaserTask.hh
You can imitate the code from here. It serves for :- Include communication objects headers and Webots headers.
- Define some specific constant parameters.
- Define private variables and functions which are used for Webots, communicate between ports and to do some threading.
- Define public variables which are used througsh the execution of the program.
-
LaserTask.cc
You can have a look at the code from here. Some functions can be copied as it since they don't need to be modified : theconstructor
, thedestructor
,int activityName::on_exit()
andvoid activityName::runStep(webots::Robot *robot)
.-
int activityName::on_entry()
This function serves to configure the SmartSoft sensor's parameters using the Webots sensor's parameters because it is executed only at start. The part to modify according to the code mentionned above is in thefor
loop. Use the Webots documentation of the sensors you implement such as the Lidar's documentation which displays all the function available in parallel of the SmartSoft documentation. -
int activityName::on_execute()
This function serves to execute the components tasks following this order :- Wait until simulation step finished.
- Get and update data from port(s).
- Check if transmission(s) worked.
- Execute the task using the data received and compute command(s) or data.
- Send out the results through port(s).
- Make a simulation step.
-