Projects Research & Design Hub

Taking RPLIDAR Out for a Spin (Part 2)

Written by Jeff Bachiochi

Intelligence Upgrade

In Part 1, Jeff stepped you through the hardware and software development choices in his project using RPLIDAR, a 360-degree laser range scanner that uses a laser triangulation ranging principle to calculate distance. In Part 2, he looks at the plot made using the Liberty Basic application, and determines exactly what data he needs to make his project more user friendly.

  • How to program a 360-degree laser scanner
  • How to invoke API commands using a serial terminal program
  • How to work with RPLIDAR’s API commands
  • How to use Liberty Basic to make a plotting program
  • Pololu A-Star module
  • Slamtec RPLIDAR-A1 360 laser range scanner
  • Arduino Mega module
  • Liberty Basic

I was almost run down this week in a parking lot. I had just finished a conversation with a friend and was walking across the active area of the lot toward my Jeep. I turned back to shout to my friend, and out of the corner of my eye I saw a car exiting a parking space. The driver obviously didn’t see me, even though I was standing directly in his path. As I jumped to the side, my hand smashed down on the front hood of his Tesla. Startled by the noise, the driver quickly hit the brakes. If I hadn’t leaped out of the way, I would now be a hood ornament. He opened his window to ask if I was all right. I said, “I thought the Tesla had an autopilot.” He said he was distracted with the radio and hadn’t turned it on yet!

Call me old fashioned, but I don’t think I will ever put my life, those of my passengers or others outside my vehicle on the line by giving up control of my car to an automaton. Driving an automobile is not only a pleasure, but also a massive responsibility. Imagine walking around with a cocked and loaded weapon in your hand, trying not to point it at anyone. That’s a scary thought. Even those with a carry permit know a gun is never pointed at anything they don’t intend to shoot. The gun and automobile both have the ability to maim or kill.

The one piece of tech that is most used by autonomous vehicles is LIDAR. I began last month to investigate the RPLIDAR being sold by Shanghai Slamtec. For $100 you can have a 360-degree laser scanner. Please refer back to last month’s article (March 2020, Circuit Cellar 356) [1] to get the skinny on this device. The API, which is explained in the Interface Protocol and Application Notes available on the Slamtec website [2], handles commands through the module’s serial interface. A TTL/USB dongle allows the device to plug into your PC. Using a serial terminal, you can send commands to the RPLIDAR and receive data packets containing continual measurements.

OFFLOADING THE MCU
Anyone who has worked with microcontrollers (MCUs) knows that there is a limitation on how much work can be done before running out of horsepower. I’ve been touting the advantages of offloading tasks to other processors, so you don’t get bogged down with the low-level stuff. The RPLIDAR seems to be a case in point. I don’t want my MCU to have to process a stream of data from the RPLIDAR, because it has better things to do. This led me to devising an interim interface that can handle the RPLIDAR stream of data. To do this, I used an Arduino, which exposes a user-friendly side to the RPLIDAR’s API.

Last month’s project [1] created an interface that accepted two-letter text commands and translated them into API functions. By typing in “SC” for instance, you can begin a scan command. Under API control, the scan sends out a laser pulse, measures its reflection, computes a distance to object, and sends out a 5-byte data packet. This happens continuously. The data packet contains reflection strength, angle in degrees and distance in millimeters. The LSB of the reflection strength is set to a “1” after it passes 0 degrees, so you can tell when a complete rotation has been made. Note: Every scan begins wherever the rotating head happens to be at the time. Angles are arbitrary and cannot be controlled.

I wanted to limit the streaming to at least one complete rotation at a time, so that I could build a table of distance entries based on angles 0-359. After the streaming data has filled the table, I automatically stop the scan and allow the users to retrieve any or all data they are interested in. It seems to me that many times you don’t need all that data, so I added my own commands for narrowing down what I want. More on this shortly.

— ADVERTISMENT—

Advertise Here

I left off last month explaining how to write a small Liberty Basic program to display 360 degrees of data, just to help assure me that my data was correct. You can refer to Figure 1 to see a scan of my dining room using RPLIDAR, the Arduino interface and the Liberty Basic program to display the data. The small black ring is the RPLIDAR. The larger red ring is 1 meter radius from RPLIDAR. Using the ZOOM function, the display data (and 1-meter ring) is adjusted to an appropriate scale for the window size.

FIGURE 1. The Liberty Basic program I wrote for last month’s Part 1 article demonstrates the scan capabilities of the RPLIDAR laser scanner. LB gives me a quick tool for writing PC applications—in this case, to visualize the scan data extracted from RPLIDAR’s serial communication channel.

