Main Content

Sign Following Robot with ROS in MATLAB

This example shows you how to use MATLAB® to control a simulated robot running on a separate ROS-based simulator over a ROS network. It then shows how to generate a ROS node for the control algorithm and deploy it to the remote device running ROS. The example shown here uses ROS and MATLAB for simulation, and MATLAB Coder™ for code generation and deployment. For the other examples with ROS 2 or Simulink®, see:

In this example, you run MATLAB script that implements a sign-following algorithm and controls the simulated robot to follow a path based on signs in the environment. The algorithm receives the location information and camera information from the simulated robot, which is running in a separate ROS-based simulator. The algorithm detects the color of the sign and sends the velocity commands to turn the robot based on the color. In this example, the algorithm is designed to turn left when robot encounters a blue sign and turn right when robot encounters a green sign. Finally the robot stops when it encounters a red sign.

Connect to a Robot Simulator

Start a ROS-based simulator for a differential-drive robot and configure MATLAB® connection with the robot simulator.

To follow along with this example, download a virtual machine using instructions in Get Started with Gazebo and a Simulated TurtleBot.

  • Start the Ubuntu® virtual machine desktop.

  • In the Ubuntu desktop, click the Gazebo Sign Follower ROS icon to start the Gazebo world built for this example.

  • Specify the IP address and port number of the ROS master in Gazebo so that MATLAB® can communicate with the robot simulator. For this example, the ROS master in Gazebo is http://192.168.192.129:11311 and your host computer address is 192.168.31.1.

  • Start the ROS 1 network using rosinit.

masterIP = '192.168.192.129';
rosinit(masterIP,11311)
Initializing global node /matlab_global_node_14355 with NodeURI http://192.168.192.1:51931/

Setup ROS Communication

Create publishers and subscribers to relay messages to and from the robot simulator over ROS network. You need subscribers for the image and odometry data. To control the robot, set up a publisher to send velocity commands using /cmd_vel. The rossubscriber and rospublisher functions support code generation for message structures only. To return a message structure, specify the name-value pair argument, "DataFormat","struct", when creating subscribers and publishers.

imgSub = rossubscriber("/camera/rgb/image_raw","sensor_msgs/Image","DataFormat","struct");

odomSub = rossubscriber("/odom","nav_msgs/Odometry","DataFormat","struct");

[velPub, velMsg] = rospublisher("/cmd_vel", "geometry_msgs/Twist","DataFormat","struct");

Define the image processing color threshold parameters. Each row defines the threshold values for the different colors.

colorThresholds = [100 255 0 55 0 50; ... % Red
                   0 50 50 255 0 50; ...  % Green
                   0 40 0 55 50 255]';    % Blue

Create Sign Following Controller Using Stateflow® Chart

This example provides an example helper MATLAB Stateflow® chart that takes in the image size, coordinates from processed image, and the robot odometry poses. The chart provides linear and angular velocity to drive the robot based on these inputs.

controller = ExampleHelperSignFollowingControllerChart;
open('ExampleHelperSignFollowingControllerChart');

Run Control Loop

This section runs the controller to receive images and move the robot to follow the sign. The controller does the following steps:

  • Gets the latest image and odometry message from the ROS network.

  • Runs the algoritm for detecting image features (ExampleHelperSignFollowingProcessImg).

  • Generates control commands from the Stateflow® chart using step.

  • Publishes the velocity control commands to the ROS network.

To visualize the masked image the robot sees, change the value of doVisualization variable to true.

ExampleHelperSignFollowingSetupPreferences;

% Control the visualization of the mask
doVisualization = false;

r = rosrate(10);
receive(imgSub); % Wait to receive an image message before starting the loop
receive(odomSub);
while(~controller.done)
    % Get latest sensor messages and process them
    imgMsg = imgSub.LatestMessage;
    odomMsg = odomSub.LatestMessage;
    [img,pose] = ExampleHelperSignFollowingROSProcessMsg(imgMsg, odomMsg);
    
    % Run vision and control functions
    [mask,blobSize,blobX] = ExampleHelperSignFollowingProcessImg(img, colorThresholds);
    step(controller,'blobSize',blobSize,'blobX',blobX,'pose',pose);
    v = controller.v;
    w = controller.w;
    
    % Publish velocity commands
    velMsg.Linear.X = v;
    velMsg.Angular.Z = w;
    send(velPub,velMsg);
    
    % Optionally visualize
    % NOTE: Visualizing data will slow down the execution loop.
    % If you have Computer Vision Toolbox, we recommend using
    % vision.DeployableVideoPlayer instead of imshow.
    if doVisualization
        imshow(mask);
        title(['Linear Vel: ' num2str(v) ' Angular Vel: ' num2str(w)]);
        drawnow('limitrate');
    end
    % Pace the execution loop.
    waitfor(r);
end

You should see the robot moving in the ROS-based robot simulator as shown below.

