这篇博文详细记录在windows系统调试ydlidar的全过程
ydlidar采用全无线连接方式,测距雷达放在迷你机器人(型号tianbotmini,中文名天宝迷你)上如下图所示,需要usb无线设备接受雷达信息:
装配雷达的机器人和接收器
由于使用机器人操作系统(ROS1和ROS2),需要安装机器人操作系统的请参考如下:
下面开始操作,使用SDK版本为1.4.7,发布日期为2020年3月31日。
Linux系统下使用简单不做介绍,这里重点围绕windows
ydlidar SDK提供了控制命令和激光扫描数据传输的实现使用C/C++应用程序接口(API),基本结构如下图所示:
架构
vcpkg
这里可以看到使用cmake的详细参数,接着就可以完成配置愉快编译啦。
新建build文件夹:
build文件夹
使用如下命令进行配置:
配置顺利成功完成
然后进入build文件夹看一看???
VS工程
熟悉的画面出现啦。
主要Debug或Release版本选择x64,然后点击
主函数main代码如下,非常重要,稍后博文会介绍如何将其接入ROS,愉快玩耍:
#include "CYdLidar.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
using namespace ydlidar;
#if defined(_MSC_VER)
#pragma comment(lib, "ydlidar_driver.lib")
#endif
int main(int argc, char *argv[]) {
printf("__ ______ _ ___ ____ _ ____ \n");
printf("\\ \\ / / _ \\| | |_ _| _ \\ / \\ | _ \\ \n");
printf(" \\ V /| | | | | | || | | |/ _ \\ | |_) | \n");
printf(" | | | |_| | |___ | || |_| / ___ \\| _ < \n");
printf(" |_| |____/|_____|___|____/_/ \\_\\_| \\_\\ \n");
printf("\n");
fflush(stdout);
std::string port;
ydlidar::init(argc, argv);
std::map<std::string, std::string> ports =
ydlidar::YDlidarDriver::lidarPortList();
std::map<std::string, std::string>::iterator it;
if (ports.size() == 1) {
port = ports.begin()->second;
} else {
int id = 0;
for (it = ports.begin(); it != ports.end(); it++) {
printf("%d. %s\n", id, it->first.c_str());
id++;
}
if (ports.empty()) {
printf("Not Lidar was detected. Please enter the lidar serial port:");
std::cin >> port;
} else {
while (ydlidar::ok()) {
printf("Please select the lidar port:");
std::string number;
std::cin >> number;
if ((size_t)atoi(number.c_str()) >= ports.size()) {
continue;
}
it = ports.begin();
id = atoi(number.c_str());
while (id) {
id--;
it++;
}
port = it->second;
break;
}
}
}
int baudrate = 230400;
std::map<int, int> baudrateList;
baudrateList[0] = 115200;
baudrateList[1] = 128000;
baudrateList[2] = 153600;
baudrateList[3] = 230400;
baudrateList[4] = 512000;
printf("Baudrate:\n");
for (std::map<int, int>::iterator it = baudrateList.begin();
it != baudrateList.end(); it++) {
printf("%d. %d\n", it->first, it->second);
}
while (ydlidar::ok()) {
printf("Please select the lidar baudrate:");
std::string number;
std::cin >> number;
if ((size_t)atoi(number.c_str()) > baudrateList.size()) {
continue;
}
baudrate = baudrateList[atoi(number.c_str())];
break;
}
if (!ydlidar::ok()) {
return 0;
}
bool isSingleChannel = false;
bool isTOFLidar = false;
std::string input_channel;
std::string input_tof;
printf("Whether the Lidar is one-way communication[yes/no]:");
std::cin >> input_channel;
std::transform(input_channel.begin(), input_channel.end(),
input_channel.begin(),
[](unsigned char c) {
return std::tolower(c); // correct
});
if (input_channel.find("yes") != std::string::npos) {
isSingleChannel = true;
}
if (!ydlidar::ok()) {
return 0;
}
printf("Whether the Lidar is a TOF Lidar [yes/no]:");
std::cin >> input_tof;
std::transform(input_tof.begin(), input_tof.end(),
input_tof.begin(),
[](unsigned char c) {
return std::tolower(c); // correct
});
if (input_tof.find("yes") != std::string::npos) {
isTOFLidar = true;
}
if (!ydlidar::ok()) {
return 0;
}
std::string input_frequency;
float frequency = 8.0;
while (ydlidar::ok() && !isSingleChannel) {
printf("Please enter the lidar scan frequency[3-15.7]:");
std::cin >> input_frequency;
frequency = atof(input_frequency.c_str());
if (frequency <= 15.7 && frequency >= 3.0) {
break;
}
fprintf(stderr,
"Invalid scan frequency,The scanning frequency range is 5 to 12 HZ, Please re-enter.\n");
}
if (!ydlidar::ok()) {
return 0;
}
CYdLidar laser;
//<! lidar port
laser.setSerialPort(port);
//<! lidar baudrate
laser.setSerialBaudrate(baudrate);
//<! fixed angle resolution
laser.setFixedResolution(false);
//<! rotate 180
laser.setReversion(false); //rotate 180
//<! Counterclockwise
laser.setInverted(false);//ccw
laser.setAutoReconnect(true);//hot plug
//<! one-way communication
laser.setSingleChannel(isSingleChannel);
//<! tof lidar
laser.setLidarType(isTOFLidar ? TYPE_TOF : TYPE_TRIANGLE);
//unit: °
laser.setMaxAngle(180);
laser.setMinAngle(-180);
//unit: m
laser.setMinRange(0.01);
laser.setMaxRange(64.0);
//unit: Hz
laser.setScanFrequency(frequency);
std::vector<float> ignore_array;
ignore_array.clear();
laser.setIgnoreArray(ignore_array);
bool ret = laser.initialize();
if (ret) {
ret = laser.turnOn();
}
while (ret && ydlidar::ok()) {
bool hardError;
LaserScan scan;
if (laser.doProcessSimple(scan, hardError)) {
fprintf(stdout, "Scan received[%llu]: %u ranges is [%f]Hz\n",
scan.stamp,
(unsigned int)scan.points.size(), 1.0 / scan.config.scan_time);
fflush(stdout);
} else {
fprintf(stderr, "Failed to get Lidar Data\n");
fflush(stderr);
}
}
laser.turnOff();
laser.disconnecting();
return 0;
}
编译界面如下:
调试环境
分别用debug和release调试一下吧。
很顺利,都分别生成了ydlidar_test.exe。
ydlidar顺利出现
这时候build下会分别多出debug和release两个文件夹,进入release:
详细文件列表
插上无线接收器,打开天宝迷你电源开关,一切配网正确:
测试
设置波特率等参数如下所示:
参数配置1
但是请依据雷达具体型号配置参数哦,如果不正确建立连接获取状态。
参数配置2
更多具体内容参考SDK文档的readme与API。很全!
API文档
一共199页,满足你的各种需求。