Based on the 1-meter ring, you can estimate the room as being 12′ × 20′ (4 × 7 meters). The Liberty Basic program requests a scan, and then creates a 360-element array, consisting of the distances that the RPLIDAR calculates for each measurement. As stated earlier, the process is asynchronous, so scan measurements begin wherever the rotating head is at the time the command is given. Potentially, you may not get 360 measurements in one rotation.

You could increase the number of sampling rotations to fill in any angles that were missed the first time. There may be angle entries in the array that were not measured, either because they didn’t occur during the process, or the distances were outside the min and max distances. Whether the laser bounces off an object and sufficient energy is received back at the receiver depends on an object’s material, color, target size and surface angle.

ADDITIONAL COMMANDS
Now we get to the real purpose of this project. When an MCU is used to operate a robotic platform, it shouldn’t have to waste execution time asking for a scan, receiving 360 degrees of data and making some analysis to determine the best way to proceed. In last month’s article, I used an Arduino MEGA2560 to prototype the circuit. It has multiple hardware serial ports. This would not fit well on the RPLIDAR module. However, since the RPLIDAR uses a piggyback board to take the LIDAR and MOTOR connections and bring them into a single header, this PCB could be replaced with one on which our project is built. To accomplish this, I used an A-Star from Pololu [3]. The A-Star uses a MEGA328PB, which also has multiple hardware serial ports, but in a DIP26 0.6″ package.

The A-Star has an onboard USB connector, so it is programmable without a dongle. TTL serial ports are brought out with all I/O through the DIP pins. Not much I/O is used on the A-Star, other than one hardware serial port to the RPLIDAR and one hardware serial port to any external robotic platform, and a single output to control the RPLIDAR motor. While RPLIDAR requires 5V to operate, the serial port transmit line is at a 3.3V level. In many instances, the 5V TTL input on your MCU would interpret the 3.3V level correctly, but in this case, it was not seen at all by the A-Star. It wasn’t until I added a level translator on the RPLIDAR’s transmit line that the A-Star’s port began to read the transmitted data.

To use this project, my external platform needs a serial port. Even a software serial port will work here, because we no longer have to deal with transmitting and receiving at the same time. Just make a request and get a terse response, with no calculations. Let’s look at the extra commands (menu items) beyond those available in the RPLIDAR’s API.

To help make this project user-friendly, all commands are implemented using two ASCII characters with an ending <CR>. While these are easy to use, I often add a displayable menu. If you forget what’s available, just type in a “?”. The menu is split into two parts for convenience. The original API commands are given in Listing 1 in black, and my added commands are highlighted in red. Listing 2 shows the sub-menu.

RP Lidar 2-Letter Menu
SCan
INfo
DAta
Clear Path
Object Path

Sub Menu
2-Letter plus ‘=’ and a value
Angle Left of center=? (0-180), presently aaa
Angle Right of center=? (0-180), presently aaa
Distance miN (mm)=? (100-150), presently ddddd
Distance maX (m)=? (0-15), presently dddddd

? this menu

LISTING 1 – The menu is split into two parts for convenience, the menu shown here and a sub menu (Listing2). Here, the original API commands are given in in black, and my added commands are highlighted in red.

— ADVERTISMENT—

Advertise Here

RP Lidar 2-Letter Sub Menu
REset
STop
HEalth
Sample Rate
Mode Count
maX Distance
Answer Type
Time per Sample
Mode Typical
Mode Name
2-Letter plus ‘=’ and a value
ID=? (0-2), presently #
RPm=? (0-255)
? main menu

LISTING 2 – API commands sub menu

It’s important to remember here that the “SCan” API command continuously sends 5-byte angle/distance packets, until you send a “STop” command. I’ve modified this to stop automatically, once 360 degrees of data has been received. All other API commands merely pass on their responses. It also can be noted that most API commands do not require any input. The last four of my extra commands set the boundaries for the first two extra command responses.

The “Clear Path” command returns the angle at which RPLIDAR has found no objects for the longest distance. The “Object Path” command returns the angle at which RPLIDAR has found the nearest object. Certainly, you could pull this information from an array of 360 distances. However, all this data might very well overload your MCU. To make these two commands more practical, the four additional commands allow you to limit or filter the results.

Separate “Angle Left” and “Angle Right” of center filters keep the answer relevant to the situation. As your need becomes more specific, you can narrow the search area. Initially, you may want to choose a general direction of travel based on the longest straight shot. Once a direction has been established, you may wish to reduce the angle of coverage to avoid objects that may be within your path.

