1. 程式人生 > >鐳射雷達學習筆記(一)資料採集

鐳射雷達學習筆記(一)資料採集

鐳射雷達或者叫鐳射測距儀資料採集比較簡單,有位好心的網友提供了一篇部落格專門講這個,這裡就不再贅述,貼出連結,需要的直接去看原文,鐳射雷達的型號:UTM-30LX。

當前網上關於鐳射雷達的資料比較少,畢竟用的人不是很多。開發環境主流的還是C/C++,官方提供的例程也都是C/C++的。

官網資料:http://www.hokuyo-aut.jp/02sensor/07scanner/download/urg_programs_en/  上面包括鐳射雷達的驅動和採集軟體都有提供,需要的話只需要按照上面的步驟去做就可以。

雖然鐳射雷達的型號不同,採集部分的程式碼不同,但是資料處理部分的方法確實相同的,在接下來的日子裡我會逐漸共享我使用鐳射雷達資料所用到的演算法和程式碼,共同學習,共同進步。

     現在的開發語言是C/C++,控制檯程式,為了便於快速實現以及進行圖形的顯示,使用了OpenCV2.4的程式碼。當然也有人用Labview或者Matlab開發鐳射雷達,不同的方法之間各有利弊,同時也看個人的喜好。Labview介面部分很簡單快捷,程式設計效率也很高,但是感覺演算法的實現稍微麻煩些;Matlab程式設計效率高,常用函式齊全。Matlab和Labview開發鐳射雷達一個共同的問題是程式的可移植性。我更加希望我的程式可以移植到嵌入式平臺上,不管是Linux環境或者裸機環境。www.it165.net

鐳射雷達資料採集程式:(UTM-30LX)


