语音巡逻
通过前面的课程讲解,我们已经理解了整个实现语音自定义交互的过程。接下来我们将学习如何通过语音交互功能来控制我们的机器人进行巡逻。而我们的语音导航也是基于前面讲解的自定义交互模式设计的一种功能实现。
1 整体效果
运行默认demo后,我们可以通过语音来向机器人下达开始巡逻或者结束巡逻指令,从而实现让机器人运行在设定的点位进行巡逻的效果。
1.1 实现过程
1.1.1 仿真使用
首先我们得通过唤醒词小道小道
将机器人唤醒,让其进入唤醒状态。
故我们的前面讲解的 语音离线命令词检测
和 VAD检测节点
需要先行启动:
roslaunch handsfree_speech offline_interactive_ros.launch//语音交互功能节点
rosrun handsfree_speech vad_record.py//VAD检测节点
然后运行 语音巡逻节点
:
rosrun handsfree_speech multi_point_patrol.py//语音巡逻节点
根据语音教程第一节的内容,我们可以先使用仿真环境进行测试来查看一下语音交互的效果在这里我们也提供了相应的仿真环境:
roslaunch handsfree_2dnav navigation.launch
这两个都是仿真环境,在空间不够空旷的情况下或者还没熟练的情况下,执行其中任意一条指令即能进行仿真测试。
通过仿真环境,我们可以用语音交互的功能查看执行效果,并进行语音功能的相关调试。
1.1.2 实机使用
我们在对语音功能熟悉了之后,便可以开始让机器人进行实际环境的调试。
首先还是启动我们的 语音交互节点
和 VAD检测节点
:
roslaunch handsfree_speech offline_interactive_ros.launch//语音交互功能节点
rosrun handsfree_speech vad_record.py//vad检测节点
- 然后运行
一键导航节点
(my_map为先前雷达建图
教程中所创建的地图名称):
roslaunch handsfree_2dnav navigation.launch map_name:=my_map
这个启动命令会启动底盘驱动节点
、激光雷达节点
、move_base导航节点
以及rviz可视化节点
初始位置的标定:我们可以通过RVIZ可视化工具上方工具栏中的
2D Pose Estimate
来标定初始化位置,直到机器人在地图中的位置和机器人实际的位置一样。启动语音巡逻节点 :
rosrun handsfree_speech multi_point_patrol.py//语音巡逻节点
一切就绪后,您就可以尝试语音巡逻功能的使用了。
1.2 控制核心
XL_goal=0
XL_finish=0
rospy.init_node('smach_serial_demo2',log_level=rospy.DEBUG)
server_movebase = actionlib.SimpleActionClient('/move_base', move_base_msgs.msg.MoveBaseAction)
connect_state = server_movebase.wait_for_server()
points = [[11.3,50.1], # target point 1 only need x and y
[14.7,41.9], # target point 2
[16.9,18.2], # target point 3
[10.4,25.4]] # target point 4
您可以在此部分代码设置机器人的巡逻点位。
-----------------------------------
def speech_callback(msg):
#rospy.loginfo(msg)
global XL_goal
global XL_finish
if msg.data == 'patrol':
XL_goal=1
elif msg.data == 'stoppatrol':
XL_goal=0
elif msg.data == 'shutdown':
XL_finish=1
----------------------------------
def execute(self, ud):
goal = gen_new_movebase_goal('map',
self.__target_x,
self.__target_y,
self.__next_target_x,
self.__next_target_y)
if XL_goal==1:
server_movebase.send_goal(goal)
# todo: what should robot do when failed to finish the target point?
is_server_availabel = server_movebase.wait_for_result()
if is_server_availabel is False:
return 'error_exit'
else:
if XL_finish==1:
return 'error_exit'
else:
return 'next_point'
----------------------------------
with smach_serial_demo2:
while XL_goal==0:
b=0
if XL_goal==1 and a==0:
a+1
# to point in points list into state machine
for target_point in range(0, size_points, 1):
next_target_point = (target_point+1) % size_points
name_target_point = 'POINT%d' % target_point
name_next_target_point = 'POINT%d' % next_target_point
smach.StateMachine.add(name_target_point,
MoveToPoint(target_x=points[target_point][0],
target_y=points[target_point][1],
next_target_x=points[next_target_point][0],
next_target_y=points[next_target_point][1]),
transitions={'next_point': name_next_target_point})
smach_serial_demo2.execute()
修改我们的SMACH状态机的状态,当小道小道
唤醒后,使用开始巡逻
指令发出,SMACH状态机开始工作,进行巡逻任务。当小道小道
唤醒后,使用结束巡逻
指令发出,SMACH状态机停止工作,结束巡逻任务。
1.3 关于smach状态机
smach提供了actionlib整合和smach viewer两大组件。samch viewer可以实时查看任务执行当前的状态结点位置,以便于开发调试。smach还整合了动作状态,例如定点导航,可以把topic,service转化为状态,也可以把一个类转化为状态结点。smach还可以实现状态的并发执行,任务的重复执行,层次嵌套复杂的状态机。
SMACH 有利于控制机器人复杂动作的具体实现。在SMACH中,所有可能的状态和状态转移都能被明 确定义。SMACH有以下特点:
快速原型: 利用基于Python的状态机语法,能够快速构建可执行的状态机。
复杂状态机: SMACH支持设计、维护和调试大型的复杂的层次状态机。
自省: SMACH可以创建状态机的自省程序,包括状态转移、用户数据等要素的初始化。
由于SMACH旨在提供任务级的状态机描述,因此并不适用于无结构性的任务,以及需要较高执行效率的底层系统。
这里就是一直在判断当前的状态是否到了新的节点,如果是,则机器人会进行下一个动作状态的任务,并开始巡逻循环。
当结束巡逻指令发出后,SMACH状态机将通过我们设计的条件来判断状态,当满足巡逻结束的条件时,我们的状态机到了新的状态时,会因为不满足条件,而不发送下一个节点的信息给/move_base
,从而实现停止巡逻的状态。
当退出语音
指令发出后,满足了机器人完成任务的标志位信息,其会切换SMACH自身的状态为结束状态,并关闭相关进程。
下面是一个科大讯飞的错误码信息查询,如果在调用科大讯飞的时候报错了相关的错误码,可以通过这个链接查询。 科大讯飞错误码信息查询