The robot follows the signs and stops at the final STOP sign. Reset the Gazebo scene after simulation using the /gazebo/reset_simulation service. Create a rossvcclient object for the service and use the call object function to call the service and reset the Gazebo simulation scene.

gazeboResetClient = rossvcclient('/gazebo/reset_simulation','DataFormat','struct');
call(gazeboResetClient);

Generate and Deploy ROS Node

After the controller is verified, the next step is to generate a ROS node for the sign following robot algorithm using MATLAB Coder™ and deploy it on the remote Virtual Machine running Gazebo. Deployment enables ROS nodes to run on the remote machines directly, resulting in faster executions. Create a MATLAB Coder configuration object that uses "Robot Operating System (ROS)" hardware. For 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. Set the build action to 'Build and Run' so that the deployed ROS node starts running after code generation.

cfg = coder.config("exe");
cfg.Hardware = coder.hardware("Robot Operating System (ROS)");
cfg.Hardware.DeployTo = 'Remote Device';
cfg.Hardware.RemoteDeviceAddress = '192.168.192.129';
cfg.Hardware.RemoteDeviceUsername = 'user';
cfg.Hardware.RemoteDevicePassword = 'password';
cfg.Hardware.BuildAction = "Build and run";

Use DeploySignFollowingRobotROS function that contains the controller algorithm code verified in the previous section. Run the following command to generate the ROS node and deploy the controller. You should see the robot moving in the Gazebo world.

codegen DeploySignFollowingRobotROS -config cfg
Created archive file 'C:\Users\avijayar\OneDrive - MathWorks\Documents\MATLAB\Examples\ros-ex22554512\DeploySignFollowingRobotROS.tgz'.
Created build shell script 'C:\Users\avijayar\OneDrive - MathWorks\Documents\MATLAB\Examples\ros-ex22554512\build_ros_model.sh'.
---
Copy the archive and the shell script to a ROS device to build the ROS node.
Connecting to ROS device '192.168.192.129'.
Using Catkin workspace '~/catkin_ws' to build ROS node.
---
Transferring generated code for 'DeploySignFollowingRobotROS' to ROS device.
Starting build for ROS node.
---
tar: Ignoring unknown extended header keyword 'SCHILY.fflags'
tar: Ignoring unknown extended header keyword 'SCHILY.fflags'
tar: Ignoring unknown extended header keyword 'SCHILY.fflags'
Catkin project directory: /home/user/catkin_ws/src/deploysignfollowingrobotros
tar: Ignoring unknown extended header keyword 'SCHILY.fflags'
tar: Ignoring unknown extended header keyword 'SCHILY.fflags'
tar: Ignoring unknown extended header keyword 'SCHILY.fflags'


-- Using CATKIN_DEVEL_PREFIX: /home/user/catkin_ws/devel
-- Using CMAKE_PREFIX_PATH: /home/user/catkin_ws/devel;/opt/ros/melodic
-- This workspace overlays: /home/user/catkin_ws/devel;/opt/ros/melodic
-- Found PythonInterp: /usr/bin/python2 (found suitable version "2.7.17", minimum required is "2") 
-- Using PYTHON_EXECUTABLE: /usr/bin/python2
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/user/catkin_ws/build/test_results
-- Found gtest sources under '/usr/src/googletest': gtests will be built
-- Found gmock sources under '/usr/src/googletest': gmock will be built

-- Found PythonInterp: /usr/bin/python2 (found version "2.7.17") 
-- Using Python nosetests: /usr/bin/nosetests-2.7
-- catkin 0.7.29
-- BUILD_SHARED_LIBS is on
-- BUILD_SHARED_LIBS is on

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~  traversing 25 packages in topological order:
-- ~~  - kortex_move_it_config (metapackage)
-- ~~  - universal_robot (metapackage)
-- ~~  - ur_bringup
-- ~~  - ur_description
-- ~~  - ur_gazebo
-- ~~  - ur_msgs
-- ~~  - kortex_control
-- ~~  - kortex_description
-- ~~  - kortex_gazebo
-- ~~  - kortex_driver
-- ~~  - kortex_examples
-- ~~  - deploysignfollowingrobotros
-- ~~  - examplehelperdeploysignfollowingrobotros
-- ~~  - gazebo_version_helpers
-- ~~  - gazebo_grasp_plugin
-- ~~  - roboticsgroup_gazebo_plugins
-- ~~  - ur_driver
-- ~~  - ur10_moveit_config
-- ~~  - ur3_moveit_config
-- ~~  - ur5_moveit_config
-- ~~  - gen3_move_it_config
-- ~~  - gen3_robotiq_2f_85_move_it_config
-- ~~  - kortex_gazebo_camera
-- ~~  - kortex_gazebo_depth
-- ~~  - mw_vision_example
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin metapackage: 'kortex_move_it_config'
-- ==> add_subdirectory(ros_kortex/kortex_move_it_config/kortex_move_it_config)
-- +++ processing catkin metapackage: 'universal_robot'
-- ==> add_subdirectory(universal_robot/universal_robot)
-- +++ processing catkin package: 'ur_bringup'
-- ==> add_subdirectory(universal_robot/ur_bringup)
-- +++ processing catkin package: 'ur_description'
-- ==> add_subdirectory(universal_robot/ur_description)
-- +++ processing catkin package: 'ur_gazebo'
-- ==> add_subdirectory(universal_robot/ur_gazebo)
-- +++ processing catkin package: 'ur_msgs'
-- ==> add_subdirectory(universal_robot/ur_msgs)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy

