ROS packages for ROS Melodic related to perception running on a Raspberry Pi 4 B for an autonomous 2WD Robot to sense in the environment.
Grove - Ultrasonic Ranger
To avoid obstacles the Grove ultrasonic ranger from Seeed Studio is used. We will create a ROS package with catkin create pkg PKG_NAME [--catkin-deps [DEP [DEP ...]]]
:
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
The package depends on the two ROS client libraries rospy
and roscpp
.
To signalise the current distance to obstacles the sensor_msgs/Range
message is used.
After connecting the signal pin of the sensor to (physical) GPIO 11 of the Raspberry Pi 4 B and power it with 5V and ground, we can test its functionality with the available
python script ultrasonic.py
from Seed Studio.
The following shows the truncated output of the ultrasonic.py
script when moving an obstacle in front of the sensor. We see that the distance value changes as expected.
fjp@ubuntu:~/git/2wd-robot/ros/src/grove_ultrasonic_ranger/src$ sudo python ultrasonic.py
SeeedStudio Grove Ultrasonic get data and print
Ultrasonic Measurement
Distance : 2.0 CM
Ultrasonic Measurement
Distance : 2.1 CM
Ultrasonic Measurement
Distance : 2.0 CM
Ultrasonic Measurement
Distance : 3.5 CM
Ultrasonic Measurement
Distance : 3.5 CM
Ultrasonic Measurement
Distance : 2.4 CM
Ultrasonic Measurement
Distance : 12.9 CM
...
Ultrasonic Measurement
Distance : 45.8 CM
Ultrasonic Measurement
Distance : 510.7 CM
Ultrasonic Measurement
Distance : 510.7 CM
Ultrasonic Measurement
Distance : 45.7 CM
Ultrasonic Measurement
Distance : 161.8 CM
Ultrasonic Measurement
Distance : 26.9 CM
Ultrasonic Measurement
Distance : 18.3 CM
Ultrasonic Measurement
Distance : 160.9 CM
Ultrasonic Measurement
Distance : 158.3 CM
Ultrasonic Measurement
Distance : 159.4 CM
...
Modified GroveUltrasonicRanger Library
To use the ultrasonic ranger as a ROS node it is convenient to wrap the sensor functionality in a class.
This provides an easy to extend interface for the ultrasonic ranger (API)
Therefore I copied the core functionality of the ultrasonic.py
script from Seeed Studio in a class named GroveUltrasonicRanger
.
Executing the grove_ultrasonic_ranger.py
will result in the following output:
fjp@ubuntu:~/git/2wd-robot/ros/src/grove_ultrasonic_ranger/src$ sudo python grove_ultrasonic_ranger.py
SeeedStudio Grove Ultrasonic get data and print
Distance : 0.051 m
Distance : 0.069 m
Distance : 0.098 m
Distance : 0.131 m
Distance : 0.153 m
Distance : 0.172 m
Distance : 0.207 m
Distance : 0.210 m
Distance : 0.234 m
Distance : 0.256 m
GPIO.cleanup()
GPIO.cleanup() done
ROS Node for Ultrasonic Ranger
ROS provides the Range Message in the sensor_msgs header. This message type can be used to write a wrapper that will act as a ROS node for the Grove ultrasonic sensor.
To design this node we will send out measurements periodically over a topic of type sensor_msgs/Range
.
The code for this node is in ranger.py
.
After writing the node we need to build the packages in the workspace with catkin build
.
fjp@ubuntu:~/git/2wd-robot/ros$ catkin build
----------------------------------------------------------------
Profile: default
Extending: [env] /opt/ros/melodic
Workspace: /home/fjp/git/2wd-robot/ros
----------------------------------------------------------------
Build Space: [exists] /home/fjp/git/2wd-robot/ros/build
Devel Space: [exists] /home/fjp/git/2wd-robot/ros/devel
Install Space: [unused] /home/fjp/git/2wd-robot/ros/install
Log Space: [missing] /home/fjp/git/2wd-robot/ros/logs
Source Space: [exists] /home/fjp/git/2wd-robot/ros/src
DESTDIR: [unused] None
----------------------------------------------------------------
Devel Space Layout: linked
Install Space Layout: None
----------------------------------------------------------------
Additional CMake Args: None
Additional Make Args: None
Additional catkin Make Args: None
Internal Make Job Server: True
Cache Job Environments: False
----------------------------------------------------------------
Whitelisted Packages: None
Blacklisted Packages: None
----------------------------------------------------------------
Workspace configuration appears valid.
NOTE: Forcing CMake to run for each package.
----------------------------------------------------------------
[build] Found '1' package in 0.0 seconds.
[build] Updating package table.
Starting >>> catkin_tools_prebuild
Finished <<< catkin_tools_prebuild [ 9.9 seconds ]
Starting >>> grove_ultrasonic_ranger
Finished <<< grove_ultrasonic_ranger [ 12.0 seconds ]
[build] Summary: All 2 packages succeeded!
[build] Ignored: None.
[build] Warnings: None.
[build] Abandoned: None.
[build] Failed: None.
[build] Runtime: 21.9 seconds total.
[build] Note: Workspace packages have changed, please re-source setup files to use them.
As the final note of the build output suggests, we have to source
the setup.bash
files in the devel
space.
fjp@ubuntu:~/git/2wd-robot/ros$ source devel/setup.bash
To make the ranger
node executable we have to modify the ranger.py
file:
fjp@ubuntu:~/git/2wd-robot/ros/src/grove_ultrasonic_ranger/src$ sudo chmod a+x ranger.py
Then we can test the node using rosrun
:
fjp@ubuntu:~/git/2wd-robot/ros$ sudo su
[sudo] password for fjp:
root@ubuntu:/home/fjp/git/2wd-robot/ros# source devel/setup.bash
root@ubuntu:/home/fjp/git/2wd-robot/ros# rosrun grove_ultrasonic_ranger ranger.py
Distance : 1.617 m
Distance : 1.617 m
Distance : 1.617 m
Distance : 0.108 m
Distance : 0.092 m
Distance : 0.099 m
This lets the node publish range messages which we can capture in another terminal window using rostopic
.
First we use rostopic list
to find the name of the topic we are interested in:
fjp@ubuntu:~/git/2wd-robot/ros$ rostopic list
/distance
/rosout
/rosout_agg
We named our topic /distance
which we can use with the rostopic echo
command to see the published messages:
fjp@ubuntu:~/git/2wd-robot/ros$ rostopic echo /distance
header:
seq: 1
stamp:
secs: 1576778377
nsecs: 746809959
frame_id: "ranger_distance"
radiation_type: 0
field_of_view: 0.261799007654
min_range: 0.019999999553
max_range: 3.5
range: 1.61674261093
---
header:
seq: 2
stamp:
secs: 1576778378
nsecs: 459048986
frame_id: "ranger_distance"
radiation_type: 0
field_of_view: 0.261799007654
min_range: 0.019999999553
max_range: 3.5
range: 1.61261284351
---
header:
seq: 3
stamp:
secs: 1576778379
nsecs: 172172069
frame_id: "ranger_distance"
radiation_type: 0
field_of_view: 0.261799007654
min_range: 0.019999999553
max_range: 3.5
range: 1.61657905579
---
header:
seq: 4
stamp:
secs: 1576778379
nsecs: 884002923
frame_id: "ranger_distance"
radiation_type: 0
field_of_view: 0.261799007654
min_range: 0.019999999553
max_range: 3.5
range: 1.61277639866
---
header:
seq: 5
stamp:
secs: 1576778380
nsecs: 596549034
frame_id: "ranger_distance"
radiation_type: 0
field_of_view: 0.261799007654
min_range: 0.019999999553
max_range: 3.5
range: 1.67693090439
---
Informational Distance Measurements
To provide additional information when an obstacle is too close or the robot has no obstacle in front of it we use REP-117 as guideline.
To successfully implement this REP, checks for valid measurements should use floating-point standards and follow this form:
if(minimum_range <= value && value <= maximum_range){ // Represents expected pre-REP logic and is the only necessary condition for most applications.
// This is a valid measurement.
} else if( !isfinite(value) && value < 0){
// Object too close to measure.
} else if( !isfinite(value) && value > 0){
// No objects detected in range.
} else if( isnan(value) ){
// This is an erroneous, invalid, or missing measurement.
} else {
// The sensor reported these measurements as valid, but they are discarded per the limits defined by minimum_range and maximum_range.
}
Comments