机器人|通过外部程序获得Moveit-Rviz的MotionPlanning面板相同的操控能力
在Moveit-Rviz启动之后,在机器人的末端会显示一个Interactive Marker用来指示目标方位,可以通过鼠标来移动和旋转该Marker,操作时会有一个虚拟的机器人随之运动。当按下MotionPlanning面板中的Plan按钮便会显示从当前方位到目标方位的一个运动轨迹。当按下Execute按钮后机器人就会实际运动到目标方位。
Moveit在rviz中提供的操控Topic 当勾选MotionPlanning面板中的"Allow External Comm."选项的时候,在ROS上就会出现如下的几个Topic:
- /rviz/moveit/plan : 和Rviz中MotionPlanning面板提供的Plan按钮功能一样,该topic的消息类型为std_msgs/Empty,发送一个这样的消息到该Topic就相当与按下了Plan按钮。
- /rviz/moveit/execute : 和Rviz中MotionPlanning面板提供的Execute按钮功能一样
- /rviz/moveit/select_planning_group : 用于选择你想要控制的Planning Group的Topic。其消息类型为std_msgs/String。你可以在命令终端下选择Planning Group,例如
rostopic pub /rviz/moveit/select_planning_group std_msgs/String "hand"
- /rviz/moveit/update_{goal,start}_state : 和MotionPlanning面板中"State State"和"Goal State"下选框中的"current"是同样的功能。
- /rviz/moveit/update_custom_{goal,start}_state : 该Topic用于给机器人设置一个指定的状态,其消息类型为moveit_msgs/RobotState。
- /rviz/moveit/move_marker/goal_#{link_name} : 指定交互式marker的方位的Topic。link_name是Planning Group中的末端连杆的名称,例如"/rviz/moveit/move_marker/goal_panda_link8。其中"panda_link8"为panda机器人本体的最后一个连杆。该Topic的消息类型为geometry_msgs/PoseStamped。
- /rviz_moveit_motion_planning_display/robot_interactive_interactive_marker_topic/update : 该Topic会发布经过确认的有效的IMarker方位。我们可以用来更新IMarker的实际goalPose。
- /execute_trajectory/status : 当moveit通过Execute执行实际的轨迹运动时,就会通过该Topic发布执行的状态。因此当我们进行实际的轨迹运动时就可以通过该Topic来检查完成结果。该Topic类型为actionlib_msgs/GoalStatusArray。
在这个例子中,我们使用adsw按键来控制Marker在XY平面的移动,通过上下箭头按键控制X方向上的移动。
#!/usr/bin/env python
# coding: UTF-8import rospy
import sys, select, termios, ttyfrom moveit_msgs.msg import RobotState
from geometry_msgs.msg import PoseStamped
from visualization_msgs.msg import InteractiveMarkerUpdate
import moveit_commanderclass IMarkerKeyboard:
def __init__(self):
self.pre_pose= PoseStamped()
self.planning_groups_tips = {}
self.ttySettings=termios.tcgetattr(sys.stdin)
# 获得机器人的当前实际位置
group_name = "arm"# 这是对机器人进行moveit配置定义的关节组名称
self.group = moveit_commander.MoveGroupCommander(group_name)
self.robot = moveit_commander.RobotCommander()
self.curPose=self.group.get_current_pose()
self.initState= self.robot.get_current_state()
# 创建相关
self.goalState_pub = rospy.Publisher("/rviz/moveit/update_custom_goal_state",
RobotState,queue_size=5)
self.marker_pub = rospy.Publisher("/rviz/moveit/move_marker/goal_link_6",
PoseStamped,queue_size=5)
self.update_sub = rospy.Subscriber("/rviz_moveit_motion_planning_display/robot_interaction_interactive_marker_topic/update",
InteractiveMarkerUpdate,self.updateGoal)
rospy.sleep(2)# 确保rviz能收到消息
# 将IMarker移动到与实际位置一致
self.goalState_pub.publish(self.initState)
rospy.sleep(1)# 回调函数通过接收update Topic来更新Marker的目标位置
def updateGoal(self, msg):
if len(msg.poses) > 0:
self.curPose.pose.position = msg.poses[0].pose.position
self.curPose.pose.orientation = msg.poses[0].pose.orientationdef getKey(self):
tty.setraw(sys.stdin.fileno())
select.select([sys.stdin],[],[],0)
key= sys.stdin.read(1)
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self.ttySettings)
return keydef run(self):
print("wait key...")
while(True) :
key = self.getKey()
if key=='-':
goalPose=self.curPose
goalPose.pose.position.z -=0.01
self.marker_pub.publish(goalPose)
elif key=='=':
goalPose=self.curPose
goalPose.pose.position.z +=0.01
self.marker_pub.publish(goalPose)
elif key=='a':
goalPose=self.curPose
goalPose.pose.position.x -=0.01
self.marker_pub.publish(goalPose)
elif key == 'd':
goalPose =self.curPose
goalPose.pose.position.x += 0.01
self.marker_pub.publish(goalPose)
elif key == 's':
goalPose =self.curPose
goalPose.pose.position.y -= 0.01
self.marker_pub.publish(goalPose)
elif key == 'w':
goalPose =self.curPose
goalPose.pose.position.y += 0.01
self.marker_pub.publish(goalPose)
if(key == '\x03'):# Ctrl+C
breakdef main():
rospy.init_node('marker_test', anonymous=True)
app=IMarkerKeyboard()
app.run()
returnif __name__ == '__main__':
main()
使用手柄的简单控制 在手柄控制中,使用如下按键或摇杆进行控制:
- 左摇杆上下: X方向粗控制
- 左摇杆左右: Y方向粗控制
- LEFT-RIGHT: X方向细控制
- UP-DOWN: Y方向细控制
- 右摇杆上下: Z方向粗控制
- X-Y: Z方向细控制
import rospy
from moveit_msgs.msg import RobotState
from geometry_msgs.msg import PoseStamped
from visualization_msgs.msg import InteractiveMarkerUpdate
from sensor_msgs.msg importJoy
import moveit_commanderclass IMarkerJoystick:
def __init__(self):
self.pre_pose= PoseStamped()
self.planning_groups_tips = {}
self.ttySettings=termios.tcgetattr(sys.stdin)
# 获得机器人的当前实际位置
group_name = "arm"# 这是对机器人进行moveit配置定义的关节组名称
self.group = moveit_commander.MoveGroupCommander(group_name)
self.robot = moveit_commander.RobotCommander()
self.curPose=self.group.get_current_pose()
self.initState= self.robot.get_current_state()
# 创建相关
self.goalState_pub = rospy.Publisher("/rviz/moveit/update_custom_goal_state",
RobotState,queue_size=5)
self.marker_pub = rospy.Publisher("/rviz/moveit/move_marker/goal_link_6",
PoseStamped,queue_size=5)
self.update_sub = rospy.Subscriber("/rviz_moveit_motion_planning_display/robot_interaction_interactive_marker_topic/update",
InteractiveMarkerUpdate,self.updateGoal)
self.joy_sub = rospy.Subscriber("/joy", Joy, self.joyCB, queue_size=1)
rospy.sleep(2)# 确保rviz能收到消息
# 将IMarker移动到与实际位置一致
self.goalState_pub.publish(self.initState)
rospy.sleep(1)# 回调函数通过接收update Topic来更新Marker的目标位置
def updateGoal(self, msg):
if len(msg.poses) > 0:
self.curPose.pose.position = msg.poses[0].pose.position
self.curPose.pose.orientation = msg.poses[0].pose.orientationdef joyCB(self,msg):
goalPose = self.curPose
status = XBoxStatus(msg)
print(status.select, status.start)
print(status.circle, status.center, status.cross, status.square)
# 粗调
if status.left_analog_x <=-0.55 :
goalPose.pose.position.x -=0.001
elif status.left_analog_x >= 0.55 :
goalPose.pose.position.x +=0.001
if status.left_analog_y <= -0.55:
goalPose.pose.position.y -= 0.001
elif status.left_analog_y >= 0.55:
goalPose.pose.position.y += 0.001
if status.right_analog_y<=-0.55:
goalPose.pose.position.z -=0.001
if status.right_analog_y>=0.55:
goalPose.pose.position.z += 0.001
# 细调
if status.left:
goalPose.pose.position.x -=0.001
if status.right:
goalPose.pose.position.x +=0.001
if status.up:
goalPose.pose.position.y -=0.001
if status.down:
goalPose.pose.position.y +=0.001
if status.square:
goalPose.pose.position.z -=0.001
if status.triangle:
goalPose.pose.position.z +=0.001
self.marker_pub.publish(goalPose)
推荐阅读
- gitlab|gitlab 通过备份还原 admin/runner 500 Internal Server Error
- 分享!如何分分钟实现微信扫二维码调用外部浏览器打开指定页面的功能
- whlie循环和for循环的应用
- 剑指|剑指 Offer 13. 机器人的运动范围(dfs,bfs)
- 如何通过锻炼的方法治疗前列腺肥大
- HttpClient对外部网络的操作
- 通过复盘快速成长(附模板)
- 历史上的今天|【历史上的今天】2 月 16 日(世界上第一个 BBS 诞生;中国计算机教育开端;IBM 机器人赢得智能竞赛)
- 基于stm32智能风扇|基于stm32智能风扇_一款基于STM32的智能灭火机器人设计
- MyBatis|MyBatis Generator配置