Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interfacing RPLidar to EV3/ev3dev #491

Closed
bmegli opened this issue Jan 5, 2016 · 32 comments
Closed

Interfacing RPLidar to EV3/ev3dev #491

bmegli opened this issue Jan 5, 2016 · 32 comments

Comments

@bmegli
Copy link
Member

bmegli commented Jan 5, 2016

In bmegli/ev3dev-mapping#1 @jabrena said:

Today, I will try to connect the RPLidar with the USB Adapter directly in order to know if it is possible to receive data:
http://www.slamtec.com/en-US/rplidar/index/5

If you have time, check some PDFs here:
http://www.slamtec.com/static/media/2014/09/rplidar/rplidar_sdk_v1.4.5.7z
rplidar_sdk_v1.4.5\doc\en.US\rplidar_sdk_manual_en.pdf

@bmegli
Copy link
Member Author

bmegli commented Jan 5, 2016

@bmegli replied

If you have time, check some PDFs here:

Hardware-Wise:

Yes, it should be possible to use it both with USB adapter and directly (soldering somewhat in line with XV11 Lidar, not exactly)

The USB adapter uses CP2102 chip for USB2UART bridge. The driver should be already included in any modern linux kernel (CP210x).

In fact it's included in ev3dev kernel tree:

ev3dev-kernel\drivers\usb\serial\cp210x.c

So good news - USB2UART bridge used in your adapter should be working out of the box in ev3dev. Anyway, after plugging the device type:

dmesg | tail

to make sure.

Software-Wise later if I have time.

@bmegli
Copy link
Member Author

bmegli commented Jan 5, 2016

More from @bmegli

Software-Wise sketch:

When you connect the adapter the USB2UART bridge should be reachable at:

/dev/ttyUSB0 or something along the line

You will have to compile the driver/sample applications from the SDK.
You have two basic routes here:

  1. You can compile it directly on your EV3
  2. You can setup a cross-compiler and compile it on your PC

Anyway, follow SDK documentation.

For building on EV3 you will probably need something along the lines:
apt-get install build-essentials

Maybe something more.

You will definitely encounter some problems along the way and get three or four headaches ;-)

But... it's also certainly doable.

Good luck.

@bmegli
Copy link
Member Author

bmegli commented Jan 5, 2016

Even more from @bmegli

Ok, some final remarks and guesses.

When you build SDK you will also end up with static or dynamic library with RPLidar driver API.

You can use this library also from Java.

Ugh, and we should move the RPLidar integration discussion to separate thread.

@bmegli
Copy link
Member Author

bmegli commented Jan 5, 2016

Oh, ok.

I see that you are communicating with it somewhat directly from Java or is it some Arduino library?

You don't have to compile the SDK driver library if you don't need it.

You can directly communicate using dev/ttyUSB0 (or something...) if you already know how.
So it may be a matter of converting your code from Wire Arduino notation to UART communication (some form of read/write with all the abstractions java provides).

