主要参考:

  • MoveIt编程实现关节空间机械臂运动(正运动学)
    https://blog.csdn.net/zzu_seu/article/details/90611186
  • MoveIt编程实现关节空间机械臂运动(逆运动学)
    https://blog.csdn.net/zzu_seu/article/details/90612876

其他参考:

  • python下MoveIt使用语句的解析
    https://www.ncnynl.com/archives/201610/1033.html

00 MoveIt

在之前的工作中,在启动moveit后,启动了RViz图形界面,然后拖动机械臂末端,再点击“plan”实现轨迹的规划,点击“execute"执行机械臂的运动。
而实际工作中大都是通过编程的方式控制,而不是Rviz的图形化控制。

在MoveIt中有三个主要的控制接口可实现机械臂进行控制,如图所示,。

c++使用move_group_interface;python使用moveit_commander。使用moveit控制机械臂时,把他们放入头文件。

01 准备工作:创建功能包

cd ~/ur_ws/src# 创建功能包 control_robot
catkin_create_pkg control_robot std_msgs rospy roscpp moveit_ros_planning_interface moveit_ros_move_grouproscd control_robot# 新建scripts文件夹(用来放置python程序)
mkdir scripts# 新建.py文件
touch demo.py# 将.py文件变为可执行文件
sudo chmod +x talker.py

说明:

  • 使用catkin_create_pkg创建功能包,第一个参数是功能包名字,第二个参数是功能包的依赖。
    后续如果想再给功能包添加其他依赖,需要在CMakeList.txt中修改(在find_package里),
  • 创建后的功能包里有/src文件夹了,这个用以放置c++文件;
    python文件需要创建/script文件夹
  • 使用touch语句新建文件
  • 对于python文件,创建后需要把它修改为可执行文件;
    对于c++文件,每次修改后都要catkin_make
  • 对于python文件,另一个需要特别注意的是在.py文件的第一行要有:#!/usr/bin/env python

02 正运动学

2.1 python

#!/usr/bin/env python
# -*- coding: utf-8 -*-import rospy, sys
import moveit_commanderclass MoveItFkDemo:def __init__(self):# 初始化move_group的API,出现roscpp是因为底层是通过C++进行实现的moveit_commander.roscpp_initialize(sys.argv)# 初始化ROS节点,节点名为'moveit_fk_demo'rospy.init_node('moveit_fk_demo', anonymous=True)       # 初始化需要使用move group控制的机械臂中的arm grouparm = moveit_commander.MoveGroupCommander('manipulator')# 设置机械臂运动的允许误差值,单位弧度arm.set_goal_joint_tolerance(0.001)# 设置允许的最大速度和加速度,范围0~1arm.set_max_acceleration_scaling_factor(0.5)arm.set_max_velocity_scaling_factor(0.5)# 控制机械臂先回到初始化位置,home是setup assistant中设置的arm.set_named_target('home')arm.go()  #让机械臂先规划,再运动,阻塞指令,直到机械臂到达home后再向下执行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.set_named_target('home')arm.go()rospy.sleep(1)# 关闭并退出moveitmoveit_commander.roscpp_shutdown()moveit_commander.os._exit(0)if __name__ == "__main__":try:MoveItFkDemo()except rospy.ROSInterruptException:pass

说明:

  • 对于python程序,首行需要有
#!/usr/bin/env python
  • 如果有中文注释,需要加
# -*- coding: utf-8 -*-
  • 对于ur机械臂,Planning Groupmanipulator,这个可以在rviz的界面中看到
arm = moveit_commander.MoveGroupCommander('manipulator')

  • 正运动学机械臂的执行方式
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)

2.2 c++