The second filter is “Distance maX” and “Distance miN.” These allow the response to stay within the two distances. All distances outside these will be not be considered. Therefore, if you find one object, you can eliminate it by adjusting the max or min and requesting another path command. Both max and min angle and distance filters remain at their present values until redefined, even if another “SCan” command is requested. Path commands will continue to use the data collected since the last “SCan” command.

We’ve seen how the “SCan” command has been modified to collect 360 degrees of data and then stop scanning. Last month’s article demonstrated how the “Data” command could be used in the Liberty Basic RPLIDAR mapping application, to verify that the angle/distance packets were being received correctly. Our extra commands will now operate on the data as collected by the “SCan” command, without having to absorb the total 360-degree array by our controlling MCU. All the heavy lifting is done by this project, and simple answers are returned to the requestor.

APPLYING LIMITS
Setting limits allows a response to become more meaningful. Gathering data with the last four commands is accomplished by extending the two-letter commands to include the “=” character and a decimal value. The equal sign in a command is used to index into a received string to locate the user’s input value (Listing 3).

n = Serial.readBytesUntil(0x0D, userInput, lengthUC);
if(userInput[0]>0x1F)
{
userCommand = (userInput[0]);
userSubCommand = (userInput[1]);
if(userInput[2] == ‘=’)
{
valueCommand = 0;
for(x = 3; x < n; x++)
{
valueCommand = (valueCommand * 10) + (userInput[x] - 0x30);
}
valueCommand = valueCommand * MySign;
}
}

LISTING 3 – As shown here, gathering data with the last four commands is accomplished by extending the two-letter commands to include the “=” character and a decimal value.

Gathering the decimal number (valueCommand) is handled on a digit basis. If a new digit is found, it gets added to any (previous value × 10). Normally the RPLIDAR or any other distance-measuring device is affixed to the platform, such that measurements are referenced to the front. For ease of use, we’ll consider the front to be 0 degrees, with increasing angles to the right (clockwise) and decreasing angles to the left (counter clockwise). Commands for angles are therefore referenced to 0 degrees. An angle to the left is subtracted from 360 degrees, and an angle to the right is added to 0. The 360-degree array (entry offsets 0-359) is therefore searched from the left angle to the end of the array (359 degrees), and also from 0 degrees to the right angle.

The “Distance maX” and “Distance miN” commands are used to intentionally eliminate certain distances—either those closer than the minimum or those further away than the maximum distance. For instance, you would use these if you see an object at 48” at angle 30 degrees, and reduce the maximum distance to 45”. Based on the same data, if the new angle to an object 45″ away is less than 30 degrees, you may be approaching a barrier that is closer to the left. Otherwise, you may be approaching a barrier that’s closer to the right.

By using a combination of “Clear Path” and “Object Path” commands, you can find the safest direction to move, while avoiding objects directly in your path. I used different routines for each of these commands, first “Clear Path,” as shown in Listing 4. Initially, the Clear Path distance (myDistance) is set to the distanceMin. This is only increased when a distance in any of the checked angle array offsets (distance[]) is less than the distanceMax and greater than the myDistance. All the angles from 0 degrees to angleRight and angleLeft to 0 degrees are checked.

// from 0 to angleRight and from angleLeft to 259,
// find Angle with longest distance
myDistance = distanceMin;
for(int a=0; a<=angleRight; a++)
{
if(distance[a]<distanceMax && distance[a]>myDistance)
{
myDistance = distance[a];
myAngle = a;
}
}
for(int a=360+angleLeft; a<=359; a++)
{
if(distance[a]<distanceMax && distance[a]>myDistance)
{
myDistance = distance[a];
myAngle = a;
}
}

LISTING 4 – Routine for the “Clear Path” command

— ADVERTISMENT—

Advertise Here

In the Object Path command (Listing 5), (myDistance) is set to the distanceMax. The variable, myDistance is only decreased when a distance in any of the checked angle array offsets (distance[]) is greater than the distanceMin and less than the myDistance. All the angles from 0 degrees to angleRight and angleLeft to 0 degrees are checked.

// from 0 to angleRight and from angleLeft to 259,
// find Angle with shortest distance
myDistance = distanceMax;
for(int a=0; a<=angleRight; a++)
{
if(distance[a]>distanceMin && distance[a]<myDistance)
{
myDistance = distance[a];
myAngle = a;
}
}
for(int a=360+angleLeft; a<=359; a++)
{
if(distance[a]>distanceMin && distance[a]<myDistance)
{
myDistance = distance[a];
myAngle = a;
}
}

