sl_lidarprotocol_codec.cpp
Go to the documentation of this file.
1 /*
2  * Slamtec LIDAR SDK
3  *
4  * Copyright (c) 2014 - 2023 Shanghai Slamtec Co., Ltd.
5  * http://www.slamtec.com
6  *
7  */
8  /*
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 
34 
35 #include "sdkcommon.h"
36 #include "hal/byteorder.h"
37 #include "hal/abs_rxtx.h"
38 #include "hal/thread.h"
39 #include "hal/types.h"
40 #include "hal/assert.h"
41 #include "hal/locker.h"
42 #include "hal/socket.h"
43 #include "hal/event.h"
44 
45 #include "sl_lidar_driver.h"
46 #include "sl_crc.h"
47 #include <algorithm>
48 
49 #include "sl_async_transceiver.h"
50 #include "sl_lidarprotocol_codec.h"
51 
52 
53 
54 namespace sl { namespace internal {
55 
56 
57 
60  , _listener(NULL)
61  , _op_locker(true)
62 {
63  onDecodeReset();
64 }
65 
67  onDecodeReset();
68 }
69 
70 
71 
73 {
75  _listener = listener;
76 }
77 
79 {
80  size_t actualSize = 2; //1-byte's sync byte, 1-byte's cmd byte
81 
82  if (message->cmd & RPLIDAR_CMDFLAG_HAS_PAYLOAD) {
83  actualSize += (message->getPayloadSize() & 0xFF);
84  actualSize += 2; //1-byte for size field, 1-byte for checksum
85  }
86 
87  return actualSize;
88 }
89 
90 
92 {
93  _u8 checksum = 0;
94  size_t writeSize = std::min<size_t>(*size, estimateLength(message));
95  size_t currentPos = 0;
96 
97  while (currentPos < writeSize) {
98  _u8 currentTxByte;
99  switch (currentPos) {
100  case 0: // sync byte
101  currentTxByte = RPLIDAR_CMD_SYNC_BYTE;
102  break;
103  case 1: // cmd byte
104  currentTxByte = message->cmd;
105  break;
106  case 2: // size byte
107  currentTxByte = (_u8)message->getPayloadSize();
108  break;
109  default:
110  {
111  size_t payloadPos = currentPos - 3;
112  if (payloadPos == message->getPayloadSize()) {
113  // checksum byte
114  currentTxByte = checksum;
115  assert(currentPos + 1 == writeSize);
116  }
117  else {
118  // payload
119  currentTxByte = message->getDataBuf()[payloadPos];
120  }
121  }
122  }
123 
124 
125  checksum ^= currentTxByte;
126  buffer[currentPos++] = currentTxByte;
127  } while (0);
128 
129  *size = currentPos;
130 }
131 
134  // flush the pending data
136  // reset to initial state
137  _rx_pos = 0;
139 }
140 
141 
142 void RPLidarProtocolCodec::onDecodeData(const void* buffer, size_t size)
143 {
145 
146  const _u8* data = reinterpret_cast<const _u8*>(buffer);
147  const _u8* dataEnd = data + size;
148 
149 
150  while (data != dataEnd) {
151  _u8 currentByte = *data;
152  ++data;
153 
154  switch (_working_states & ((_u32)STATUS_LOOP_MODE_FLAG - 1)) {
155  case STATUS_WAIT_SYNC1:
156  if (currentByte == RPLIDAR_ANS_SYNC_BYTE1) {
158  }
159  break;
160  case STATUS_WAIT_SYNC2:
161  if (currentByte == RPLIDAR_ANS_SYNC_BYTE2) {
163  _rx_pos = 0; // init rx pos for recv size and flag
164  }
165  else {
166  // reset to the initial state
168  }
169  break;
171  {
172  assert(sizeof(_decodingMessage.len) >= 4);
173  _u8* byteArr = reinterpret_cast<_u8*>(&_decodingMessage.len);
174  byteArr[_rx_pos++] = currentByte;
175 
176  if (_rx_pos == 4) {
179 
180  // 30bit size + 2bit flag has been received
182  if (flagbits & RPLIDAR_ANS_PKTFLAG_LOOP) {
184  }
186  // alloc buffer
188  _rx_pos = 0;
189  }
190  }
191  break;
192  case STATUS_WAIT_TYPE:
193  // save the type field as a cmd
194  _decodingMessage.cmd = currentByte;
195 
196  // recv payload...
199 
201  // zero payload packet?
203  }
204  break;
205  case STATUS_RECV_PAYLOAD:
206  _decodingMessage.getDataBuf()[_rx_pos++] = currentByte;
207 
208  if ((size_t)_rx_pos == _decodingMessage.getPayloadSize()) {
210  // rewind to the payload recv status in loop mode
211  _rx_pos = 0;
212  }
213  else {
214  // reset the decoder
216  }
217 
218  IProtocolMessageListener* cachedLister = _listener;
219 
220  autolock.forceUnlock(); //unlock the oplock to prevent deadlock
221 
222 
223  if (cachedLister) {
225  }
226 
227  _op_locker.lock(); // relock it
228  }
229  break;
230  }
231 
232  }
233 }
234 
235 
236 
237 
238 }}
sdkcommon.h
sl::internal::RPLidarProtocolCodec::RPLidarProtocolCodec
RPLidarProtocolCodec()
Definition: sl_lidarprotocol_codec.cpp:58
sl_lidarprotocol_codec.h
sl::internal::ProtocolMessage::getPayloadSize
size_t getPayloadSize() const
Definition: sl_async_transceiver.h:66
sl::internal::RPLidarProtocolCodec::onEncodeData
virtual void onEncodeData(message_autoptr_t &message, _u8 *txbuffer, size_t *size)
Definition: sl_lidarprotocol_codec.cpp:91
RPLIDAR_ANS_SYNC_BYTE1
#define RPLIDAR_ANS_SYNC_BYTE1
Definition: rplidar_protocol.h:43
sl::internal::RPLidarProtocolCodec::_listener
IProtocolMessageListener * _listener
Definition: sl_lidarprotocol_codec.h:77
sl::internal::RPLidarProtocolCodec::onDecodeReset
virtual void onDecodeReset()
Definition: sl_lidarprotocol_codec.cpp:132
types.h
sl::internal::ProtocolMessage::cleanData
void cleanData()
Definition: sl_async_transceiver.cpp:131
sl::internal::RPLidarProtocolCodec::_working_states
_u32 _working_states
Definition: sl_lidarprotocol_codec.h:81
RPLIDAR_ANS_PKTFLAG_LOOP
#define RPLIDAR_ANS_PKTFLAG_LOOP
Definition: rplidar_protocol.h:46
byteorder.h
sl::internal::ProtocolMessage::len
size_t len
Definition: sl_async_transceiver.h:44
rp::hal::AutoLocker::forceUnlock
void forceUnlock()
Definition: locker.h:196
sl::internal::RPLidarProtocolCodec::_op_locker
rp::hal::Locker _op_locker
Definition: sl_lidarprotocol_codec.h:79
sl::internal::RPLidarProtocolCodec::STATUS_LOOP_MODE_FLAG
@ STATUS_LOOP_MODE_FLAG
Definition: sl_lidarprotocol_codec.h:57
RPLIDAR_ANS_HEADER_SUBTYPE_SHIFT
#define RPLIDAR_ANS_HEADER_SUBTYPE_SHIFT
Definition: rplidar_protocol.h:49
sl::internal::RPLidarProtocolCodec::STATUS_WAIT_SYNC1
@ STATUS_WAIT_SYNC1
Definition: sl_lidarprotocol_codec.h:52
assert.h
sl::internal::ProtocolMessage::getDataBuf
_u8 * getDataBuf()
Definition: sl_async_transceiver.h:61
_u8
uint8_t _u8
Definition: rptypes.h:63
sl::internal::IProtocolMessageListener
Definition: sl_lidarprotocol_codec.h:41
size
sl_u8 size
Definition: sl_lidar_protocol.h:4
sl::internal::RPLidarProtocolCodec::onDecodeData
virtual void onDecodeData(const void *buffer, size_t size)
Definition: sl_lidarprotocol_codec.cpp:142
locker.h
sl_crc.h
sl::internal::RPLidarProtocolCodec::STATUS_RECV_PAYLOAD
@ STATUS_RECV_PAYLOAD
Definition: sl_lidarprotocol_codec.h:56
sl::internal::IAsyncProtocolCodec
Definition: sl_async_transceiver.h:85
rp::hal::AutoLocker
Definition: locker.h:188
sl
Definition: sl_crc.h:38
RPLIDAR_ANS_HEADER_SIZE_MASK
#define RPLIDAR_ANS_HEADER_SIZE_MASK
Definition: rplidar_protocol.h:48
RPLIDAR_CMD_SYNC_BYTE
#define RPLIDAR_CMD_SYNC_BYTE
Definition: rplidar_protocol.h:39
sl::internal::RPLidarProtocolCodec::STATUS_WAIT_SIZE_FLAG
@ STATUS_WAIT_SIZE_FLAG
Definition: sl_lidarprotocol_codec.h:54
event.h
sl::internal::RPLidarProtocolCodec::exitLoopMode
void exitLoopMode()
Definition: sl_lidarprotocol_codec.cpp:66
sl::internal::RPLidarProtocolCodec::_decodingMessage
ProtocolMessage _decodingMessage
Definition: sl_lidarprotocol_codec.h:78
rp::hal::Locker::lock
Locker::LOCK_STATUS lock(unsigned long timeout=0xFFFFFFFF)
Definition: locker.h:60
sl::internal::RPLidarProtocolCodec::setMessageListener
void setMessageListener(IProtocolMessageListener *l)
Definition: sl_lidarprotocol_codec.cpp:72
sl::internal::message_autoptr_t
std::shared_ptr< ProtocolMessage > message_autoptr_t
Definition: sl_async_transceiver.h:82
sl::internal::ProtocolMessage::cmd
_u8 cmd
Definition: sl_async_transceiver.h:45
abs_rxtx.h
sl::internal::ProtocolMessage::fillData
void fillData(const void *buffer, size_t size)
Definition: sl_async_transceiver.cpp:123
RPLIDAR_CMDFLAG_HAS_PAYLOAD
#define RPLIDAR_CMDFLAG_HAS_PAYLOAD
Definition: rplidar_protocol.h:40
sl::internal::RPLidarProtocolCodec::estimateLength
virtual size_t estimateLength(message_autoptr_t &message)
Definition: sl_lidarprotocol_codec.cpp:78
sl_async_transceiver.h
socket.h
RPLIDAR_ANS_SYNC_BYTE2
#define RPLIDAR_ANS_SYNC_BYTE2
Definition: rplidar_protocol.h:44
sl::internal::RPLidarProtocolCodec::STATUS_WAIT_TYPE
@ STATUS_WAIT_TYPE
Definition: sl_lidarprotocol_codec.h:55
le32_to_cpu
#define le32_to_cpu(x)
Definition: byteorder.h:44
data
sl_u8 data[0]
Definition: sl_lidar_protocol.h:5
_u32
uint32_t _u32
Definition: rptypes.h:69
thread.h
sl::internal::IProtocolMessageListener::onProtocolMessageDecoded
virtual void onProtocolMessageDecoded(const ProtocolMessage &)=0
sl::internal::RPLidarProtocolCodec::_rx_pos
int _rx_pos
Definition: sl_lidarprotocol_codec.h:82
sl_lidar_driver.h
sl::internal::RPLidarProtocolCodec::STATUS_WAIT_SYNC2
@ STATUS_WAIT_SYNC2
Definition: sl_lidarprotocol_codec.h:53


rplidar_ros
Author(s):
autogenerated on Fri Aug 2 2024 08:42:14