And final remark (ok, so the last final wasn't final):

EV3 will not be probably fast enough to read samples one be one and process them at the same time (doing odometry and stuff in below milisecond time).

You will probably end up packetizing the LIDAR readings to some say k samples read, processing/odometry and next k samples or some other scheme you can think about (e.g. reading asynchronously and processing odometry in the meantime, whatever you like).

@bmegli
Copy link
Member Author

bmegli commented Jan 5, 2016

So it may be a matter of converting your code from Wire Arduino notation to UART communication

Or may be not because communicatiation with the device may be different from communication with the adapter (which handles also the engine)

@jabrena
Copy link

jabrena commented Jan 5, 2016

Give me some hours, Normally I had the device with Arduino, I am going to test with the USB Adapter.

@jabrena
Copy link

jabrena commented Jan 5, 2016

Hi @bmegli,

It run nice in EV3Dev!!!

I connected the LIDAR 2D with the USB Adapter and the system recognize the device. Later I started reading /dev/ttyUSB0

Details:

root@ev3dev:/home# lsusb
Bus 001 Device 003: ID 10c4:ea60 Cygnal Integrated Products, Inc. CP210x UART Bridge / myAVR mySmartUSB light
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Details:

root@ev3dev:/home# lsusb -D /dev/bus/usb/001/003
Device: ID 10c4:ea60 Cygnal Integrated Products, Inc. CP210x UART Bridge / myAVR mySmartUSB light
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x10c4 Cygnal Integrated Products, Inc.
  idProduct          0xea60 CP210x UART Bridge / myAVR mySmartUSB light
  bcdDevice            1.00
  iManufacturer           1 Silicon Labs
  iProduct                2 CP2102 USB to UART Bridge Controller
  iSerial                 3 0001
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              2 CP2102 USB to UART Bridge Controller
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
Device Status:     0x0000
  (Bus Powered)

I compiled the driver without any problem and I run the example included with the SDK:

make[2]: Leaving directory '/home/sdk/sdk/app/ultra_simple'
make[1]: Leaving directory '/home/sdk/sdk/app'
root@ev3dev:/home/sdk/sdk# ls
Makefile  cross_compile.sh  mak_def.inc  output    sdk
app       mak_common.inc    obj          prebuild  workspaces
root@ev3dev:/home/sdk/sdk# cd output/
root@ev3dev:/home/sdk/sdk/output# ls
Linux
root@ev3dev:/home/sdk/sdk/output# cd Linux/
root@ev3dev:/home/sdk/sdk/output/Linux# ls
Release
root@ev3dev:/home/sdk/sdk/output/Linux# cd Release/
root@ev3dev:/home/sdk/sdk/output/Linux/Release# ls
librplidar_sdk.a  simple_grabber  ultra_simple
root@ev3dev:/home/sdk/sdk/output/Linux/Release# ./ultra_simple 
RPLidar health status : 0
S  theta: 1.66 Dist: 00400.25 Q: 30 
   theta: 2.88 Dist: 00401.75 Q: 26 
   theta: 4.00 Dist: 00405.75 Q: 20 
   theta: 5.27 Dist: 00409.75 Q: 12 
   theta: 6.39 Dist: 00000.00 Q: 0 
   theta: 6.72 Dist: 00611.75 Q: 14 
   theta: 7.84 Dist: 00618.50 Q: 16 

The another example program run nice too:

root@ev3dev:/home/sdk/sdk/output/Linux/Release# ./simple_grabber 
Simple LIDAR data grabber for RPLIDAR.
Usage:
./simple_grabber <com port> [baudrate]
The default baudrate is 115200. Please refer to the datasheet for details.
root@ev3dev:/home/sdk/sdk/output/Linux/Release# ./simple_grabber /dev/ttyUSB0 115200
RPLIDAR S/N: 95C299F3C1E39AF2A2E09AF006133230
Firmware Ver: 1.14
Hardware Rev: 0
RPLidar health status : OK. (errorcode: 0)
waiting for data...


                                                    ***                    
                                                    *****                  
                                                    *****                  
                                                    *****                  
                                                  * *****                  
                                                  * *****                  
                                                  * *****                  
                                                  *******                  
                                                  *******                  
                                                  *******                  
                                          *       *******                  
                                       ** ****** ********                  
                                       ******************                  
                                       *******************                 
 *                                    ********************              *  
****                                  ********************         ********
*****                                 ******************** ****************
***************************************************************************
---------------------------------------------------------------------------
Do you want to see all the data? (y/n) 

I suppose that the object used to manage the device is: librplidar_sdk.a

I will research a bit to know how to connect with Java.

Tomorrow, I will continue with the library.
https://github.com/jabrena/ev3dev-lang-java/milestones/0.2.0

💃 💃 💃

@bmegli
Copy link
Member Author

bmegli commented Jan 6, 2016

This is super-awesome!

Good job and good luck with further work.

@bmegli
Copy link
Member Author

bmegli commented Jan 6, 2016

One more thing that occured to me..

I sometimes build wrappers for native libraries to .Net. While it is possible to do it manually there are now tools that make it automatically.

Same should be true for Java. Before coding a manual wrapper for the API look for a tool that can do it for you (basically generate java classes automatically).

The tools are usually not perfect and you have to correct some errors afterwards but they spare you a lot of work.

@jabrena
Copy link

jabrena commented Jan 6, 2016

Yes, one alternative could be the creation of a Wrapper.

Another alternative could be coding a driver directly. In github, exist some Drivers. The commands to handle this sensor are:

Start_Scan = "\xA5\x20" #Begins scanning
Force_Scan = "\xA5\x21" #Overrides anything preventing a scan
Health = "\xA5\x52" #Returns the state of the Lidar
Stop_Scan = "\xA5\x25" #Stops the scan
RESET = "\xA5\x40" #Resets the device

So, using this serial library:
https://github.com/rxtx/rxtx

I could develop a Class to manage RPLidar.

Using apt, it is easy to install the library:

apt-get install librxtx-java

Another interesting library could be:
https://github.com/Pi4J/pi4j/
http://pi4j.com/example/serial.html

In Python side, exist a driver ready to run. Yesterday, I tested it too.
https://github.com/jmccormack200/RPLidar/blob/master/LidarPrint.py

root@ev3dev:/home# cd python/
root@ev3dev:/home/python# python LidarPrint.py 
/dev/ttyUSB0
Connecting
...
(146, 131)
(147, 132)
(148, 133)
(150, 134)
(151, 135)
(154, 135)
(156, 137)
(158, 139)
(161, 140)
(164, 141)
(166, 142)

Pic running:
https://scontent-mad1-1.xx.fbcdn.net/hphotos-xpf1/v/t1.0-9/8137_10153343872143527_7861294983472015783_n.jpg?oh=7428a88e1205632b6bec2239b8ecec61&oe=5700BAF1

@bmegli
Copy link
Member Author

bmegli commented Jan 6, 2016

And another one: JTermios

http://www.sparetimelabs.com/purejavacomm/purejavacomm.php

Choices, choices... ;-)