-- ur_msgs: 6 messages, 2 services
-- +++ processing catkin package: 'kortex_control'
-- ==> add_subdirectory(ros_kortex/kortex_control)
-- +++ processing catkin package: 'kortex_description'
-- ==> add_subdirectory(ros_kortex/kortex_description)
-- +++ processing catkin package: 'kortex_gazebo'
-- ==> add_subdirectory(ros_kortex/kortex_gazebo)
-- Boost version: 1.65.1
-- Found the following Boost libraries:
--   thread
--   system
--   filesystem
--   program_options
--   regex
--   iostreams
--   date_time
--   chrono
--   atomic
-- Found Protobuf: /usr/lib/x86_64-linux-gnu/libprotobuf.so;-lpthread (found version "3.0.0") 

-- Boost version: 1.65.1
-- Looking for OGRE...
-- Found Ogre Ghadamon (1.9.0)
-- Found OGRE: optimized;/usr/lib/x86_64-linux-gnu/libOgreMain.so;debug;/usr/lib/x86_64-linux-gnu/libOgreMain.so
-- Looking for OGRE_Paging...
-- Found OGRE_Paging: optimized;/usr/lib/x86_64-linux-gnu/libOgrePaging.so;debug;/usr/lib/x86_64-linux-gnu/libOgrePaging.so
-- Looking for OGRE_Terrain...
-- Found OGRE_Terrain: optimized;/usr/lib/x86_64-linux-gnu/libOgreTerrain.so;debug;/usr/lib/x86_64-linux-gnu/libOgreTerrain.so
-- Looking for OGRE_Property...
-- Found OGRE_Property: optimized;/usr/lib/x86_64-linux-gnu/libOgreProperty.so;debug;/usr/lib/x86_64-linux-gnu/libOgreProperty.so
-- Looking for OGRE_RTShaderSystem...
-- Found OGRE_RTShaderSystem: optimized;/usr/lib/x86_64-linux-gnu/libOgreRTShaderSystem.so;debug;/usr/lib/x86_64-linux-gnu/libOgreRTShaderSystem.so
-- Looking for OGRE_Volume...
-- Found OGRE_Volume: optimized;/usr/lib/x86_64-linux-gnu/libOgreVolume.so;debug;/usr/lib/x86_64-linux-gnu/libOgreVolume.so
-- Looking for OGRE_Overlay...
-- Found OGRE_Overlay: optimized;/usr/lib/x86_64-linux-gnu/libOgreOverlay.so;debug;/usr/lib/x86_64-linux-gnu/libOgreOverlay.so
-- Found Protobuf: /usr/lib/x86_64-linux-gnu/libprotobuf.so;-lpthread;-lpthread (found suitable version "3.0.0", minimum required is "2.3.0") 
-- Config-file not installed for ZeroMQ -- checking for pkg-config
-- Checking for module 'libzmq >= 4'
--   Found libzmq , version 4.2.5
-- Checking for module 'uuid'
--   Found uuid, version 2.31.1
-- Checking for module 'tinyxml2'
--   Found tinyxml2, version 7.0.1
-- Looking for dlfcn.h - found
-- Looking for libdl - found
-- FreeImage.pc not found, we will search for FreeImage_INCLUDE_DIRS and FreeImage_LIBRARIES
-- Checking for module 'gts'
--   Found gts, version 0.7.6
-- Checking for module 'libswscale'
--   Found libswscale, version 4.8.100
-- Checking for module 'libavdevice >= 56.4.100'
--   Found libavdevice , version 57.10.100

-- Checking for module 'libavformat'
--   Found libavformat, version 57.83.100
-- Checking for module 'libavcodec'
--   Found libavcodec, version 57.107.100
-- Checking for module 'libavutil'
--   Found libavutil, version 55.78.100
-- Checking for module 'jsoncpp'
--   Found jsoncpp, version 1.7.4
-- Checking for module 'yaml-0.1'
--   Found yaml-0.1, version 0.1.7
-- Checking for module 'libzip'
--   Found libzip, version 1.1.2
-- +++ processing catkin package: 'kortex_driver'
-- ==> add_subdirectory(ros_kortex/kortex_driver)
include is not empty, exiting...

