07
2025
-
04
基于RDK X3的“校史通”机器人:SLAM导航+智能交互,让校史馆活起来!
浏览:454
发布:2025-04-07 13:30:23
智慧校园:校史馆也疯狂
在科技狂飙的今天,连校史馆都卷起来了!我们给校史馆配了个“社牛”机器人:
- 主动迎宾:机器人通过视觉识别,主动上前打招呼,告别“自助式”参观。
- 语音互动:边带路边讲解,校史知识随问随答,参观体验更生动。
- 智能导航:运用SLAM技术灵活避障,规划最佳路线,确保游客不错过任何亮点。
这一创新让校史馆从静态展览变身智能互动空间,有望能提升参观体验——跑得贼稳团队
一、特色与创新
本项目通过前沿技术融合,打造了一款智能校史馆向导机器人,具备以下核心创新点:
1.1 会聊天的历史通
- 听得清:采用六路环形麦克风+R818降噪板,在嘈杂环境中也能精准捕捉提问,像朋友聊天一样自然。
- 答得妙:接入语音模块和大语言模型,不仅能指路,还能化身"校史百事通",随时解答"学校第一任校长是谁?"这类刁钻问题。
- 主动撩:告别传统屏幕"你问我答"模式,机器人会主动迎宾,边走边讲解,让参观像逛博物馆有私人导览。
1.2 自带导航老司机
- 认路准:通过激光雷达+深度相机融合SLAM技术,5分钟就能"摸清"整个校史馆布局,自动生成最佳参观路线。
- 躲人稳:遇到突然出现的参观人群,能像老司机般灵活绕行,绝不会"撞车"尬场。
- 解说忙:带路时还会贴心地提醒:"左侧展柜是1958年建校文物,要停下来看看吗?"
1.3 高定版钢铁侠战衣
- 为场景而生:自主设计的车体兼顾灵活性与稳定性,能在狭窄展区间自如转身,底盘防撞设计避免磕碰文物。
- 模块化升级:像乐高一样可快速更换电池、传感器等模块,适应未来功能扩展需求。
二、功能设计
2.1 总体设计
为提升校史馆的智能化服务,本项目设计了"小莫"智能导览机器人,采用模块化架构,实现精准交互与自主导航。
核心设计思路:
- 用户友好交互:访客通过语音或触摸屏与机器人互动,指令传递至中央控制系统。
- 智能决策中枢:控制模块整合SLAM定位、AI语音识别、环(huán)境(jìng)感(gǎn)知(zhī)数(shù)据(jù),实(shí)时(shí)生(shēng)成(chéng)最(zuì)优(yōu)导(dǎo)览(lǎn)方(fāng)案(àn)。
- 精准执行反馈:导航模块驱动机器人移动,语音系统同步讲解,形成"问-答(dá)-导(dǎo)"闭(bì)环(huán)体(tǐ)验(yàn)。
技(jì)术(shù)亮(liàng)点(diǎn):
✔ 听(tīng)得(de)懂(dǒng):抗(kàng)噪(zào)麦(mài)克(kè)风(fēng)+AI语音模型,准确识别访客需求
✔ 找得准:激光雷达SLAM实时建图,动态规划避障路径
✔ 讲得活:大语言模型赋能,校史讲解媲美专业导游