@bmegli
Copy link
Member Author

bmegli commented Jan 11, 2016

Ok, I am closing it for now. Let me know if you want to reopen for some reason.

To sum up, this is what you have achieved:

  1. The original USB adapter for RPLidar works out of the box in ev3dev. One can communicate with the device using /dev/ttyUSB0
  2. The RPLidar API and samples from the SDK can be compiled and run without problem.

C/C++ language:

RPLidar is ready to use almost out of the box

Other languages:

One can probably use the API or communicate using /dev/ttyUSB0 directly. This can still be a major chalenge.

@sarandaegus
Copy link

sarandaegus commented Dec 18, 2016

Hi, i am new in this forum, i had try run the code python "LidarPrint.py" with my RPLIDAR A2, but this not funcionally, i only change the next line code:

if __name__ == "__main__":
    #COM4 was used on my computer, this will change based on
    #your setup and whether you're on Windows/Mac/Linux
    #port = '/dev/ttyUSB0'
    #port = 20
    port = "/dev/ttyUSB0"
    ser = serial.Serial(port, 115200, timeout = 5)
    ser.setDTR(False)
    print ser.name
    #Create a Lidar instance, this will immidiately start printing.
    #To edit where the data is sent, edit the GetPoints Method
    lidar = Lidar(ser)

i understand thar i have to change the last code line, because i am working in Debian Software (Linux) and the COM port dont exist, the usb port of the sensor is "/dev/ttyUSB0"

when i run this, appears this:

/dev/ttyUSB0
Connecting
...

I have to work with the sample code of RPLIDAR (ultra_simple, simple_grabber) and this work in raspberry.

somebody know what is the problem? @bmegli @jabrena

Please, i am waiting for yours responses. this is for mi master's degree tesis.

Thank you

Sergio Aranda

@rhempel
Copy link
Member

rhempel commented Dec 18, 2016

When is the thesis due?

@sarandaegus
Copy link

Hi, On February but this had to be complete at last days on January.
Sorry for my english.

@bmegli bmegli reopened this Dec 20, 2016
@bmegli
Copy link
Member Author

bmegli commented Dec 20, 2016

Hi @sarandaegus,

First - I don't own RPLidar so my help will be limited.

ultra_simple, simple_grabber

Those are officially supported by LIDAR manufacturer and you should follow documantation here:

http://www.slamtec.com/download/lidar/documents/en-us/LR002_SLAMTEC_rplidar_sdk_v0.1_en.pdf

@jabrena followed it and got it working so it seems to be the right path.

The easiest would be to build SDK directly on EV3 (e.g. call make in SDK directrory with makefile provided that you have gcc toolchain installed)

"LidarPrint.py"

As I understand by "LidarPrint.py" you mean that one:

https://github.com/jmccormack200/RPLidar/blob/master/LidarPrint.py

This is in theory place where you should ask but the repository seems to be abandoned.

I would start from the one which tries to start scan and just outputs raw hex data:

https://github.com/jmccormack200/RPLidar/blob/master/Lidar_Tests/LinuxHello.py

If nothing comes out on the screen I would investigate the connection with the device/tty settings/drivers layer.

Maybe @jabrena who owns RPLidar and got it working can be of more help.

other ways

I would probably start by using some tool I know for serial communication like picocom and send the scan command to LIDAR according to its communication protocol:

