ROS复习
一、考试时间、形式、日期
已经考完了
二、题型
- 选择 10*2
- 判断 4*2
- 多选 4*3
- 简答 2*5
- 程序填空 5*2
- 程序阅读 2*20
三、不知道随便写
知识点不完整,复习用,“我的补充”不是考试内容。
四、课程知识点、难点
1、1-3章课后复习题
1.1 单元测试一
1.[单选]机器人操作系统的全称是? D
A. React Operating System
B. Router Operating System
C. Request of Service
D. Robot Operating System
2.[单选] ROS Kinetic 最佳适配的 Linux 版本是? C
A. CentOS 7
B. Ubuntu 14.04
C. Ubuntu 16.04
D. Ubuntu 18.04
3.[单选]下列哪个不是 ROS 的特点? C
A.开源
B.分布式架构
C.强实时性
D.模块化
4.[单选] ROS 官方二进制包可以通过以下哪个命令安装(假定 Kinetic 版本)? D
A. sudo apt-get install ROS_kinetic_pacakgename
B. sudo apt-get install ROS-Kinetic- pacakgename
C. sudo apt-get install ros_kinetic_packagename
D. sudo apt-get install ros- kinetic-packagename
5.[单选] ROS 最早诞生于哪所学校的实验室? B
A.麻省理工学院(MIT)
B.斯坦福大学(Stanford)
C.加州大学伯克利分校(UC. Berkeley)
D.卡内基梅隆大学(CMU)
6.[多选]下列哪些是 ROS 的发行版本? ABD
A. Indigo
B. Jade
C. Xenial
D. Kinetic
7.[多选]查看 https://robots.ros.org/页面的机器人,下列哪些支持 ROS? ABCD
A. Pioneer 3-AT
B. XBot
C. TurtleBot3
D. PR2
1.2 单元测试二
1.[单选]如果要 clone 一个 ROS 的软件包,下列哪个路径是合理的存放位置? C
A. ~/catkin_ws/devel
B. ~/catkin_ws/
C. ~/my_ws/src
D. ~/catkin_ws/build
2.[单选]默认情况下,catkin_make 生成的 ROS 可执行文件放在哪个路径? C
A. catkin_ws/src
B. catkin_ws/
C. catkin_ws/devel
D. catkin_ws/build
3.[多选]一个 ROS 的 pacakge 要正常的编译,必须要有哪些文件? BD
A. *.cpp
B. CMakeLists.txt
C. *.h
D. package.xml
4.[单选]关于 ROS Node 的描述,哪一项是错误的? B
A. Node 启动前会向Master 注册
B. Node 可以先于 ROS Master 启动
C. Node 是 ROS 可执行文件运行的实例
D. Node 是 ROS 的进程
5.[单选]关于.launch 文件的描述,以下哪一项是错的? C
A.可以加载配置好的参数,方便快捷
B.通过 roslaunch 命令来启动 launch 文件
C.在 roslaunch 前必须先 roscore
D.可以一次性启动多个节点,减少操作
6.[单选]想要查看“/odom”话题发布的内容,应该用哪个命令? A
A. rostopic echo /odom
B. rostopic content /odom
C. rostopic info /odom
D.rostopic print/odom
7.[多选]关于 Topic 通信的描述,下列选项正确的有? AC
A.Topic 是一种异步通信机制
B.一个 Topic 至少要有一个发布者和一个接收者
C.查看当前活跃的 Topic 可以通过 rostopic list 命令
D.一个 Node 最多只能发布一个 Topic
8.[判断]同一个 Topic 上可以有多个发布者。 A
A.正确
B.错误
9.[单选]下列有关 Service 与 Topic 通信区别的描述,说法错误的是? B
A. Topic 是异步通信,Service 是同步通信
B.多个 Server 可以同时提供同一个 Service
C. Topic 通信是单向的,Service 是双向的
D. Topic 适用于传感器的消息发布,Service 适用于偶尔调用的任务
10.[单选]已知一个 service 叫做“/GetMap”,查看该 service 的类型可以用哪条指令? B
A.rosservice echo /GetMap
B.rosservice type /GetMap
C.rossrv type /GetMap
D.rosservice list /GetMap
11.[单选]在 parameter server 上添加 param 的方式不包括? A
A.通过 rosnode 命令添加 param
B.通过 rosparam 命令添加 param
C.在 launch 中添加 param
D.通过 ROS 的 API 来添加 param
12.[单选]下列选项中关于 Action 的描述错误的是? C
A. Action 通信的双方也是 Client 和 Server
B. Action 的 Client 可以发送目标 goal,也可以请求取消 cancel
C. action 文件与.srv 文件写法一致
D. Action 通常用在长时间的任务中
13.[多选]下列选项中关于 ROS 通信方式的描述正确的是? BCD
A.现在要设计一个节点,开发路径规划功能,输入是目标点和起始点,输出是路径,适合用 Topic 通信方式
B.传感器消息发布一般都采用 Topic 形式发布
C. Action 更适合用在执行时间长、并且需要知道状态和结果的场景
D.机械臂关节的逆解计算适合用 Service 通信
1.3 单元测试三
1.[单选] Gazebo 是一款什么工具? C
A.调试
B.可视化
C.仿真
D.命令行
2.[单选] rqt_graph 可以用来查看计算图,以下说法错误的是? C
A.计算图反映了节点之间消息的流向
B. rqt_graph 中的椭圆代表节点
C. rqt_graph 可以看到所有的 topic、service 和 action
D.计算图反映了所有运行的节点
3.[单选]下列选项中关于 rosbag 的描述错误的是? A
A. rosbag 可以记录和回放 service
B. rosbag 可以记录和回放 topic
C. rosbag 记录的结果为.bag 文件
D. rosbag 可以指定记录某一个或多个 topic
4.[多选] Rviz 可以图形化显示哪些类型的数据? ABCD
A.激光 LaserScan
B.点云 PointCloud
C.机器人模型 RobotModel
D.轨迹 Path 以上类型数据 Rviz
2、第二章 ROS系统架构
2.1 比较Topic与Service通信
(包括通信方式、通信模型、映射关系、应用场景)
2.2 关闭一个节点的方法。
- ctrl c (与快捷键的设置有关)
- rosnode kill 节点名称
- kill 进程名称
- 调用ros::shutdown()来手动关闭节点
2.3 我的补充
(1)catkin工作空间架构
(2)src、build、devel文件夹作用
(3)CMakeLists.txt 规定catkin编译的规则 例如:源文件、依赖项、目标文件
cmake_minimum_required() #指定catkin最低版本
project() #指定软件包的名称
find_package() #指定编译时需要的依赖项
add_message_files()/add_service_files()/add_action_files()
#添加消息文件/服务文件/动作文件
generate_messages() #生成消息、服务、动作
catkin_package() #指定catkin信息给编译系统生成Cmake文件
add_library()/add_executable() #指定生成库文件、可执行文件
target_link_libraries() #指定可执行文件去链接哪些库
catkin_add_gtest() #添加测试单元
install() #生成可安装目标
(4)package.xml 定义package的属性 例如:包名、版本号、作者、依赖等
<package> <!--根标签-->
<name> <!--包名-->
<version> <!--版本号-->
<description> <!--包描述-->
<maintainer> <!--维护者-->
<license> <!--软件许可-->
<buildtool_depend> <!--编译工具-->
<build_depend> <!--编译时的依赖-->
<run_depend> <!--运行时的依赖-->
</package>
(5)常用指令
-
rospack
查找某个pkg的地址 $ rospack find package_name
列出本地所有pkg $ rospack list
-
roscd
跳转到某个pkg路径下 $ roscd package_name
-
rosls
列举某个pkg下的文件信息 $ rosls package_name
-
rosed
编辑pkg中的文件 $ roscd package_name file_name
-
catkin_create_pkg
创建一个pkg $ catkin_create_pkg <pkg_name> [deps]
-
rosdep
安装某个pkg所需的依赖 $ rosdep install [pkg_name]
-
rosrun
启动一个node $ rosrun [pkg_name] [node_name]
-
rosnode
列出当前运行的node信息 $ rosnode list 显示某个node的详细信息 $ rosnode info [node_name] 结束某个node $ rosnode kill [node_name]
-
roslaunch
启动master和多个node$ roslaunch [pkg_name] [file_name.launch]
(6)master
每个node启动时都要向master注册,管理node之间的通信
(7)topic工作流程
(8)Message topic内容的数据类型定义在*.msg文件中
基本msg包括
bool, int8, int16, int32, int64(以及uint)
float32, float64, string
time, duration, header
可变长数组array[], 固定长度数组array[C]
(9)topic与message命令
(10)service (srv文件是用来描述服务(service)数据类型)
(11)参数服务器(Parameter server)
节点存储参数的地方,用于配置参数,全局共享参数。使用XMLRPC数据类型更加的静态,维护着一个数据字典,字典里存储着各种参数和配置
(12)参数服务器维护方式
命令行维护:$ rosparam set/get/list/...launch文件内读写:launch文件内读写:launch文件中有很多标签,而与参数服务器相关的标签只有两个,一个是<param>,另一个是<rosparam>。这两个标签功能比较相近,但<param>一般只设置一个参数。node源码:修改ROS的node源码,也就是利用API来对参数服务器进行操作。
(13)动作库(Actionlib)
action也是一种请求响应机制的通信方式Action带有连续反馈,可以随时查看任务进度,也可以终止请求,这样的特性使得它在一些特别的机制中拥有很高的效率,比较适合实现长时间的通信过程Action规范文件的后缀名是.action
3、第四章 ROS客户端库
3.1 简述
ROS为机器人开发者们提供了不同语言的编程接口,比如C++的接口叫做roscpp,python的接口叫做rospy,Java的接口叫做rosjava。
3.2 roscpp与rospy对比
• rospy和roscpp区别: (1)rospy没有NodeHandle,例如创建publisher、subscriber等操作都被直接封装成了rospy中的函数或类,调用起来简单直观。 (2)rospy一些接口的命名和roscpp不一致,有些地方需要开发者注意,避免调用错误。 • 用Python来写ROS程序开发效率大大提高 • Python的执行效率较低,同样一个功能用Python运行的耗时会高于C++ • 开发SLAM、路径规划、机器视觉等方面的算法时,往往优先选择C++ • ROS中绝大多数基本指令,例如rostopic、roslaunch都是用python开发的,简单轻巧。
3.3 rospy库开发的Topic通信案例pytalker.py
#!/usr/bin/env python
#coding=utf-8
import rospy
#倒入自定义的数据类型
from topic_demo.msg import gps
def talker():
#Publisher 函数第一个参数是话题名称,第二个参数 数据类型,现在就是我们定义的msg 最后一个是缓冲区的大小
#queue_size: None(不建议) #这将设置为阻塞式同步收发模式!
#queue_size: 0(不建议)#这将设置为无限缓冲区模式,很危险!
#queue_size: 10 or more #一般情况下,设为10 。queue_size太大了会导致数据延迟不同步。
pub = rospy.Publisher('gps_info', gps , queue_size=10)
#anonymous=True表示后面定义相同的node名字时候,按照序号进行排列
rospy.init_node('pytalker', anonymous=True)
#更新频率是1hz
rate = rospy.Rate(1)
x=1.0
y=2.0
state='working'
while not rospy.is_shutdown():
#计算距离
rospy.loginfo('Talker: GPS: x=%f ,y= %f',x,y)
pub.publish(gps(state,x,y))
x=1.03*x
y=1.01*y
rate.sleep()
if __name__ == '__main__':
talker()
3.4 rospy库开发的Topic通信案例pylistener.py
#!/usr/bin/env python
#coding=utf-8
import rospy
import math
#导入mgs到pkg中
from topic_demo.msg import gps
#回调函数输入的应该是msg
def callback(gps):
distance = math.sqrt(math.pow(gps.x, 2)+math.pow(gps.y, 2))
rospy.loginfo('Listener: GPS: distance=%f, state=%s', distance, gps.state)
def listener():
rospy.init_node('pylistener', anonymous=True)
#Subscriber函数第一个参数是topic的名称,第二个参数是接受的数据类型 第三个参数是回调函数的名称
rospy.Subscriber('gps_info', gps, callback)
rospy.spin()
if __name__ == '__main__':
listener()
3.5 roscpp库开发的Topic通信案例talker.cpp
//ROS头文件<ros/ros.h>
#include <ros/ros.h>
//自定义msg产生的头文件,位于topic_demo包下,名称为gps.h(由CMakelist.txt指定)
#include <topic_demo/gps.h>
int main(int argc, char **argv)
{
//用于解析ROS参数,第三个参数为本节点名
ros::init(argc, argv, "talker");
//实例化句柄,初始化node(句柄相当于talker的别名,用于创建talker类型的对象)
ros::NodeHandle nh;
//自定义gps msg
topic_demo::gps msg;
msg.x = 1.0;
msg.y = 1.0;
msg.state = "working";
//创建publisher
ros::Publisher pub = nh.advertise<topic_demo::gps>("gps_info", 1);
//定义发布的频率
ros::Rate loop_rate(1.0);
//循环发布msg
while (ros::ok())
{
//以指数增长,每隔1秒更新一次
msg.x = 1.03 * msg.x ;
msg.y = 1.01 * msg.y;
ROS_INFO("Talker: GPS: x = %f, y = %f ", msg.x ,msg.y);
//以1Hz的频率发布msg
pub.publish(msg);
//根据前面定义的频率, sleep 1s
loop_rate.sleep();//根据前面的定义的loop_rate,设置1s的暂停
}
return 0;
}
3.6 我的补充
(1)roscpp
①ros::init() 解析传入的ROS参数,创建node第一步需要用到的函数。 ②ros::NodeHandle 和topic、service、param等交互的公共接口。 ③ros::master 包含从master查询信息的函数。 ④ros::this_node 包含查询这个进程(node)的函数。 ⑤ros::service 包含查询服务的函数。 ⑥ros::param 包含查询参数服务器的函数,而不需要用到NodeHandle。 ⑦ros::names 包含处理ROS图资源名称的函数。
(2) listener.cpp
//ROS头文件#include <ros/ros.h>//包含自定义msg产生的头文件#include <topic_demo/gps.h>//ROS标准msg头文件#include <std_msgs/Float32.h>void gpsCallback(const topic_demo::gps::ConstPtr &msg){ //计算离原点(0,0)的距离 std_msgs::Float32 distance; distance.data = sqrt(pow(msg->x,2)+pow(msg->y,2)); //float distance = sqrt(pow(msg->x,2)+pow(msg->y,2)); ROS_INFO("Listener: Distance to origin = %f, state: %s",distance.data,msg->state.c_str());}int main(int argc, char **argv){ ros::init(argc, argv, "listener"); ros::NodeHandle n; ros::Subscriber sub = n.subscribe("gps_info", 1, gpsCallback); //ros::spin()用于调用所有可触发的回调函数。将进入循环,不会返回,类似于在循环里反复调用ros::spinOnce()。 ros::spin(); return 0;}
4、第五章 机器人建模与仿真
4.1在URDF中,机器人模型由哪些部件组成
• URDF(Unified Robot Description Format,统一机器人描述格式)
在URDF中,机器人模型由连接件(link)和关节(joint)、传感器 (sensor)、传动件(transmission)等部件组成
4.2哪个标签是完整机器人模型的最顶层标签
<robot> </robot>
4.3 mycar.urd文件源码
<robot name="mycar"> <link name="base_link" /> <link name="right" /> <link name="left" /> <link name="rplidar"/> <joint name="right" type="continuous"> <parent link="base_link"/> <child link="right"/> </joint> <joint name="left" type="continuous"> <parent link="base_link"/> <child link="left"/> </joint> <joint name="rplidar_joint" type="fixed"> <parent link="base_link"/> <child link="rplidar"/> </joint></robot>
<robot name="mycar"> <link name="base_link" /> <link name="right" /> <link name="left" /> <link name="rplidar"/> <joint name="right" type="continuous"> <origin rpy="0 0 0" xyz="0 -0.2 0.07"/> <parent link="base_link"/> <child link="right"/> </joint> <joint name="left" type="continuous"> <origin rpy="0 0 0" xyz="0 0.2 0.07"/> <parent link="base_link"/> <child link="left"/> </joint> <joint name="rplidar_joint" type="fixed"> <origin xyz="0.2 0 0.12"/> <parent link="base_link"/> <child link="rplidar"/> </joint></robot>
<robot name="mycar"> <link name="base_link"> <visual> <geometry> <cylinder length=".06" radius="0.27"></cylinder> </geometry> <origin rpy="0 0 0" xyz="0 0 0.1"/> <material name="white"> <color rgba="1 1 1 1"/> </material> </visual> </link> <link name="right"> <visual> <geometry> <cylinder length="0.04" radius="0.07"/> </geometry> <origin rpy="1.5707 0 0" xyz="0 0 0"/> <material name="black"> <color rgba="0 0 0 1"/> </material> </visual> </link> <link name="left"> <visual> <geometry> <cylinder length="0.04" radius="0.07"/> </geometry> <origin rpy="1.5707 0 0" xyz="0 0 0"/> <material name="black"/> </visual> </link> <joint name="right" type="continuous"> <origin rpy="0 0 0" xyz="0 -0.2 0.07"/> <parent link="base_link"/> <child link="right"/> </joint> <joint name="left" type="continuous"> <origin rpy="0 0 0" xyz="0 0.2 0.07"/> <parent link="base_link"/> <child link="left"/> </joint> <link name="rplidar"> <inertial> <mass value="1e-5"/> <origin rpy="0 0 0" xyz="0 0 0"/> <inertia ixx="1e-6" ixy="0" ixz="0" iyy="1e-6" iyz="0" izz="1e-6"/> </inertial> <visual> <origin rpy="0 0 0" xyz="0 0 0"/> <geometry> <mesh filename="package://urdf_demo/urdf/rplidar.dae"/> </geometry> </visual> <collision> <origin rpy="0 0 0" xyz="0 0 0"/> <geometry> <cylinder length=".04" radius="0.035"></cylinder> </geometry> </collision> </link> <joint name="rplidar_joint" type="fixed"> <axis xyz="0 1 0"/> <origin xyz="0.2 0 0.12"/> <parent link="base_link"/> <child link="rplidar"/> </joint></robot>
5、第六章 机器视觉
5.1 ROS图像话题的消息类型是什么
sensor_msgs/Image
压缩图像的消息类型为sensor_msgs/CompressedImage
5.2 人脸检测face_detector.launch
<launch> <node pkg="robot_vision" name="face_detector" type="face_detector.py" output="screen"> <remap from="input_rgb_image" to="/usb_cam/image_raw" /> <rosparam> haar_scaleFactor: 1.2 haar_minNeighbors: 2 haar_minSize: 40 haar_maxSize: 60 </rosparam> <param name="cascade_1" value="$(find robot_vision)/data/haar_detectors/haarcascade_frontalface_alt.xml" /> <param name="cascade_2" value="$(find robot_vision)/data/haar_detectors/haarcascade_profileface.xml" /> </node></launch>
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
import cv2
import numpy as np
from sensor_msgs.msg import Image, RegionOfInterest
from cv_bridge import CvBridge, CvBridgeError
class faceDetector:
def __init__(self):
rospy.on_shutdown(self.cleanup);
# 创建cv_bridge
self.bridge = CvBridge()
self.image_pub = rospy.Publisher("cv_bridge_image", Image, queue_size=1)
# 获取haar特征的级联表的XML文件,文件路径在launch文件中传入
cascade_1 = rospy.get_param("~cascade_1", "")
cascade_2 = rospy.get_param("~cascade_2", "")
# 使用级联表初始化haar特征检测器
self.cascade_1 = cv2.CascadeClassifier(cascade_1)
self.cascade_2 = cv2.CascadeClassifier(cascade_2)
# 设置级联表的参数,优化人脸识别,可以在launch文件中重新配置
self.haar_scaleFactor = rospy.get_param("~haar_scaleFactor", 1.2)
self.haar_minNeighbors = rospy.get_param("~haar_minNeighbors", 2)
self.haar_minSize = rospy.get_param("~haar_minSize", 40)
self.haar_maxSize = rospy.get_param("~haar_maxSize", 60)
self.color = (50, 255, 50)
# 初始化订阅rgb格式图像数据的订阅者,此处图像topic的话题名可以在launch文件中重映射
self.image_sub = rospy.Subscriber("input_rgb_image", Image, self.image_callback, queue_size=1)
def image_callback(self, data):
# 使用cv_bridge将ROS的图像数据转换成OpenCV的图像格式
try:
cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
frame = np.array(cv_image, dtype=np.uint8)
except CvBridgeError, e:
print e
# 创建灰度图像
grey_image = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 创建平衡直方图,减少光线影响
grey_image = cv2.equalizeHist(grey_image)
# 尝试检测人脸
faces_result = self.detect_face(grey_image)
# 在opencv的窗口中框出所有人脸区域
if len(faces_result)>0:
for face in faces_result:
x, y, w, h = face
cv2.rectangle(cv_image, (x, y), (x+w, y+h), self.color, 2)
# 将识别后的图像转换成ROS消息并发布
self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8"))
def detect_face(self, input_image):
# 首先匹配正面人脸的模型
if self.cascade_1:
faces = self.cascade_1.detectMultiScale(input_image,
self.haar_scaleFactor,
self.haar_minNeighbors,
cv2.CASCADE_SCALE_IMAGE,
(self.haar_minSize, self.haar_maxSize))
# 如果正面人脸匹配失败,那么就尝试匹配侧面人脸的模型
if len(faces) == 0 and self.cascade_2:
faces = self.cascade_2.detectMultiScale(input_image,
self.haar_scaleFactor,
self.haar_minNeighbors,
cv2.CASCADE_SCALE_IMAGE,
(self.haar_minSize, self.haar_maxSize))
return faces
def cleanup(self):
print "Shutting down vision node."
cv2.destroyAllWindows()
if __name__ == '__main__':
try:
# 初始化ros节点
rospy.init_node("face_detector")
faceDetector()
rospy.loginfo("Face detector is started..")
rospy.loginfo("Please subscribe the ROS image.")
rospy.spin()
except KeyboardInterrupt:
print "Shutting down face detector node."
cv2.destroyAllWindows()
5.3 工业应用中的机器视觉与普通计算机视觉等的区别、特点
1.机器视觉是一项综合技术,其中包括数字图像处理技术、机械工程技术、 控制技术、电光源照明技术,光学成像技术、传感器技术、模拟与数字视频技术、计算机软硬件技术、人机接口技术等。2.机器视觉更强调实用性,适应恶劣环境,合理的性价比,通用的工业接 口,有较高的容错能力和安全性,有较强的通用性和可移植性。
5.4 我的补充
(1)标定
摄像头这种精密仪器对光学器件的要求较高,由于摄像头内部与外部的一些 原因,生成的物体图像往往会发生畸变,为了避免数据源造成的误差,需要 针对摄像头的参数进行标定。
ROS官方提供了用于双目和单目摄像头标定的功能包为camera_calibration
(2)opencv 裤
(3)功能包ar_track_alvar是针对PR2机器人使用的二维码识别例程
物体识别与物体跟踪: ORK功能包
6、第七章 机器语音
6.1 PocketSphinx
它是一个离线的计算量和体积都很小的嵌入式语音识别引擎。
Pocketsphinx 功能包的核心节点是recognizer.py文件。这个文件通过麦克风收 集语音信息,然后调用语音识别库进行识别并生成文本信息,通过
/recognizer/output消息进行发布,其他节点可以通过订阅该消息获取识别结果, 并进行相应的处理。
6.2 AIML
人工智能标记语言aiml(Artificial Intelligence Markup Language)是一种创建自然语言软件代理的XML语言。
AIML主要用于实现机器人的语言交流功能,用户可以与机器人说话,而机 器人可以通过一个自然语言的软件代理,也可以给出一个聪明的回答。
6.3 AIML代码
<aiml version="1.0.1" encoding="UTF-8">
<category>
<pattern> HOW ARE YOU </pattern>
<template> I AM FINE </template>
</category>
</aiml>
(1)标签
所有的AIML代码都要介于和标签之间,该标签包含文件的版本 号和编码格式。
(2)标签
标签表示一个基本的知识块,包含一条输入语句和一条输出语句, 用来匹配机器人和人交流过程中的一问一答或一问多答,但不允许多问一答 或多问多答的匹配。
(3)标签
标签表示用户输入语句的匹配,在上边的例子中,用户一旦输入 “How are you”,机器人就会找到这个匹配。
标签内的语句必须大写。
(4)标签
标签表示机器人应答语句,机器人找到相应的输入匹配语句之后, 会输出该应答语句。
7、第八章 机器人 SLAM 与自主导航
7.1 目前cartographer主要基于什么传感器来实现SLAM
激光雷达
7.2 目前室内服务机器人的主流传感器方案
RGB-D摄像头成本较低,是目前室内服务机器人的主流传感器方案
7.3 ROS实现机器人的自主导航的功能包有哪些
gmapping、hector_slam、cartographer、 rgbdslam、ORB_SLAM、move_base、amcl
7.4 ROS中SLAM和自主导航的相关功能包对机器人的硬件有哪些要求
1)导航功能包对差分、轮式机器人的效果好,并且假设机器人可直接使用速度指令Twist进行控制,速度指令的定义如图所示。
linear:机器人在xyz三轴方向上的线速度,单位是m/s。
angular:机器人在xyz三轴方向上的角速度,单位是rad/s。
2)导航功能包要求机器人必须安装激光雷达等测距设备,可以获取环境深 度信息。
3)导航功能包以正方形和圆形的机器人为模板进行开发,对于其他外形的 机器人,虽然可以正常使用,但是效果可能不佳。
7.5 hector_slam与gmapping最大的不同是
不需要里程计数据,只根据激光信 息便可构建地图,基于深度数据估算里程计信 息,因此对深度传感器的数据精度有较高要求,建图的稳定性不如 gmapping。
7.6 move_base功能包的作用是
实现机器人导航中的最优路径规划
(amcl:实现二维地图中的机器人定位)
7.7 定本与导航问题需要把握的重点是什么
一是地图精确建模;二是机器人准确定 位;三是路径实时规划。
7.8 机器人的SLAM和自主导航中用于获取周围环境深度信息的传感器有哪些
激光雷达、摄像头、RGB-D摄像头
7.9 ROS中的导航功能框架及涉及到的功能包
导航的关键是机器人定位和路径规划两大部分。针对这两个核心,ROS提 供了以下两个功能包。
move_base:实现机器人导航中的最优路径规划。
amcl:实现二维地图中的机器人定位。