RTAI-ROS documentation¶
Requirements¶
For code generation only RTAI-ROS
is required.
To compile and run the generated program it requires:
- RTAI (tested with v4.0)
- ROS (tested with Hydro)
For the development version (> 1.0):
- libpopt for command line parsing (on Ubuntu it named
libpopt-dev
)
Installation¶
Copy the
rtairos
directory to$(MATLABROOT)/rtw/c/
, where$(MATLABROOT)
is the root of your Matlab installation.In Matlab change to
rtairos
directory and runsetup
>> matlabroot ans = /opt/matlab >> cd /opt/matlab/rtw/c/rtairos >> setup
This compiles all S-Functions of RTAI-ROS and adds the devices subdirectory to the search path. Make sure you have write permissions on
rtairos
.In
rtairos.tmf
change the variablesMATLAB_ROOT
,LINUX_HOME
,RTAIDIR
,COMEDI_HOME
, andROS_HOME
to your needs. Be sure to set it for the target system where you want to compile your code.- During code generation the variable
|>MATLAB_ROOT<|
will be expanded by the TLC to the Matlab installation directory. On a linux system this is normally/opt/matlab
(sometimes/usr/local/matlab
). - You can leave the variables
LINUX_HOME
,RTAIDIR
, andCOMEDI_HOME
unchanged ifrtai-config
is in the search path and can be found during build.
If you use Windows for code generation remove also the following lines:
|>START_EXPAND_RULES<|%.o : |>EXPAND_DIR_NAME<|/%.c gcc -c $(CFLAGS) $< |>END_EXPAND_RULES<|
- During code generation the variable
Uninstallation¶
To uninstall just remove the rtairos
directory. Matlab normally removes invalid directories from search path.
To remove the rtairos
directory manually from search path, run
>> rmpath $(MATLABROOT)/rtw/c/rtairos
Usage¶
The usage of RTAI-ROS will be explained using the example examples/rosdemo.mdl
.
Generate code¶
- Open your Simulink model, in our case
rosdemo.mdl
. - Open the configuration dialog Simulation → Configuration Parameters → Real-Time Workshop and select
rtairos.tlc
as System target file. If you don’t want to compile the code, select also Generate code only. - Click on Generate code. This creates the subdirectory
rosdemo_rtairos
in your current directory containig the generated source code. - Copy the directory
rosdemo_rtairos
to your RTAI Linux system.
Build¶
Change to the source directory
rosdemo_rtairos
. If you generated your code on a Windows system create a symbolic link to the make file:ln -s rosdemo.mk Makefile
Build the program:
make
Run¶
Start the ROS master:
roscore &
Set the
ROS_MASTER_URI
environment variable:export ROS_MASTER_URI=http://localhost:11311
Start the demo:
../rosdemo
Connect with ROS¶
Now you can connect to the running program using ROS, e.g:
Show all registered topics and services:
rosnode info /rosdemo
Read from topic:
rostopic echo /demo/uy
Write to topic:
rostopic pub -1 /demo/v std_msgs/Float64 2
Read all parameters of the model from parameter server:
rosparam get /rosdemo
This will give you the following output:
Config: {P1: 10.0, P3: 1.0, P4: 1.0, P5: 3.0} Constant: {Value: 1.0} Environment_Controller: Switch_Control: {Value: 0.0} Environment_Controller1: Switch_Control: {Value: 0.0} Integrator: {InitialCondition: 0.0} Log: {P1: 2.0, P3: 0.0} Publisher: {P1: 4.0, P3: -1.0} Publisher1: {P1: 1.0, P3: -1.0} Publisher2: {P1: 5.0, P3: -1.0} Publisher3: {P1: 1.0, P3: -1.0} Publisher4: {P1: 1.0, P3: -1.0} Publisher5: {P1: 1.0, P3: -1.0} Publisher6: {P1: 2.0, P3: -1.0} Pulse_Generator: {Amplitude: 1.0, Period: 10000.0, PulseWidth: 5000.0} Repeating_Sequence: Look_Up_Table1: InputValues: [0.0, 2.0, 4.0, 6.0] Table: [0.0, 2.0, 2.0, 0.0] Service: {P2: -1.0} Service1: {P2: -1.0} Subscriber: {P1: 1.0, P3: 1.0, P4: -1.0, P5: 0.0} Subscriber1: {P1: 1.0, P3: 0.0, P4: -1.0, P5: 0.0}
Change the parameters of the square wave signal:
rosparam set /rosdemo/Pulse_Generator '{Amplitude: 0.5, Period: 5000, PulseWidth: 2500}' rosservice call /rosdemo/set_parameters
Set source to trapezoidal signal:
rosservice call /demo/trapezoid
Instead of using command line tools you can use rqt, check examples/rosdemo.perspective
for a demo perspective.
Special services¶
The ROS node provides up to three special services:
/rosdemo/refresh_parameters
to write model parameters to the parameter server. This can be avoided via config block./rosdemo/set_parameters
to write modified parameters on the parameter server to the model. This can be set via config block./rosdemo/start
to start the real-time process if the program was started with-w
.
Parameters¶
There are various arguments for the program which can be shown by
../rosdemo -h
The generated program supports also parameter mapping
../rosdemo name:=new_name
To run multiple programs on the same machine it is required to set the name of the host interface task (default IFTASK
) with
../rosdemo -n TASK2
to avoid conflicts.
The number of blocks useable on a machine is restricted by the number of registrable RTAI objects set during the installation of RTAI.
You can read this number from MAX_SLOTS
in /proc/rtai/name
.
For the moment every block requires two RTAI objects, one for the shared memory and one for the semaphore.
Blocks¶
Following blocks are available to connect with ROS.
Publisher/Subscriber to read/write topics.
Available message types:
- std_msg/Bool
- std_msg/Int32
- std_msg/Float64
- std_msg/Float64MultiArray
- std_msg/Time
- geometry_msgs/Point
- geometry_msgs/PointStamped
- geometry_msgs/Twist
- geometry_msgs/TwistStamped
- geometry_msgs/Pose2D
Service to make a service call with request and reply message of type
std_msg/Empty
.Transformation publisher to publish tf messages.
Joint state publisher to publish joints.
Joystick subscriber to read from joy node.
Config to configure following parameters of the ROS node:
- Rate (default: 100 ms)
- Namespace (default: none)
- Publisher queue size (default: 10)
- Subscriber queue size (default: 10)
- If parameters should be exposed to parameter server and can be changed with
/NODE/set_parameters
(default: read only).
Logger to send a log message triggert by a raising edge.
There are additional blocks to read a Sensoray s526 counter and write to a RTAI-FIFO. All other blocks are taken from RTAI-Lab.
Advanced usage¶
Extend own S-Function¶
The following code shows the base structure to add log functionality to your own S-Function:
#ifndef MATLAB_MEX_FILE
#include <ros_block.h>
#endif
static void mdlInitializeSizes(SimStruct *S) {
ssSetNumIWork(S, 1);
ssSetNumPWork(S, 2);
}
#define MDL_START
static void mdlStart(SimStruct *S) {
#ifndef MATLAB_MEX_FILE
rosBlockInitResult_t block = registerRosBlock(S, "rosout", LOGGER, 0);
block.shm->msg.level = LOG_ERROR;
ssSetIWorkValue(S, 0, block.num);
ssSetPWorkValue(S, 0, (void *)block.shm);
ssSetPWorkValue(S, 1, (void *)block.sem);
#endif
}
static void mdlOutputs(SimStruct *S, int_T tid) {
#ifndef MATLAB_MEX_FILE
rosShmData_t *shm = (rosShmData_t *)ssGetPWorkValue(S, 0);
SEM *sem = (SEM *)ssGetPWorkValue(S, 1);
if (error) {
if (rt_sem_wait_if(sem) != 0) {
memcpy(shm->msg.text, "Error occurred", MAX_LOG_MSG_SIZE);
shm->msg.state = NEW_VALUE;
rt_sem_signal(sem);
}
}
#endif
}
static void mdlTerminate(SimStruct *S) {
#ifndef MATLAB_MEX_FILE
cleanRosBlock(ssGetIWorkValue(S, 0));
#endif
}
Add own message types¶
For the moment this requires to change the source code.
The necessary steps are shown using geometry_msgs/Vector3
as an example.
In
include/ros_defines.h
add a new preprocessor variable, e.g.:#define PUBLISHER_VECTOR3 42 // or #define SUBSCRIBER_VECTOR3 42
Include the header file in
rtmain.cpp
:#undef RT #include <geometry_msgs/Vector3.h> #define RT
For a publisher add a new case to class
RosPublisher
:void publish() { ... } else if (subType == PUBLISHER_VECTOR3) { geometry_msgs::Vector3 msg; msg.x = shmData.data[0]; msg.y = shmData.data[1]; msg.z = shmData.data[2]; pub.publish(msg); } }
For a subscriber add a new callback function to
RosSubscriber
:void callback(const geometry_msgs::Vector3 msg) { if (!this->sem_wait()) return; shm->data[0] = msg.x; shm->data[1] = msg.y; shm->data[2] = msg.z; this->sem_signal(); }
In function
rosInterface()
add an initialization block:// Subscribers } else if (rosBlockConfigs[i].type == SUBSCRIBER) { ... } else if (subscriber->subType == SUBSCRIBER_VECTOR3) { subscriber->sub = nh.subscribe<geometry_msgs::Vector3>(subscriber->name, rosConfig.subStackSize, &RosSubscriber::callback, subscriber); // Publishers } else if (rosBlockConfigs[i].type == PUBLISHER) { ... } else if (publisher->subType == PUBLISHER_VECTOR3) { publisher->pub = nh.advertise<geometry_msgs::Vector3>(publisher->name, rosConfig.pubStackSize);
Files¶
ros_block.c
: Helper functions used by ROS blocksrtairos_genfiles.tlc
: Additional script for the Target Language Compiler; creates the symbolic link on unix systems.rtairos.tlc
: Main script for the Target Language Compilerrtairos.tmf
: Makefile templatertmain.cpp
: Main programsetup.m
: Matlab installation scriptdevices/
rtairos.mdl
: Simulink library- S-Functions for Comedi:
sfun_comedi_counter_read.c
: Read countersfun_comedi_data_read.c
: Read analog inputsfun_comedi_data_write.c
: Write analog outputsfun_comedi_dio_read.c
: Read digital inputsfun_comedi_dio_write.c
: Write digital output
sfun_rtai_fifo.c
: S-Function to write FIFOs- S-Functions for ROS:
sfun_ros_config.c
: Config blocksfun_ros_joint_state.c
: Joint state publishersfun_ros_joy.c
: Joystick subscribersfun_ros_log.c
: Loggersfun_ros_publisher.c
: Publishersfun_ros_service.c
: Servicesfun_ros_subscriber.c
: Subscribersfun_ros_tf.c
: Transformation publisher
- S-Functions for RTAI-Lab (see RTAI-Lab documentation):
sfun_rtai_automatic_log.c
sfun_rtai_led.c
sfun_rtai_log.c
sfun_rtai_meter.c
sfun_rtai_scope.c
sfun_rtai_synchronoscope.c
slblocks.m
: Configuration of the simulink library
examples/
rtaitest.mdl
: RTAI-Lab examplerosdemo.mdl
: Example model; see Usagerosdemo.perspective
: A example perspective for rqt.
include/
ros_block.h
: Helper functions used by ROS blocksros_defines.h
: Defines and structs used by the main program and blocks.