Rosanswers logo

Hi All,

Had anyone had any success creating a reasonable map in ROS with just sonar and odometry data?

If so I'd like to know what map type; setup etc you used.

Currently the map is a mess (An only home brew solution works just fine) so I'm sure it must be possible.

FYI the Sonar data is being published as both Range and laser_scan message types.

EDIT - Sonar Laser Code for benefit of others:

bool ToeminatorROSBridge::publishSonarAsLaserData(ros::Time time, RobotData* pRobotData)
tf::TransformBroadcaster laser_broadcaster;
ros::NodeHandle n;

// Laser/Sonar Range Test
bool publish_laser = true;
n.param("publish_laser", publish_laser, publish_laser);
ros::Publisher laser_pub;

     laser_pub = n.advertise<sensor_msgs::LaserScan>("sonar_laser_scan", 1000);

unsigned int num_readings = 7;
double laser_frequency = 2;
//populate the LaserScan message
sensor_msgs::LaserScan scan;
   scan.header.stamp = time;
   scan.header.frame_id = "base_laser";
   scan.angle_min = -1.57;
   scan.angle_max = 1.57;
   scan.angle_increment = 3.14 / num_readings;
   scan.time_increment = (1 / laser_frequency) / (num_readings);
   scan.range_min = 0.0;
   scan.range_max = 10.0;


   for(int i=1; i<=7; i++)
    scan.ranges[i] = pRobotData->SonarMeasurements[i-1]/100.0; // Convert to Meters             

