SICK laser sensor: LMS400 generates a point cloud surface

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/YunLaowang/article/details/89709268
Brief introduction

SICK LMS400 is a single-type laser sensor Germany SICK produced, mainly applied to the measurement of indoor scene, shot visible red laser is 650nm, whose main parameters are as follows:

  • Performance: scanning frequency of 300Hz-500Hz, the resolution of 0.1 ° -1.0 ° angle Alternatively, the work area 0.7m-3.0m, the horizontal angle measuring 70 °, the measurement accuracy of ± 4mm;
  • Interface: Ethernet (TCP / IP protocol), RS232 serial port;
  • Electrical parameters: voltage supply 24VDC, power consumption 25W, housing protection class IP65;
  • Mechanical parameters: a housing die-cast aluminum material, size (length x width x height) 179 mm x 107 mm x 130 mm;
  • Temperature: Operating temperature 0 ° C ... + 40 ° C, storage temperature -20 ° C ... + 70 ° C;
  • Minimum detectable object: 30 mm x 30 mm;

Results LMS400 scanning point cloud is a two-dimensional plane, which is shown below the work area, it is noted that, when the laser is placed below FIG Fig.3, which coordinate system is positive for the Y axis forward, X is positive to the right , and the result of the scan point cloud is stored in accordance with the X coordinate descending (right to left in FIG.), i.e. following code lines.ranges.front () rightmost point representative of effective, lines.ranges .back () represents the most effective point left, do not engage in anti.

The working area of ​​the chart:


Code

Environment: 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;
}

Underlying code is based on TCP / IP communication protocol, such as the laser sending ASCII protocol: "sMN mLRstopdata" LMS400 for the representative measurement is stopped; as "sMN SetAccessMode 03 B18244B6" corresponds to a set of authorized client user level and so on more agreements see the official documentation.

注意:上述操作激光的流程是:打开一次激光(构造函数内的start()函数)、多次采集数据(while循环)、关闭一次激光(析构函数内的stop()函数);但是如果你的需求是只在有需要的时候才打激光采集数据,而不是打完激光一直采数据的话,则其执行流程应该修改为:打开1次-采数据1次-关闭1次,相应的代码应修改为start()-采数据-stop(),否则可能会出现只能采集1次数据,第2次采集的数据完全不对的问题。总之,关闭激光以后,再次采集数据之前重新打开激光即可。

结果

使用LMS400扫描的书包:

资源链接
  1. SICK官方Github:https://github.com/SICKAG/
  2. LMS400相关的API: asr_sick_lms_400 Namespace Reference
  3. ROS相关:asr_sick_lms_400-ROS Wiki
备注
  1. 完整工程CSDN下载链接:SICK—LMS400激光传感器测距程序【Win10+VS2015】
  2. 该代码是在官方提供ROS驱动的基础上进行的二次封装,相关src及include文件在Github上也能找到。

Guess you like

Origin blog.csdn.net/YunLaowang/article/details/89709268