3333#include " AP_Proximity_RPLidarA2.h"
3434
3535#include < AP_HAL/AP_HAL.h>
36- #include " AP_Proximity_RPLidarA2.h"
3736#include < AP_InternalError/AP_InternalError.h>
3837
3938#include < ctype.h>
@@ -75,15 +74,6 @@ void AP_Proximity_RPLidarA2::update(void)
7574 return ;
7675 }
7776
78- // request device info 3sec after reset
79- // required for S1 support that sends only 9 bytes after a reset (A1,A2 send 63)
80- uint32_t now_ms = AP_HAL::millis ();
81- if ((_state == State::RESET) && (now_ms - _last_reset_ms > 3000 )) {
82- send_request_for_device_info ();
83- _state = State::AWAITING_RESPONSE;
84- _byte_count = 0 ;
85- }
86-
8777 get_readings ();
8878
8979 // check for timeout and set health status
@@ -112,6 +102,8 @@ float AP_Proximity_RPLidarA2::distance_max() const
112102 return 12 .0f ;
113103 case Model::S1:
114104 return 40 .0f ;
105+ case Model::S2:
106+ return 50 .0f ;
115107 }
116108 return 0 .0f ;
117109}
@@ -127,18 +119,20 @@ float AP_Proximity_RPLidarA2::distance_min() const
127119 case Model::C1:
128120 case Model::S1:
129121 return 0 .2f ;
122+ case Model::S2:
123+ return 0 .05f ;
130124 }
131125 return 0 .0f ;
132126}
133127
128+ // reset lidar
134129void AP_Proximity_RPLidarA2::reset_rplidar ()
135130{
136131 static const uint8_t tx_buffer[2 ] {RPLIDAR_PREAMBLE, RPLIDAR_CMD_RESET};
137132 _uart->write (tx_buffer, 2 );
138133 Debug (1 , " LIDAR reset" );
139- // To-Do: ensure delay of 8m after sending reset request
140134 _last_reset_ms = AP_HAL::millis ();
141- reset () ;
135+ _state = State::RESET ;
142136}
143137
144138// set Lidar into SCAN mode
@@ -165,114 +159,36 @@ void AP_Proximity_RPLidarA2::send_request_for_device_info()
165159 Debug (1 , " Sent device information request" );
166160}
167161
168- void AP_Proximity_RPLidarA2::consume_bytes (uint16_t count)
169- {
170- if (count > _byte_count) {
171- INTERNAL_ERROR (AP_InternalError::error_t ::flow_of_control);
172- _byte_count = 0 ;
173- return ;
174- }
175- _byte_count -= count;
176- if (_byte_count) {
177- memmove ((void *)&_payload[0 ], (void *)&_payload[count], _byte_count);
178- }
179- }
180-
181- void AP_Proximity_RPLidarA2::reset ()
182- {
183- _state = State::RESET;
184- _byte_count = 0 ;
185- }
186-
187- bool AP_Proximity_RPLidarA2::make_first_byte_in_payload (uint8_t desired_byte)
188- {
189- if (_byte_count == 0 ) {
190- return false ;
191- }
192- if (_payload[0 ] == desired_byte) {
193- return true ;
194- }
195- for (auto i=1 ; i<_byte_count; i++) {
196- if (_payload[i] == desired_byte) {
197- consume_bytes (i);
198- return true ;
199- }
200- }
201- // just not in our buffer. Throw everything away:
202- _byte_count = 0 ;
203- return false ;
204- }
205-
206162void AP_Proximity_RPLidarA2::get_readings ()
207163{
208- Debug (2 , " CURRENT STATE: %u " , (unsigned )_state);
209- const uint32_t nbytes = _uart->available ();
210- if (nbytes == 0 ) {
211- return ;
212- }
213- const uint32_t bytes_to_read = MIN (nbytes, sizeof (_payload)-_byte_count);
214- if (bytes_to_read == 0 ) {
215- INTERNAL_ERROR (AP_InternalError::error_t ::flow_of_control);
216- reset ();
217- return ;
218- }
219- const uint32_t bytes_read = _uart->read (&_payload[_byte_count], bytes_to_read);
220- if (bytes_read == 0 ) {
221- // this is bad; we were told there were bytes available
222- INTERNAL_ERROR (AP_InternalError::error_t ::flow_of_control);
223- reset ();
224- return ;
225- }
226- _byte_count += bytes_read;
227-
228- uint32_t previous_loop_byte_count = UINT32_MAX;
229- while (_byte_count) {
230- if (_byte_count >= previous_loop_byte_count) {
231- // this is a serious error, we should always consume some
232- // bytes. Avoid looping forever.
233- INTERNAL_ERROR (AP_InternalError::error_t ::flow_of_control);
234- _uart = nullptr ;
235- return ;
236- }
237- previous_loop_byte_count = _byte_count;
238-
164+ uint16_t _bytes_read = 0 ;
165+ Debug (2 , " CURRENT STATE: %u " , (unsigned )_state);
166+ while (_uart->available () && _bytes_read < MAX_BYTES_CONSUME) {
239167 switch (_state){
240168 case State::RESET: {
241- // looking for 0x52 at start of buffer; the 62 following
242- // bytes are "information"
243- if (!make_first_byte_in_payload (' R' )) { // that's 'R' as in RPiLidar
169+ if (AP_HAL::millis () - _last_reset_ms < 1000 ) {
244170 return ;
245171 }
246- if (_byte_count < 63 ) {
247- return ;
248- }
249- #if RP_DEBUG_LEVEL
250- // optionally spit out via mavlink the 63-bytes of cruft
251- // that is spat out on device reset
252- Debug (1 , " Got RPLidar Information" );
253- char xbuffer[64 ]{};
254- memcpy ((void *)xbuffer, (void *)&_payload.information , 63 );
255- gcs ().send_text (MAV_SEVERITY_INFO, " RPLidar: (%s)" , xbuffer);
256- #endif
257- // 63 is the magic number of bytes in the spewed-out
258- // reset data ... so now we'll just drop that stuff on
259- // the floor.
260- consume_bytes (63 );
172+ _uart->discard_input ();
261173 send_request_for_device_info ();
262174 _state = State::AWAITING_RESPONSE;
263175 continue ;
264176 }
265177 case State::AWAITING_RESPONSE:
266- if (_payload[0 ] != RPLIDAR_PREAMBLE) {
267- // this is a protocol error. Reset.
268- reset ();
178+ // descriptor packet has 7 byte in total
179+ if (_uart->available () < sizeof (_descriptor)) {
269180 return ;
270181 }
182+ _uart->read (&_payload[0 ], sizeof (_descriptor));
183+ _bytes_read += sizeof (_descriptor);
271184
272- // descriptor packet has 7 byte in total
273- if (_byte_count < sizeof (_descriptor)) {
185+ if (_payload[0 ] != RPLIDAR_PREAMBLE) {
186+ Debug (1 , " protocol error" );
187+ // this is a protocol error do a reset.
188+ reset_rplidar ();
274189 return ;
275190 }
191+
276192 // identify the payload data after the descriptor
277193 static const _descriptor SCAN_DATA_DESCRIPTOR[] {
278194 { RPLIDAR_PREAMBLE, 0x5A , 0x05 , 0x00 , 0x00 , 0x40 , 0x81 }
@@ -293,31 +209,33 @@ void AP_Proximity_RPLidarA2::get_readings()
293209 } else {
294210 // unknown descriptor. Ignore it.
295211 }
296- consume_bytes (sizeof (_descriptor));
297212 break ;
298213
299214 case State::AWAITING_DEVICE_INFO:
300- if (_byte_count < sizeof (_payload.device_info )) {
215+ if (_uart-> available () < sizeof (_payload.device_info )) {
301216 return ;
302217 }
218+ _uart->read (&_payload[0 ], sizeof (_payload.device_info ));
219+ _bytes_read += sizeof (_payload.device_info );
303220 parse_response_device_info ();
304- consume_bytes (sizeof (_payload.device_info ));
305221 break ;
306222
307223 case State::AWAITING_SCAN_DATA:
308- if (_byte_count < sizeof (_payload.sensor_scan )) {
224+ if (_uart-> available () < sizeof (_payload.sensor_scan )) {
309225 return ;
310226 }
227+ _uart->read (&_payload[0 ], sizeof (_payload.sensor_scan ));
228+ _bytes_read += sizeof (_payload.sensor_scan );
311229 parse_response_data ();
312- consume_bytes (sizeof (_payload.sensor_scan ));
313230 break ;
314231
315232 case State::AWAITING_HEALTH:
316- if (_byte_count < sizeof (_payload.sensor_health )) {
233+ if (_uart-> available () < sizeof (_payload.sensor_health )) {
317234 return ;
318235 }
236+ _uart->read (&_payload[0 ], sizeof (_payload.sensor_health ));
237+ _bytes_read += sizeof (_payload.sensor_health );
319238 parse_response_health ();
320- consume_bytes (sizeof (_payload.sensor_health ));
321239 break ;
322240 }
323241 }
@@ -344,6 +262,10 @@ void AP_Proximity_RPLidarA2::parse_response_device_info()
344262 model = Model::S1;
345263 device_type = " S1" ;
346264 break ;
265+ case 0x71 :
266+ model = Model::S2;
267+ device_type = " S2" ;
268+ break ;
347269 default :
348270 Debug (1 , " Unknown device (%u)" , _payload.device_info .model );
349271 }
@@ -356,12 +278,13 @@ void AP_Proximity_RPLidarA2::parse_response_data()
356278{
357279 if (_sync_error) {
358280 // out of 5-byte sync mask -> catch new revolution
359- Debug (1 , " OUT OF SYNC" );
281+ Debug (1 , " OUT OF SYNC" );
360282 // on first revolution bit 1 = 1, bit 2 = 0 of the first byte
361283 if ((_payload[0 ] & 0x03 ) == 0x01 ) {
362284 _sync_error = 0 ;
363- Debug (1 , " RESYNC" );
285+ Debug (1 , " RESYNC" );
364286 } else {
287+ Debug (1 , " NO RESYNC" );
365288 return ;
366289 }
367290 }
@@ -412,7 +335,7 @@ void AP_Proximity_RPLidarA2::parse_response_data()
412335
413336void AP_Proximity_RPLidarA2::parse_response_health ()
414337{
415- // health issue if status is "3" ->HW error
338+ // health issue if status is "3" -> HW error
416339 if (_payload.sensor_health .status == 3 ) {
417340 Debug (1 , " LIDAR Error" );
418341 }
0 commit comments