-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
-- Boost version: 1.65.1
-- Found the following Boost libraries:
--   system

-- kortex_driver: 386 messages, 217 services

-- +++ processing catkin package: 'kortex_examples'
-- ==> add_subdirectory(ros_kortex/kortex_examples)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
-- +++ processing catkin package: 'deploysignfollowingrobotros'
-- ==> add_subdirectory(deploysignfollowingrobotros)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
-- +++ processing catkin package: 'examplehelperdeploysignfollowingrobotros'
-- ==> add_subdirectory(examplehelperdeploysignfollowingrobotros)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy

-- +++ processing catkin package: 'gazebo_version_helpers'
-- ==> add_subdirectory(ros_kortex/third_party/gazebo-pkgs/gazebo_version_helpers)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
-- Boost version: 1.65.1
-- Found the following Boost libraries:
--   thread
--   system
--   filesystem
--   program_options
--   regex
--   iostreams
--   date_time
--   chrono
--   atomic
-- Found Protobuf: /usr/lib/x86_64-linux-gnu/libprotobuf.so;-lpthread (found version "3.0.0") 
-- Boost version: 1.65.1
-- Looking for OGRE...
-- Found Ogre Ghadamon (1.9.0)
-- Found OGRE: optimized;/usr/lib/x86_64-linux-gnu/libOgreMain.so;debug;/usr/lib/x86_64-linux-gnu/libOgreMain.so
-- Looking for OGRE_Paging...
-- Found OGRE_Paging: optimized;/usr/lib/x86_64-linux-gnu/libOgrePaging.so;debug;/usr/lib/x86_64-linux-gnu/libOgrePaging.so
-- Looking for OGRE_Terrain...
-- Found OGRE_Terrain: optimized;/usr/lib/x86_64-linux-gnu/libOgreTerrain.so;debug;/usr/lib/x86_64-linux-gnu/libOgreTerrain.so
-- Looking for OGRE_Property...
-- Found OGRE_Property: optimized;/usr/lib/x86_64-linux-gnu/libOgreProperty.so;debug;/usr/lib/x86_64-linux-gnu/libOgreProperty.so
-- Looking for OGRE_RTShaderSystem...
-- Found OGRE_RTShaderSystem: optimized;/usr/lib/x86_64-linux-gnu/libOgreRTShaderSystem.so;debug;/usr/lib/x86_64-linux-gnu/libOgreRTShaderSystem.so
-- Looking for OGRE_Volume...
-- Found OGRE_Volume: optimized;/usr/lib/x86_64-linux-gnu/libOgreVolume.so;debug;/usr/lib/x86_64-linux-gnu/libOgreVolume.so
-- Looking for OGRE_Overlay...
-- Found OGRE_Overlay: optimized;/usr/lib/x86_64-linux-gnu/libOgreOverlay.so;debug;/usr/lib/x86_64-linux-gnu/libOgreOverlay.so
-- Found Protobuf: /usr/lib/x86_64-linux-gnu/libprotobuf.so;-lpthread;-lpthread (found suitable version "3.0.0", minimum required is "2.3.0") 
-- Config-file not installed for ZeroMQ -- checking for pkg-config
-- Checking for module 'libzmq >= 4'
--   Found libzmq , version 4.2.5

-- Checking for module 'uuid'
--   Found uuid, version 2.31.1
-- Checking for module 'tinyxml2'
--   Found tinyxml2, version 7.0.1
-- Looking for dlfcn.h - found
-- Looking for libdl - found
-- FreeImage.pc not found, we will search for FreeImage_INCLUDE_DIRS and FreeImage_LIBRARIES
-- Checking for module 'gts'
--   Found gts, version 0.7.6
-- Checking for module 'libswscale'
--   Found libswscale, version 4.8.100
-- Checking for module 'libavdevice >= 56.4.100'
--   Found libavdevice , version 57.10.100
-- Checking for module 'libavformat'
--   Found libavformat, version 57.83.100
-- Checking for module 'libavcodec'
--   Found libavcodec, version 57.107.100

-- Checking for module 'libavutil'
--   Found libavutil, version 55.78.100
-- Checking for module 'jsoncpp'
--   Found jsoncpp, version 1.7.4
-- Checking for module 'yaml-0.1'
--   Found yaml-0.1, version 0.1.7
-- Checking for module 'libzip'
--   Found libzip, version 1.1.2
CMake Warning at /opt/ros/melodic/share/catkin/cmake/catkin_package.cmake:166 (message):
  catkin_package() DEPENDS on 'gazebo' but neither 'gazebo_INCLUDE_DIRS' nor
  'gazebo_LIBRARIES' is defined.
Call Stack (most recent call first):
  /opt/ros/melodic/share/catkin/cmake/catkin_package.cmake:102 (_catkin_package)
  ros_kortex/third_party/gazebo-pkgs/gazebo_version_helpers/CMakeLists.txt:29 (catkin_package)