http://www.slamtec.com/download/lidar/documents/en-us/LR001_SLAMTEC_rplidar_protocol_v0.2_en.pdf

This is more-or-less equivalent to LinuxHello.py.

other ideas

Are you using USB hub? (is RPLidar the only thing plugged to your EV3 USB? If not it may not be /dev/tty/USB0)

@sarandaegus
Copy link

sarandaegus commented Dec 20, 2016

Hi @bmegli thank you for response.

Ok i only use raspberry pi conected for usb port with the RPLIDAR sensor, i dont have EV3.

Ultra_simple and simple_grabber is run ok in my raspberry.

The problem is when i run LidarPrint.py, now i jut run the LinuxHello.py code, and it is ok, onle appear in my screem : a55a0500004081, only these, the datasheet say me that this is ok, but now i have new question : how control the motor ? it is automatic.

And '/dev/USB0' is correctly connected.

I am using RPLIDAR A2. the second version

sorry for my english

Sergio

@bmegli
Copy link
Member Author

bmegli commented Dec 20, 2016

@sarandaegus you should probably be asking those questions at slamtec

but now i have new question : how control the motor ? it is automatic.

Is it automatic or you need to control it?

A quick scan through RPLidar SDK docs at slamtec shows that:

Function Name Brief Introduction
startMotor()
Request RPLIDAR to start the motor rotating.
For RPLIDAR A1, this interface will enable DTR to set the motor
start rotating by default.
For RPLIDAR A2, this interface will start the motor by using the
default duty cycle and configure the rotating speed.
stopMotor() Request RPLIDAR to stop the motor rotating.

So for RPLidar A1 it was somehow connected to serial DTR (it might have been false that made it active, don't assume that enable DTR means set it to true)

For RPLidar A2 it is something else.

A glimpse through the SDK code reveals that:

u_result RPlidarDriverSerialImpl::startMotor()
{
    if (_isSupportingMotorCtrl) { // RPLIDAR A2
        setMotorPWM(DEFAULT_MOTOR_PWM);
        delay(500);
        return RESULT_OK;
    } else { // RPLIDAR A1
        rp::hal::AutoLocker l(_lock);
        _rxtx->clearDTR();
        delay(500);
        return RESULT_OK;
    }
}


u_result RPlidarDriverSerialImpl::setMotorPWM(_u16 pwm)
{
    u_result ans;
    rplidar_payload_motor_pwm_t motor_pwm;
    motor_pwm.pwm_value = pwm;

    {
        rp::hal::AutoLocker l(_lock);

        if (IS_FAIL(ans = _sendCommand(RPLIDAR_CMD_SET_MOTOR_PWM,(const _u8 *)&motor_pwm, sizeof(motor_pwm)))) {
            return ans;
        }
    }

    return RESULT_OK;
}

... reveals that it sends command RPLIDAR_CMD_SET_MOTOR_PWM on serial with some argument specyfying motor power.

To sum up:

  • it seems that the python code you are using has motor control for RPLidar A1 (motor by clearing DTR)
  • for RPLidar A2 you may have to send command to set motor pwm at some level, if it's not automatic when sending Scan

Finally - consult your official documentation, everything seems to be there.

@bmegli
Copy link
Member Author

bmegli commented Dec 20, 2016

So you may have to replace:

ser.setDTR(False)

with

ser.write(Set_Motor_PWM)

where Set_Motor_PWM is message to be constructed according to RPLidar protocol. You may have to read it's answer also.

Consult the docs for the details

@jabrena
Copy link

jabrena commented Dec 23, 2016

hi @sarandaegus,

The Script which I used was for RPLIDAR v1. Any progress with the comment from @bmegli ?

I will buy this new model this year but at the moment, I don´t have the device at home to help you directly.

Another alternative for this Script, could be create a wrapper from C output with Python/Java if you continue blocked. Last year, I was testing integrating Python with Java but maybe to avoid this kind of problems another alternative is creating a bridge directly from Driver from Slamtec.
http://intermediate-and-advanced-software-carpentry.readthedocs.io/en/latest/c++-wrapping.html
http://www.slamtec.com/download/lidar/sdk/rplidar_sdk_v1.5.7.zip

Another alternative is using a ROS node, but in this case, the complexity of the solution will increase.
https://github.com/robopeak/rplidar_ros

Merry Christmas everyone on #EV3Dev

Cheers

Juan Antonio

@sarandaegus
Copy link

sarandaegus commented Dec 23, 2016

Hi everybody! Already solved the problem!.

I tried another metod, I want to share with you all.

Ok, first you need to download the .rar in your raspberry pi. normaly this is the folder.

if you know, you need write: make in sdk/ if you wanto to create 'obj' and 'output' and run the demo "ultra_simple" or "simple_grabber".

Go to:

pi@raspberrypi:~/sdk/app/ultra_simple $ nano main.cpp

Here you add new line code, in my case i need to capture the "theta" and "distance" and transmit via UART port connected xbee module.

before that you add new library, because you will use GPIO raspberry, go to:

pi@raspberrypi:~/sdk/app/ultra_simple $ nano Makefile

image

the new line is in color red, "wiringpi" is a library for GPIO for defect is instally en RPI3, if you dont have this, you need downloand this, and "-lm" this call a library math.h

if all is ok, return a sdk and write:

pi@raspberrypi:~/sdk $ make

after:

pi@raspberrypi:~/sdk/output/Linux/Release $ sudo ./ultra_simple

I hope it helps.

Thank you

Thanks everyone for your help

Sorry for my english.

Sergio Aranda

@jabrena
Copy link

jabrena commented Dec 24, 2016

Congrats Sergio

Cheers

@sarandaegus
Copy link

sarandaegus commented Dec 26, 2016

https://www.youtube.com/watch?v=2PQa9VWxrGs

@bmegli
Copy link
Member Author

bmegli commented Dec 26, 2016

Ok!

Great that you got it working, thanks for the link!

I admit I got a little confused what you had working and what you had problem with ;-)
(e.g. I thought you had SDK examples working and problem with 3rd party python script)

