MaixSense-A010 接入 ROS
MaixSense 是什么
MaixSense 系列产品搭载 TOF 深度摄像头,目前有 MaixSense-A010 和 MaixSense-A075V 两款产品。
MS-A010 是一款由 BL702 + 炬佑 100x100 TOF 模组所组成的极致性价比的 TOF 3D 传感器模组,最大支持 100x100 的分辨率和 8 位精度,并且带有 240×135 的 LCD 显示屏可实时预览 color map 后的深度图。
而 MS-A075V 是一款具有 RGB 功能的 3D TOF 摄像机模组,该模组可以实现 Linux 免驱的即插即用,实现实时彩色 3D 显示。
参数如下:
MaixSense 能做什么
远中近物体实拍
高精度的映射物品摆放距离的差异,点云图可直观感受到更真实的可视化。
人流统计
可实时监控人流,进行高精度、大分辨率的统计。
小车避障
可搭载于小车移动并判断画面是否有障碍物,模组自带 LCD 屏幕精准显示距离并做出反应规避障碍物。
键盘灯跟随
实现超酷炫的键盘灯跟随,实时跟踪手部的位置,再根据手部的位置映射键盘灯。
体积测量
外接 MCU
MS-A010 拥有强大的兼容性,基于串口协议的数据传输。
可外接 K210 bit 这样的单片机开发板或树莓派之类的 linux 开发板来进行二次开发。
接入 ROS1 / ROS2
双支持 ROS 系统,开放 ROS1+ROS2 接入功能包,可快速获得深度数据及深度图。
TOF 技术
TOF: 是一种距离测量的方法,通过测量发射器和反射器之间的超声波/微波/光等信号的“飞行时间”来计算两者之间的距离。 可以实现TOF测距的是TOF传感器。 最常用的是红外线或激光测距。
物体之间的距离存在差异。 该模块通过捕获的深度值的差异来显示冷色和暖色。冷暖色随着距离的映射而变化,距离越近色调呈暖调(橘红)而越远色调呈冷调(蓝色)。
更多详细资料不再赘述,见:https://wiki.sipeed.com/hardware/zh/maixsense/maixsense-a010/maixsense-a010.html
接入 ROS1(Linux)
publisher 代码(使用 type-C 虚拟串口)
代码(网上下载)
不要下载网站上的那个接入包,实测不好用。用下面这个:
git clone https://github.com/sipeed/MaixSense_ROS.git
然后我把目录下的 ros1 挪到了自己常用的工作空间,目录结构如下。(视个人情况而定)
cd ~/mynewestros
catkin_make
运行 publisher
rosrun sipeed_tof_ms_a010 node device:="/dev/ttyUSB0"
效果类似于如下:(当时是使用了不好用的旧接入包,所以只看输出的四个参数即可)
rqt 查看帧率
Plugins —> Topics —> Message Publisher
然后运行节点:
rosrun sipeed_tof_ms_a010 node device:="/dev/ttyUSB0"
效果如下:
rviz 预览
rosrun sipeed_tof_ms_a010 node device:="/dev/ttyUSB0"
rviz
代码里 header.frame_id 是什么,Global Options - Fixed Frame 就填什么。
subscriber 代码(使用 type-C 虚拟串口)
运行 subscriber
rosrun sipeed_tof_ms_a010 msghandler device:="/dev/ttyUSB0"
代码(自行编写)
#include <ros/ros.h>
#include <sensor_msgs/Image.h>
#include <sensor_msgs/PointCloud2.h>
#include <iostream>
void pointDepthCallback(const sensor_msgs::ImageConstPtr& msg)
{
// 打印点云中的点数
// ROS_INFO("Received point cloud with %d points", msg->width * msg->height);
}
void pointCloudCallback(const sensor_msgs::PointCloud2ConstPtr& msg)
{
// 打印点云中的点数
ROS_INFO("Received point cloud with %d points", msg->width * msg->height);
}
int main (int argc, char **argv)
{
// 初始化ROS节点
ros::init(argc, argv, "point_cloud_processor");
// 创建节点句柄
ros::NodeHandle nh("~");
std::string s;
nh.param<std::string>("device", s, "/dev/ttyUSB0");
std::cout << "use device: " << s << std::endl;
std::string from_device(s.substr(5));
std::stringstream sd;
std::stringstream sc;
// 订阅深度信息
sd.str("");
sd << "/" << from_device << "/depth";
std::cout << sd.str() << std::endl;
ros::Subscriber sub_depth = nh.subscribe<sensor_msgs::Image>(strdup(sd.str().c_str()), 1, pointDepthCallback);
std::cout << strdup(sd.str().c_str()) << std::endl;
// 订阅点云数据
sc.str("");
sc << "/" << from_device << "/cloud";
std::cout << sc.str() << std::endl;
ros::Subscriber sub_cloud = nh.subscribe<sensor_msgs::PointCloud2>(strdup(sc.str().c_str()), 1, pointCloudCallback);
std::cout << strdup(sc.str().c_str()) << std::endl;
// 循环处理ROS消息
ros::spin();
return 0;
}
这里有个小坑,明天再说吧,早该下班了~
看一下实现效果吧:
注意!!
在运行节点时,所填的参数不一定是“/dev/ttyUSB0”,可能是“/dev/ttyUSB1”、/dev/ttyUSB2“”、“/dev/ttyUSB3”……
所以要提前查看一下有效的 USB 口。
ls /dev/ttyUSB
# 然后狂摁Tab