-- +++ processing catkin package: 'gazebo_grasp_plugin'
-- ==> add_subdirectory(ros_kortex/third_party/gazebo-pkgs/gazebo_grasp_plugin)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy

-- Boost version: 1.65.1
-- Found the following Boost libraries:
--   thread
--   system
--   filesystem
--   program_options
--   regex
--   iostreams
--   date_time
--   chrono
--   atomic
-- Found Protobuf: /usr/lib/x86_64-linux-gnu/libprotobuf.so;-lpthread (found version "3.0.0") 
-- Boost version: 1.65.1
-- Looking for OGRE...
-- Found Ogre Ghadamon (1.9.0)
-- Found OGRE: optimized;/usr/lib/x86_64-linux-gnu/libOgreMain.so;debug;/usr/lib/x86_64-linux-gnu/libOgreMain.so
-- Looking for OGRE_Paging...
-- Found OGRE_Paging: optimized;/usr/lib/x86_64-linux-gnu/libOgrePaging.so;debug;/usr/lib/x86_64-linux-gnu/libOgrePaging.so
-- Looking for OGRE_Terrain...
-- Found OGRE_Terrain: optimized;/usr/lib/x86_64-linux-gnu/libOgreTerrain.so;debug;/usr/lib/x86_64-linux-gnu/libOgreTerrain.so
-- Looking for OGRE_Property...
-- Found OGRE_Property: optimized;/usr/lib/x86_64-linux-gnu/libOgreProperty.so;debug;/usr/lib/x86_64-linux-gnu/libOgreProperty.so
-- Looking for OGRE_RTShaderSystem...
-- Found OGRE_RTShaderSystem: optimized;/usr/lib/x86_64-linux-gnu/libOgreRTShaderSystem.so;debug;/usr/lib/x86_64-linux-gnu/libOgreRTShaderSystem.so
-- Looking for OGRE_Volume...
-- Found OGRE_Volume: optimized;/usr/lib/x86_64-linux-gnu/libOgreVolume.so;debug;/usr/lib/x86_64-linux-gnu/libOgreVolume.so
-- Looking for OGRE_Overlay...
-- Found OGRE_Overlay: optimized;/usr/lib/x86_64-linux-gnu/libOgreOverlay.so;debug;/usr/lib/x86_64-linux-gnu/libOgreOverlay.so
-- Found Protobuf: /usr/lib/x86_64-linux-gnu/libprotobuf.so;-lpthread;-lpthread (found suitable version "3.0.0", minimum required is "2.3.0") 
-- Config-file not installed for ZeroMQ -- checking for pkg-config
-- Checking for module 'libzmq >= 4'
--   Found libzmq , version 4.2.5
-- Checking for module 'uuid'
--   Found uuid, version 2.31.1
-- Checking for module 'tinyxml2'
--   Found tinyxml2, version 7.0.1
-- Looking for dlfcn.h - found
-- Looking for libdl - found
-- FreeImage.pc not found, we will search for FreeImage_INCLUDE_DIRS and FreeImage_LIBRARIES

-- Checking for module 'gts'
--   Found gts, version 0.7.6
-- Checking for module 'libswscale'
--   Found libswscale, version 4.8.100
-- Checking for module 'libavdevice >= 56.4.100'
--   Found libavdevice , version 57.10.100
-- Checking for module 'libavformat'
--   Found libavformat, version 57.83.100
-- Checking for module 'libavcodec'
--   Found libavcodec, version 57.107.100
-- Checking for module 'libavutil'
--   Found libavutil, version 55.78.100
-- Checking for module 'jsoncpp'

--   Found jsoncpp, version 1.7.4
-- Checking for module 'yaml-0.1'
--   Found yaml-0.1, version 0.1.7
-- Checking for module 'libzip'
--   Found libzip, version 1.1.2
CMake Warning at /opt/ros/melodic/share/catkin/cmake/catkin_package.cmake:166 (message):
  catkin_package() DEPENDS on 'gazebo' but neither 'gazebo_INCLUDE_DIRS' nor
  'gazebo_LIBRARIES' is defined.
Call Stack (most recent call first):
  /opt/ros/melodic/share/catkin/cmake/catkin_package.cmake:102 (_catkin_package)
  ros_kortex/third_party/gazebo-pkgs/gazebo_grasp_plugin/CMakeLists.txt:34 (catkin_package)


-- +++ processing catkin package: 'roboticsgroup_gazebo_plugins'
-- ==> add_subdirectory(ros_kortex/third_party/roboticsgroup_gazebo_plugins)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy

