23 uint16_t crc = 0xFFFF;
25 for(pos = 0; pos < len; pos++) {
26 crc ^= (uint16_t)buf[pos];
28 for(i = 8; i != 0; i--)
30 if((crc & 0x0001) != 0)
42 #define SERIAL_PORT_HANDLE HANDLE
43 #define PORT_NOT_OPENED INVALID_HANDLE_VALUE
53 HANDLE
OpenSerialPort_(
const char* portFileName, uint32_t baudrate,
bool verbose) {
54 HANDLE ttyHandle = CreateFile(TEXT(portFileName), GENERIC_READ, 0,
55 NULL, OPEN_EXISTING, 0 , NULL);
56 if(ttyHandle == INVALID_HANDLE_VALUE) {
58 puts(
"Error: unable to open serial connection "
59 "(possibly serial port is not available)");
60 return INVALID_HANDLE_VALUE;
62 COMMTIMEOUTS timeouts = { 3000, 3000, 3000, 3000, 3000 };
63 bool returnCode = SetCommTimeouts(ttyHandle, &timeouts);
66 puts(
"Error: unable to set serial port timeouts");
67 CloseHandle(ttyHandle);
68 return INVALID_HANDLE_VALUE;
71 returnCode = GetCommState(ttyHandle, &dcb);
74 puts(
"Error: unable to get serial port parameters");
75 CloseHandle(ttyHandle);
76 return INVALID_HANDLE_VALUE;
78 dcb.BaudRate = baudrate;
79 dcb.fAbortOnError =
true;
80 returnCode = SetCommState(ttyHandle, &dcb);
83 puts(
"Error: unable to set serial port parameters");
84 CloseHandle(ttyHandle);
85 return INVALID_HANDLE_VALUE;
148 printf(
"Warning: unsupported baudrate %u. Using 9600.\n",
154 #define SERIAL_PORT_HANDLE int
155 #define PORT_NOT_OPENED -1
164 int ttyHandle = open(portFileName, O_RDWR | O_NONBLOCK | O_NDELAY);
167 puts(
"Error: unable to open serial connection "
168 "(possibly serial port is not available)");
171 struct termios ttyCtrl;
172 memset(&ttyCtrl, 0,
sizeof ttyCtrl);
173 if(tcgetattr(ttyHandle, &ttyCtrl) != 0) {
175 puts(
"Error: unable to get serial port parameters");
180 cfsetospeed(&ttyCtrl, baudCode);
181 cfsetispeed(&ttyCtrl, baudCode);
183 ttyCtrl.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS);
184 ttyCtrl.c_cflag |= CS8;
188 ttyCtrl.c_cc[VMIN] = 0;
189 ttyCtrl.c_cc[VTIME] = 30;
190 ttyCtrl.c_cflag |= CREAD | CLOCAL;
191 ttyCtrl.c_iflag &= ~(IXON | IXOFF | IXANY);
192 ttyCtrl.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
193 ttyCtrl.c_oflag &= ~OPOST;
194 tcflush(ttyHandle, TCIFLUSH);
195 if(tcsetattr(ttyHandle, TCSANOW, &ttyCtrl) != 0) {
197 puts(
"Error: unable to set serial port parameters");
212 int16_t res = buffer[0] |
213 (((uint16_t)buffer[1]) << 8);
219 uint32_t res = buffer[0] |
220 (((uint32_t)buffer[1]) << 8) |
221 (((uint32_t)buffer[2]) << 16) |
222 (((uint32_t)buffer[3]) << 24);
228 int32_t res = buffer[0] |
229 (((uint32_t)buffer[1]) << 8) |
230 (((uint32_t)buffer[2]) << 16) |
231 (((uint32_t)buffer[3]) << 24);
242 uint8_t indCur = ind;
261 uint8_t ind = hedge->lastValues_next;
263 hedge->positionBuffer[ind].
address =
267 (((uint32_t)buffer[6]) << 8) |
268 (((uint32_t)buffer[7]) << 16) |
269 (((uint32_t)buffer[8]) << 24);
271 int16_t vx = buffer[9] |
272 (((uint16_t)buffer[10]) << 8);
273 hedge->positionBuffer[ind].
x = vx * 10;
275 int16_t vy = buffer[11] |
276 (((uint16_t)buffer[12]) << 8);
277 hedge->positionBuffer[ind].
y = vy * 10;
279 int16_t vz = buffer[13] |
280 (((uint16_t)buffer[14]) << 8);
281 hedge->positionBuffer[ind].
z = vz * 10;
283 uint16_t vang = buffer[17] |
284 (((uint16_t)buffer[18]) << 8);
285 hedge->positionBuffer[ind].
angle = ((float)(vang & 0x0fff)) / 10.0f;
291 return hedge->positionBuffer[ind];
295 uint8_t ind = hedge->lastValues_next;
297 hedge->positionBuffer[ind].
address =
301 (((uint32_t)buffer[6]) << 8) |
302 (((uint32_t)buffer[7]) << 16) |
303 (((uint32_t)buffer[8]) << 24);
305 int32_t vx = buffer[9] |
306 (((uint32_t)buffer[10]) << 8) |
307 (((uint32_t)buffer[11]) << 16) |
308 (((uint32_t)buffer[12]) << 24);
309 hedge->positionBuffer[ind].
x = vx;
311 int32_t vy = buffer[13] |
312 (((uint32_t)buffer[14]) << 8) |
313 (((uint32_t)buffer[15]) << 16) |
314 (((uint32_t)buffer[16]) << 24);
315 hedge->positionBuffer[ind].
y = vy;
317 int32_t vz = buffer[17] |
318 (((uint32_t)buffer[18]) << 8) |
319 (((uint32_t)buffer[19]) << 16) |
320 (((uint32_t)buffer[20]) << 24);
321 hedge->positionBuffer[ind].
z = vz;
323 uint16_t vang = buffer[23] |
324 (((uint16_t)buffer[24]) << 8);
325 hedge->positionBuffer[ind].
angle = ((float)(vang & 0x0fff)) / 10.0f;
331 return hedge->positionBuffer[ind];
339 for(i = 0; i < n_used; i++) {
353 uint8_t n = buffer[5];
359 if((1 + n * 8) != buffer[4])
362 for(i = 0; i < n; i++) {
366 x = buffer[ofs + 1] |
367 (((uint16_t)buffer[ofs + 2]) << 8);
368 y = buffer[ofs + 3] |
369 (((uint16_t)buffer[ofs + 4]) << 8);
370 z = buffer[ofs + 5] |
371 (((uint16_t)buffer[ofs + 6]) << 8);
388 uint8_t n = buffer[5];
394 if((1 + n * 14) != buffer[4])
397 for(i = 0; i < n; i++) {
401 x = buffer[ofs + 1] |
402 (((uint32_t)buffer[ofs + 2]) << 8) |
403 (((uint32_t)buffer[ofs + 3]) << 16) |
404 (((uint32_t)buffer[ofs + 4]) << 24);
405 y = buffer[ofs + 5] |
406 (((uint32_t)buffer[ofs + 6]) << 8) |
407 (((uint32_t)buffer[ofs + 7]) << 16) |
408 (((uint32_t)buffer[ofs + 8]) << 24);
409 z = buffer[ofs + 9] |
410 (((uint32_t)buffer[ofs + 10]) << 8) |
411 (((uint32_t)buffer[ofs + 11]) << 16) |
412 (((uint32_t)buffer[ofs + 12]) << 24);
429 uint8_t* dataBuf = &buffer[5];
451 uint8_t* dataBuf = &buffer[5];
476 uint8_t* dataBuf = &buffer[5];
482 for(i = 0; i < 4; i++) {
500 uint8_t input_buffer[256];
502 uint8_t nBytesInBlockReceived = 0;
505 struct pollfd fds[1];
514 printf(
"Opened serial port %s with baudrate %u\n",
518 uint8_t receivedChar;
519 bool readSuccessed =
true;
522 OVERLAPPED osReader = { 0 };
524 osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
525 if(osReader.hEvent == NULL) {
526 printf(
"Failed create event\n");
531 readSuccessed = ReadFile(ttyHandle, &receivedChar, 1, &nBytesRead, NULL);
544 CloseHandle(osReader.hEvent);
547 fds[0].fd = ttyHandle;
548 fds[0].events = POLLIN;
549 pollrc = poll(fds, 1, 1000);
552 if((fds[0].revents & POLLIN) == 0)
555 nBytesRead = read(ttyHandle, &receivedChar, 1);
557 readSuccessed =
false;
559 if(nBytesRead && readSuccessed) {
560 bool goodByte =
false;
561 input_buffer[nBytesInBlockReceived] = receivedChar;
564 switch(nBytesInBlockReceived) {
566 goodByte = (receivedChar == 0xff);
569 goodByte = (receivedChar == 0x47);
575 dataId = (((uint16_t)receivedChar) << 8) + input_buffer[2];
587 goodByte = (receivedChar == 0x10);
594 goodByte = (receivedChar == 0x16);
597 goodByte = (receivedChar == 0x20);
600 goodByte = (receivedChar == 0x2a);
603 goodByte = (receivedChar == 0x20);
612 nBytesInBlockReceived++;
616 nBytesInBlockReceived = 0;
620 nBytesInBlockReceived++;
621 if(nBytesInBlockReceived >= 7 + input_buffer[4]) {
627 EnterCriticalSection(&hedge->
lock_);
629 pthread_mutex_lock(&hedge->
lock_);
657 LeaveCriticalSection(&hedge->
lock_);
659 pthread_mutex_unlock(&hedge->
lock_);
674 nBytesInBlockReceived = 0;
706 InitializeCriticalSection(&hedge->
lock_);
708 pthread_mutex_init(&hedge->
lock_, NULL);
711 puts(
"Not enough memory");
725 puts(
"Not enough memory");
753 int32_t avg_x = 0, avg_y = 0, avg_z = 0;
754 double avg_ang = 0.0;
755 uint32_t max_timestamp = 0;
757 bool highRes =
false;
759 EnterCriticalSection(&hedge->
lock_);
761 pthread_mutex_lock(&hedge->
lock_);
768 for(i = 0; i < real_values_count; i++) {
794 position_valid =
true;
796 position_valid =
false;
799 position_valid =
false;
801 LeaveCriticalSection(&hedge->
lock_);
803 pthread_mutex_unlock(&hedge->
lock_);
809 position->
angle = avg_ang;
811 position->
ready = position_valid;
813 return position_valid;
833 uint8_t addressesNum = 0;
837 bool alreadyProcessed =
false;
838 if(addressesNum != 0)
839 for(j = 0; j < addressesNum; j++) {
841 alreadyProcessed =
true;
847 addresses[addressesNum++] =
address;
850 xm = ((double)position.
x) / 1000.0;
851 ym = ((double)position.
y) / 1000.0;
852 zm = ((double)position.
z) / 1000.0;
855 printf(
"Address: %d, X: %.3f, Y: %.3f, Z: %.3f, Angle: %.1f at time T: %u\n",
858 printf(
"Address: %d, X: %.2f, Y: %.2f, Z: %.2f, Angle: %.1f at time T: %u\n",
872 EnterCriticalSection(&hedge->
lock_);
874 pthread_mutex_lock(&hedge->
lock_);
880 LeaveCriticalSection(&hedge->
lock_);
882 pthread_mutex_unlock(&hedge->
lock_);
895 if(positions.
updated || (!onlyNew)) {
900 for(i = 0; i < n; i++) {
902 xm = ((double)b->
x) / 1000.0;
903 ym = ((double)b->
y) / 1000.0;
904 zm = ((double)b->
z) / 1000.0;
906 printf(
"Stationary beacon: address: %d, X: %.3f, Y: %.3f, Z: %.3f \n",
909 printf(
"Stationary beacon: address: %d, X: %.2f, Y: %.2f, Z: %.2f \n",
923 EnterCriticalSection(&hedge->
lock_);
925 pthread_mutex_lock(&hedge->
lock_);
931 LeaveCriticalSection(&hedge->
lock_);
933 pthread_mutex_unlock(&hedge->
lock_);
947 if(rawDistances.
updated || (!onlyNew)) {
948 for(i = 0; i < 4; i++) {
951 printf(
"Raw distance: %02d ==> %02d, Distance= %.3f \n",
967 EnterCriticalSection(&hedge->
lock_);
969 pthread_mutex_lock(&hedge->
lock_);
975 LeaveCriticalSection(&hedge->
lock_);
977 pthread_mutex_unlock(&hedge->
lock_);
989 if(rawIMU.
updated || (!onlyNew)) {
990 printf(
"Raw IMU: Timestamp: %08d, aX=%05d aY=%05d aZ=%05d gX=%05d gY=%05d gZ=%05d cX=%05d cY=%05d cZ=%05d \n",
1005 EnterCriticalSection(&hedge->
lock_);
1007 pthread_mutex_lock(&hedge->
lock_);
1013 LeaveCriticalSection(&hedge->
lock_);
1015 pthread_mutex_unlock(&hedge->
lock_);
1024 float x_m, y_m, z_m;
1030 if(fusionIMU.
updated || (!onlyNew)) {
1031 x_m = fusionIMU.
x / 1000.0;
1032 y_m = fusionIMU.
y / 1000.0;
1033 z_m = fusionIMU.
z / 1000.0;
1035 qw = fusionIMU.
qw / 10000.0;
1036 qx = fusionIMU.
qx / 10000.0;
1037 qy = fusionIMU.
qy / 10000.0;
1038 qz = fusionIMU.
qz / 10000.0;
1040 vx = fusionIMU.
vx / 1000.0;
1041 vy = fusionIMU.
vy / 1000.0;
1042 vz = fusionIMU.
vz / 1000.0;
1044 ax = fusionIMU.
ax / 1000.0;
1045 ay = fusionIMU.
ay / 1000.0;
1046 az = fusionIMU.
az / 1000.0;
1048 printf(
"IMU fusion: Timestamp: %08d, X=%.3f Y= %.3f Z=%.3f q=%.3f,%.3f,%.3f,%.3f v=%.3f,%.3f,%.3f a=%.3f,%.3f,%.3f \n",
1050 (
float)x_m, (
float)y_m, (
float)z_m,
1051 (
float)
qw, (
float)
qx, (
float)
qy, (
float)
qz,
1052 (
float)
vx, (
float)
vy, (
float)
vz,
1053 (
float)
ax, (
float)
ay, (
float)
az);
1067 WaitForSingleObject(hedge->
thread_, INFINITE);
1069 pthread_join(hedge->
thread_, NULL);