Main Content

Generate a Standalone ROS Node from MATLAB®

This example shows how to generate C++ code for a standalone ROS node from a MATLAB function. It then shows how to build and run the ROS node on a Windows® machine.

Prerequisites

  • This example requires MATLAB Coder™.

  • A Ubuntu Linux system with ROS and an SSH server installed is necessary for building and running the generated C++ code. You can use your own Ubuntu ROS system, or you can use the Linux virtual machine for ROS Toolbox examples (see Get Started with Gazebo and a Simulated TurtleBot for instructions).

  • You must have access to a C/C++ compiler that is configured properly. You can use mex -setup cpp to view and change the default compiler. For more details, see Change Default Compiler.

Control a ROS-Enabled Robot with a Function

Open the function robotROSFeedbackControl, which contains a proportional controller introduced in the Feedback Control of a ROS-Enabled Robot example. This function subscribes to the /odom topic to get the current odometry status of the robot, and then publishes the output of a proportional controller as a geometry_msgs/Twist message to the /cmd_vel topic. Doing so provides the control commands for the robot to move towards the desired position.

Copy the robotROSFeedbackControl function to your local directory and change the defaultDesiredPos variable to the desired coordinates.

Start an a Gazebo Empty World from the Linux virtual machine by opening the Gazebo Empty application on the desktop. In the Linux virtual machine for ROS Toolbox, the robot is located at the [0,0] location by default.

Run the following commands to create a MATLAB ROS node in the same ROS network as the virtual machine. Verify if you observe the same ROS nodes as shown below.

d = rosdevice;
rosinit(d.DeviceAddress)
rosnode list

Run the controller and observe that the robot is moving towards the published destination. At the same time, observe the trajectory of the robot that shows up in a MATLAB figure. Keep this figure open to compare the behavior of MATLAB execution and the generated executable node.

robotROSFeedbackControl

You can change the desired destination while the robot is moving. To do so, open a new terminal from the virtual machine, source the ROS repository, and publish the new destination coordinates in the form of a std_msgs/Float64MultiArray message to the /dest topic.

~$ source /opt/ros/melodic/local_setup.bash
~$ rostopic pub -1 /dest std_msgs/Float64MultiArray "{data:[0,0]}"

You can terminate the controller any time using Ctrl-C or typing in the following command in the terminal from the virtual machine. Note that if you open a new terminal in the virtual machine, you must source the ROS repository.

~$ rostopic pub -1 /stop std_msgs/Bool "1"

You can also tweak the distanceThre, linearVelocity, and rotationGain values in robotROSFeedbackControl.m to obtain the desired robot behavior. For the proportional controller in this example, the following parameter ranges provide robust performance. Alternatively, you can replace the proportional controller with a custom controller for performance comparison.

distanceThre: 0<x<1
linearVelocity: 0<x<3
rotationGain: 0<x<6

To observe the behavior, reset the robot on the virtual machine by pressing Ctrl-R in Gazebo.

Create a Function for Code Generation

To generate a standalone C++ node, modify the function to make it compatible for code generation.

  • Because objects do not support code generation, replace them with structs for rospublisher, rossubscriber, and rosmessage. Specify the name-value pair "DataFormat","struct" in the respective function calls to create them as structures.

  • Save the modified MATLAB function to robotROSFeedbackControlCodegen.m. Ensure any other modifications that you made in robotROSFeedbackControl function are reflected in robotROSFeedbackControlCodegen.

Generate Executable for robotROSFeedbackControlCodegen

Generate an executable node for the robotROSFeedbackControlCodegen function. Specify the hardware as 'Robot Operating System (ROS)'. Set the build action to Build and run so that the ROS node starts running after you generate it. Call plotPath to plot the robot trajectory.

cfg = coder.config('exe');
cfg.Hardware = coder.hardware('Robot Operating System (ROS)');
cfg.Hardware.BuildAction = 'Build and run';
codegen robotROSFeedbackControlCodegen -args {} -config cfg
plotPath

The configuration generates and runs the ROS node on your local host computer by default. You can opt to deploy and run the ROS node on a remote device (such as on a virtual machine) instead by modifying cfg.Hardware. For example, if you are using the Linux virtual machine for ROS Toolbox, set the following configuration parameters before remote deployment. Note that the actual values might be different for your remote device. Verify them before deployment.

cfg.Hardware.RemoteDeviceAddress = '192.168.243.144';
cfg.Hardware.RemoteDeviceUsername = 'user';
cfg.Hardware.RemoteDevicePassword = 'password';
cfg.Hardware.DeployTo = 'Remote Device';

Verify Generated ROS Node

After the generated executable starts running, for the same destination coordinates, verify that the trajectory of the robot is similar to what you observe during MATLAB execution. You can also observe the robot moving in Gazebo on the virtual machine. You can publish a different destination coordinate while the robot is in motion. Refer to the Control a ROS-Enabled Robot with a Function section, which shows how to publish a new set of destination coordinates through a virtual machine terminal.

Terminate the generated ROS node by pressing Ctrl-C or sending a message to the /stop topic.

Shut down the ROS system.

rosshutdown

Related Topics