-- Boost version: 1.65.1
-- Found the following Boost libraries:
--   thread
--   system
--   filesystem
--   program_options
--   regex
--   iostreams
--   date_time
--   chrono
--   atomic
-- Found Protobuf: /usr/lib/x86_64-linux-gnu/libprotobuf.so;-lpthread (found version "3.0.0") 
-- Boost version: 1.65.1
-- Looking for OGRE...
-- Found Ogre Ghadamon (1.9.0)
-- Found OGRE: optimized;/usr/lib/x86_64-linux-gnu/libOgreMain.so;debug;/usr/lib/x86_64-linux-gnu/libOgreMain.so
-- Looking for OGRE_Paging...
-- Found OGRE_Paging: optimized;/usr/lib/x86_64-linux-gnu/libOgrePaging.so;debug;/usr/lib/x86_64-linux-gnu/libOgrePaging.so
-- Looking for OGRE_Terrain...
-- Found OGRE_Terrain: optimized;/usr/lib/x86_64-linux-gnu/libOgreTerrain.so;debug;/usr/lib/x86_64-linux-gnu/libOgreTerrain.so
-- Looking for OGRE_Property...
-- Found OGRE_Property: optimized;/usr/lib/x86_64-linux-gnu/libOgreProperty.so;debug;/usr/lib/x86_64-linux-gnu/libOgreProperty.so
-- Looking for OGRE_RTShaderSystem...
-- Found OGRE_RTShaderSystem: optimized;/usr/lib/x86_64-linux-gnu/libOgreRTShaderSystem.so;debug;/usr/lib/x86_64-linux-gnu/libOgreRTShaderSystem.so
-- Looking for OGRE_Volume...
-- Found OGRE_Volume: optimized;/usr/lib/x86_64-linux-gnu/libOgreVolume.so;debug;/usr/lib/x86_64-linux-gnu/libOgreVolume.so
-- Looking for OGRE_Overlay...
-- Found OGRE_Overlay: optimized;/usr/lib/x86_64-linux-gnu/libOgreOverlay.so;debug;/usr/lib/x86_64-linux-gnu/libOgreOverlay.so
-- Found Protobuf: /usr/lib/x86_64-linux-gnu/libprotobuf.so;-lpthread;-lpthread (found suitable version "3.0.0", minimum required is "2.3.0") 
-- Config-file not installed for ZeroMQ -- checking for pkg-config
-- Checking for module 'libzmq >= 4'
--   Found libzmq , version 4.2.5
-- Checking for module 'uuid'
--   Found uuid, version 2.31.1
-- Checking for module 'tinyxml2'
--   Found tinyxml2, version 7.0.1
-- Looking for dlfcn.h - found
-- Looking for libdl - found
-- FreeImage.pc not found, we will search for FreeImage_INCLUDE_DIRS and FreeImage_LIBRARIES

-- Checking for module 'gts'
--   Found gts, version 0.7.6
-- Checking for module 'libswscale'
--   Found libswscale, version 4.8.100
-- Checking for module 'libavdevice >= 56.4.100'
--   Found libavdevice , version 57.10.100
-- Checking for module 'libavformat'
--   Found libavformat, version 57.83.100
-- Checking for module 'libavcodec'
--   Found libavcodec, version 57.107.100
-- Checking for module 'libavutil'
--   Found libavutil, version 55.78.100
-- Checking for module 'jsoncpp'
--   Found jsoncpp, version 1.7.4

-- Checking for module 'yaml-0.1'
--   Found yaml-0.1, version 0.1.7
-- Checking for module 'libzip'
--   Found libzip, version 1.1.2
-- Boost version: 1.65.1
-- +++ processing catkin package: 'ur_driver'
-- ==> add_subdirectory(universal_robot/ur_driver)

-- +++ processing catkin package: 'ur10_moveit_config'
-- ==> add_subdirectory(universal_robot/ur10_moveit_config)
-- +++ processing catkin package: 'ur3_moveit_config'
-- ==> add_subdirectory(universal_robot/ur3_moveit_config)
-- +++ processing catkin package: 'ur5_moveit_config'
-- ==> add_subdirectory(universal_robot/ur5_moveit_config)

-- +++ processing catkin package: 'gen3_move_it_config'
-- ==> add_subdirectory(ros_kortex/kortex_move_it_config/gen3_move_it_config)
-- +++ processing catkin package: 'gen3_robotiq_2f_85_move_it_config'
-- ==> add_subdirectory(ros_kortex/kortex_move_it_config/gen3_robotiq_2f_85_move_it_config)
-- +++ processing catkin package: 'kortex_gazebo_camera'
-- ==> add_subdirectory(kortex_gazebo_camera)
-- +++ processing catkin package: 'kortex_gazebo_depth'
-- ==> add_subdirectory(kortex_gazebo_depth)
-- +++ processing catkin package: 'mw_vision_example'
-- ==> add_subdirectory(mw_vision_example)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy

-- Configuring done