LISTING 5 – Routine for the “Object Path” command

IMPLEMENTATION
Last month, I showed the Arduino MEGA 2560 board connected to the RPLIDAR, using TTL serial connections. While the schematic remains the same, I removed the RPLIDAR’s piggyback PCB that just takes the motor and LIDAR connectors and combines them into a single connector, which is used by the supplied TTL-to-USB dongle for connection to a PC. This was used by the Liberty Basic application that ran on the PC, producing the dining room map shown in Figure 1.

A piece of protoboard was cut to fit the RPLIDAR in place of its piggyback interface PCB. I needed to purchase the appropriate motor and LIDAR connectors, to be able to connect the existing RPLIDAR cables to my new interface PCB. The Pololu A-Star actually comes in four models—3.3V and 5V, each with either 16MHz or 20 MHz speeds. I used the 5V, 16MHz model for compatibility with the MEGA.

The A-Star comes in a DIP24 0.6″ format. I soldered-on the included male headers, so I could use plug-in female strips on the prototype board. Other than the seven connections for the RPLIDAR (which now includes a level shifter on RX2), the other serial ports’ TTL connections were brought out to a header socket, which makes it easy to connect to any platform to which I wish to add distance measurements (Figure 2).

FIGURE 2 – With the original Arduino MEGA 2560—a bit large to be retrofitted to the RPLIDAR—I substituted an Pololu A-Star module and mounted it on a piece of protoboard cut to fit as a replacement for the RPLIDAR 8piggyback PCB.

This requires only 5V, ground, TX and RX from the external device. RPLIDAR requires approximately 500mA to start up. Once started, this will remain under that value even with the motor enabled, which draws approximately 100mA by itself. Figure 3 shows the finished project.

FIGURE 3 – The finished system is no larger than the original RPLIDAR, but now it is much smarter, and can be effectively used even with less powerful MCUs.

When the original piggyback board was removed, I found some unused circuitry on the bottom of the PCB (Figure 4). This PCB has “Robo peak screen printer” on the top side, so I Googled this and found a website [4] on which it states: “RoboPeak is a research & development team in robotics platforms and applications, founded in 2009.” I could find no mention of this circuitry, and no apparent contact info.

FIGURE 4 – When I removed the original piggyback PCB from the RPLIDAR, I found an unpopulated mystery circuitry on its bottom. So far no information has been discovered about it, other than that it was made by RoboPeak.

It’s pretty easy to see that this unpopulated circuitry was made to interface RPLIDAR to an MCU. There is also a USB connector that would eliminate the need for a dongle when connecting to a PC. It’s too bad that information on this isn’t available, because it might be just what I believe is necessary to make this usable with smaller controllers.

BEYOND THE BOT
Do you have a 3D printer? How about a 3D scanner? Given the accuracy of the RPLIDAR, I think it could be used as a full body scanner. Rotate the RPLIDAR 90 degrees, so it scans vertically. Mount it at about 36″ from the floor, and it should give a pretty good accounting of a thin slice of large object. We simply need to rotate RPLIDAR around the object to take 360 slices. Of course, it would be easier to rotate the object in front of the RPLIDAR. This would require an indexing Lazy Susan—preferably, one with a very large weight capacity. Hmm, I smell another project. Too much to do, so little time. 

RESOURCES

References:

[1] March 2020, Circuit Cellar 356
[2] http://bucket.download.slamtec.com/b42b54878a603e13c76a0a0500b53595846614c6/LR001_SLAMTEC_rplidar_protocol_v1.1_en.pdf
[3] A-Star microcontrollers by Polulu:  https://www.pololu.com/category/149/a-star-programmable-controllers
[4] Website for Robo peak:  www.robopeak.com

Pololu | www.pololu.com
Slamtec | www.slamtec.com

PUBLISHED IN CIRCUIT CELLAR MAGAZINE • APRIL 2020 #357 – Get a PDF of the issue


Don't miss out on upcoming issues of Circuit Cellar. Subscribe today!

 
 
Note: We’ve made the October 2017 issue of Circuit Cellar available as a free sample issue. In it, you’ll find a rich variety of the kinds of articles and information that exemplify a typical issue of the current magazine.


Would you like to write for Circuit Cellar? We are always accepting articles/posts from the technical community. Get in touch with us and let's discuss your ideas.

Become a Sponsor
Website | + posts

Jeff Bachiochi (pronounced BAH-key-AH-key) has been writing for Circuit Cellar since 1988. His background includes product design and manufacturing. You can reach him at: [email protected] or at: www.imaginethatnow.com.