1 of 63

ROS Tutorial

Paul Buzaud

2 of 63

  • Using a lot of differents sensors /library/drivers

  • Real time computation and communication

  • Flexibility between local and remote systems with differents data types involved

Robotic imply:

3 of 63

How to manage the communication between these differents systems?

  • ROS = Robot Operating System
    • Peer to peer
    • Distributed
    • Multilingual (c++, python, java ...)
    • Free and open source
    • Permit differents process to exchange data in real time

4 of 63

How does this work:

Core of ros is the ROSMASTER, it don’t own but register all the ros component on the local/remote network:

Basic tutorial:

  • Rosnode = Python/C++ executable
  • Rostopics = communication address between ros subscriber and ros publisher
  • Rosparam = set variable on the rosmaster

Advanced tutorial (don‘t have to remember it for now):

  • Rosservice = synchronous request/response
  • RosActionServer= asynchronous client/server communication

5 of 63

Rosmaster registered 3 topics/address:

  • “/temperature”
  • “/test”
  • “/test/test”

One ROS publisher communicate some float to one ros subscriber on the “/temperature” topic/address

6 of 63

Example:

The switch subscriber connected to the “/temperature” topic don’t get any data because the rosmessage type is wrong (Can’t parse data)

The forecast subscriber will receive data from the thermometer 1 and 2

Topics:

  • “/temperature” which is used
  • “/test” and “/test/test” are not used

7 of 63

Let’s implement this in Python:

Publisher.py side:

#!/usr/bin/env python or #!/usr/bin/env python3 if noetic

import rospy

from std_msgs.msg import Float64

# Define this script as a rosnode/rosexecutable which

#will be register in the rosmaster

rospy.init_node('publisher', anonymous=True)

#initialize the publisher with the topics/address "/temperature",

# message type is a Float64

pub = rospy.Publisher('/temperature', Float64, queue_size=10)

# basic while loop which check if the rosmaster is alive

while not rospy.is_shutdown():

#create a temperature msg as a float64

temperature_msg = Float64()

#set the temperature published to 72 fahrenheit

temperature_msg.data = 72.

#publish the message on the "/temperature" address through the publisher

pub.publish(temperature_msg)

#wait 1 second until sending the new message

rospy.sleep(1)

Subscriber.py side:

#!/usr/bin/env python or #!/usr/bin/env python3 if noetic

import rospy

from std_msgs.msg import Float64

#function triggered by the subscriber

def temperature_callback(msg):

#print the msg data receive by the subscriber in the terminal

print(msg.data)

# Define this script as a rosnode/ros executable which will be register in the rosmaster

rospy.init_node('subscriber', anonymous=True)

#initialize the subscriber whith the topics/address "/temperature", message type is a Float64

# whenever a new message will ne published on the "/temperature" topic,

#the temperature_callback function will be triggered

rospy.Subscriber("/temperature", Float64, temperature_callback)

# spin() simply keeps python from exiting until this node is stopped

#and keeps the subscriber callback running

rospy.spin()

8 of 63

Exercice:

  • Write the two chunk of code in the previous slide respectively to some files from scratch named “publisher.py” and “subscriber.py”. Read carefully what each line does.
  • Open 3 terminals
  • Start the rosmaster by using the command “roscore”
  • Then run: “python publisher.py” in one terminal and “python subscriber.py” in the other terminal
  • The output of the “subscriber.py” in the terminal should be 72 because it is the float sent by the publisher to the subscriber. Then you can go to the next step.

The scripts should work properly if you have a clean installation of ros. If not, check also if in your bashrc, you have got the line: “source /opt/ros/{$distro can be melodic or kinetic or noetic….}/setup.bash”

9 of 63

Things to remember:

  • rospy.init_node('publisher', anonymous=True) => permits to “rosify”your code by registering your executable on the rosmaster
  • Publisher implementation is actually 2 lines:
    • pub = rospy.Publisher('/temperature', Float64, queue_size=10) => publisher initialization with topic/address and rosmessage type
    • pub.publish(msg) => publish the msg as argument on the publisher topic/address here it is “/temperature”
  • Subscriber implementation is 1 line and one callback function definition:
    • rospy.Subscriber("/temperature", Float64, temperature_callback) => subscriber initialization with topic/address and rosmessage type and “pointer” to the callback function

    • def temperature_callback(msg): => function which will be triggered by the subscriber everytime it will receive a msg. Msg can then be processed

10 of 63