001./*! 002.
\file 003.\brief Sample to get URG data using Win32 004. 005.\author Satofumi KAMIMURA 006. 007.$Id: capture_sample.cpp 1724 2010-02-25 10:43:11Z satofumi $ 008. 009.Compling and execute process 010.- In case of Visual Studio 011.- Select capture_sample.sln from capture_sample.zip 012.- When Visual Studio is started, press F5 to build and execute.
013.- If COM port is not found, then change the com_port in main function. 014. 015.- In case of MinGW, Cygwin 016.- % g++ capture_sample.cpp -o capture_sample 017.- % ./capture_sample 018.- If COM port is not found, then change the com_port in main function. 019. 020.\attention Change com_port, com_baudrate values in main() with relevant values. 021.\attention We are not responsible for any loss or damage occur by using this program 022.\attention We appreciate the suggestions and bug reports 023.*/ 024. 025.#define _CRT_SECURE_NO_WARNINGS 026. 027.#include <windows.h> 028.#include <cstdio> 029.#include <cstdlib> 030.#include <cstring> 031.#include <string> 032. 033.using namespace std; 034. 035. 036.// To record the output of SCIP,define RAW_OUTPUT 037.//#define RAW_OUTPUT 038. 039.#if defined(RAW_OUTPUT) 040.static FILE* Raw_fd_ = NULL; 041.#endif 042. 043. 044.enum { 045.Timeout = 1000,               // [msec] 046.EachTimeout = 2,              // [msec] 047.LineLength = 64 + 3 + 1 + 1 + 1 + 16, 048.}; 049. 050.static HANDLE HCom = INVALID_HANDLE_VALUE; 051.static int ReadableSize = 0; 052.static char* ErrorMessage = "no error."; 053. 054. 055./*! 056.\brief Manage sensor information 057.*/ 058.typedef struct 059.{ 060.enum { 061.MODL = 0,                   //!< Sensor model information 062.DMIN,                       //!< Minimum measurable distance [mm] 063.DMAX,                       //!< Maximum measurable distance [mm] 064.ARES,                       //!< Angle of resolution 065.AMIN,                       //!< Minimum measurable area 066.AMAX,                       //!< Maximum measurable area 067.AFRT,                       //!< Front direction value 068.SCAN,                       //!< Standard angular velocity 069.}; 070.string model;                 //!< Obtained MODL information 071.long distance_min;            //!< Obtained DMIN information 072.long distance_max;            //!< Obtained DMAX information 073.int area_total;               //!< Obtained ARES information 074.int area_min;                 //!< Obtained AMIN information 075.int area_max;                 //!< Obtained AMAX information 076.int area_front;               //!< Obtained AFRT information 077.int scan_rpm;                 //!< Obtained SCAN information 078. 079.int first;                    //!< Starting position of measurement 080.int last;                     //!< End position of measurement 081.int max_size;                 //!< Maximum size of data 082.long last_timestamp;          //!< Time stamp when latest data is obtained 083.} urg_state_t; 084. 085. 086.// Delay 087.static void delay(int msec) 088.{ 089.Sleep(msec); 090.} 091. 092. 093.static int com_changeBaudrate(long baudrate) 094.{ 095.DCB dcb; 096. 097.GetCommState(HCom, &dcb); 098.dcb.BaudRate = baudrate; 099.dcb.ByteSize = 8; 100.dcb.Parity = NOPARITY; 101.dcb.fParity = FALSE; 102.dcb.StopBits = ONESTOPBIT; 103.SetCommState(HCom, &dcb); 104. 105.return 0; 106.} 107. 108. 109.// Serial transceiver 110.static int com_connect(const char* device, long baudrate) 111.{ 112.#if defined(RAW_OUTPUT) 113.Raw_fd_ = fopen("raw_output.txt", "w"); 114.#endif 115. 116.char adjust_device[16]; 117._snprintf(adjust_device, 16, "\\\\.\\%s", device); 118.HCom = CreateFileA(adjust_device, GENERIC_READ | GENERIC_WRITE, 0, 119.NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 120. 121.if (HCom == INVALID_HANDLE_VALUE) { 122.return -1; 123.} 124. 125.// Baud rate setting 126.return com_changeBaudrate(baudrate); 127.} 128. 129. 130.static void com_disconnect(void) 131.{ 132.if (HCom != INVALID_HANDLE_VALUE) { 133.CloseHandle(HCom); 134.HCom = INVALID_HANDLE_VALUE; 135.} 136.} 137. 138. 139.static int com_send(const char* data, int size) 140.{ 141.DWORD n; 142.WriteFile(HCom, data, size, &n, NULL); 143.return n; 144.} 145. 146. 147.static int com_recv(char* data, int max_size, int timeout) 148.{ 149.if (max_size <= 0) { 150.return 0; 151.} 152. 153.if (ReadableSize < max_size) { 154.DWORD dwErrors; 155.COMSTAT ComStat; 156.ClearCommError(HCom, &dwErrors, &ComStat); 157.ReadableSize = ComStat.cbInQue; 158.} 159. 160.if (max_size > ReadableSize) { 161.COMMTIMEOUTS pcto; 162.int each_timeout = 2; 163. 164.if (timeout == 0) { 165.max_size = ReadableSize; 166. 167.} else { 168.if (timeout < 0) { 169./* If timeout is 0, this function wait data infinity */ 170.timeout = 0; 171.each_timeout = 0; 172.} 173. 174./* set timeout */ 175.GetCommTimeouts(HCom, &pcto); 176.pcto.ReadIntervalTimeout = timeout; 177.pcto.ReadTotalTimeoutMultiplier = each_timeout; 178.pcto.ReadTotalTimeoutConstant = timeout; 179.SetCommTimeouts(HCom, &pcto); 180.} 181.} 182. 183.DWORD n; 184.ReadFile(HCom, data, (DWORD)max_size, &n, NULL); 185.#if defined(RAW_OUTPUT) 186.if (Raw_fd_) { 187.for (int i = 0; i < n; ++i) { 188.fprintf(Raw_fd_, "%c", data[i]); 189.} 190.fflush(Raw_fd_); 191.} 192.#endif 193.if (n > 0) { 194.ReadableSize -= n; 195.} 196. 197.return n; 198.} 199. 200. 201.// The command is transmitted to URG 202.static int urg_sendTag(const char* tag) 203.{ 204.char send_message[LineLength]; 205._snprintf(send_message, LineLength, "%s\n", tag); 206.int send_size = (int)strlen(send_message); 207.com_send(send_message, send_size); 208. 209.return send_size; 210.} 211. 212. 213.// Read one line data from URG 214.static int urg_readLine(char *buffer) 215.{ 216.int i; 217.for (i = 0; i < LineLength -1; ++i) { 218.char recv_ch; 219.int n = com_recv(&recv_ch, 1, Timeout); 220.if (n <= 0) { 221.if (i == 0) { 222.return -1;              // timeout 223.} 224.break; 225.} 226.if ((recv_ch == '\r') || (recv_ch == '\n')) { 227.break; 228.} 229.buffer[i] = recv_ch; 230.} 231.buffer[i] = '\0'; 232. 233.return i; 234.} 235. 236. 237.// Trasmit command to URG and wait for response 238.static int urg_sendMessage(const char* command, int timeout, int* recv_n) 239.{ 240.int send_size = urg_sendTag(command); 241.int recv_size = send_size + 2 + 1 + 2; 242.char buffer[LineLength]; 243. 244.int n = com_recv(buffer, recv_size, timeout); 245.*recv_n = n; 246. 247.if (n < recv_size) { 248.// if received data size is incorrect 249.return -1; 250.} 251. 252.if (strncmp(buffer, command, send_size -1)) { 253.// If there is mismatch in command 254.return -1; 255.} 256. 257.// !!! check checksum here 258. 259.// Convert the response string into hexadecimal number and return that value 260.char reply_str[3] = "00"; 261.reply_str[0] = buffer[send_size]; 262.reply_str[1] = buffer[send_size + 1]; 263.return strtol(reply_str, NULL, 16); 264.} 265. 266. 267.// Change baudrate 268.static int urg_changeBaudrate(long baudrate) 269.{ 270.char buffer[] = "SSxxxxxx\r"; 271._snprintf(buffer, 10, "SS%06d\r", baudrate); 272.int dummy = 0; 273.int ret = urg_sendMessage(buffer, Timeout, &dummy); 274. 275.if ((ret == 0) || (ret == 3) || (ret == 4)) { 276.return 0; 277.} else { 278.return -1; 279.} 280.} 281. 282. 283.// Read out URG parameter 284.static int urg_getParameters(urg_state_t* state) 285.{ 286.// Read parameter 287.urg_sendTag("PP"); 288.char buffer[LineLength]; 289.int line_index = 0; 290.enum { 291.TagReply = 0, 292.DataReply, 293.Other, 294.}; 295.int line_length; 296.for (; (line_length = urg_readLine(buffer)) > 0; ++line_index) { 297. 298.if (line_index == Other + urg_state_t::MODL) { 299.buffer[line_length - 2] = '\0'; 300.state->model = &buffer[5]; 301. 302.} else if (line_index == Other + urg_state_t::DMIN) { 303.state->distance_min = atoi(&buffer[5]); 304. 305.} else if (line_index == Other + urg_state_t::DMAX) { 306.state->distance_max = atoi(&buffer[5]); 307. 308.} else if (line_index == Other + urg_state_t::ARES) { 309.state->area_total = atoi(&buffer[5]); 310. 311.} else if (line_index == Other + urg_state_t::AMIN) { 312.state->area_min = atoi(&buffer[5]); 313.state->first = state->area_min; 314. 315.} else if (line_index == Other + urg_state_t::AMAX) { 316.state->area_max = atoi(&buffer[5]); 317.state->last = state->area_max; 318. 319.} else if (line_index == Other + urg_state_t::AFRT) { 320.state->area_front = atoi(&buffer[5]); 321. 322.} else if (line_index == Other + urg_state_t::SCAN) { 323.state->scan_rpm = atoi(&buffer[5]); 324.