Skip to content

Latest RPLidar firmware has broken this library #15

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

Closed
zlite opened this issue Mar 1, 2021 · 26 comments
Closed

Latest RPLidar firmware has broken this library #15

zlite opened this issue Mar 1, 2021 · 26 comments
Assignees

Comments

@zlite
Copy link
Contributor

zlite commented Mar 1, 2021

Starting in 2021, all RPLidar hardware is shipping with firmware 1.29, which breaks this library (error shown is "Incorrect descriptor starting bytes", but that just means that it got no data). Slamtec says that this may be due to the default scan mode being changed to boost mode. They say that they do not support Python(!) and are not intending to fix these libraries. They say it's up to us to fix them ourselves :-(

AFAIK there is no way to downgrade the firmware to a previous version (last known good was 1.27), so I think that until distributors can get Slamtec to help fix these libraries, we have to now consider the RPLidar devices unsupported in Python

@ladyada
Copy link
Member

ladyada commented Mar 1, 2021

@zlite is there a document with the protocol output for 1.29

@zlite
Copy link
Contributor Author

zlite commented Mar 1, 2021

Yes, it's here. I don't think that the protocol has changed, but rather the default mode has changed from standard to boost.

@ladyada
Copy link
Member

ladyada commented Mar 1, 2021

doesn't look like there's that much different, wanna take a poke at adding a scan mode query check

@caternuson
Copy link

(error shown is "Incorrect descriptor starting bytes", but that just means that it got no data).

Is it that or because something changed in the return and this check now fails:

if not descriptor.startswith(SYNC_BYTE + SYNC_BYTE2):
raise RPLidarException("Incorrect descriptor starting bytes")

Try enabling logging which should print the actual descriptor value.

@zlite
Copy link
Contributor Author

zlite commented Mar 5, 2021

Looks like another Python library solved it this way:
Roboticia/RPLidar@787ff8d

@makermelissa
Copy link
Collaborator