laser_broadcaster.sendTransform(tf::StampedTransform(tf::Transform(tf::createQuaternionFromRPY(0, 0, degree_to_radian(ROS_FrontSonarAngle)), 
                                                                    tf::Vector3(0.0, 0.15, 0.0)),
return true;

Many Thanks


Originally posted by MarkyMark2012 on ROS Answers with karma: 1834 on 2012-08-15

Post score: 1

Original comments

Comment by Kristof on 2013-07-14:
Hi Mark, Did you make any progress on this? I am currently grappling with the exact same question. Thanks!

Comment by MarkyMark2012 on 2013-08-27:
Hi Kirstof - sorry for the late reply.

No not really - I upgraded to groovy and knackered my system & not really had time to sort it out. I was slightly perplexed why I couldn't get anything decent when my home brew app could do a reasonable job.

Comment by albert on 2016-05-25:
Hi Mark, I did the same thing with 13 sonar. But have problem to clear obstacles in map when the obstacle is not there anymore. Can you give me some advice?

Comment by MarkyMark2012 on 2016-05-31:
@albert What map(s) set up do you have?

Comment by albert on 2016-06-01:
I used the costmap_2d package in the navigation stack,

Comment by bill on 2017-01-12:
can you upload the code of costmap_2d ? i have the same problem

Comment by ahendrix on 2017-01-12:
costmap_2d is part of the navigation stack. Like most ROS packages, the link to the source code is on the costmap_2d wiki page, and that points to github: https://github.com/ros-planning/navigation

Comment by bill on 2017-01-13:
i mean ,how you connect the sonar data with the costmap_2d, sorry for the stupid question but i am new in ros

Comment by MarkyMark2012 on 2017-01-13:
@bil - Whilst I never did it - other suggest creating a course laserscan - the data of which is made up from the sonar results

Comment by ahendrix on 2017-01-13:
There's also now a costmap layer specifically for range (IR and ultrasonic) sensors: http://wiki.ros.org/range_sensor_layer . @bill if you have further specific questions it would be better to ask a new question.


4 Answers 4


Rosanswers logo

Ultrasonic sensors suffer from several drawbacks such as bandwith and cross-sensivity. Published accuracy values for ultrasonics are based on perpendicular reflections of the sound wave off an acoustically reflective material. Narrow opening angle for the sound beam in order to obtain precise directional information about objects that are encountered, you cannot acquire depth data points but rather entire regions of constant depth this means the sensors tell us only that there is a object at the area of the measurement cone. If two or more sonar's are fired together then they could pick up each other "ping" resulting in a false readings. These limitations make ultrasonic rangers bad map builders in my opinion. Hope helps you

Originally posted by cagatay with karma: 1850 on 2012-08-16

This answer was ACCEPTED on the original site

Post score: 1

Original comments

Comment by MarkyMark2012 on 2012-08-16:
Yep I know - as mentioned maps I've generated in the past (as have others) - non ROS give a resonable depiction of the environment. I'm thinking SLAM needs more data in this case. Any suggestion for a simple occupancy grid I could use?


Rosanswers logo

I've never tried it.

Maybe someone has succeeded, but most people report needing something more accurate, like a laser range finder.

Originally posted by joq with karma: 25443 on 2012-08-16

This answer was NOT ACCEPTED on the original site

Post score: 1

Original comments

Comment by MarkyMark2012 on 2012-08-16:
My home brew (non-ROS) mapping s/w does a reasonable job. It's a dynamic occupancy grid however. Was hoping there was a ROS way :)

Comment by TimboInSpace on 2014-04-18:
Would you be able to post your homebrew solution somewhere? I'm attempting a very similar project and am about to go down the ultrasonic > laserscan conversion route. Also did you eventually have any success with this approach?

Comment by MarkyMark2012 on 2014-04-22:
Hi - Nope didn't get anywhere with it annoyingly - although trying to get an XTION to play ball at the moment. Re home brew solution - the core is a Bayesian probability map with a navigation side. Nothing to do with ROS - not sure if that's what you want?

Comment by Mehdi. on 2016-04-04:
"nothing to do with ROS" what does that even mean? Just wrap your code into a ROS package and let people use it if it is as good as it sounds.

Comment by MarkyMark2012 on 2016-05-31:
means I wrote my own algo's/mapping/nav code from scratch

Comment by scopus on 2017-10-22:
hi,@MarkyMark2012, which slam packages did you use for sonar slam? gmapping, karto? Thanks!

Comment by TimboInSpace on 2017-10-23:
Not sure about MarkyMark2012, but I used mine with gmapping on a fairly coarse map. Worked decently in the end. Good luck!

Comment by scopus on 2017-10-24:
Thank you very much for your advices@TimboInSpace


Rosanswers logo

I did something similar.

Since most of the packages use a laser message you can construct a laser_scanner message using the different readings of your sonar and then use this message in any of the Slam packages available on ROS. However the results may not be very good depending on the quality of the readings.

Originally posted by Mario Garzon with karma: 802 on 2012-08-16

This answer was NOT ACCEPTED on the original site

Post score: 4

Original comments

Comment by MarkyMark2012 on 2012-08-16:
Yeah that's what I've done - the 7 sonars are represeted as 7 laser_scan messages. Although results are very poor. Did you get anything approaching that of usable out of it? Part of the problem, I think, is that the cone of the sonar isn't represented.

Comment by mukut_noob on 2016-04-07:
Hello mark, I am also thinking of doing the same thing with Sonar...but where did u write the code for it? And how?

Comment by MarkyMark2012 on 2016-04-07:

I used the laser message format to construct a message from the sonar data. Obviously this data is very course on comparison and to be honest the results weren't that good.

I'll put the code when I get a chance if you need it


Comment by mukut_noob on 2016-04-07:
Yes please! It would be very helpful.

Comment by MarkyMark2012 on 2016-04-11:
Added to the original question

Comment by mukut_noob on 2016-04-12:
Okk thank you very much...BTW what microcontroller are u using?

Comment by mukut_noob on 2016-04-12:
Actually I am on a Raspberry Pi 2 and For the Sonar I need to mention the gpio pin numbering so where can I do it and can the code that u have written be written in python?

Comment by MarkyMark2012 on 2016-04-12:
Re Python - Yes that can be converted, then you can add the sonar driver/gpio code to it.

Comment by mukut_noob on 2016-04-12:
Are there any tutorials on how to write a node in python?

Comment by Mario Garzon on 2016-04-12:
We used 5 sonars distributed (more or less 35° between each other) They were controlled by an Arduino. The laser scanner message was created by repeating each sonar reading 35 times, to have one degree for each "laser" data. This worked for avoiding obstacles, similar to a bumper but not for mapping

Comment by MarkyMark2012 on 2016-04-13:
@mukut_noob - yes loads start here - http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28python%29

Comment by sohartma on 2020-01-17:
@mukut_noob Did you convert the code to python? Can you post it?


Rosanswers logo

Hi MarkyMark,

I have had success with this setup. I made a small differential-drive bot that mapped using sonar, wheel odometry, and inertial sensors. Some of the key parts that made it work:

  • Stagger your sonar sensor's phase, especially if the sensors are looking in the same direction (or opposite by 180degrees). Use time division on the sampling. This greatly reduces noise.
  • BUFFER YOUR SONAR DATA. This is extremely important! My implementation used two sonar sensors that swept side to side. To get it to work, I had to buffer it for ~0.5s (thus creating a "laserscan" of about 25 data points) - it will not work very well if you publish single- or two-point "laserscans"
  • Use a coarse occupancy gridmap. I had good results with only 2.5cm pixels and large. (Also, since I was doing this on an arduino, it was a great way to drop the floating point numbers and use raw bytes instead)
  • Your localization will suffer from the extra delay due to buffering the sonar. If your robot doesn't need to respond quickly, it's better to use a coordinate transform snapshotted during the middle of the buffering operation, not at the end.

So YES this was a success for my project. Slow localization wasn't an issue for the environment I was using the robot in. If you have an extra couple hundred dollars, I'd opt for a cheap laserscanner. The objective of my project was to do SLAM on as small a budget as possible.

Originally posted by TimboInSpace with karma: 141 on 2016-05-31

This answer was NOT ACCEPTED on the original site

Post score: 3

Original comments

Comment by roborag on 2017-01-21:
Hi Timboln, I am using a similar setup with 5 sonar, odometry and imu with arduino. can you give some more idea on converting sonar data to laser data ? any links or video of ya robot will help. I want to do collision avoidance and localization in a known map.

Comment by jxl on 2017-04-13:
@TimboInSpace,what did you mean " Use time division on the sampling. BUFFER YOUR SONAR DATA,To get it to work, I had to buffer it for ~0.5s (thus creating a "laserscan" of about 25 data points)",how did you create 25 points with your 2 sonars? Thanks a lot

Comment by Mbuijs on 2018-05-28:
Example: assuming the range is 3 meters, the time needed to capture 1 sample is (6 m / 340 m/s) = 0.0029 s. Rounding down. Assuming that you get up to 5 measurements per sample and running nav stack at 10 Hz, that results in 25 measurements per cycle.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.