#include <ros/ros.h>
#include <moveit/move_group_interface/move_group_interface.h>int main(int argc, char **argv)  //主函数
{//ros初始化节点,节点名为moveit_fk_demoros::init(argc, argv, "moveit_fk_demo");//多线程ros::AsyncSpinner spinner(1);//开启新的线程spinner.start();//初始化需要使用move group控制的机械臂中的arm groupmoveit::planning_interface::MoveGroupInterface arm("manipulator");//设置机械臂运动的允许误差arm.setGoalJointTolerance(0.001);//设置允许的最大速度和加速度arm.setMaxAccelerationScalingFactor(0.5);arm.setMaxVelocityScalingFactor(0.5);// 控制机械臂先回到初始化位置arm.setNamedTarget("home");arm.move(); //规划+运动sleep(1);//定义一个数组,存放6个关节的信息double targetPose[6] = {0.391410, -0.676384, -0.376217, 0.0, 1.052834, 0.454125};//关节的向量,赋值std::vector<double> joint_group_positions(6);joint_group_positions[0] = targetPose[0];joint_group_positions[1] = targetPose[1];joint_group_positions[2] = targetPose[2];joint_group_positions[3] = targetPose[3];joint_group_positions[4] = targetPose[4];joint_group_positions[5] = targetPose[5];//将关节值写入arm.setJointValueTarget(joint_group_positions);arm.move(); //规划+移动sleep(1);// 控制机械臂再回到初始化位置arm.setNamedTarget("home");arm.move();sleep(1);//关闭并退出ros::shutdown(); return 0;
}

说明:

  • c++正运动学的方式:
arm.setJointValueTarget(joint_group_positions);
arm.move(); //规划+移动
sleep(1);
  • 开辟多线程
    对于一些只订阅一个话题的简单节点来说,我们使用ros::spin()进入接收循环,每当有订阅的话题发布时,进入回调函数接收和处理消息数据。
    但是更多的时候,一个节点往往要接收和处理不同来源的数据,并且这些数据的产生频率也各不相同,当我们在一个回调函数里耗费太多时间时,会导致其他回调函数被阻塞,导致数据丢失。
    这种场合需要给一个节点开辟多个线程,保证数据流的畅通。它有start()stop() 函数,并且在销毁的时候会自动停止。
    其中,开辟多线程:
ros::AsyncSpinner spinner(1);

03 逆运动学

3.1 python

#!/usr/bin/env python
# -*- coding: utf-8 -*-import rospy, sys
import moveit_commander
from geometry_msgs.msg import PoseStamped, Poseclass MoveItIkDemo:def __init__(self):# 初始化move_group的APImoveit_commander.roscpp_initialize(sys.argv)# 初始化ROS节点rospy.init_node('moveit_ik_demo')# 初始化需要使用move group控制的机械臂中的arm grouparm = moveit_commander.MoveGroupCommander('manipulator')# 获取终端link的名称,这个在setup assistant中设置过了end_effector_link = arm.get_end_effector_link()# 设置目标位置所使用的参考坐标系reference_frame = 'base_link'arm.set_pose_reference_frame(reference_frame)# 当运动规划失败后,允许重新规划arm.allow_replanning(True)# 设置位置(单位:米)和姿态(单位:弧度)的允许误差arm.set_goal_position_tolerance(0.001)arm.set_goal_orientation_tolerance(0.01)# 设置允许的最大速度和加速度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)# 设置机械臂工作空间中的目标位姿,位置使用x、y、z坐标描述,# 姿态使用四元数描述,基于base_link坐标系target_pose = PoseStamped()#参考坐标系,前面设置了target_pose.header.frame_id = reference_frametarget_pose.header.stamp = rospy.Time.now() #时间戳?#末端位置   target_pose.pose.position.x = 0.2593target_pose.pose.position.y = 0.0636target_pose.pose.position.z = 0.1787#末端姿态,四元数target_pose.pose.orientation.x = 0.70692target_pose.pose.orientation.y = 0.0target_pose.pose.orientation.z = 0.0target_pose.pose.orientation.w = 0.70729# 设置机器臂当前的状态作为运动初始状态arm.set_start_state_to_current_state()# 设置机械臂终端运动的目标位姿arm.set_pose_target(target_pose, end_effector_link)# 规划运动路径,返回虚影的效果traj = arm.plan()# 按照规划的运动路径控制机械臂运动arm.execute(traj)rospy.sleep(1)  #执行完成后休息1s# 控制机械臂回到初始化位置arm.set_named_target('home')arm.go()# 关闭并退出moveitmoveit_commander.roscpp_shutdown()moveit_commander.os._exit(0)if __name__ == "__main__":MoveItIkDemo()

3.2 c++