-- Generating done
-- Build files have been written to: /home/user/catkin_ws/build
[  0%] Built target sensor_msgs_generate_messages_lisp
[  0%] Built target std_msgs_generate_messages_py
[  0%] Built target std_msgs_generate_messages_nodejs
[  0%] Built target std_msgs_generate_messages_lisp
[  0%] Built target std_msgs_generate_messages_cpp
[  0%] Built target std_msgs_generate_messages_eus
[  0%] Built target actionlib_msgs_generate_messages_py
[  0%] Built target rosgraph_msgs_generate_messages_lisp
[  0%] Built target roscpp_generate_messages_eus
[  0%] Built target geometry_msgs_generate_messages_lisp

[  0%] Built target rosgraph_msgs_generate_messages_py
[  0%] Built target roscpp_generate_messages_nodejs
[  0%] Built target geometry_msgs_generate_messages_cpp
[  0%] Built target geometry_msgs_generate_messages_nodejs
[  0%] Built target rosgraph_msgs_generate_messages_cpp
[  0%] Built target rosgraph_msgs_generate_messages_eus
[  0%] Built target actionlib_msgs_generate_messages_cpp
[  0%] Built target roscpp_generate_messages_lisp
[  0%] Built target actionlib_msgs_generate_messages_nodejs
[  0%] Built target rosgraph_msgs_generate_messages_nodejs
[  0%] Built target roscpp_generate_messages_py
[  0%] Built target actionlib_msgs_generate_messages_eus
[  0%] Built target roscpp_generate_messages_cpp
[  0%] Built target geometry_msgs_generate_messages_eus
[  0%] Built target actionlib_msgs_generate_messages_lisp
[  0%] Built target geometry_msgs_generate_messages_py
[  0%] Built target sensor_msgs_generate_messages_py
[  0%] Built target nav_msgs_generate_messages_py
[  0%] Built target sensor_msgs_generate_messages_cpp
[  0%] Built target sensor_msgs_generate_messages_eus
[  0%] Built target nav_msgs_generate_messages_nodejs
[  0%] Built target nav_msgs_generate_messages_cpp
[  0%] Built target nav_msgs_generate_messages_eus
[  0%] Built target sensor_msgs_generate_messages_nodejs
[  0%] Built target nav_msgs_generate_messages_lisp
Scanning dependencies of target deploysignfollowingrobotros
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/DeploySignFollowingRobotROS_data.cpp.o