Hi, do you have any idea where to download firmware 1.29? It looks like the latest on their website is 1.27.0 (https://www.slamtec.com/en/Support#rplidar-a-series).

@zlite
Copy link
Contributor Author

zlite commented Mar 5, 2021 via email

@makermelissa
Copy link
Collaborator

Do you have one of the ones with 1.29 you could test if I were to make changes? I can test that it still works on the old ones at least.

@zlite
Copy link
Contributor Author

zlite commented Mar 6, 2021 via email

@makermelissa
Copy link
Collaborator

Ok, want to test out #16?

@zlite
Copy link
Contributor Author

zlite commented Mar 9, 2021 via email

@makermelissa
Copy link
Collaborator

Ok, I'll probably need to get one with 1.29 firmware then as there's probably a bunch of differences.

@benlbroussard
Copy link

I've got 1.28, which works, but is getting 2k scans/second, when it could be getting 8k using boost.

I'm looking at the c++ sdk here: https://github.com/Slamtec/rplidar_sdk/blob/master/sdk/sdk/include/rplidar_cmd.h#L59

Also, the protocol document talks about boost mode (hq mode in the c++ code) but doesn't give the hex value (0x83).

I'd love to see boost mode implemented as the solution to this! Also, get lidar conf (0x84) could be used to ensure backward compatibility.

@makermelissa
Copy link
Collaborator

Thank you @benlbroussard,

The feedback was very helpful. It sounds like the changes I made were in the right direction and I just need to add boost mode handling. I'll give that a try and update my PR as soon as I finish up with another task.

@zlite
Copy link
Contributor Author

zlite commented Mar 15, 2021

A little update. I can get the Robotica library to work with the 1.29 firmware, at least as far as the below example goes:

from rplidar import RPLidar
lidar = RPLidar('COM7')

info = lidar.get_info()
print(info)

health = lidar.get_health()
print(health)

for i, scan in enumerate(lidar.iter_scans()):
    print('%d: Got %d measures' % (i, len(scan)))
    if i > 10:
        break
lidar.stop()
lidar.stop_motor()
lidar.disconnect()

Output:

{'model': 24, 'firmware': (1, 29), 'hardware': 7, 'serialnumber': 'EBB399F6C9E59AD2C5E59CF717613412'}
('Good', 0)
0: Got 52 measures
1: Got 63 measures
2: Got 61 measures
3: Got 62 measures
4: Got 58 measures
5: Got 56 measures
6: Got 55 measures
7: Got 56 measures
8: Got 61 measures
9: Got 61 measures
10: Got 57 measures
11: Got 60 measures

But your library still generates a "Descriptor length mismatch"

@zlite
Copy link
Contributor Author

zlite commented Mar 15, 2021

This also works with the Robotica library:

import sys
import numpy as np
from rplidar import RPLidar

def run():
    '''Main function'''
    lidar = RPLidar('COM7')
    data = []
    try:
        print('Recording measurments... Press Crl+C to stop.')
        for scan in lidar.iter_scans():
            data.append(np.array(scan))
            print(scan)
    except KeyboardInterrupt:
        print('Stopping.')
    lidar.stop()
    lidar.disconnect()


if __name__ == '__main__':
    run()

Output:

Recording measurments... Press Crl+C to stop.
[(15, 40.3125, 504.5), (15, 55.65625, 251.75), (15, 104.09375, 166.75), (15, 119.75, 157.5), (15, 120.328125, 298.5), (15, 122.28125, 294.0), (15, 201.578125, 780.0), (15, 202.859375, 778.0), (15, 204.21875, 779.75), (15, 205.453125, 782.5), (15, 206.765625, 786.5), (15, 208.015625, 790.75), (15, 209.390625, 794.25), (15, 210.703125, 797.5), (15, 211.921875, 802.75), (15, 213.15625, 809.75), (15, 224.28125, 1288.75), (15, 225.5625, 1308.75), (15, 226.796875, 1331.0), (15, 228.0625, 1352.75), (15, 229.359375, 1378.5), (15, 230.6875, 1411.5), (15, 231.921875, 1442.0), (15, 233.21875, 1472.25), (15, 245.25, 389.75), (15, 247.8125, 396.75), (15, 249.109375, 397.75), (15, 268.59375, 596.25), (15, 269.859375, 597.25), (15, 271.15625, 605.0), (15, 272.34375, 610.75), (15, 273.609375, 625.0), (15, 274.84375, 634.5), (15, 278.4375, 2014.5), (8, 282.40625, 1751.25), (14, 283.71875, 1760.25), (15, 285.046875, 1761.75), (15, 286.359375, 1766.75), (15, 287.640625, 1771.75), (15, 288.9375, 1779.25), (15, 290.21875, 1791.0), (8, 291.46875, 1799.75), (15, 295.3125, 1957.5), (15, 301.828125, 2036.25), (15, 322.3125, 297.5), (15, 348.109375, 246.0), (15, 349.46875, 246.25), (15, 349.75, 242.75), (15, 351.71875, 241.5), (15, 354.0, 242.5), (15, 353.5625, 243.75), (15, 357.171875, 244.75)]

@makermelissa
Copy link
Collaborator

Thanks, that's actually pretty helpful as I was referencing it for my update.

@makermelissa
Copy link
Collaborator

@zlite I updated the PR a bit. Want to try that out? I think that's about the best I can do without a 1.29 firmware model in hand to actually work with.

@zlite
Copy link
Contributor Author

zlite commented Mar 17, 2021

Still getting "wrong body size" I'm afraid. Sorry! The RPLidars sold by Seeed on Amazon are using the new 1.29 firmware

Also the import in the repo's readme of from adafruit_circuitpython_rplidar import RPLidar doesn't work. You have to use from adafruit_rplidar import RPLidar instead

@makermelissa
Copy link
Collaborator

Oh, ok. Wrong body size is a different error, so that's progress.

@zlite
Copy link
Contributor Author

zlite commented Mar 17, 2021

Actually, the first time you run it the error is "wrong body size". The second time it's "Incorrect descriptor starting bytes". Then back to "wrong body size" and so on forever

@satiowadahc
Copy link

Debugging and debugging and debugging... timeout=3... huh everything's working...

@zlite
Copy link
Contributor Author

zlite commented Apr 29, 2021

As in "lidar = RPLidar(None, PORT_NAME, timeout=3)"?

Cool! I'll give it a try

@satiowadahc
Copy link

satiowadahc commented Apr 29, 2021

Also Express needs a payload now
?? can be 0x00-0x04

        if scan_type == "express":
            print(cmd)
            self._send_payload_cmd(cmd, b"\x??\x00\x00\x00\x00")

@zlite
Copy link
Contributor Author

zlite commented May 4, 2021

@satiowadahc It works! That's so crazy, but timeout=3 was the secret.

Will submit a PR with a corrected example. I've tested it with both old and new RPLidar firmware

@makermelissa This is good news. I think you've cracked it. Bravo

@makermelissa
Copy link
Collaborator

Fixed via #17

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

6 participants