Exercice:

  • Using the publisher and subscriber implementation from the last slide, improve these code to publish random temperature between 0 and 100 fahrenheit.
  • Then implement another publisher inside the “subscriber.py” in order to publish on the address “/cold_or_hot” if the temperature received is cold or hot (cold is lesser than 70 and hot is more than 70). You can use either ros std_msgs/Bool or std_msgs/String to show the result in a string or in a boolean. Don’t forget to initialize the temperature message value before publishing it.
  • To check if you have got the right value published, open a new terminal and run the command: “rostopic echo /cold_or_hot”. This command is like a subscriber created “on-the-fly” which will print all the data published on this topic/address into the terminal. If nothing shows up, you are not publishing anything. You can also try to use: “rostopic echo /temperature”, to see the temperature published by your publisher.py

11 of 63

Rosnodes and catkin workspace

12 of 63

Rosnode = Python/C++ executable

  • Remember we have use the “ros_init” function to register our python executable in the rosmaster
  • Several commands in the terminal give information about nodes:

  • Try them while your code is running. Write also rosnode in the terminal and use the tab autocompletion to see all the available rosnode commands which are less important than the “list” and “info” one.

13 of 63

How to setup a proper ros environment and create a ros package?

> mkdir -p ~/whatevername_ws/src

  • First of all create a catkin_workspace:
  • Only thing which matter is to create the “src” directory this is where you can clone, create, and edit source code for the packages you want to build. The “whatevername_ws” part is just to create a root directory to your catkin workspace, it can be anything you want.

  • Remember also to add this line “source/opt/ros/{your_distro}/setup.bash” to your “~/.bashrc” file with the command ({your_distro} = noetic or melodic or kinetic ...

> echo 'source /opt/ros/{your_distro}/setup.bash' >> ~/.bashrc

14 of 63

How to setup a proper ros environment and create a ros package?

  • Go into the “src” directory previously created with:

> cd ~/whatevername_ws/src

  • Here you will be able to “git clone” some ros project or create your project
  • Let say we want to create a package for our previous exercice, use the following command to create an empty ros package:

> catkin_create_pkg ros_thermometer

15 of 63

How to setup a proper ros environment and create a ros package?

  • Go into your newly created package:

> cd ~/whatevername_ws/src/ros_thermometer

  • Create a scripts directory:

> mkdir -p ~/whatevername_ws/src/ros_thermometer/scripts

  • Then copy/past your publisher.py and your subscriber.py into this script directory

16 of 63

How to setup a proper ros environment and create a ros package?

  • Structure of directory from src should look like this:

  • Package.xml resolve standard ros dependencies
  • CMakelists.txt take care of the compilation rules and dependencies

17 of 63

Take a look at the package xml

Nothing is really important in this as it is still empty beside:

  • <name> -> is your name of package
  • <buildtool_depend> -> compilation tool

As our scripts use rospy libraries and std_msgs for type like float64/String/Bool, we add these dependencies with the <depend> tag

18 of 63

Take a look at the CMakeLists.txt

without all the comments

Cmake_minimum_required -> version of cmake required for the compilation

project()->name of your ros package

find _package -> prevent the compilation if some dependencies are not solved

First of all find_package permits to avoid to generate the building if some of your dependency listed are not present. We added the std_msgs and the rospy dependency in this.

Our CMake doesn’t require a lot of things because python is interpreted not compiled. C++ required a lot of others modifications to generate the executable

19 of 63

  • As the compilation won’t generate the executable for you as it is in python and python is an interpreted language. You should use the following commands to generate them:

> chmod +x ~/whatevername_ws/src/ros_thermometer/scripts/publisher.py

> chmod +x ~/whatevername_ws/src/ros_thermometer/scripts/subscriber.py

20 of 63

  • When it is done, launch the compilation to generate the package. You have to go at the root of your catkin workspace:

> cd ~/whatevername_ws/

  • And compile your package with the command:

> catkin build (you will need to install catkin-tools first)

Or

> catkin_make (default compilation system)

21 of 63

  • Now that your package is compiled, you should see 3 folders at the root of your catkin_workspace:

22 of 63

Run your node !

  • Before running your executable, you have to keep in mind that you just compiled a ros package but this package is still not visible to your ros environment. To do so, you should source it with the following command:

> source devel/setup.bash

  • This command is really important and should be run everytime you want to use your package or other people ros libraries that you compile in your current catkin workspace !

23 of 63

Run your node !

  • Open 3 terminals
  • Launch a roscore in one
  • Launch source ~/whatevername_ws/devel/setup.bash in another one then run the command: rosrun ros_thermometer publisher.py. You should be able to use the “tab” key to autocomplete this command
  • Launch source ~/whatevername_ws/devel/setup.bash in another one then the command: rosrun ros_thermometer subscriber.py.
  • You should get the same result as in the exercice if you rostopic echo /cold_or_hot or if you rostopic echo /temperature in another terminal

24 of 63

What did we do here?

  • The catkin_make command has generated a ros package thanks to the CMakelist.txt and the package.xml file and put all the compiled files in the build and devel directory
  • By using the source devel/setup.bash, we index this new ros package into the ros environment then it is possible to access the executable that we have developed through the terminal
  • Finally, the command rosrun ros_package executable (rosrun ros_thermometer publisher.py) permits to run the python file that we wrote

25 of 63

Is there a easier way to run nodes ?

  • Using another terminal to run a new executable everytime is not convenient, that’s why roslaunch exist. It permits:
    • To load some static parameters into a node when it starts
    • Map the differents topics between the nodes
    • Launch several packages and nodes with one command line

26 of 63

What is roslaunch?

  • A xml file in which you defines all the nodes that you want to launch, their parameters and their mapped topics
  • It can be run after sourcing the catkin workspace with the commands:
    • Roslaunch name_of_the_package name_of_the_launch_file.launch
    • Roslaunch path_to_file.launch
  • The linux tab autocompletion works if the launch file is located in a launch directory at the root of your package
  • The extension of the file is “.launch”

27 of 63

How does it look like?

  • First of all create a new directory into your package call “launch”:

> mkdir -p ~/whatevername_ws/src/ros_thermometer/launch

  • Then inside create a file call “basic.launch”, it can be whatever name you want with the extension “.launch
  • The file structure of your package should look like this now:

28 of 63

How does a launch file look like?

29 of 63

Exercice:

  • Replacing the nodes and package inside the previous launch file structure, write the basic.launch file with our “publisher.py” and our “subscriber.py” nodes
    • Here the package is “ros_thermometer”
    • One executable is “publisher.py”
    • The other one is “subscriber.py”
  • When your launch file is ready, source your catkin workspace to index the launch file inside it:

source ~/whatevername_ws/devel/setup.bash

  • Then use the command: roslaunch name_of_package name_of_launchfile

roslaunch ros_thermometer basic.launch

30 of 63

Exercice:

  • All the nodes should have been launched, you can check that with the “rosnode list” command or by “rostopic echo /cold_or_not” and “/temperature”. It should show the same result than in the previous exercise

31 of 63

What if we want to add some parameter to a rosnode/process ?

  • Because we don’t want to rewrite the scripts codes everytime we run a demo, ros implements a way to customize your node from the launch file directly
  • First of all, you can remap the topics inside your publisher and your subscriber dynamically using the <remap> xml tag
  • From previous exercice basic.launch file:

<launch>

<node name="thermometer_subscriber" pkg="ros_thermometer" type="subscriber.py" output="screen"/>

<node name="thermometer_publisher" pkg="ros_thermometer" type="publisher.py" output="screen">

<remap from="/temperature" to="test_remap"/>

</node>

</launch>

This is a one line node definition

This is a two line node definition, the remap is inside the node definition

32 of 63

What if we want to add some parameter to a rosnode/process ?

  • Change your basic.launch with the previous remapping and launch it with (don’t forget to source it before launching it):

roslaunch ros_thermometer basic.launch

  • Then in another terminal run:

Rostopic list

  • You should see another topic called “/test_remap”. If you rostopic echo it, it will show the informations published by your publisher. Your subscriber shouldn’t work anymore because nothing is published anymore on the /temperature topic

33 of 63

What happened?

By using the remapping tag inside the

publisher node, we change the

topic address of publication to /test_remap

All the messages are published on the /test_remap

The subscriber don’t get any message because it is still subscribed to the /temperature topic

34 of 63

What happened?

  • The remap tag <remap from=”/temperature” to=”/test_remap”/> located inside the publisher node change the topics mapping. “From” refers always to the topic indexed inside the publisher/subscriber into the node and “To” refers to the new topic address that we point for the remapping.

  • Here “From” resolve the mapping inside the “publisher.py” executable:

rospy.Publisher('/temperature', Float64, queue_size=10)

  • And change it dynamically thanks to the “To” tag:

rospy.Publisher('/test_remap', Float64, queue_size=10)

35 of 63

Exercice

  • Change your launch file in order to let your “publisher.pycommunicates the temperature to your “subscriber.py” through the “/test_remap” topic. Then instead of publishing the information if the temperature is cold or not on the “/cold_or_hot” topic, publish it on a topic called “/hot_or_cold”. Your application should work the same way as before. You can check it with the “rostopic echo“ commands. Like before launch the application with “roslaunch ros_thermometer basic.launch” and don’t forget to source it beforehand.

36 of 63

What if we want to add some parameter to a rosnode/process ?

  • Remapping is one thing that is important to know in order to bind differents nodes from differents libraries and make them work together thanks to the launch file. Then you will be able to bind a vehicle motor to a joystick and do a lot of others combination of nodes and ros libraries.

  • Another way to dynamically customize a rosnode is to load some static rosparameter inside a rosnode

37 of 63

Loading rosparameter in a rosnode through roslaunch

  • Let’s say, we want to specify in our thermometer publisher if the temperature is computed in Celcius or in Fahrenheit. We need a rosparameter for that.
  • Simplest way to do this is to specify this rosparameter in your launch file like this:

<param name="unit" value="Fahrenheit"/>

  • Param tag is to setup the parameter in the launch file
  • Name is the address of your parameter on the rosmaster
  • Value is the actual value of your parameter

38 of 63

Loading rosparameter in a rosnode through roslaunch

  • Let’s create a new launch file call parameter_testing.launch inside the launch directory. In this launch file, there is our “publisher.py” and “subscriber.py” nodes and I added the initialization of a parameter called unit with fahrenheit as value

<launch>

<param name="unit" value="Fahrenheit"/>

<node name="thermometer_publisher" pkg="ros_thermometer" type="publisher.py" output="screen">

</node>

<node name="thermometer_subscriber" pkg="ros_thermometer" type="subscriber.py" output="screen"/>

</launch>

39 of 63

Loading rosparameter in a rosnode through roslaunch

  • Launch this file with the command roslaunch package name_of_launchfile:

roslaunch ros_thermometer parameter_testing.launch

  • Your application works like before but the thing which is new is the rosparameter loading. To check if it exist on the rosmaster, run the command:

Rosparam list

40 of 63

Loading rosparameter in a rosnode through roslaunch

  • Let’s see what is inside this rosparameter address, with the command rosparam get address_of_parameter . Notice the rosparam “get” work the same way as rostopic echo in the sense it shows information at a ros address.

Rosparam get /unit

  • So now our parameter is registered in ros, we can access it in our python code with the line: your_variable = rospy.get_param(address_of_parameter)
  • Here it will be for an example:

variable = rospy.get_param(“/unit”)

41 of 63

Exercice

  • Launch your parameter_testing.launch
  • Load the “/unit” parameter inside your “publisher.py” by modifying the code and print it in the terminal with “rospy.logwarn(your_variable)” or print(your_variable)
  • Change your parameter_testing.launch file to load “/unit” as Celsius instead of fahrenheit and modify “your publisher.py” accordingly in order to always publish temperature in fahrenheit (assuming your random number generator give celsius values when the “/unit” parameter is set to celsius):

Formula is: (0°C × 9/5) + 32 = 32°F

  • Test your publisher.py output with rostopic echo command

42 of 63

Things to remember:

<param name="unit" value="Fahrenheit"/>

variable = rospy.get_param(“/unit”)

Getting the value of one parameter on the rosmaster in python

Loading rosparameter on the rosmaster throught launch file

Loading rosparameter on the rosmaster throught terminal

Rosparam get /unit

Getting rosparameter on the rosmaster throught terminal

Rosparam set /unit Celsius

43 of 63

Rosparameter namespace

  • Now modify your parameter_testing.launch file, by adding a new unit parameter inside a node like this:

  • Then launch the command :

Rosparam list

<launch>

<param name="unit" value="Celsius"/>

<node name="thermometer_publisher" pkg="ros_thermometer" type="publisher.py" output="screen">

<param name="unit" value="Fahrenheit"/>

</node>

<node name="thermometer_subscriber" pkg="ros_thermometer" type="subscriber.py" output="screen"/>

</launch>

44 of 63

Rosparameter namespace

  • As we can see in the last slide, we loaded two “unit” parameters but with different namespace. If you get them with rosparam get commands, you will notice that the “/thermometer_publisher/unit” is the one that we loaded inside the node in the launch file. And “thermometer_publisher” is the node name. The node namespace has been added to the name of the parameter

  • However the one which will be loaded inside the publisher won’t be this one, as we use this line to get the parameter unit in our publisher:

variable = rospy.get_param(“/unit”) # the “/” before unit represents the absolute path

45 of 63

Rosparameter namespace

  • To load the one that has the namespace “/thermometer_publisher/unit”, you have to use the private parameter character “~” before your namespace. The previous line will then become:

variable = rospy.get_param(“~unit”) # the “~” before unit represents the relative private path

  • Ros will automatically take care of the namespace resolution

  • Try it out by changing your publisher code by adding the private parameter loading and print the 2 types of temperature that you get inside your node to verify it

46 of 63

Rosparameter namespace

  • In your launch file you can also use the tag <group ns=””> which defines a namespace. Modify your launch file with this tag. I used the namespace “test” in it.

  • Now use the following command:

Rosparam list

<launch>

<group ns="test">

<param name="unit" value="Celsius"/>

<node name="thermometer_publisher" pkg="ros_thermometer" type="publisher.py" output="screen">

<param name="unit" value="Fahrenheit"/>

</node>

<node name="thermometer_subscriber" pkg="ros_thermometer" type="subscriber.py" output="screen"/>

</group>

</launch>

47 of 63

Rosparam namespace

  • Your node should have crashed because he can’t load the “/unit” parameter. This is an expected behaviour because the “/unit” parameter is no more present on the rosmaster as we have :”/test/thermometer_publisher/unit” and “/test/unit”
  • To resolve this error, you can change your line:

variable = rospy.get_param(“/unit”) variable = rospy.get_param(“unit”)

  • Removing the “/” (absolute path) character will change how ros resolve the unit namespace. The get_param function will add all the parents namespace tag present in the launch file in front of the “unit” string.
  • The private “~” (private relative path) will just add all the parent namespace tag in front of the “name_of_node/unit”.

48 of 63

Things to remember !

  • “/” Absolute path for get_param will get the whole absolute path of the param
  • “” Public relative path for get_param will add all the namespace parent tag before the name of the param when getting it
  • “~” Private relative path for get_param will add all the namespace parent tag and name of the node before the name of the param when getting it
  • Putting a param tag inside a node tag in the launch file will load the param with the namespace of the node’s name
  • Putting a param tag inside a namespace tag in the launch file will load the param with name of namespace in front of it. This thing is additive with all the parent namespace and nodes.

49 of 63

Things to remember !

  • Definition of a namespace in a launch file

<group ns=”test”>

</group>

  • Ros resolve the address the same way for the parameter, the topics, nodes ...
  • Good practice is :
    • to have “/” (absolute) used for global parameters loaded in severals packages
    • to have “~” (private relative) used for the parameter in a node
    • to have “”(public relative) used for the topic to facilitate remapping them

50 of 63

Multiple parameters loading

  • Using the <param> tag is good to load parameter, the problem is that you have to add one new line for each parameter.
  • To load multiple parameter in one line you should use “yaml” files. A yaml file look like a json file (https://blog.stackpath.com/yaml/)
  • Create in your package a directory called “params” or whatever you want:

mkdir -p ~/whatevername_ws/src/ros_thermometer/params

  • Inside this directory create the file “basic_params.yaml” or whatever name you want with the extension “.yaml”

touch ~/whatevername_ws/src/ros_thermometer/params/basic_params.yaml

51 of 63

Multiple parameters loading

  • Inside this file add some lines. For an example:

  • To load this file as a rosparameter inside your launch file, you should add the line in your launch file:

is_sim: true,

test_yaml: {

x_gain: 0.8,

y_gain: 0.1,

z_gain: 0.4,

center_point: [0.1,0.4,0.3]

}

<rosparam command="load" file="$(find ros_thermometer)/params/basic_params.yaml"/>

52 of 63

Multiple parameters loading

  • Your launch file should look like this then:

<launch>

<group ns ="test">

<rosparam command="load" file="$(find ros_thermometer)/params/basic_params.yaml"/>

<param name="unit" value="Celsius"/>

<node name="thermometer_publisher" pkg="ros_thermometer" type="publisher.py" output="screen">

<param name="unit" value="Fahrenheit"/>

</node>

<node name="thermometer_subscriber" pkg="ros_thermometer" type="subscriber.py" output="screen"/>

</group>

</launch>

53 of 63

Multiple parameters loading

  • Launch this launch file and check the rosparam list:

Rosparam list

  • As you can see, all our parameters inside our yaml file have been loaded. Moreover, they respect their parent namespace (/test) because we loaded the file inside a namespace.
  • There is also a difference between the parameter defined at the root of our yaml file and the parameters which are son of the “test_yaml” object in our yaml file. This “test_yaml” namespace has been added to these parameter while loading. You can check the data inside these parameters with rosparam get

54 of 63

Conclusion

  • Now you should understand the concept behind rosnodes, rostopics, rosparameters and the resolution of namespace in ros
  • If you want a blank python package that you have to fullfill with your code, clone the package at this address:

Git clone http://192.168.1.101/infrastructure/ros_python_package_template

You will have to rename the project name in the CMakelist.txt and package.xml, the python class, the name of the executable and the import to your convenience. Easiest way to do it is to open it inside pycharm,

Use the Ctrl+Shift +R shortcut and replace all the ros_python_package_template occurence to your package name. Then rename the scripts/executables files

55 of 63

Ros network and ros tools

56 of 63

Ros network

  • For now we have launch all our nodes on a local machine but we need to be able to send some data over the network in order to let sensors/robots exchange informations between each other or just to command them.

  • To do so, 2 things are important to setup:
    • Make sure that the robots can ping the rosmaster laptop
    • Make sure that the differents nodes are launch in a configured ros environment

57 of 63

Ros network: pinging part

  • First of all define which laptop will you use as a rosmaster and then run on it the command. It will give you some IP informations :

ifconfig

wlo1: represents here my wifi port on the

Local machine

Inet below it: 192.168.1.241 represents my

IP address on my wifi network

58 of 63

Ros network: pinging part

  • From another laptop, I will use the ping command ping IP_Address:

Ping YOUR_ROSMASTER_IP_ADDRESS

  • If the command works, you should see something like this:

Do the same from all the others robots to the rosmaster or from the rosmaster to all the others robots. Using the ifconfig to get their IP address

59 of 63

Ros Network: environment of the nodes

  • Now you are sure that the rosmaster can communicate with other robot through the network
  • Remember the rosmaster register all the nodes / topics/ parameters on it, everything is set as an address on it and the rosmaster will take care of routing the informations between the differents robots.
  • However, it is important for each node to know where the rosmaster is and where they are relative to the whole network. To do so, 2 environment variables have to be set before running the node.

60 of 63

Ros Network: environment of the nodes

  • Modify the file ~/.bashrc on the rosmaster by adding the following line:

export ROS_IP=xxx.www.zzzz.aaa (ip of computer on the network)

Here the ip of my rosmaster is 192.168.1.241, so:

export ROS_IP=192.168.1.241 (ip of computer on the network)

I will add this line in my ~/.bashrc. You can open this file using: gedit ~/.bashrc or nano ~/.bashrc in a terminal

61 of 63

Ros Network: environment of the nodes

  • Modify the file ~/.bashrc on the other robots by adding the two following line:

export ROS_MASTER_URI=http://xxx.www.zzzz.aaa:11311 (ip of the remote master on the network)

export ROS_IP=xxx.www.zzzz.aaa (ip of the current robot on the network)

Here the ip of my rosmaster is 192.168.1.241, so:

export ROS_MASTER_URI=http://192.168.1.241:11311 (ip of the remote master on the network)

export ROS_IP=xxx.www.zzzz.aaa (ip of the robot on the network depending on the ifconfig result on this robot can be whatever 192.168.1.XXX)

I will add these two lines in their ~/.bashrc. You can open this file using: gedit ~/.bashrc or nano ~/.bashrc in a terminal

62 of 63

Ros Network: environment of the nodes

  • When you will have modify all these ~/.bashrc files on all the laptop, open a new terminal on the rosmaster and run a roscore on it.
  • Notes that opening a new terminal will automatically source the ~/.bashrc file into the newly created terminal. If you don’t want to create a new terminal, you can also use the command:

source ~/.bashrc

  • It will setup the current terminal environment. When it is done, launch the node that you want in it. The newly created node will interact with your remote rosmaster and the others robots. Ros take care of everything in the background

63 of 63

Exercise

  • Using 2 laptops, try to launch your “publisher.py” on one laptop and the “subscriber.py” on the other laptop and test if your ros_thermometer application still work. You can launch whichever node you want on the rosmaster : publisher or subscriber; You will have to break your basic.launch file into to part to differentiate the launch of your publisher and the one of your subscriber. Then launch one on them on the rosmaster and second on the other laptop