版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YunLaowang/article/details/89709268
简介
SICK LMS400是德国SICK公司生产的单线型激光传感器,主要应用于室内场景的测量,打出的激光是650nm可见红光,其主要参数如下:
- 性能:扫描频率300Hz-500Hz、角度分辨率0.1°-1.0°可选、工作区域0.7m-3.0m、水平测量角度70°、测量精度±4mm;
- 接口:Ethernet(TCP/IP协议)、RS232串口;
- 电子参数:供电电压24VDC、功耗25W、外壳防护等级IP65;
- 机械参数:外壳材质压铸铝、尺寸(长 x 宽 x 高)179 mm x 107 mm x 130 mm;
- 温度:工作环境温度0°C…+40°C,储存温度–20°C…+70°C;
- 最小可检测物体:30 mm x 30 mm;
LMS400扫描的结果是二维平面点云,其工作区域如下图所示,需要注意的是,当激光如下Fig.3图放置时,其坐标系是Y轴朝前为正、X朝右为正,而且扫描的点云结果是按照X坐标由大到小(如图从右往左)进行存储的,即下述代码中的lines.ranges.front()代表最右边的有效点,lines.ranges.back()代表最左边的有效点,千万不要搞反。
工作区域图表:
代码
环境:Win10+VS2015+PCL1.8
// LMS400连续扫描
#include<iostream>
#include<stdio.h>
#include<fstream>
//pcl
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <conio.h>
#include "LMS400.h"
#define KEYDOWN( vk ) ( 0x8000 & ::GetAsyncKeyState( vk ) )
using namespace std;
int main(int argc, char** argv)
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
LMS400* m_lms = new LMS400();
// pcl
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("Single Lines Viewer"));
double layer = 0; // 点云的层次
while (true)
{
if (KEYDOWN(VK_ESCAPE) > 0) // 按ESC退出
break;
// 激光扫描
m_lms->spin();
LaserScan lines = m_lms->getLaserScan();
// pcl
for (size_t i = 0; i < lines.size(); i++)
{
pcl::PointXYZRGB p;
p.x = lines[i].getX(); // 等效于lines.ranges[i].getX(),重载了操作符:[]
p.y = lines[i].getY(); // z值
p.z = layer;
p.b = 0;
p.g = 0;
p.r = 255;
cloud->points.push_back(p);
}
layer += 0.005; // 将扫描的结果间隔0.005mm进行存储
cout << "spining" << endl;
}
// 设置并保存点云
cloud->height = 1;
cloud->width = cloud->points.size();
cout << "point cloud size = " << cloud->points.size() << endl;
cloud->is_dense = false;
pcl::io::savePCDFile("pointcloud.pcd", *cloud);
// 显示结果
viewer->addCoordinateSystem(0.3); // X(红)Y(绿)Z(蓝)
viewer->setPosition(0, 0); // 设置在视图坐标系的位置
viewer->addPointCloud<pcl::PointXYZRGB>(cloud, "sample cloud"); // 将点云数据添加到视窗中
//用于改变显示点云的尺寸,可以利用该方法控制点云在视窗中的显示方法,
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");// 设置点云显示属性,
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(1000));
}
delete m_lms;
WSACleanup();
return 0;
}
代码的底层是基于TCP/IP协议进行通讯,如向激光发送ASCII码协议:"sMN mLRstopdata"对于LMS400代表的就是停止测量;如"sMN SetAccessMode 03 B18244B6"对应的是设置用户等级为authorized client等等,更多协议参见官方文档。
注意:上述操作激光的流程是:打开一次激光(构造函数内的start()函数)、多次采集数据(while循环)、关闭一次激光(析构函数内的stop()函数);但是如果你的需求是只在有需要的时候才打激光采集数据,而不是打完激光一直采数据的话,则其执行流程应该修改为:打开1次-采数据1次-关闭1次,相应的代码应修改为start()-采数据-stop(),否则可能会出现只能采集1次数据,第2次采集的数据完全不对的问题。总之,关闭激光以后,再次采集数据之前重新打开激光即可。
结果
使用LMS400扫描的书包:
资源链接
- SICK官方Github:https://github.com/SICKAG/
- LMS400相关的API: asr_sick_lms_400 Namespace Reference
- ROS相关:asr_sick_lms_400-ROS Wiki
备注
- 完整工程CSDN下载链接:SICK—LMS400激光传感器测距程序【Win10+VS2015】
- 该代码是在官方提供ROS驱动的基础上进行的二次封装,相关src及include文件在Github上也能找到。