The HomeBrewed Ultrasonic ROS2 Sensor

11 views
Skip to first unread message

camp .

unread,
Sep 17, 2025, 2:40:14 PM (5 days ago) Sep 17
to HomeBrew Robotics Club
Hello Andrew!
    This is for you!

    Last year, the "ROS Discussion Group" created a "HomeBrewed Ultrasonic ROS2 Sensor" based on the ROS2 "Simple Publisher" tutorial.

    We basically combined this Python-based ultrasonic sensor program:

Using a Raspberry Pi distance sensor (ultrasonic sensor HC-SR04)

    With the ROS2 Simple Publisher:

Writing a simple publisher and subscriber (Python)

    First, connect the Raspberry Pi and HC-SR04 distance sensor according to the Python-based ultrasonic sensor program above, ensuring it works in Python before converting it into a ROS2 topic.

    Next, create the "simple publisher" (and subscriber) as instructed on the Pi and ensure it works. That is, you type "ros2 run py_pubsub talker" and it says, "hello world." Then, in another terminal window, type "ros2 run py_pubsub listener"; it should hear the text, "hello world."

    Finally, replace "publisher_member_function.py" and "ultrasonic_distance.py" with the modified contents from this GitHub:

cpeavy2/Smarty_Head

    "ultrasonic_distance.py" needs to be in the same directory as "publisher_member_function.py."

    You'll need to compile (colcon build).

    Launch "talker" and then "ROS2 topic echo /distance." You should then see the ultrasonic distance expressed as the topic "/distance."

    What we've observed is that when no obstacles are detected, the Python program displays a solid 12-meter reading. In contrast, when viewed through the "ROS2 topic echo /distance," the value appears to fluctuate erratically, ranging from 1 to 12. When an obstacle is detected, the reading is solid.

    The hypothesis is that the different timing of the Python program and the Simple Publisher causes this volatility.

Thanks,
Camp


agmiller

unread,
Sep 17, 2025, 6:25:15 PM (5 days ago) Sep 17
to HomeBrew Robotics Club



From GPIO's ReadMe...
  "Note that this module is unsuitable for real-time or timing critical applications. This is because you can not predict when Python will be busy garbage collecting. It also runs under the Linux kernel which is not suitable for real time applications - it is multitasking O/S and another process may be given priority over the CPU, causing jitter in your program. "

For the  HomeBrewed Ultrasonic ROS2 Sensor, the concern was with these While() loops that check for the transition of the GPIO_ECHO pin, here...
   https://github.com/cpeavy2/Smarty_Head/blob/12df90a05ddbd04d0a1b4748d3d0792b24aa4946/modded_ultrasonic_distance.py#L31

1) When the loop is checking and rechecking GPIO_ECHO, Python can jump off to execute some other thread, or to do garbage collection and house cleaning.  By the time Python returns to running this loop, it can be long after the pin has changed state. This will add jitter to the TimeElapsed values.    On a busy system, the echo pulse could even be missed, and there is no max timeout checking in the loop code.  Threading delays would not be an issue for the simple single-threaded Python program, but the ROS publisher has timers and callbacks that should be expected to deregulate the looping timer.

2) Similar to the jitter introduced by Python threading, Ubuntu's multiprocessing kernel would also periodically disrupt Python, adding jitter to the TimeElapsed values in a similar way.  Giving the Publisher process higher scheduler priority (lower Nice() value) would help, but would not alleviate the multiprocessing interruptions.

I respect the effort made to handle these sensors directly.  The typical solution is to use a dedicated microcontroller that can perform the time of flight measurement in realtime.

I might try to rewrite this module to use GPIO's interrupt callbacks.  This would add max timeout values, and might better detect pin state changes.  It would not be realtime, but it might be more consistent than the current code.

The best solution would be to integrate the sensor readings.   Save the last five or last eleven ElapsedTime values, and publish the median value from that list.  You would still publish at the same sample rate, but jittery high and low false readings would be ignored.   This sample integration should have minimal impact on mapping, except on extremely fast moving bots.

- Andrew -

Marco Walther

unread,
Sep 17, 2025, 7:05:04 PM (5 days ago) Sep 17
to hbrob...@googlegroups.com
All what Andrew wrote is true!!

When I looked around for the best way to do this kind of thing with the
Raspberry Pi, I came across a close cousin of the HC-SR04, the US-100.
That seems to be able to all the measurements internally (in one of it's
modes) and talk 9600 baud serial to the 'computer'. That would probably
be a much better way to handle this with a Pi alone;-)

https://www.adafruit.com/product/4019

Does somebody have experience with that sensor [in serial mode]?