#include <string>
#include <ros/ros.h>
#include <moveit/move_group_interface/move_group_interface.h>int main(int argc, char **argv)
{//初始化节点ros::init(argc, argv, "moveit_fk_demo");//多线程ros::AsyncSpinner spinner(1);//开启线程spinner.start();//初始化需要使用move group控制的机械臂中的arm groupmoveit::planning_interface::MoveGroupInterface arm("manipulator");//获取终端link的名称std::string end_effector_link = arm.getEndEffectorLink();//设置目标位置所使用的参考坐标系std::string reference_frame = "base_link";arm.setPoseReferenceFrame(reference_frame);//当运动规划失败后,允许重新规划arm.allowReplanning(true);//设置位置(单位:米)和姿态(单位:弧度)的允许误差arm.setGoalPositionTolerance(0.001);arm.setGoalOrientationTolerance(0.01);//设置允许的最大速度和加速度arm.setMaxAccelerationScalingFactor(0.2);arm.setMaxVelocityScalingFactor(0.2);// 控制机械臂先回到初始化位置arm.setNamedTarget("home");arm.move(); //规划+运动sleep(1); //停1s钟// 设置机器人终端的目标位置geometry_msgs::Pose target_pose;//四元数,设置末端姿态target_pose.orientation.x = 0.70692;target_pose.orientation.y = 0.0;target_pose.orientation.z = 0.0;target_pose.orientation.w = 0.70729;//设置末端位置target_pose.position.x = 0.2593;target_pose.position.y = 0.0636;target_pose.position.z = 0.1787;// 设置机器臂当前的状态作为运动初始状态arm.setStartStateToCurrentState();// 将目标位姿写入arm.setPoseTarget(target_pose);// 进行运动规划,计算机器人移动到目标的运动轨迹,此时只是计算出轨迹,并不会控制机械臂运动moveit::planning_interface::MoveGroupInterface::Plan plan;moveit::planning_interface::MoveItErrorCode success = arm.plan(plan);//输出成功与否的信息ROS_INFO("Plan (pose goal) %s",success?"":"FAILED");   //让机械臂按照规划的轨迹开始运动if(success)arm.execute(plan);sleep(1);// 控制机械臂先回到初始化位置arm.setNamedTarget("home");arm.move();sleep(1);ros::shutdown(); return 0;
}

04 注意事项

❤ 对于仿真来说,无论是c++还是python,都是先运行gazebo、moveit和rviz(rviz可以不运行,只运行前两个),然后开始运行自己写的代码。

roslaunch ur_gazebo ur3_bringup.launchroslaunch ur3_moveit_config ur3_moveit_planning_execution.launch sim:=true# rviz可以不运行
roslaunch ur3_moveit_config moveit_rviz.launch rviz_config:=$(rospack find ur3_moveit_config)/launch/moveit.rviz

❤ 无论是c++还是python,都可能需要修改CMakeList.txt 添加依赖,如

find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgsmoveit_ros_planning_interfacemoveit_ros_move_group
)

