IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> UR机械臂学习(7-1):MoveIt简单编程实现机械臂运动(正逆运动学) -> 正文阅读

[Python知识库]UR机械臂学习(7-1):MoveIt简单编程实现机械臂运动(正逆运动学)

主要参考:

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_group

roscd 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_commander
 
class 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 group
        arm = moveit_commander.MoveGroupCommander('manipulator')
        
        # 设置机械臂运动的允许误差值,单位弧度
        arm.set_goal_joint_tolerance(0.001)
 
        # 设置允许的最大速度和加速度,范围0~1
        arm.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)
        
        # 关闭并退出moveit
        moveit_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_demo
    ros::init(argc, argv, "moveit_fk_demo");
    //多线程
    ros::AsyncSpinner spinner(1);
    //开启新的线程
    spinner.start();
 
    //初始化需要使用move group控制的机械臂中的arm group
    moveit::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, Pose
 
 
class MoveItIkDemo:
    def __init__(self):
 
        # 初始化move_group的API
        moveit_commander.roscpp_initialize(sys.argv)
        
        # 初始化ROS节点
        rospy.init_node('moveit_ik_demo')
                
        # 初始化需要使用move group控制的机械臂中的arm group
        arm = 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_frame
        target_pose.header.stamp = rospy.Time.now() #时间戳?
        #末端位置   
        target_pose.pose.position.x = 0.2593
        target_pose.pose.position.y = 0.0636
        target_pose.pose.position.z = 0.1787
        #末端姿态,四元数
        target_pose.pose.orientation.x = 0.70692
        target_pose.pose.orientation.y = 0.0
        target_pose.pose.orientation.z = 0.0
        target_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()
 
        # 关闭并退出moveit
        moveit_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 group
    moveit::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.launch

roslaunch 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 COMPONENTS
  roscpp
  rospy
  std_msgs
  moveit_ros_planning_interface
  moveit_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++程序的时:

rosrun control_robot demo_node

运行python程序的时:

rosrun control_robot demo.py

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

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

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-07-27 16:10:51  更:2021-07-27 16:10:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/8 0:05:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码