amiro-os / include / amiro / Lidar.h @ 5d138bca
History | View | Annotate | Download (7.266 KB)
1 |
#ifndef LIDAR_H_
|
---|---|
2 |
#define LIDAR_H_
|
3 |
|
4 |
// Top view
|
5 |
/* __________
|
6 |
// / | \
|
7 |
// / O \
|
8 |
// / H O K U Y O \
|
9 |
// | |
|
10 |
// | |
|
11 |
// \ U R G /
|
12 |
// scannedData[NUMBER_OF_STEPS] = END_STEP \/ \/ STARTING_STEP = scannedData[0]
|
13 |
// \__________/
|
14 |
*/
|
15 |
|
16 |
#include <string.h> // memcpy |
17 |
#include <stdlib.h> |
18 |
|
19 |
#include <amiro/bus/spi/HWSPIDriver.hpp> |
20 |
#include <amiro/Constants.h> // CAN::LIGHT_RING_ID |
21 |
#include <ch.hpp> |
22 |
#include <hal.h> |
23 |
#include <chprintf.h> |
24 |
#include <evtimer.h> |
25 |
|
26 |
// DO CONFIGURATION HERE : START
|
27 |
// Important: SD_SPEED_PREFIX + SD_SPEED has to have 6 characters: e.g. 019200 or 115200
|
28 |
#define SD_SPEED_PREFIX // Prefix < 0 | 0 | | | | > |
29 |
#define SD_SPEED 250000 // Baudrate < 19200 | 57600 | 115200 | 250000 | 500000 | 750000 > |
30 |
#define UPDATE_LIDAR_PERIOD_MSEC MS2ST(1000) // Periodic sensor value fetch in ms |
31 |
// Scan acquire message : START
|
32 |
// Uncomment the specific character decoding to make it available
|
33 |
#define USE_2CHAR_CODE
|
34 |
// #define USE_3CHAR_CODE // TODO Not implemented yet
|
35 |
#define DATA_ACQ_2CHAR_CODE "MS" |
36 |
#define DATA_ACQ_3CHAR_CODE "MD" |
37 |
// Important: STARTING_STEP_PREFIX + STARTING_STEP has to have 4 characters: e.g. 0005 0044 0320
|
38 |
#define STARTING_STEP_PREFIX 00 |
39 |
#define STARTING_STEP 44 |
40 |
// Important: END_STEP_PREFIX + END_STEP has to have 4 characters: e.g. 0005 0725 0320
|
41 |
#define END_STEP_PREFIX 0 |
42 |
#define END_STEP 725 |
43 |
#define CLUSTER_COUNT 00 |
44 |
#define SCAN_INTERVALL 0 |
45 |
#define NUMBER_OF_INTERVALL 01 |
46 |
// Scan acquire message : END
|
47 |
// DO CONFIGURATION HERE : END
|
48 |
|
49 |
// Internal calculations and definitions
|
50 |
#if defined(USE_2CHAR_CODE) && defined(USE_3CHAR_CODE)
|
51 |
# error("USE_2CHAR_CODE and USE_3CHAR_CODE are defined. Only one of them is allowed!") |
52 |
#elif !defined(USE_2CHAR_CODE) && !defined(USE_3CHAR_CODE)
|
53 |
# error("USE_2CHAR_CODE and USE_3CHAR_CODE are not defined. Define one of them!") |
54 |
#elif defined(USE_2CHAR_CODE)
|
55 |
# define DATA_ACQ_CODE DATA_ACQ_2CHAR_CODE
|
56 |
# define NUMBER_OF_CHARACTERS (END_STEP - STARTING_STEP + 1) * 2 |
57 |
#elif defined(USE_3CHAR_CODE)
|
58 |
# define DATA_ACQ_CODE DATA_ACQ_3CHAR_CODE
|
59 |
# define NUMBER_OF_CHARACTERS (END_STEP - STARTING_STEP + 1) * 3 |
60 |
#endif
|
61 |
#define NUMBER_OF_STEPS (END_STEP - STARTING_STEP + 1) |
62 |
|
63 |
#define STR_HELPER(x) #x |
64 |
#define STR(x) STR_HELPER(x)
|
65 |
|
66 |
#define LF "\n" |
67 |
|
68 |
namespace amiro { |
69 |
|
70 |
class Lidar : public chibios_rt::BaseStaticThread<256> {
|
71 |
public:
|
72 |
/**
|
73 |
* Possible setups for the LIDAR: POWER_ONLY (The LIDAR will be powererd, but no serial IO is performed [Need for USB IO]); SERIAL_IO (Power and serial communication via lidar driver)
|
74 |
*/
|
75 |
enum SETUP {POWER_ONLY, SERIAL_IO};
|
76 |
|
77 |
/**
|
78 |
* Writes the last scan into the given array
|
79 |
*
|
80 |
* @param scanData Array of size NUMBER_OF_STEPS which will be override
|
81 |
* with the scanned data
|
82 |
*
|
83 |
* @return True if scanData holds the current data, False if no data have been copied
|
84 |
*/
|
85 |
bool_t getScan(uint16_t (&scanData)[NUMBER_OF_STEPS]); |
86 |
|
87 |
/**
|
88 |
* Returns the value NUMBER_OF_STEPS which is the amount of datapoints per scan
|
89 |
*
|
90 |
* @return Amount of data in one scan
|
91 |
*/
|
92 |
uint16_t getNumberOfValues(); |
93 |
|
94 |
protected:
|
95 |
virtual msg_t main(); |
96 |
|
97 |
/**
|
98 |
* Do a scan and update the datapoints in scanData
|
99 |
*/
|
100 |
msg_t updateSensorVal(); |
101 |
|
102 |
/**
|
103 |
* Print received data until "\n\n" was received
|
104 |
*/
|
105 |
void printData();
|
106 |
|
107 |
/**
|
108 |
* Receive data until "\n\n" and compare it to the given string
|
109 |
* Note: If the command did not work, use printData() instead
|
110 |
* and compare the reply with chapter "9. Response to Invalid Commands"
|
111 |
*
|
112 |
* @param compareString String to compare with
|
113 |
*
|
114 |
* @return True if string was equal, false if not
|
115 |
*/
|
116 |
bool_t checkDataString(const char compareString[]); |
117 |
/**
|
118 |
* Send the command which let the LIDAR send its details
|
119 |
*/
|
120 |
void printDetails();
|
121 |
|
122 |
/**
|
123 |
* Send the command which let the LIDAR send its specifications
|
124 |
*/
|
125 |
void printSpecification();
|
126 |
|
127 |
/**
|
128 |
* Send the command which let the LIDAR send its information
|
129 |
*/
|
130 |
void printInformation();
|
131 |
|
132 |
/**
|
133 |
* Tells you, if the sensor is ready for work
|
134 |
*
|
135 |
* @return True for operability, False if not
|
136 |
*/
|
137 |
inline bool_t getIsReady();
|
138 |
|
139 |
/**
|
140 |
* Do the two character encoding after the manual
|
141 |
*
|
142 |
* @param char1 High character
|
143 |
* @param char2 Low character
|
144 |
*
|
145 |
* @return Encoded data
|
146 |
*/
|
147 |
inline uint16_t twoCharacterEncoding(uint8_t &char1, uint8_t &char2);
|
148 |
|
149 |
/**
|
150 |
* Blocking function which writes the received character to the given variable
|
151 |
*
|
152 |
* @param data Container for the variable
|
153 |
* @param timeoutMs Timeout in millisecond
|
154 |
*
|
155 |
* @return True if data was received, False if timed out (NOTE timeoutMs should by much smaller than UPDATE_LIDAR_PERIOD_MSEC)
|
156 |
*/
|
157 |
bool_t getData(uint8_t &data, uint32_t timeoutMs); |
158 |
|
159 |
/**
|
160 |
* Container for the scanned data
|
161 |
*
|
162 |
* @brief The "+1" character is for holding the last sum which is transmitted
|
163 |
* by the LIDAR. It is not used, but it makes the algorithm much easier
|
164 |
* we we do not care about it
|
165 |
*/
|
166 |
static uint8_t scannedData[NUMBER_OF_CHARACTERS + 1]; |
167 |
|
168 |
/**
|
169 |
* Flushes the input queue of the SD2 serial device
|
170 |
*/
|
171 |
inline void flushSD2InputQueue(); |
172 |
|
173 |
/**
|
174 |
* Possible states for the receiver state machine
|
175 |
*/
|
176 |
enum STATE {SEND_SCAN_CMD, DATA_VALID_CHECK, DATA_START_CHECK, DATA_RECORD, DATA_DECODE, DATA_SHOW, FAIL, FINISH};
|
177 |
|
178 |
/**
|
179 |
* Current state of the machine
|
180 |
*/
|
181 |
STATE step = SEND_SCAN_CMD; |
182 |
|
183 |
/**
|
184 |
* This is the status which comes after the command echo "\n99b\n"
|
185 |
*/
|
186 |
const uint8_t validScanTag[5] = {10,57,57,98,10}; |
187 |
|
188 |
/**
|
189 |
* Index for the received status
|
190 |
*/
|
191 |
uint8_t checkStatusIdx = 0;
|
192 |
|
193 |
/**
|
194 |
* Index for the received status
|
195 |
*/
|
196 |
|
197 |
/**
|
198 |
* Hold the board id
|
199 |
*/
|
200 |
uint8_t boardId; |
201 |
|
202 |
/**
|
203 |
* Hold the setup configuration for the lidar
|
204 |
*/
|
205 |
SETUP setup; |
206 |
|
207 |
/**
|
208 |
* Holds the current input
|
209 |
*/
|
210 |
uint8_t newInput = 0xFF;
|
211 |
|
212 |
/**
|
213 |
* Holds the last input
|
214 |
*/
|
215 |
uint8_t lastInput = 0xFF;
|
216 |
|
217 |
/**
|
218 |
* Counter for the received characters of the data points
|
219 |
*/
|
220 |
uint16_t dataIdx = 0;
|
221 |
|
222 |
/**
|
223 |
* Temporary variable which hold the amount of receved bytes
|
224 |
*/
|
225 |
uint32_t dataCounter = 0;
|
226 |
|
227 |
/**
|
228 |
* Holds the information, if scannedData holds the last sensor scan
|
229 |
*/
|
230 |
bool_t isReady = false;
|
231 |
|
232 |
/**
|
233 |
* Holds the information, if the datachunk was not transmitted completely
|
234 |
*/
|
235 |
bool_t isFail = false;
|
236 |
|
237 |
private:
|
238 |
|
239 |
EvTimer evtimer; |
240 |
|
241 |
public:
|
242 |
/**
|
243 |
* Constructor
|
244 |
*
|
245 |
* @param boardId Board ID which can be found in ControllerAreaNetwork.h.
|
246 |
* It is used to setup the LIDAR for exactly this board
|
247 |
*/
|
248 |
Lidar(const uint8_t boardId, Lidar::SETUP setup);
|
249 |
|
250 |
/**
|
251 |
* Constructor
|
252 |
*
|
253 |
* Disable the LIDAR
|
254 |
* TODO Why "virtual ~Lidar() = 0;"
|
255 |
*/
|
256 |
~Lidar(); |
257 |
|
258 |
}; |
259 |
|
260 |
} |
261 |
#endif /* LIDAR_H_ */ |