Thanks,
-- Marco
> sr04/ <https://tutorials-raspberrypi.com/raspberry-pi-ultrasonic-
> sensor-hc-sr04/>
>
>     With the ROS2 Simple Publisher:
>
> Writing a simple publisher and subscriber (Python)
> https://docs.ros.org/en/jazzy/Tutorials/Beginner-Client-Libraries/
> Writing-A-Simple-Py-Publisher-And-Subscriber.html <https://
> docs.ros.org/en/jazzy/Tutorials/Beginner-Client-Libraries/Writing-A-
> Simple-Py-Publisher-And-Subscriber.html>
>
>     First, connect the Raspberry Pi and HC-SR04 distance sensor
> according to the Python-based ultrasonic sensor program above,
> ensuring it works in Python before converting it into a ROS2 topic.
>
>     Next, create the "simple publisher" (and subscriber) as
> instructed on the Pi and ensure it works. That is, you type "ros2
> run py_pubsub talker" and it says, "hello world." Then, in another
> terminal window, type "ros2 run py_pubsub listener"; it should hear
> the text, "hello world."
>
>     Finally, replace "publisher_member_function.py" and
> "ultrasonic_distance.py" with the modified contents from this GitHub:
>
> cpeavy2/Smarty_Head
> https://github.com/cpeavy2/Smarty_Head <https://github.com/cpeavy2/
> Smarty_Head>
>
>     "ultrasonic_distance.py" needs to be in the same directory as
> "publisher_member_function.py."
>
>     You'll need to compile (colcon build).
>
>     Launch "talker" and then "ROS2 topic echo /distance." You
> should then see the ultrasonic distance expressed as the topic "/
> distance."
>
>     What we've observed is that when no obstacles are detected, the
> Python program displays a solid 12-meter reading. In contrast, when
> viewed through the "ROS2 topic echo /distance," the value appears to
> fluctuate erratically, ranging from 1 to 12. When an obstacle is
> detected, the reading is solid.
>
>     The hypothesis is that the different timing of the Python
> program and the Simple Publisher causes this volatility.
>
> Thanks,
> Camp
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "HomeBrew Robotics Club" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to hbrobotics+...@googlegroups.com
> <mailto:hbrobotics+...@googlegroups.com>.
> To view this discussion visit https://groups.google.com/d/msgid/
> hbrobotics/bfa20158-3b5d-41c0-bb5f-fa7c930ee455n%40googlegroups.com
> <https://groups.google.com/d/msgid/hbrobotics/bfa20158-3b5d-41c0-bb5f-
> fa7c930ee455n%40googlegroups.com?utm_medium=email&utm_source=footer>.

agmiller

unread,
Sep 17, 2025, 7:54:16 PM (5 days ago) Sep 17
to HomeBrew Robotics Club

Another interesting enhancement to this module would be to support multiple SR04 sensors, sequencing their pings to avoid sonic interference from each other.     

- A - 

Marco Walther

unread,
Sep 17, 2025, 8:05:08 PM (5 days ago) Sep 17
to hbrob...@googlegroups.com
Then you `really` want a micro controller and just send the results
upstream.

I believe, the original Arduino Ultrasonic sensor library already
supports up to eight sensors. You just have to order them in a way that
they don't read each other;-)

-- Marco

>
> - A -
>
> --
> You received this message because you are subscribed to the Google
> Groups "HomeBrew Robotics Club" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to hbrobotics+...@googlegroups.com
> <mailto:hbrobotics+...@googlegroups.com>.
> To view this discussion visit https://groups.google.com/d/msgid/
> hbrobotics/a4803a76-a430-4765-aa39-346970e3c910n%40googlegroups.com
> <https://groups.google.com/d/msgid/hbrobotics/a4803a76-a430-4765-
> aa39-346970e3c910n%40googlegroups.com?utm_medium=email&utm_source=footer>.

Steve " 'dillo" Okay

unread,
Sep 18, 2025, 4:22:33 PM (4 days ago) Sep 18
to HomeBrew Robotics Club
On Wednesday, September 17, 2025 at 6:05:08 PM UTC-6 Marco Walther wrote:
On 9/17/25 16:54, 'agmiller' via HomeBrew Robotics Club wrote:
>
> Another interesting enhancement to this module would be to support
> multiple SR04 sensors, sequencing their pings to avoid sonic
> interference from each other.

Then you `really` want a micro controller and just send the results
upstream.

I believe, the original Arduino Ultrasonic sensor library already
supports up to eight sensors. You just have to order them in a way that
they don't read each other;-)

...or something like this which can handle up to 8 sonars and manages the sequencing for you :) 
I've got this on Tenacity for the front & back sonars:
https://www.tindie.com/products/arielnh56/octosonar-connect-8-x-hc-sr04-to-arduino/

Demo(from a few years ago) of it in action:
https://www.youtube.com/watch?v=5bhV57BE6UQ

HTH,
'dillo

 
Reply all
Reply to author
Forward
0 new messages