❤ 对于c++,每次运行完成都要catkin_make;
另外建立完c++文件后,需要修改CMakeList.txt(这里文件名为demo.cpp

add_executable(demo_node src/demo.cpp)target_link_libraries(demo_node ${catkin_LIBRARIES})

❤ 对于python,需要注意的是一开始把py文件变为可执行文件

sudo chmod +x [文件名].py

然后在py文件开头加上如下语句:

#!/usr/bin/env python

如果其中有中文注释,再加上:

# -*- coding: utf-8 -*-

❤ 运行c++程序的时:
(这个也要看具体CMakeList.txt里的写法,也有可能是rosrun control_robot demo

rosrun control_robot demo_node

运行python程序的时:

rosrun control_robot demo.py

05 其他参考代码和遇到的问题

https://blog.csdn.net/gyxx1998/article/details/118935792

UR机械臂学习(7-1):MoveIt简单编程实现机械臂运动(正逆运动学)相关推荐

  1. Sawyer机械臂学习系列之Moveit!配置

    Sawyer机械臂学习系列之Moveit!配置 前言 1.Sawyer SDK安装及配置 2.Moveit!安装 3.Sawyer机械臂Moveit!配置 4.查看配置结果 前言 1.Sawyer S ...

  2. 机械臂学习——舵机的速度控制、坐标变换、DH模型、正运动学解、逆运动学解

    机械臂学习 文章目录 机械臂学习 前言 一.舵机的速度控制 1.舵机概述 2.代码实现 二.机械臂的坐标变换 1.坐标变换 2.坐标的几何概述 三.DH模型和正运动学解 四.逆运动学解 1.逆运动学几 ...

  3. UR机械臂学习(7-2):MoveIt简单编程实现机械臂运动——一些参考代码和遇到的问题

    创建功能包 cd ~/ur_ws/src# 创建功能包 control_robot catkin_create_pkg control_robot std_msgs rospy roscpproscd ...

  4. UR机械臂学习(8):Python实现机械臂运动控制(不使用MoveIt)

    以下是在gazebo仿真中使用,如果是控制真实机械臂,只需要修改订阅的话题即可 后期肯定会自己进行轨迹算法规划,用moveit的话想要更换算法太麻烦,所以尝试自己写程序不通过moveit来控制机械臂. ...

  5. UR机械臂学习(5-1):驱动真实机械臂准备工作——示教器配置

    在使用Universal_Robots_ROS_Driver驱动真实机械臂前,需要在示教器上安装urcap 版本说明 使用的版本是 Ubuntu18.04 + ROS melodic + UR3(CB ...

  6. 6轴机械臂(拟人臂+球形腕(三轴相交于一点))正逆运动学求解

    1.DH坐标下机械臂参数 theta=[pi/10,pi/2,pi/4,-pi/4,pi/4,-pi/8];%关节角度 a=[0, 0.260, 0.025, 0, 0, 0];%连杆长度 d=[0, ...

  7. UR机械臂学习(5-2):使用Universal_Robots_ROS_Driver驱动真实机械臂

    使用的版本是 Ubuntu18.04 + ROS melodic + UR3(CB3.12) 因为后续需要使用手控器,手控器的驱动需要在Ubuntu18.04下才可以使用. 这篇文章是电脑上的设置,关 ...

  8. UR机械臂正逆运动学求解

    最近有个任务:求解UR机械臂正逆运动学,在网上参考了一下大家的求解办法,众说纷纭,其中有些朋友求解过程非常常规,但是最后求解的8组解,只有4组可用.在这里我介绍一个可以求解8组解析解的方法,供大家参考 ...

  9. UR机械臂仿真和用上位机编程控制

    UR机械臂仿真和用上位机编程控制 在没有实物UR机械臂时怎么办,优傲提供了仿真工具可以满足开发者需求,这样也减少了实际操作机械臂时的麻烦. 需要下载和安装的软件 虚拟机 使用VMware是不错的选择, ...

最新文章

  1. github打开出错
  2. Visual Studio 2008 快捷键大全
  3. python单用户登录_Django实现单用户登录的方法示例
  4. Android 人脸照片对比,人脸对比
  5. 让WKWebView支持NSURLProtocol
  6. php自动加载基类文件
  7. Android笔记 fragment通信
  8. 【Elasticsearch】 es 7.6 索引墓碑
  9. php 简单的socket,【技术产品】PHP如何实现简单的Socket
  10. java播放加密后的wav文件,使用Java实时同时播放WAV文件
  11. 三人表决器Verilog
  12. linux 部署 ibase4j,ibase4j学习
  13. 质疑江民电脑保护系统,涉嫌抄袭
  14. 纯净PE推荐——优启通 v3.3.2019.0605
  15. vim配置——C/C++代码自动补全
  16. 武汉大学计算机学院保研清华,清北11人保送武大法学院,网友表示看不懂,高校老师表示:正常...
  17. assoc fetch mysql 用法_php mysql_fetch_assoc 循环遍历表格
  18. pve万兆网卡驱动_PVE+lede+DSM网卡硬盘直通+win10
  19. CSP 202109-4 收集卡牌
  20. linux C之alarm函数(更改)

热门文章

  1. 【spark基础】之client模式下--conf读取外部文件
  2. 短域名服务设计与实现
  3. Flink HA配置
  4. html css分别是什么单位,CSS的deg是什么单位?
  5. 路由器和电脑IP地址、端口号、网卡mac查询方式
  6. 处理器协同机制其三C++内存顺序与栅栏(及依赖性读屏障)
  7. java设计模式之策略模式应用:订单手续费计算
  8. 光端机连接示意图详细连接方式图解
  9. 最适合深夜失眠听的歌,听了最容易入睡的歌曲推荐
  10. python小数乘法计算_小数乘法100道