You've already forked Applications-LidarBot
mirror of
https://github.com/m5stack/Applications-LidarBot.git
synced 2026-05-20 10:23:34 -07:00
129 lines
3.5 KiB
C++
129 lines
3.5 KiB
C++
#include "X2driver.h"
|
|
|
|
extern void updateData(void *);
|
|
|
|
X2::X2(void) {
|
|
;;
|
|
}
|
|
|
|
uint16_t X2::cover_crc(uint8_t *msg, uint8_t *data, uint16_t data_len) {
|
|
uint16_t crc = 0x000;
|
|
uint16_t length = data_len / 2;
|
|
uint16_t *msg_ptr = (uint16_t *)msg;
|
|
uint16_t *data_ptr = (uint16_t *)data;
|
|
|
|
if(data_len % 2 == 1) {
|
|
return 0xffff;
|
|
}
|
|
|
|
for (uint16_t i = 0; i < 4; i++) {
|
|
crc ^= *msg_ptr++;
|
|
}
|
|
|
|
for(uint16_t i = 0; i < length; i++) {
|
|
crc ^= *data_ptr++;
|
|
}
|
|
|
|
return crc >> 8 | crc << 8;
|
|
}
|
|
|
|
//all data will catch from serial and send in here
|
|
void X2::lidar_data_deal(uint8_t data_in) {
|
|
//plus the data to this buff
|
|
rx_buf[rx_ptr++] = data_in;
|
|
|
|
if(rx_ptr > 1022) {
|
|
rx_ptr = 0;
|
|
}
|
|
|
|
//we check if we catch the next package.
|
|
if(data_in == 0x55 && last_value == 0xaa) {
|
|
state = 1;
|
|
}
|
|
|
|
//we process the data we catch if the package is already finish.
|
|
if(state == 1) {
|
|
state = 0;
|
|
|
|
//check the head
|
|
if(rx_ptr > 10 && rx_buf[0] == 0xaa && rx_buf[1] == 0x55) {
|
|
memcpy(lidar_data.buf, rx_buf, 8);
|
|
memcpy(&lidar_data.buf[8], &rx_buf[10], rx_ptr - 2 - 10);
|
|
lidar_data.length = rx_ptr;
|
|
|
|
//decode the startAngle and endAngle
|
|
startAngle = float((lidar_data.buf[4] |(lidar_data.buf[5] << 8)) >> 1);
|
|
endAngle = float((lidar_data.buf[6] |( lidar_data.buf[7] << 8)) >> 1);
|
|
|
|
//check bcc
|
|
uint16_t bcc = cover_crc(lidar_data.buf, &lidar_data.buf[8], rx_ptr - 2 - 10);
|
|
if (bcc == ((rx_buf[8] << 8) | rx_buf[9])) {
|
|
|
|
//whether the package is the first package and whether map data is already show on the screen
|
|
if ((lidar_data.buf[2] & 0x01) && disPlayFlag == 0) {
|
|
if(xSemaphoreTake(xSemaphore, 0) == pdTRUE) {
|
|
memcpy(dismap.mapdata, tmpmap.mapdata, sizeof(float) * 720);
|
|
updateData(tmpmap.mapdata);
|
|
xSemaphoreGive( xSemaphore );
|
|
}
|
|
memset(tmpmap.mapdata, 0, sizeof(float) * 1000);
|
|
disPlayFlag = 1;
|
|
}
|
|
else {
|
|
bufCopy(&lidar_data.buf[8], rx_ptr - 2 - 10);
|
|
}
|
|
}
|
|
else {
|
|
//crc error or startAng < endAng
|
|
//we can see which angle is error here.
|
|
Serial.printf("startAngle: %f, endAngle: %f \r\n", startAngle / 64, endAngle / 64);
|
|
}
|
|
}
|
|
memset(rx_buf, 0, rx_ptr);
|
|
rx_ptr = 0;
|
|
|
|
//we add the head to the next package which we were already receive.
|
|
rx_buf[rx_ptr++] = 0xaa;
|
|
rx_buf[rx_ptr++] = 0x55;
|
|
}
|
|
last_value = data_in;
|
|
}
|
|
|
|
//here for the data we want to show on screen.
|
|
//lidar point decode here and copy the data to the tmpBuf.
|
|
void X2::bufCopy(uint8_t *buff, uint8_t len) {
|
|
float angleI = 0;
|
|
float distanceI = 0;
|
|
float angCorrectI = 0;
|
|
float X = 0;
|
|
float Y = 0;
|
|
|
|
int leng = len / 2;
|
|
float preAngle = endAngle - startAngle;
|
|
if (preAngle < 0.0) {
|
|
preAngle = preAngle + 360.0 * 64;
|
|
}
|
|
preAngle = preAngle/((leng - 1) * 1.0);
|
|
|
|
for (int i = 0; i < len; i+= 2) {
|
|
angleI = preAngle*(i/2.0) + startAngle;
|
|
distanceI = int((buff[i] | (buff[i + 1] << 8)) / 4.0);
|
|
|
|
angCorrectI = (atan(21.8*(155.3 - distanceI) / (155.3*distanceI)) * 180 / 3.1415) * 64.0;
|
|
angleI = (angleI + angCorrectI) / 64.0;
|
|
|
|
if (angleI > 360.0) {
|
|
angleI = angleI - 360;
|
|
}
|
|
|
|
angleI = angleI * 3.1415 / 180;
|
|
|
|
int recvAngle = floorf(angleI * 180 / 3.1415 * 2);
|
|
float recvDistanceI = distanceI;
|
|
|
|
tmpmap.mapdata[recvAngle] = distanceI;
|
|
// Serial.printf("ori:%f dist:%d\r\n", distanceI, uint16_t(distanceI));
|
|
tmpData.mapdata[recvAngle] = uint16_t(distanceI);
|
|
}
|
|
}
|