[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/rt_nonfinite.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/rtGetNaN.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/rtGetInf.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/DeploySignFollowingRobotROS_initialize.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/DeploySignFollowingRobotROS_terminate.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/DeploySignFollowingRobotROS.cpp.o

[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/sensor_msgs_ImageStruct.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/std_msgs_HeaderStruct.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/ros_TimeStruct.cpp.o

[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/nav_msgs_OdometryStruct.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/geometry_msgs_PoseWithCovarianceStruct.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/geometry_msgs_PoseStruct.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/geometry_msgs_PointStruct.cpp.o

[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/geometry_msgs_QuaternionStruct.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/geometry_msgs_TwistWithCovarianceStruct.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/geometry_msgs_TwistStruct.cpp.o

[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/geometry_msgs_Vector3Struct.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/minOrMax.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/tic.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/rosReadImage.cpp.o

[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/quat2eul.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/toc.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/CoderTimeAPI.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/ExampleHelperSignFollowingProcessImg.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/Subscriber.cpp.o

/home/user/catkin_ws/src/deploysignfollowingrobotros/Subscriber.cpp: In member function 'void coder::ros::Subscriber::matlabCodegenDestructor()':
/home/user/catkin_ws/src/deploysignfollowingrobotros/Subscriber.cpp:86:35: warning: deleting 'void*' is undefined [-Wdelete-incomplete]
     delete (this->SubscriberHelper);
                                   ^
/home/user/catkin_ws/src/deploysignfollowingrobotros/Subscriber.cpp: In member function 'void coder::ros::b_Subscriber::matlabCodegenDestructor()':
/home/user/catkin_ws/src/deploysignfollowingrobotros/Subscriber.cpp:98:35: warning: deleting 'void*' is undefined [-Wdelete-incomplete]
     delete (this->SubscriberHelper);
                                   ^

[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/Publisher.cpp.o

[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/ExampleHelperSignFollowingControllerChart.cpp.o
[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/Rate.cpp.o

[  0%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/main.cpp.o

[100%] Building CXX object deploysignfollowingrobotros/CMakeFiles/deploysignfollowingrobotros.dir/ros_structmsg_conversion.cpp.o

[100%] Linking CXX executable /home/user/catkin_ws/devel/lib/deploysignfollowingrobotros/deploysignfollowingrobotros
/usr/bin/c++   -std=c++0x -fpermissive   CMakeFiles/deploysignfollowingrobotros.dir/coder_posix_time.c.o CMakeFiles/deploysignfollowingrobotros.dir/DeploySignFollowingRobotROS_data.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/rt_nonfinite.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/rtGetNaN.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/rtGetInf.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/DeploySignFollowingRobotROS_initialize.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/DeploySignFollowingRobotROS_terminate.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/DeploySignFollowingRobotROS.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/sensor_msgs_ImageStruct.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/std_msgs_HeaderStruct.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/ros_TimeStruct.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/nav_msgs_OdometryStruct.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/geometry_msgs_PoseWithCovarianceStruct.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/geometry_msgs_PoseStruct.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/geometry_msgs_PointStruct.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/geometry_msgs_QuaternionStruct.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/geometry_msgs_TwistWithCovarianceStruct.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/geometry_msgs_TwistStruct.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/geometry_msgs_Vector3Struct.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/minOrMax.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/tic.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/rosReadImage.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/quat2eul.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/toc.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/CoderTimeAPI.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/ExampleHelperSignFollowingProcessImg.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/Subscriber.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/Publisher.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/ExampleHelperSignFollowingControllerChart.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/Rate.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/main.cpp.o CMakeFiles/deploysignfollowingrobotros.dir/ros_structmsg_conversion.cpp.o  -o /home/user/catkin_ws/devel/lib/deploysignfollowingrobotros/deploysignfollowingrobotros -Wl,-rpath,/opt/ros/melodic/lib /opt/ros/melodic/lib/libroscpp.so /usr/lib/x86_64-linux-gnu/libboost_filesystem.so /opt/ros/melodic/lib/librosconsole.so /opt/ros/melodic/lib/librosconsole_log4cxx.so /opt/ros/melodic/lib/librosconsole_backend_interface.so /usr/lib/x86_64-linux-gnu/liblog4cxx.so /usr/lib/x86_64-linux-gnu/libboost_regex.so /opt/ros/melodic/lib/libxmlrpcpp.so /opt/ros/melodic/lib/libroscpp_serialization.so /opt/ros/melodic/lib/librostime.so /opt/ros/melodic/lib/libcpp_common.so /usr/lib/x86_64-linux-gnu/libboost_system.so /usr/lib/x86_64-linux-gnu/libboost_thread.so /usr/lib/x86_64-linux-gnu/libboost_chrono.so /usr/lib/x86_64-linux-gnu/libboost_date_time.so /usr/lib/x86_64-linux-gnu/libboost_atomic.so -lpthread /usr/lib/x86_64-linux-gnu/libconsole_bridge.so.0.4 -lrt -ldl 
[100%] Built target deploysignfollowingrobotros

Base path: /home/user/catkin_ws
Source space: /home/user/catkin_ws/src
Build space: /home/user/catkin_ws/build
Devel space: /home/user/catkin_ws/devel
Install space: /home/user/catkin_ws/install
####
#### Running command: "make cmake_check_build_system" in "/home/user/catkin_ws/build"
####
####
#### Running command: "make deploysignfollowingrobotros -j2 -l2" in "/home/user/catkin_ws/build"
####

---
Running ROS node.
---
The node will connect to the ROS master at 'http://192.168.192.129:11311' and advertise its address as '192.168.192.129'.
Use the 'rosdevice' object to stop the node or restart it with different settings.
Code generation successful.

The robot follows the signs and stops at the final STOP sign. Reset the Gazebo scene after the node executes by calling the rossvcclient object, gazeboResetClient.

call(gazeboResetClient);

Rerun the deployed node using rosdevice

To rerun the deployed ROS node from MATLAB, create a rosdevice object specifying the deviceAddress, username, and password values of the Virtual Machine running Gazebo. This establishes an SSH connection between the ROS device and MATLAB. Check the available nodes on the connected remote device. Verify that the deployed ROS node, deploysignfollowingrobotros, exists on the remote device .

gazeboVMDevice = rosdevice('192.168.192.129','user','password');
gazeboVMDevice.AvailableNodes
ans = 1×18 cell
    {'_setup_util.py'}    {'deploysignfollowingrobot'}    {'deploysignfollowingrobotros'}    {'env.sh'}    {'example_actuator_configuration_cpp'}    {'example_cartesian_poses_with_notifications_cpp'}    {'example_full_arm_movement_cpp'}    {'example_vision_configuration_cpp'}    {'examplehelperdeploysignfollowingrobotros'}    {'kortex_arm_driver'}    {'libgazebo_grasp_fix.so'}    {'libgazebo_version_helpers.so'}    {'libkortex_driver_generated_files.so'}    {'libroboticsgroup_gazebo_disable_link_plugin.so'}    {'libroboticsgroup_gazebo_mimic_joint_plugin.so'}    {'libur10_kin.so'}    {'libur3_kin.so'}    {'libur5_kin.so'}

Run the ROS node deployed on the remote device using runNode function. The robot follows the signs and stops at the final STOP sign.

runNode(gazeboVMDevice,'deploysignfollowingrobotros')
The node 'deploysignfollowingrobotros' is already running on the ROS device. Use the 'stopNode' function to stop it.