2.2功能设计
2.21硬件升级:打造更灵敏的机器人
原厂配置的语音和视觉模块存在明显不足:
- 原有问题:麦克风拾音模糊、摄像头成像质量差,仅支持4个基础指令
- 改进方案:
- 听(tīng)觉(jué)系(xì)统(tǒng):采用(yòng)6路环(huán)形麦克风阵列配合R818专业降噪板,实现会议级降噪效果
- 视觉系统:升级为索尼IMX219传感器,配备120°广角镜头,支持高清拍摄
2.22模(mó)块(kuài)化(huà)系(xì)统架构
功能模块 | 核心组件 | 主要功能 | 性能参数 |
感知系统 | 激光雷达+深度相机 | 环境探测与识别 | 10米探测范围,±2cm精度 |
控制系统 | Jetson Nano+RDK X3 | 数据处理与决策 | 支持实时建图与导航 |
驱动系统 | 精密伺服电机 | 运动控制 | 0.8m/s移动速度 |
交互系统 | 语音处理引擎 | 语(yǔ)音(yīn)识(shi)别(bié)与(yǔ)合(hé)成(chéng) | 200ms响应时间 |
2.24智能工作流程
- 环境感知:通过多传感器采集周围环境数据
- 数据处理:Jetson Nano处理导航数据,RDK X3运行交互模型
- 任务执行:根据分析结果执行导览或解答任务
2.25 系统接口设计
- 硬件连接:采用高速USB3.0接口传输传感器数据
- 软件通信:基于ROS框架实现模块间高效协作
三、系统实现
3.1硬件实现
首先对语音模块进行集成,通过PLA外壳和螺柱螺栓实现了稳固的固定。然后使用USB连接麦克风和免驱声卡。
3.2软件实现
3.2.1环境感知
机器人的环境感知传感器为雷达与深度相机,下面介绍如何基于这两个传感器实(shí)现(xiàn)环(huán)境(jìng)感知的。
传感器包括雷达和深度相机。首先,关于雷达部分,可以通过克隆GitHub上的官方雷达ydlidar_ros_driver包来实现:
(git clone
https://github.com/YDLIDAR/ydlidar_ros_driver.git/ydlidar_ws/src/ydlidar_ros_driver)
接着cd到所在的目录下,通过catkin_make构建ydlidar_ros_driver包,下一步配置包环境,使用如下指令添加永久工作区环境变量:
($echo
"source ~/ydlidar_ws/devel/setup.bash" >> ~/.bashrc)
($source ~/.bashrc)
最(zuì)后(hòu),如(rú)图(tú)4.1将(jiāng)lidar_view.launch文件(jiàn)中(zhōng)的(de)lidar.launch改(gǎi)为(wèi)X2.launch小(xiǎo)莫(mò)使(shǐ)用(yòng)的(de)雷(léi)达(dá)型(xíng)号(hào)为(wèi)X2就(jiù)完(wán)成(chéng)配(pèi)置(zhì)了(le)。

随(suí)后(hòu)打(dǎ)开(kāi)rviz工(gōng)具(jù),查(chá)看(kàn)雷(léi)达(dá)扫(sǎo)描(miáo)效(xiào)果(guǒ),命(mìng)令(lìng)如(rú)下(xià):
(roslaunch limo_bringup
lidar_rviz launch)
默(mò)认(rèn)情(qíng)况(kuàng)下(xià),雷(léi)达(dá)的(de)扫(sǎo)描(miáo)范(fàn)围(wéi)是(shì)360度(dù),但(dàn)可(kě)以(yǐ)根(gēn)据(jù)需(xū)要(yào)在(zài)launch文件(jiàn)中(zhōng)修(xiū)改(gǎi)参(cān)数(shù)以(yǐ)改(gǎi)变(biàn)雷(léi)达(dá)的(de)扫(sǎo)描(miáo)范(fàn)围(wéi)。对(duì)于(yú)小(xiǎo)莫(mò)使(shǐ)用(yòng)的(de)X2雷(léi)达(dá),在(zài)ROS内(nèi)遵(zūn)循(xún)右(yòu)手(shǒu)定(dìng)则(zé),角(jiǎo)度(dù)范(fàn)围(wéi)为(wèi)[-180, 180]。


至此,机器人已经完成了对两个环境感知传感器的适配,这意味着它现在能够全面感知并理解周围环境的情况。
3.2.2底盘驱动
在实现环境感知模块之后,系统需要将感知到的环境信息用于实际的运动控制,因此底盘驱动模块的设计与实现显得尤为重要。接下来,我们将介绍底盘驱动模块的具体实现方法。
移动底盘需要通过程序驱动才能实现移动机器人的运动,移动机器人的底盘驱动程序分为两个版本,分别为C++版本和Python版本,两个版本都可以控制移动机器人运动。
Python版本的代码仅有三个⽂件组成驱动程序,init.py的作⽤为申明需要使(shǐ)用(yòng)的(de)⽂(⽂)件(jiàn)limomsg.py的(de)作(zuò)⽤(⽤)为(wèi)驱(qū)动(dòng)成(chéng)所(suǒ)需(xū)要(yào)的(de)消(xiāo)息(xi),limo.py是(shì)主程(chéng)序(xù),它(tā)的(de)作(zuò)用(yòng)是(shì)驱(qū)动(dòng)移(yí)动(dòng)机(jī)器(qì)人(rén)。
(函(hán)数(shù)名称(chēng))() | (函(hán)数(shù)作(zuò))(⽤(⽤))() |
(EnableCommand()) | (控制使能)() |
(SetMotionCommand()) | (设置移动命令)() |
(GetLinearVelocity()) | (获取线速度)() |
(GetAngularVelocity()) | (获取)(⻆)(速度)() |
(GetSteeringAngle()) | (获取内转)(⻆⻆)(度)() |
(GetLateralVelocity()) | (获取横移速度)() |
(GetControlMode()) | (获取控制模式)() |
(GetBatteryVoltage()) | (获取电池电量)() |
(GetErrorCode()) | (获(huò)取(qǔ)错(cuò)误(wù)代(dài)码(mǎ))() |
(GetRightWheelOdem()) | (获取左轮)(⾥)(程计)() |
(GetLeftWheelOdem()) | (获取右轮)(⾥)(程计)() |
(GetIMUAccelData()) | (获取)(IMU)(的加速度)() |
(GetIMUGyroData()) | (获取陀螺仪的数据)() |
(GetIMUYawData()) | (获取)(IMU)(的航向)(⻆)() |
(GetIMUPichData()) | (获取俯仰)(⻆)() |
(GetIMURollData()) | (获取横滚)(⻆)() |
3.2.3动态避障
底(dǐ)盘(pán)驱(qū)动(dòng)为(wèi)车(chē)辆(liàng)提(tí)供(gōng)了(le)动(dòng)力(lì),而(ér)避(bì)障(zhàng)则(zé)是(shì)确(què)保(bǎo)车(chē)辆(liàng)在(zài)运(yùn)动(dòng)过(guò)程(chéng)中(zhōng)能(néng)够(gòu)安(ān)全地(de)避(bì)开(kāi)障(zhàng)碍(ài)物(wù),两(liǎng)者(zhě)需(xū)要(yào)密(mì)切(qiè)合(hé)作(zuò),因(yīn)此(cǐ)该(gāi)机(jī)器(qì)人(rén)使(shǐ)用(yòng)了(le)两(liǎng)种(zhǒng)动(dòng)态避障算法进行雷达避障。
首先用到的库是teb_local_planner,由move_base包进行调用
(sudo
apt-get install ros-kinetic-teb-local-planner)
(sudo
apt-get install ros-kinetic-teb-local-planner-tutorials)

在实际使用中,避障能力受到参数调整的影响极大,稍有不慎便可能导致撞上障碍物。为此,我们总结了一套仅适用于小莫的TEB调参方法及适配于室内避障的范围。
我们定义避障效果的好坏是通过同等障碍物距离下LIMO响应的快慢来直观感受的,参数是在rqt_reconfigure界面里调整的。经过测试发现,关闭多路径并行规划和使用Costmap Converter可以显著提升避障效果。降低迭代次数no_inner/outer_iterations和减小局部成本地图的大小也能显著改善性能。相较之下,降低max_lookahead_distance的效果较为一般,而增大规划周期和控制周期则会影响整体效果。使用单点footprint并结合最小障碍物距离约束,对效果的提升不太显著,并且可能影响整体性能。

至此,TEB算法的配置已经完成,但由于TEB算法容易陷入局部最优问题,且在处理密集障碍物或狭窄空间时可能会产生不稳定的路径规划结果,因此需要引入第二个算法——DWA(动态窗口法)算法进行补充。通过这种方法,DWA算法能够动态调整机器人的路径规划,避免局部最优问题,并在密集障碍物或狭窄空间中提供更稳定的路径规划结果,从而补足了TEB算法的不足。

3.2.4 地(de)图(tú)构建
在(zài)车(chē)辆(liàng)在(zài)复(fù)杂(zá)环(huán)境(jìng)中(zhōng)执(zhí)行(xíng)动(dòng)态(tài)避(bì)障(zhàng)的(de)过(guò)程(chéng)中(zhōng),实(shí)时(shí)感(gǎn)知(zhī)到(dào)的(de)障(zhàng)碍物信息不仅为安全行驶提供了保障,接下来就是建图步骤。
SLAM建图是小莫机器人进行地图构建的核心原理,指的是即时定位和建图,SLAM建图主要是有以下三个过程:
一是预处理,对雷达点云数据进行处理,包括清除异常值,以确保数据质量。这个过程有助于提高雷达测量的准确性和可靠性(xìng)。简而言之,点云数据的优化是确保雷达捕获的环境信息准确无误的关键步骤。以激光作为信号源,由激光器发射出的脉冲激光,打到周围障碍物上,引起散射。
一部分光波会反射到激光雷达的接收器上,再根据激光测距原理计算,就可以得到从激光雷达到目标点的距离。关于点云:通俗来说,激光雷达获取的周围环境信息,被称为点云。它是能反映机器人所在环境中“眼睛”能看到的一个部分。雷达点云数据呈现了物体的精确位置,包括角度和距离,形成了分布式的空间信息集合。这(zhè)些(xiē)数(shù)据(jù)为(wèi)机(jī)器(qì)人(rén)或(huò)系统提供了关于其周围环境的详细三维视图。
二是匹配,在当前环境中,将点云数据与已有地图进行对照,以定位相应位置。激光SLAM系统通过比较不同时间点的点(diǎn)云(yún)数(shù)据(jù),来(lái)计(jì)算(suàn)激(jī)光(guāng)雷(léi)达(dá)的(de)移(yí)动(dòng)距离和方向变化,实现机器人的自我定位。
三是地(de)图更新,新一轮激光雷达数据会被整合进原始地图,以此更新地图。
SLAM的过程已经详细阐释,下面将通过三种算法实现SLAM建图:
一是gmapping,通过以下命令将gmapping安装在小莫上,创建相关launch文件即可使用。
sudo apt-get install ros-melodic-gmapping
sudo apt-get install ros-melodic-teleop_twist_keyboard
sudo apt install ros-melodic-map-server
在(zài)gmapping功能包中,slam_gmapping节点扮演着核心角色,它处理多种话题和服务来实现SLAM。具体来说,它订阅tf话题以获取雷达和里程计之间的坐标转换信息,以及/scan话题来接收雷达扫描数据。此外,它发布map_metadata和map话题,分别提供地图的元数据和栅格数据,这些数据通常在rviz中可视化展示。节点还发布~entropy话题,用于估计机器人姿态的不确定性。同时,它提供dynamic_map服务,以供请求地图数据之(zhī)用(yòng)。
二是Cartographer,通过以下命令将Cartographe安装在小莫上,创建相关launch文件即可使用:
sudo apt install ros-foxy-cartographer
sudo apt install ros-foxy-cartographer-ros
在Cartographer调参测试发现,概率通过公式离散化的uint8数值小于127时,空闲概率更大;数值大于127时,占用概率更大。
我们看到,层数越高,图像变得越来越粗糙,黑色部分明显膨胀,因此,我们选定滑动窗口为width=1作为参数。
同时,我们也为(wèi)小(xiǎo)莫的四种运动模态创建了两个建图launch文件,其中履带模式、麦克拉姆轮模式都可以与差速模式共用一个launch文件。
至此,两种建图算法已经成功配置实现,除cartographer选定参数width=1外,其余参数经测试发现适用于小莫机器人,故均选用默认参数使用。
3.2.5自主导航
实(shí)时(shí)感(gǎn)知(zhī)到(dào)的(de)障(zhàng)碍(ài)物(wù)信(xìn)息(xi)为(wèi)安(ān)全行(xíng)驶(shǐ)提(tí)供(gōng)了(le)保(bǎo)障(zhàng),同(tóng)时(shí)地(de)图(tú)构(gòu)建(jiàn)也(yě)提(tí)供(gōng)了(le)重(zhòng)要(yào)的(de)环(huán)境(jìng)数(shù)据(jù),为(wèi)后(hòu)续(xù)路径规(guī)划(huà)和(hé)导(dǎo)航(háng)奠(diàn)定(dìng)了(le)坚(jiān)实(shí)的(de)基(jī)础(chǔ)。
路径规(guī)划(huà)的(de)前(qián)提(tí)是(shì)定(dìng)位(wèi),定(dìng)位(wèi)功(gōng)能(néng)是(shì)用(yòng)来(lái)计算机器人在全局地图上的具体位置。虽然SLAM技术包含了定位算法,但它主要用于在导航开始前构建全局地图,而实时定位则是在导航过程中使用,我们选用的是AMCL蒙特卡洛定位系统,这一系统专门用于导航时的机器人定位,定位方法算法流程如下:

在小莫中,AMCL定位输入以下命令安装,配置如图4.11的launch文件即可备用:
([1]) https://wiki.ros.org/move_base
([1]) amcl - ROS Wiki
sudo apt-get install ros-melodic-navigation
AMCL需要订阅的服务是/scan激光雷达数据和/tf坐标变换消息,它发布的话题中,最重要的是/amcl_pose,这是机器人在地图中的位姿估计。

AMCL则负责机器人在环境中的定位,在导航过程中还需要能实现路径规划和避障的“地图”,即代价地图(Cost Map),它通过为地图中的每个栅格分配一个“代价”值,来表示机器人在该位置的移动难度或风险。
Costmap2D 类维护了每个栅格的代价值。Layer 类是虚基类,它统一了各插件costmap层的接口。其中最主要的接口函数有:
initialize函数,它调用onInitialize函数,分别对各costmap 层进行初始化;matchSize函数,在StaticLayer 类和ObstacleLayer 类中,该函数调用了CostmapLayer类matchSize 函数,初始化各costmap 层的size,分辨率,原点和默认代价值,并保持与layered_costmap 一致。对于inflationLayer 类,根据膨胀半径计算了随距离变化的cost 表。后面就可以用距离来查询膨胀栅格的cost 值。同时定义了seen_数组,该数组用于标记栅格是否已经被遍历过。对于VoxelLayer 类,则初始化了体素方格的size;
updateBounds 函数,调整当前costmap 层需要更新的大小范围。对于StaticLayer类,确定costmap 的更新范围为静态地图的大小,注意:静态层一般只用在全局costmap中。对于ObstacleLayer 类,遍历clearing_observations 中的传感器数据确定障碍物的边界。
其中initialize 函数和matchSize 函数分别只执行一次。updateBounds 函数和updateCosts 函数则会周期执行,其执行频率由map_update_frequency 决定。
CostmapLayer 类同时继承了Layer 类和Costmap2D 类,并提供了几个更新cost 值的操作方法。StaticLayer 类和ObstacleLayer 类需要保存实例化costmap 层的cost 值,所以都继承了CostmapLayer 类。StaticLayer 类使用静态栅格地图数据更新自己的costmap。ObstacleLayer 类使用传感器数据更新自己的costmap 。VoxelLayer 类相对于ObstacleLayer 类则多考虑了z轴的数据。效果的区别主要体现在障碍物的清除方面。一个是二维层面的清除,一个是三维里的清除。
代价地图已经内嵌到下文提及的move_base的功能包中,无需单独配置。
至此,万事具备,导航准备工作已经完成,已经可以开始在小莫上实现自主导航了。
move_base功能包需要使用本节前文提及的所有模块:深度相机提供的画面会集成在导航操作界面中,供用户实时了解机器人的位置和环境;雷达数据不仅用于避障,还参与SLAM建图,为导航提供可靠的地图信息和障碍物检测;雷达避障的两个局部规划器分别负责不同的避障任务,与move_base中的全局规划器配合,共同实现整体路径规划的优化和调整;AMCL包则持续反馈机器人在地图中的位姿信息,确保导航时能够依赖代价地图(Cost Map)进行实时路径规划和调整。通过这些模块的协同工作,小莫机器人能够在复杂环境中实现精准的自主导航,确保安全和高效的路径规划。
通过以下指令便可以安装move_base包:
sudo apt-get install ros-melodic-navigation
同时,我们也为小莫的四种运动模态创建了两个导航launch文件,履带模式、麦克拉姆轮模式都可以与差速模式共用一个launch文件。
至此,自主导航功能已经全部实现,为语音导航,自主建图打下了基础。
3.2.6语音交互
右键单击“此电脑”点击“管理”,在设备管理器中找到“CH340”字样,获取麦克风的端口号。
在串口选择区选择麦克风的串口,我们是连接的是COM3串口。
点击串口选择区的“打开串口”,看到如下所示页面,即成功与PC建立连接。
在命令输入区输入“{"type":"version"}”,点击“Send Raw”即可在显示区看到麦克风的版本信息。
在命令输入区输入“{"type":"wakeup_keywords", "content":{"keyword": "xiao3 huan4 xiao3 huan4", "threshold": "900"}}”点击“Send Raw”即可在显示区看到麦克风的通信信息。(“content:”表示唤醒内容,“keyword:{}”表示关键字,xiao3为小的拼音+声调,huan4为幻的拼音+声调)。
在语音开放平台申请kpi后将该文件导入,修改了appid后,添加启动时也启动hw_speaker文件。
3.2.7语言大模型
我们用大模型KIMI智能助手。KIMI API兼容Openai的接口规范,使用 openai 提供的 Python或NodeJS SDK 来调用和使用 Kimi 大模型,那么只需要将 base_url 和 api_key 替换成 Kimi 大模型的配置。

3.2.8目标检测
RDK X3提供了基于MIPI摄像头推理的Python代码,实现了加载FCOS 图像目标(biāo)检(jiǎn)测(cè)算(suàn)法(fǎ)模(mó)型(xíng)基(jī)于(yú)COCO数(shù)据(jù)集训(xun)练(liàn)的(de)80个(gè)类(lèi)别(bié)的(de)目(mù)标(biāo)检(jiǎn)测(cè),包(bāo)括(kuò)且(qiě)不(bù)限(xiàn)于(yú)人(rén)、狗(gǒu)、猫等生活中常见的类、从MIPI摄像头读取视频图像,并进行推理、解析模型输出并将结果渲染到原始视频流、通过HDMI接口输出渲染后的视频流。
选(xuǎn)用(yòng)fcos作(zuò)为(wèi)推(tuī)理(lǐ)模(mó)型(xíng)是(shì)因(yīn)为(wèi)FCOS算(suàn)法(fǎ)的(de)设(shè)计(jì)复(fù)杂(zá)度(dù),易(yì)于(yú)理(lǐ)解(jiě)和(hé)操(cāo)作(zuò);性(xìng)能(néng)优(yōu)于(yú)YOLO、SSD等(děng)检(jiǎn)测(cè)网(wǎng)络(luò);可(kě)以(yǐ)充(chōng)分(fēn)利(lì)用(yòng)CPU,减(jiǎn)少(shǎo)进(jìn)程(chéng)切(qiè)换(huàn)导(dǎo)致(zhì)的(de)资(zī)源(yuán)浪(làng)费(fèi)。
3.3各(gè)模(mó)块(kuài)协(xié)同(tóng)实(shí)现(xiàn)
各(gè)个(gè)模(mó)块(kuài)实(shí)现(xiàn)后(hòu),需(xū)要(yào)通(tōng)过(guò)集成(chéng)手(shǒu)段(duàn)实(shí)现(xiàn)各(gè)个(gè)模(mó)块(kuài)的(de)协(xié)同(tóng)配(pèi)合(hé),实(shí)现(xiàn)的(de)详(xiáng)细(xì)介(jiè)绍(shào)如(rú)下(xià)。
用(yòng)户(hù)通(tōng)过(guò)语(yǔ)音(yīn)或(huò)界(jiè)面(miàn)唤(huàn)醒(xǐng)麦(mài)克(kè)风(fēng),麦(mài)克(kè)风(fēng)拾(shi)音(yīn)之(zhī)后(hòu)对(duì)语(yǔ)音(yīn)进(jìn)行(xíng)分(fēn)析(xī)来(lái)判(pàn)断(duàn)用(yòng)户(hù)是(shì)进(jìn)行(xíng)运(yùn)动(dòng)控(kòng)制、下达指令还是进行提问从而进行下一步动作。若是对运动控制,则将信息发送到Jetson nano中进行解析执行;若是进行提问,则将内容送到大模型中,等待返回结果后进行文字转语音,再播放语音。
3.3.1用户界面实现
小莫的集成特性是本设计的创新点之一,各模块协同配合的一种纽带是靠PyQt所构建的菜单界面,如图4.27所示,窗口由欢迎窗口、主界面窗口和各个子窗口构成。欢迎窗口可键入主窗口,主窗口点击各功能按钮进入子窗口。
启动主窗口的同时也启动 dabai_u3.launch摄像头节点和limo_start.launch底盘节点,如图4.28所(suǒ)示(shì),各(gè)个(gè)功(gōng)能(néng)模块的启动与关闭汇总在主窗口中,点击即可分别开启各个launch文件启动节点,同时弹出提示框提示是否打开成功。
启动建图节点:使用subprocess.Popen数启动了一个新的进程来运行建图节点的launch文件,具体是limo_bringup limo_rtabmap_orbbec.launch,同时设置了localization:=true参数。这个参数表示要启动定位功能,这在建图的过程中很重要,因为定位可以让机器人知道自己在地图中的位置。
随机移动建图的逻辑:定义了一个random_move函数,其中包含了一个while循环,在循环中机器人会以随机的方式移动,模拟在环境中探索的过程。
在循环中,首先会生成一个随机的目标点,然后调用movebase_client函数来让机器人移动到这个目标点。
同时还会生成一个随机的方向,以便机器人移动时有一定的旋转,增加探索的多样性。
建图过程的等待和结束:在识别到“自主建图”命(mìng)令(lìng)后(hòu),会(huì)启(qǐ)动(dòng)随(suí)机(jī)移(yí)动(dòng),并(bìng)且(qiě)等(děng)待(dài)一(yī)段(duàn)时(shí)间(jiān),这(zhè)段(duàn)时(shí)间(jiān)是(shì)模(mó)拟(nǐ)机(jī)器(qì)人(rén)在(zài)环(huán)境(jìng)中(zhōng)探(tàn)索(suǒ)的(de)过(guò)程(chéng)。
在(zài)等(děng)待(dài)时(shí)间(jiān)结(jié)束(shù)后(hòu),会(huì)停(tíng)止(zhǐ)随(suí)机(jī)移(yí)动(dòng),并(bìng)且(qiě)结(jié)束(shù)建(jiàn)图(tú)节(jié)点(diǎn)的(de)运(yùn)行(xíng),同(tóng)时(shí)播(bō)放(fàng)“mapping_complete”提(tí)示(shì)音(yīn),表(biǎo)示(shì)建(jiàn)图(tú)完(wán)成(chéng)。
3.3.2语(yǔ)音(yīn)控(kòng)制(zhì)实(shí)现(xiàn)
语(yǔ)音(yīn)控(kòng)制(zhì)是(shì)小(xiǎo)莫(mò)的(de)创(chuàng)新(xīn)点(diǎn),机(jī)器(qì)人(rén)可(kě)以(yǐ)通(tōng)过(guò)语(yǔ)音(yīn)控(kòng)制(zhì)各(gè)个(gè)模(mó)块(kuài),并(bìng)实(shí)现(xiàn)功(gōng)能。
录音调用控制器:用于实现语音识别并控制相关设备。主要功能包括接收来自唤醒标志的信息,调用离线语音识别服务,处理识别结果并根据情况执行相应操作。该操作首先初始化ROS节点,并创建必要的节点句柄、服务客户端和话题订阅者。然后,在一个循环中,不断地获取离线语音识别的结果,并根据识别结果进行相应的处理。在识别结果的处理过程中,该操作首先判断唤醒状态,如果处于唤醒状态,则调用离线语音识别服务获取识别结果。根据识别结果的不同,可能执行以下操作:如果识别结果为“休眠”,则将唤醒标志置为0,使系统进入休眠状态。如果识别结果为“ok”,表示识别成功,根据具体识别到的语音内容,执行相应操作,并将唤醒标志置为0,进入休眠状态。如果识别结果为“fail”,表示识别失败,记录失败次数,并根据失败次数的不同,可能发出相应的警告信息,并在连续失败达到一定次数后,将系统置为休眠状态。如果调用离(lí)线语音识别服务失败,则记录错误信息并继续下一次循环。通过以上逻辑,该操作实现了对语音指令的识别和处理,并可以根据识别结果执行相应的控制操作,从而实现了语音控制相关设备的功能。
离线语音识别服务识别声音指令:头文件引入和全局变量声明:包括一些头文件的引入以及全局变量的声明,其中包括用于发布声音识别结果的ROS发布者、离线识别开关、一些参数设置和一些外部声明的变量。辅助函数定义:包括将字符串转换为宽字符和将宽字符转换为字符串的辅助函数,以及播放声音的函数。业务数据处理函数(business_data):用于处理录音数据,并将数据传入语音识别(bié)引(yǐn)擎(qíng)进行识别。显示离线识别结果函数(show_result):用于解析离线识别结果(guǒ)字(zì)符(fú)串,提取有效关键字和置信度。获取离线识别结果服务回调函数(Get_Offline_Recognise_Result):用于接收离线识别结果请求,并调(diào)用(yòng)相(xiāng)应(yīng)的(de)处(chù)理(lǐ)函(hán)数(shù)进(jìn)行(xíng)离线识别,并返回识别结果。主函数(main):包括ROS节点初始化、参数设置、服务、发布者的创建和一些初始化操作,然后进入循环中不断检测初始化是否成功和是否完成录音,并根据情况调用离线识别服务进行识别。
设置麦克风类型和唤醒词并唤醒语音控制:实现了一个可以与环形麦克风阵列交互的 ROS 节点,可以通过 ROS 服务设置麦克风类型和唤醒词,并通过 ROS 发布者发布唤醒标(biāo)志和唤醒角度,主要功能包括:CircleMic 类:这个类实现了与环形麦克风阵列通信的方法。它包括了初始化串口、切换麦克风类型、获取版本信息、设置唤醒词等功能。AwakeNode 类:这个类是一个ROS节(jié)点(diǎn),通(tōng)过(guò)串(chuàn)口(kǒu)与(yǔ)环(huán)形(xíng)麦(mài)克(kè)风阵列(liè)通(tōng)信(xìn),提(tí)供(gōng)了(le)三(sān)个(gè) ROS 服务:设置(zhì)麦(mài)克(kè)风(fēng)类(lèi)型(xíng)、获(huò)取(qǔ)设(shè)置(zhì)信(xìn)息(xi)、设(shè)置(zhì)唤(huàn)醒(xǐng)词。它(tā)还(hái)创(chuàng)建(jiàn)了(le)两(liǎng)个(gè) ROS 发(fā)布(bù)者(zhě),用(yòng)于(yú)发(fā)布(bù)唤(huàn)醒(xǐng)标志和唤醒角度。主函数:在主函数中,首先初始化了 ROS 节点,然后根据参数设置了环形麦克风的类型、串口和唤醒词。接着创建了一个AwakeNode 对象,初始化了 ROS 服务和发布者,并调用了环形麦克风的方法来获取唤醒结果。
通(tōng)过(guò)识(shi)别(bié)语(yǔ)音(yīn)指(zhǐ)令(lìng)执(zhí)行(xíng)相(xiāng)应(yīng)操(cāo)作(zuò):它(tā)通(tōng)过(guò)结(jié)合(hé)语(yǔ)音(yīn)识(shi)别(bié)和(hé)导(dǎo)航(háng)功(gōng)能(néng),实(shí)现(xiàn)了(le)对(duì)小车的语音指令控制,包括控制小车的移动、执行特定任务以及与用户进行交互的功能。首(shǒu)先,操作中建立了与ROS通信的发布者和订阅者。这些发布者和订阅者用于与其他ROS节点进行数据交换,以便小车能够接收语音指令并执行相应的动作。其次,该操作定义了多个函数来实现不同的功能。其中,amcl_pose_callback函数用于接收小车当前位置信息,这对于后续的导航任务至关重要;play函数用于播放特定名称的语音提示,以便与用户进行交互;pub_cmd_msg函数用于发布控制小车移动的指令,并可以设置持续时间,以实现精确的控制;movebase_client函(hán)数则用于向move_base节点发送导航目标点,并等待导航完成;add_mark_point函数用于向数据库添加标记点信(xìn)息(xi),以(yǐ)便(biàn)小车能够在地图中定位和导航;random_move函数实现了小车的随机移动功能,这对于自主建图过程中的地图探索至关重要。在主循环中,该操作通过订阅语音识别节点的话题来监听语音指令。一旦接收到特(tè)定(dìng)的(de)指(zhǐ)令(lìng),就(jiù)会(huì)调(diào)用(yòng)相(xiāng)应(yīng)的(de)处(chù)理函数执行相应的动作或任务。例如,当接收到前进、后退、左转、右转等移动指令时,该操作会调用相关的移动函数控制小车的运动;当接收到导航到特定地点的指令时,该操作会调用导航函数执行相应的任务。此外,该操作还实现了唤醒与休眠处理功能。当接收到唤醒指令时,该操(cāo)作(zuò)会(huì)播(bō)放(fàng)唤(huàn)醒(xǐng)成(chéng)功(gōng)提(tí)示(shì),并(bìng)根(gēn)据(jù)当(dāng)前(qián)小(xiǎo)车(chē)的(de)角(jiǎo)度(dù)进(jìn)行(xíng)旋转以调整朝向;当接收到休眠指令时,该操作会播放休眠提示,并暂停监听语音指令,以节省系统资源。
接着详细展开说明代码中的关键函数:
首先是amcl_pose_callback(msg)函数。这个函数用于接收小车当前位置信息,并将其存储在全局变量中供其他部分代码使用。它订阅了ROS话题/amcl_pose,该话题发布的消息包含小车在地图中的位置信息。每当有新的位置信息到达时,该函数就会被调用,并将当前(qián)位(wèi)置(zhì)信(xìn)息(xi)存(cún)储(chǔ)在(zài)全局(jú)变(biàn)量(liàng)中(zhōng)。
接(jiē)着(zhe)是(shì)play(name)函(hán)数(shù)。这(zhè)个(gè)函(hán)数(shù)用(yòng)于(yú)播(bō)放(fàng)特(tè)定(dìng)名称(chēng)的(de)语音提示,以便与用户进行交互。它使用了一个名为voice_play的模块,通过调用其中的函数实现语音播放功能。调用该函数时,将所需的语音提示的名称作为参数传递给该函(hán)数(shù),然(rán)后(hòu)它(tā)会(huì)根(gēn)据(jù)名称(chēng)播(bō)放(fàng)相(xiāng)应(yīng)的(de)语(yǔ)音(yīn)。
下一个函数是pub_cmd_msg(msg, duration)。这(zhè)个(gè)函(hán)数(shù)用(yòng)于(yú)发(fā)布(bù)控(kòng)制(zhì)小(xiǎo)车(chē)移(yí)动(dòng)的(de)指(zhǐ)令(lìng),并(bìng)可(kě)以(yǐ)设(shè)置持续时间。它接受两个参数:msg表示要发布的控制指令,duration表示指令持续的时间。在函数内部,它通过ROS发布者向话题/cmd_vel发布指令消息,控制小车的运动。同时,通过设置定时器,可以确保指令在指定的持续时间内持续执行,然后停止。
接下来是movebase_client(x, y, orientation)函(hán)数(shù)。这(zhè)个(gè)函(hán)数(shù)用(yòng)于(yú)向(xiàng)move_base节(jié)点(diǎn)发(fā)送(sòng)导(dǎo)航(háng)目(mù)标(biāo)点(diǎn),并(bìng)等(děng)待(dài)导(dǎo)航(háng)完(wán)成(chéng)。它(tā)使(shǐ)用(yòng)了(le)ROS的(de)行(xíng)为(wèi)库(kù)中(zhōng)的(de)SimpleActionClient来实现与move_base节点的通信。在函数内部,首先创建一个MoveBaseGoal对象,设置目标位置和姿态,然后向move_base节点发送这个目(mù)标,并等待导航任务完成。
然后是add_mark_point(name, x, y, orientation)函数。这个函数用于向数据库添加标记点信息。它接受标记点的名称、位置坐标和姿态作为参数,并将这些信息插入到SQLite数据库中。在函数内部,它使用了SQLite数据库连接和游标对象来执行插入操作,确保标记点信息被正确存储。
最后是random_move()函数。这个函数实现了小车的随机移动功能。它使用了Python的random模块来生成随机目标点和随机方向。在函数内部,它周期性地生成随机目标点,并调用movebase_client函数来让小车移动到这些目标点,从而实现随机移动和地图探索。
指令处理函数 words_callback(msg) 在(zài)这(zhè)个代码中扮演着至关重要的角色。它是通过订阅语音识别节点发布的话题/call_recognition/voice_words来(lái)监(jiān)听(tīng)语(yǔ)音(yīn)指(zhǐ)令(lìng)的(de)。一(yī)旦(dàn)接(jiē)收(shōu)到(dào)语(yǔ)音(yīn)指(zhǐ)令(lìng),该(gāi)函(hán)数(shù)将(jiāng)被(bèi)触(chù)发(fā),开(kāi)始(shǐ)执(zhí)行(xíng)指(zhǐ)令(lìng)处(chù)理(lǐ)流(liú)程(chéng)。
首(shǒu)先(xiān),函(hán)数(shù)会解析接收到的消息,将语音指令提取出来。这通常涉及(jí)将消息内容进行解码,以确保正确地识别和理解用户的指令。解析(xī)语(yǔ)音(yīn)指(zhǐ)令(lìng)可(kě)能(néng)包(bāo)括(kuò)文本(běn)分(fēn)词、语(yǔ)义(yì)分(fēn)析(xī)等(děng)步(bù)骤(zhòu),以(yǐ)便(biàn)准确识别用户的意图和要求。
接着,根据解析得(de)到的指令内容,函数会进入相应的处理分支。这(zhè)些(xiē)分支通常是一系列的条件语句或者是使用字典等数据结构进行指令匹配的逻辑判断。每个分支对应着一种或多种可能的指令,以及执行相应操(cāo)作的代码。
在处理指令的过程中,函数可能会调用其他函数来实现具体的操作。例如,如果接收到的是控制小车移动的指令,函数会调用控制小(xiǎo)车(chē)移(yí)动(dòng)的(de)函(hán)数(shù);如(rú)果(guǒ)接(jiē)收(shōu)到(dào)的(de)是(shì)导(dǎo)航(háng)到(dào)特(tè)定(dìng)地(de)点(diǎn)的(de)指(zhǐ)令(lìng),函(hán)数(shù)会(huì)调(diào)用(yòng)导(dǎo)航(háng)函数执行相应的导航任务。
除了执行相应操作外,指令处理函数还可能会向用户提供反馈信息。这可以通过语音提示、控制台输出、图形界面等形式来实现,以便用户了解指令的执行情况和结果。
在处理完指令后,函数可能会继续等待并监听下一个语音指令,以保持对用户的持续响应。整个指令处理函数的设计目的是使系统能够实现对用户语音指令的准确理解和及时响应,从而提高系统的交互性和用户体验。
以(yǐ)下(xià)是(shì)对(duì)每(měi)个(gè)分(fēn)支(zhī)进(jìn)行(xíng)详(xiáng)细(xì)描(miáo)述(shù):
自主建图指令分支:如(rú)果(guǒ)接(jiē)收(shōu)到(dào)的(de)语(yǔ)音(yīn)指令是"自主建图",系统将启动建图功能。首先,系统会播放开始建图的语音提示,然后启动建图节点和导航节点,让小车开始在环境中进行地图构建。在建图过程中,系统可能会调用随机移动函数,使小车在环境中探索,以获取更多的地图信息。建图完成后,系统会播放建图完成的语音提示,并关闭建图节点,以便后续的导航任务。
移动控制指令分支:如果接收到的语音指令是移(yí)动控制指令,比如"前进"、"后退"、"向左转"、"向右转"等,系统会根据指令调整小车的移动方向和速度,以执行相应的动作。例如,如果接收到"前进"指令,系统会使小车向前移动;如果接收(shōu)到(dào)"向(xiàng)左(zuǒ)转(zhuǎn)"指(zhǐ)令(lìng),系(xì)统(tǒng)会(huì)使(shǐ)小(xiǎo)车(chē)向(xiàng)左(zuǒ)转(zhuǎn)动(dòng)。
导(dǎo)航(háng)指(zhǐ)令(lìng)分(fēn)支(zhī):如(rú)果(guǒ)接(jiē)收(shōu)到(dào)的(de)语(yǔ)音(yīn)指(zhǐ)令(lìng)是(shì)导(dǎo)航(háng)指(zhǐ)令(lìng),比(bǐ)如(rú)"导(dǎo)航(háng)到(dào)前(qián)台(tái)"、"去(qù)王(wáng)老(lǎo)师(shī)办(bàn)公(gōng)室(shì)"等(děng),系(xì)统会调用相应的导航函数,使小车导航到指定的目标位置。这些导航函数会计算小车到目标位置的路径,并发送导航指令给导航节点,以实现自主导航(háng)功(gōng)能(néng)。
标记点操作分支:如果接收到的语音指令是标(biāo)记(jì)点(diǎn)操(cāo)作(zuò)指(zhǐ)令(lìng),比(bǐ)如(rú)"设(shè)置(zhì)A点(diǎn)",系(xì)统(tǒng)会(huì)获(huò)取(qǔ)当(dāng)前(qián)小(xiǎo)车(chē)的(de)位(wèi)置(zhì)信(xìn)息(xi),并(bìng)将(jiāng)其(qí)作(zuò)为(wèi)一(yī)个(gè)标(biāo)记(jì)点(diǎn)保(bǎo)存(cún)到(dào)数(shù)据(jù)库(kù)中(zhōng)。这(zhè)些(xiē)标(biāo)记(jì)点(diǎn)可(kě)以(yǐ)在(zài)后(hòu)续(xù)的(de)导(dǎo)航(háng)任(rèn)务(wu)中(zhōng)使(shǐ)用(yòng),以便小车能够到达预先设置的目标位置。
其他(tā)指(zhǐ)令(lìng)分(fēn)支:如果接收到的语音指令不属于以上任何一种情况,系统可能会播放无法识别的语音指令提示,或者不做任何响应。这种情况下,系统会保持等待状态,继续监听新的语音指令。
([1]) ydlidar_ros_driver/details.md at master · YDLIDAR/ydlidar_ros_driver · GitHub
([2]) https://vcp.developer.orbbec.com.cn/documentation
([3]) teb_local_planner - ROS Wiki
([4]) teb_local_planner - ROS Wiki
([5]) teb_local_planner - ROS Wiki
([6]) dwa_local_planner - ROS Wiki
([8]) gmapping - ROS Wiki
([9]) cartographer - ROS Wiki
([10]) https://wiki.ros.org/move_base
([11]) amcl - ROS Wiki
([12]) amcl - ROS Wiki
([13]) move_base - ROS Wiki
相关新闻