Packages are the main unit for organizing software in ROS. A package may contain ROS runtime processes (nodes), a ROS-dependent library, datasets, configuration files, or anything else that is usefully organized together. Packages are the most atomic build item and release item in ROS. Meaning that the most granular thing you can build and release is a package.
For this autonomous 2WD robot project the nodes run on a Raspberry Pi 4 to act in an environment according to sensor information.
When possible, the default name of a node should follow from the name of the executable used to launch the node. This default name can be remapped at startup to something unique.
Following REP-144 this means that each sensor will get its own package with one or more nodes to be executed. Following this scheme it will be possible to use the sensors in other projects and work with existing packages such as packages from the navigation stack.
Steps to using ROS to Control a Robot
The steps to using ROS to control a new robot areref:
- Decide on the ROS message interface.
- Write drivers for the robot’s motors.
- Write a model of the robot’s physical structure.
- Extend the model with physical properties for use in simulation with Gazebo.
- Publish coordinate transform data via tf and visualize it with rviz.
- Add sensors, with driver and simulation support.
- Apply standard algorithms, such as navigation.
Packages and Nodes
Using Sensors and Actuators in ROS
To integrate new sensors and actuators into the ROS ecosystem involves writing ROS wrappers around the APIs that we’re already using to access these devices.
If a sensor already has a Python API it is relatively straightforward to use sensors in ROS. First you should always verify that things are working as expected before you start to wrap up a sensor in ROS. If you know that the sensor is working, then anything that goes wrong will be a problem with the ROS wrapper, which will make things easier to debug.
In ROS there are two ways to work with sensor data. One way is that the sensor publishes topics which other nodes can subscribe to. Another way is that the sensor node provides measurments only when asked for using either a service or action call which other nodes can use and thereby act as clients. This decision depends on how we are going to use the sensor.
Another decision to make is how we’re going to access data from the sensor, which depends on the sensor.
Finally we need to decide what type of ROS message our wrapper will produce. Whenever possible we should use existing ROS message types because it allows us to reuse the wrapped sensor with other nodes that use the same interface types.
Create a new Catkin package
$ catkin create pkg PKG_NAME [--catkin-deps [DEP [DEP ...]]]
For example the
grove_ultrasonic_ranger package is created with the following command:
fjp@ubuntu:~/git/2wd-robot/ros/src$ catkin create pkg grove_ultrasonic_ranger --catkin-deps rospy roscpp sensor_msgs Creating package "grove_ultrasonic_ranger" in "/home/fjp/git/2wd-robot/ros/src"... Created file grove_ultrasonic_ranger/CMakeLists.txt Created file grove_ultrasonic_ranger/package.xml Created folder grove_ultrasonic_ranger/include/grove_ultrasonic_ranger Created folder grove_ultrasonic_ranger/src