Nice mix of LIDAR with XBEE communication.

I am closing the issue again, this had little to do with ev3dev from the start ;-)

@bmegli bmegli closed this as completed Dec 26, 2016
@Jerwinprabu
Copy link

I have connected lidar with raspberry. On board, I have installed QT. Can I get a sample c++ code for reading data from lidar?

@bmegli bmegli reopened this Mar 1, 2019
@bmegli
Copy link
Member Author

bmegli commented Mar 1, 2019

Depending who you ask and what concerns you.

There are examples in official rplidar-sdk

See:

  • README.md
  • sdk/app/...

@bmegli
Copy link
Member Author

bmegli commented Mar 1, 2019

There is also sample C++ code here that I wrote for my private experiments to make this:

image

But:

  • this is my "private" development branch, it is totally unsupported
  • it uses rplidar-sdk in non-standard way reading data in small chunks and timestamping it
  • it reads from lidar and sends UDP data
  • to another "private" development branch of ev3-dev-mapping-ui, totally unsupported
  • it doesn't have future, as I already found a way to timestamp the data with greater precision

Even if unsupported and non-standard, the C++ code for reading from rplidar is there as yet another example.

@Jerwinprabu
Copy link

Depending who you ask and what concerns you.

There are examples in official rplidar-sdk

See:

  • README.md
  • sdk/app/...

But only for windows examples are available, not for Linux.

@Jerwinprabu
Copy link

There is also sample C++ code here that I wrote for my private experiments to make this:

image

But:

  • this is my "private" development branch, it is totally unsupported
  • it uses rplidar-sdk in non-standard way reading data in small chunks and timestamping it
  • it reads from lidar and sends UDP data
  • to another "private" development branch of ev3-dev-mapping-ui, totally unsupported
  • it doesn't have future, as I already found a way to timestamp the data with greater precision

Even if unsupported and non-standard, the C++ code for reading from rplidar is there as yet another example.

I will try this.

@bmegli
Copy link
Member Author

bmegli commented Mar 2, 2019

But only for windows examples are available, not for Linux.

rplidar-sdk examples

  • ultra_simple
  • simple_grabber

are cross-platform (work on Linux). This is the code you are probably looking for (how to read data from lidar in C++).

I don't remember about the third example (frame_grabber). It might have been Windows specific.


On ev3dev-mapping

Even if unsupported and non-standard, the C++ code for reading from rplidar is there as yet another example.

I will try this.

This is just if you want the code example.

Unsupported means that I am not going to help with running it.

Non-standard means that this is not how most people would read from rplidar. It just solves my specific problems which are probably not your problems.


Bottom line - try rplidar-sdk examples.
They are meant as a starting point for reading from lidar in C++.

@bmegli
Copy link
Member Author

bmegli commented Mar 4, 2019

Ok, I am closing the issue, this had little to do with ev3dev (again...).

@bmegli bmegli closed this as completed Mar 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants