3 额外的知识点
ros::spin()和ros::spinOnce()的区别?
这两个都叫作ROS消息回调处理函数,两者区别在于前者调用后不会再返回,主程序到这就不再往下执行,而后者在调用后还可以继续执行之后的程序。
-
ros::spin()不会放在循环中,程序执行到这之后不会跳出来,永远执行消息的回调函数!
-
ros::spinOnce() 绝大多数会在循环里面,然后返回,跳转到下一条语句!
-
一次 ros::spinOnce()会执行完所有消息队列中的消息!进入它时,会有个当前消息计数假设当前 5次 ,它会就会执行 5次 消息回调函数。至于消息内容具体就看消息队列的大小,和处理速度了,具体看Ros消息队列。
在处理数据时,新的数据依旧在放入缓冲队列,所以缓冲区前面的信息被抛出。在设计消息接收时,耗时的操作不要放在回调函数里。
4 MoveIt!编程,驾驭机械臂运动控制
4.1 两种编程接口
“move _group" Python Interface
group = moveit_commander.MoveGroupCommander("left_arm")
pose_target = geometry_msgs.msg.Pose()
pose_target.orientation.w = 1.0
pose_target.position.x = 0.7
pose_target.position.y = -0.05
pose_target.position.z = 1.1
group.set_pose_target(pose_target)
plan1 = group.plan()
“move_group” C++ Interface
moveit::planning_interface::MoveGroup group("right_arm");
geometry_msgs::Pose target_pose;
target_pose.orientation.w = 1.0;
target_pose.position.x = 0.28;
target_pose.position.y = -0.7;
target_pose.position.z = 1.0;
group.setPoseTarget(target_pose);
moveit::planning_interface::MoveGroup::Plan my plan;
bool success = group.plan(my_plan);
编程流程
- 连接控制需要的规划组(控制谁)
- 设置目标位姿(关节空间或笛卡尔空间)
- 设置运动约束(可选,姿态等,比如端水不想打翻)
- 使用MoveIt!规划一条到达目标的轨迹
- 修改轨迹(如速度等参数)
- 执行规划出的轨迹
4.2 关节空间运动
点到点运动:不需要在笛卡尔空间规划末端运动轨迹,机器人各个关节运动不需要联动。
go()函数干了两步,先规划,再执行,且是阻塞执行。
正向运动学规划例程
$ roslaunch probot_anno_moveit_config demo.launch
$ rosrun probot_demo moveit_fk_demo.py
# 初始化需要使用move group控制的机械臂中的arm group
arm = moveit_commander.MoveGroupCommander('manipulator')
# 设置机械臂运动的允许误差值
arm.set_goal_joint_tolerance(0.001)
# 设置允许的最大速度和加速度
arm.set_max_acceleration_scaling_factor(0.5)
arm.set_max_velocity_scaling_factor(0.5)
# 控制机械臂先回到初始化位置
arm.set_named_target("home")
arm.go()
rospy.sleep(1)
# 设置机械臂的目标位置,使用六轴的位置数据进行描述(单位:弧度)
joint_positions = [0.391410, -0.676384, -0.376217, 0.0, 1.052834, 0.454125]
arm.set_joint_value_target(joint_positions)
# 控制机械臂完成运动
arm.go()
rospy.sleep(1)
# 控制机械臂先回到初始化位置
arm