UR10+gazebo+moveit吸盘抓取搬运demo

使用ur10+gazebo开发了一个简易吸盘抓取箱子码垛的仿真过程,机械臂控制使用的是moveit配置。 本博客对部分关键的代码进行解释。
代码运行环境:支持ubuntu16、 18、 20, ros版本是ros1(经过测试)。

1、搬运场景

在这里插入图片描述
场景的搭建过程大致就是先用sw建模,然后导出stl模型到gazebo世界中,另存为sdf文件,再把所有模型文件拖入gazebo世界中制作world文件。导入ur机械臂就不再赘述。

2、world文件 carry_box.world

<sdf version='1.6'>
  <world name='default'>
    <light name='sun' type='directional'>
      <cast_shadows>1</cast_shadows>
      <pose frame=''>0 0 10 0 -0 0</pose>
      <diffuse>0.8 0.8 0.8 1</diffuse>
      <specular>0.2 0.2 0.2 1</specular>
      <attenuation>
        <range>1000</range>
        <constant>0.9</constant>
        <linear>0.01</linear>
        <quadratic>0.001</quadratic>
      </attenuation>
      <direction>-0.5 0.1 -0.9</direction>
    </light>
    <model name='ground_plane'>
      <static>1</static>
      <link name='link'>
        <collision name='collision'>
          <geometry>
            <plane>
              <normal>0 0 1</normal>
              <size>100 100</size>
            </plane>
          </geometry>
          <surface>
            <contact>
              <collide_bitmask>65535</collide_bitmask>
              <ode/>
            </contact>
            <friction>
              <ode>
                <mu>100</mu>
                <mu2>50</mu2>
              </ode>
              <torsional>
                <ode/>
              </torsional>
            </friction>
            <bounce/>
          </surface>
          <max_contacts>10</max_contacts>
        </collision>
        <visual name='visual'>
          <cast_shadows>0</cast_shadows>
          <geometry>
            <plane>
              <normal>0 0 1</normal>
              <size>100 100</size>
            </plane>
          </geometry>
          <material>
            <script>
              <uri>file://media/materials/scripts/gazebo.material</uri>
              <name>Gazebo/LightGrey</name>
            </script>
          </material>
        </visual>
        <self_collide>0</self_collide>
        <enable_wind>0</enable_wind>
        <kinematic>0</kinematic>
      </link>
    </model>
    <gravity>0 0 -9.8</gravity>
    <magnetic_field>6e-06 2.3e-05 -4.2e-05</magnetic_field>
    <atmosphere type='adiabatic'/>
    <physics name='default_physics' default='0' type='ode'>
      <max_step_size>0.001</max_step_size>
      <real_time_factor>1</real_time_factor>
      <real_time_update_rate>1000</real_time_update_rate>
    </physics>
    <scene>
      <ambient>0.4 0.4 0.4 1</ambient>
      <background>0.7 0.7 0.7 1</background>
      <shadows>0</shadows>
    </scene>
    <audio>
      <device>default</device>
    </audio>
    <wind/>
    <spherical_coordinates>
      <surface_model>EARTH_WGS84</surface_model>
      <latitude_deg>0</latitude_deg>
      <longitude_deg>0</longitude_deg>
      <elevation>0</elevation>
      <heading_deg>0</heading_deg>
    </spherical_coordinates>
    <state world_name='default'>
      <sim_time>486 140000000</sim_time>
      <real_time>4 327300810</real_time>
      <wall_time>1696174243 353467065</wall_time>
      <iterations>4291</iterations>

      <model name='desk_plane'>
        <pose frame=''>-0.25 -0.25 0.35 0 -0 0</pose>
        <scale>1 1 1</scale>
        <link name='link_0'>
          <pose frame=''>-0.25 -0.25 0.35 0 -0 0</pose>
          <velocity>0 0 0 0 -0 0</velocity>
          <acceleration>-2.9e-05 -0 4.55499 -3.14158 -0.458701 -3.14159</acceleration>
          <wrench>-2.9e-05 -0 4.55499 0 -0 0</wrench>
        </link>
      </model>
      <model name='ground_plane'>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <scale>1 1 1</scale>
        <link name='link'>
          <pose frame=''>0 0 0 0 -0 0</pose>
          <velocity>0 0 0 0 -0 0</velocity>
          <acceleration>0 0 0 0 -0 0</acceleration>
          <wrench>0 0 0 0 -0 0</wrench>
        </link>
      </model>
      <model name='pidai'>
        <pose frame=''>0.3 0.45 0.3 0 -7.3e-05 1.57809</pose>
        <scale>1 1 1</scale>
        <link name='link_1'>
          <pose frame=''>0.3 0.45 0.3 0 -7.3e-05 1.57809</pose>
          <velocity>0 0 0 0 -0 0</velocity>
          <acceleration>5.3e-05 0.004276 -0 -2.24965 -0.428859 0</acceleration>
          <wrench>5.3e-05 0.004276 -0 0 -0 0</wrench>
        </link>
      </model>
      <model name='tuopan'>
        <pose frame=''>0.2 0.5 0.07 -3.14159 0 0</pose>
        <scale>1 1 1</scale>
        <link name='link_3'>
          <pose frame=''>0.2 0.5 0.07 -3.14159 0 0</pose>
          <velocity>0 0 0 0 -0 0</velocity>
          <acceleration>-0.030733 -2.32282 -0.311017 1.76562 -0.44259 0.000324</acceleration>
          <wrench>-0.030733 -2.32282 -0.311017 0 -0 0</wrench>
        </link>
      </model>
      <light name='sun'>
        <pose frame=''>0 0 10 0 -0 0</pose>
      </light>
    </state>
    <model name='pidai'>
      <link name='link_1'>
        <inertial>
          <mass>1</mass>
          <pose frame=''>1 0.3 0 0 -0 0</pose>
          <inertia>
            <ixx>0.166667</ixx>
            <ixy>0</ixy>
            <ixz>0</ixz>
            <iyy>0.166667</iyy>
            <iyz>0</iyz>
            <izz>0.166667</izz>
          </inertia>
        </inertial>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <visual name='visual'>
          <pose frame=''>0 0 0 0 -0 0</pose>
          <geometry>
            <mesh>
              <uri>/home/lzw/now_work/ur_ws/src/ur_carry_box/ur10sence/pidai.stl</uri>
              <scale>1 1 1</scale>
            </mesh>
          </geometry>
          <material>
            <lighting>1</lighting>
            <script>
              <uri>file://media/materials/scripts/gazebo.material</uri>
              <name>Gazebo/Green</name>
            </script>
          </material>
          <transparency>0</transparency>
          <cast_shadows>1</cast_shadows>
        </visual>
        <collision name='collision'>
          <laser_retro>0</laser_retro>
          <max_contacts>10</max_contacts>
          <pose frame=''>0 0 0 0 -0 0</pose>
          <geometry>
            <mesh>
              <uri>/home/lzw/now_work/ur_ws/src/ur_carry_box/ur10sence/pidai.stl</uri>
              <scale>1 1 1</scale>
            </mesh>
          </geometry>
          <surface>
            <friction>
              <ode>
                <mu>1</mu>
                <mu2>1</mu2>
                <fdir1>0 0 0</fdir1>
                <slip1>0</slip1>
                <slip2>0</slip2>
              </ode>
              <torsional>
                <coefficient>1</coefficient>
                <patch_radius>0</patch_radius>
                <surface_radius>0</surface_radius>
                <use_patch_radius>1</use_patch_radius>
                <ode>
                  <slip>0</slip>
                </ode>
              </torsional>
            </friction>
            <bounce>
              <restitution_coefficient>0</restitution_coefficient>
              <threshold>1e+06</threshold>
            </bounce>
            <contact>
              <collide_without_contact>0</collide_without_contact>
              <collide_without_contact_bitmask>1</collide_without_contact_bitmask>
              <collide_bitmask>1</collide_bitmask>
              <ode>
                <soft_cfm>0</soft_cfm>
                <soft_erp>0.2</soft_erp>
                <kp>1e+13</kp>
                <kd>1</kd>
                <max_vel>0.01</max_vel>
                <min_depth>0</min_depth>
              </ode>
              <bullet>
                <split_impulse>1</split_impulse>
                <split_impulse_penetration_threshold>-0.01</split_impulse_penetration_threshold>
                <soft_cfm>0</soft_cfm>
                <soft_erp>0.2</soft_erp>
                <kp>1e+13</kp>
                <kd>1</kd>
              </bullet>
            </contact>
          </surface>
        </collision>
        <self_collide>0</self_collide>
        <enable_wind>0</enable_wind>
        <kinematic>0</kinematic>
      </link>
      <static>1</static>
      <allow_auto_disable>1</allow_auto_disable>
      <pose frame=''>-1.09292 1.16271 0 0 -0 0</pose>
    </model>
    <model name='tuopan'>
      <link name='link_3'>
        <inertial>
          <mass>10</mass>
          <pose frame=''>0.6 0.5 0 0 -0 0</pose>
          <inertia>
            <ixx>0.166667</ixx>
            <ixy>0</ixy>
            <ixz>0</ixz>
            <iyy>0.166667</iyy>
            <iyz>0</iyz>
            <izz>0.166667</izz>
          </inertia>
        </inertial>
        <pose frame=''>-0 -0 0 0 -0 0</pose>
        <visual name='visual'>
          <pose frame=''>0 0 0 0 -0 0</pose>
          <geometry>
            <mesh>
              <uri>/home/lzw/now_work/ur_ws/src/ur_carry_box/ur10sence/tuopan.stl</uri>
              <scale>1 1 1</scale>
            </mesh>
          </geometry>
          <material>
            <lighting>1</lighting>
            <script>
              <uri>file://media/materials/scripts/gazebo.material</uri>
              <name>Gazebo/Wood</name>
            </script>
          </material>
          <transparency>0</transparency>
          <cast_shadows>1</cast_shadows>
        </visual>
        <collision name='collision'>
          <laser_retro>0</laser_retro>
          <max_contacts>10</max_contacts>
          <pose frame=''>0 0 0 0 -0 0</pose>
          <geometry>
            <mesh>
              <uri>/home/lzw/now_work/ur_ws/src/ur_carry_box/ur10sence/tuopan.stl</uri>
              <scale>1 1 1</scale>
            </mesh>
          </geometry>
          <surface>
            <friction>
              <ode>
                <mu>1</mu>
                <mu2>1</mu2>
                <fdir1>0 0 0</fdir1>
                <slip1>0</slip1>
                <slip2>0</slip2>
              </ode>
              <torsional>
                <coefficient>1</coefficient>
                <patch_radius>0</patch_radius>
                <surface_radius>0</surface_radius>
                <use_patch_radius>1</use_patch_radius>
                <ode>
                  <slip>0</slip>
                </ode>
              </torsional>
            </friction>
            <bounce>
              <restitution_coefficient>0</restitution_coefficient>
              <threshold>1e+06</threshold>
            </bounce>
            <contact>
              <collide_without_contact>0</collide_without_contact>
              <collide_without_contact_bitmask>1</collide_without_contact_bitmask>
              <collide_bitmask>1</collide_bitmask>
              <ode>
                <soft_cfm>0</soft_cfm>
                <soft_erp>0.2</soft_erp>
                <kp>1e+13</kp>
                <kd>1</kd>
                <max_vel>0.01</max_vel>
                <min_depth>0</min_depth>
              </ode>
              <bullet>
                <split_impulse>1</split_impulse>
                <split_impulse_penetration_threshold>-0.01</split_impulse_penetration_threshold>
                <soft_cfm>0</soft_cfm>
                <soft_erp>0.2</soft_erp>
                <kp>1e+13</kp>
                <kd>1</kd>
              </bullet>
            </contact>
          </surface>
        </collision>
        <self_collide>0</self_collide>
        <enable_wind>0</enable_wind>
        <kinematic>0</kinematic>
      </link>
      <static>1</static>
      <allow_auto_disable>1</allow_auto_disable>
      <pose frame=''>0.845494 -0.422476 0 0 -0 0</pose>
    </model>
    <gui fullscreen='0'>
      <camera name='user_camera'>
        <pose frame=''>3.17031 -0.472188 0.896836 -0 0.368 2.88159</pose>
        <view_controller>orbit</view_controller>
        <projection_type>perspective</projection_type>
      </camera>
    </gui>
    <model name='desk_plane'>
      <link name='link_0'>
        <inertial>
          <mass>1</mass>
          <pose frame=''>0.25 0.25 0 0 -0 0</pose>
          <inertia>
            <ixx>0.166667</ixx>
            <ixy>0</ixy>
            <ixz>0</ixz>
            <iyy>0.166667</iyy>
            <iyz>0</iyz>
            <izz>0.166667</izz>
          </inertia>
        </inertial>
        <pose frame=''>-0 -0 0 0 -0 0</pose>
        <visual name='visual'>
          <pose frame=''>0 0 0 0 -0 0</pose>
          <geometry>
            <mesh>
              <uri>/home/lzw/now_work/ur_ws/src/ur_carry_box/ur10sence/desk_plane.stl</uri>
              <scale>1 1 1</scale>
            </mesh>
          </geometry>
          <material>
            <lighting>1</lighting>
            <script>
              <uri>file://media/materials/scripts/gazebo.material</uri>
              <name>Gazebo/DarkYellow </name>
            </script>
          </material>
          <transparency>0</transparency>
          <cast_shadows>1</cast_shadows>
        </visual>
        <collision name='collision'>
          <laser_retro>0</laser_retro>
          <max_contacts>10</max_contacts>
          <pose frame=''>0 0 0 0 -0 0</pose>
          <geometry>
            <mesh>
              <uri>/home/lzw/now_work/ur_ws/src/ur_carry_box/ur10sence/desk_plane.stl</uri>
              <scale>1 1 1</scale>
            </mesh>
          </geometry>
          <surface>
            <friction>
              <ode>
                <mu>1</mu>
                <mu2>1</mu2>
                <fdir1>0 0 0</fdir1>
                <slip1>0</slip1>
                <slip2>0</slip2>
              </ode>
              <torsional>
                <coefficient>1</coefficient>
                <patch_radius>0</patch_radius>
                <surface_radius>0</surface_radius>
                <use_patch_radius>1</use_patch_radius>
                <ode>
                  <slip>0</slip>
                </ode>
              </torsional>
            </friction>
            <bounce>
              <restitution_coefficient>0</restitution_coefficient>
              <threshold>1e+06</threshold>
            </bounce>
            <contact>
              <collide_without_contact>0</collide_without_contact>
              <collide_without_contact_bitmask>1</collide_without_contact_bitmask>
              <collide_bitmask>1</collide_bitmask>
              <ode>
                <soft_cfm>0</soft_cfm>
                <soft_erp>0.2</soft_erp>
                <kp>1e+13</kp>
                <kd>1</kd>
                <max_vel>0.01</max_vel>
                <min_depth>0</min_depth>
              </ode>
              <bullet>
                <split_impulse>1</split_impulse>
                <split_impulse_penetration_threshold>-0.01</split_impulse_penetration_threshold>
                <soft_cfm>0</soft_cfm>
                <soft_erp>0.2</soft_erp>
                <kp>1e+13</kp>
                <kd>1</kd>
              </bullet>
            </contact>
          </surface>
        </collision>
        <self_collide>0</self_collide>
        <enable_wind>0</enable_wind>
        <kinematic>0</kinematic>
      </link>
      <static>1</static>
      <allow_auto_disable>1</allow_auto_disable>
      <pose frame=''>0.852331 0.937325 0 0 -0 0</pose>
    </model>
  </world>
</sdf>

需要修改的地方:
把类似于/home/lzw/now_work/ur_ws/src/ur_carry_box/ur10sence/pidai.stl绝对地址,改成自己本机上的文件地址,所有这些军需要替换。例如自己电脑的文件夹地址是/home/A/ur_ws,则改为/home/A/ur_ws/src/ur_carry_box/ur10sence/pidai.stl

3、生成box的python代码

# -*- coding: utf-8 -*-
#!/usr/bin/env python
 
import os
import rospy
from gazebo_msgs.msg import ModelState
from gazebo_msgs.srv import DeleteModel, SpawnModel
from std_msgs.msg import Header
from geometry_msgs.msg import Pose, Point, Quaternion
from math import pi,sin,cos
 

def rpy2quaternion(roll, pitch, yaw):
  x=sin(pitch/2)*sin(yaw/2)*cos(roll/2)+cos(pitch/2)*cos(yaw/2)*sin(roll/2)
  y=sin(pitch/2)*cos(yaw/2)*cos(roll/2)+cos(pitch/2)*sin(yaw/2)*sin(roll/2)
  z=cos(pitch/2)*sin(yaw/2)*cos(roll/2)-sin(pitch/2)*cos(yaw/2)*sin(roll/2)
  w=cos(pitch/2)*cos(yaw/2)*cos(roll/2)-sin(pitch/2)*sin(yaw/2)*sin(roll/2)
  return Quaternion(x,y,z,w)


# 定义生成模型的函数
def spawn_aruco_cubo_hover(name='1'):
    
    model_name = "box" + name
    model_path = "/home/lzw/now_work/ur_ws/src/ur_carry_box/sdf/box/model.sdf"
    initial_pose = Pose(position=Point(x=-0.0, y=1, z=0.6), orientation = rpy2quaternion(0,0,1.57))
 
    # 从文件加载模型
    with open(model_path, "r") as f:
        model_xml = f.read()
 
    # 调用Gazebo的SpawnModel服务
    spawn_model = rospy.ServiceProxy('/gazebo/spawn_sdf_model', SpawnModel)
    resp_sdf = spawn_model(model_name, model_xml, "", initial_pose, "world")
 
    if resp_sdf.success:
        rospy.loginfo("模型 '{}' 生成成功。".format(model_name))
    else:
        rospy.logerr("模型 '{}' 生成失败。".format(model_name))
 
# 调用生成模型的函数
if __name__ == '__main__':
    try:
        # 初始化ROS节点
        rospy.init_node('spawn_box', anonymous=True)
        spawn_aruco_cubo_hover()
    except rospy.ROSInterruptException:
        pass

需要修改的地方:
仍然是地址,原代码中 model_path = "/home/lzw/now_work/ur_ws/src/ur_carry_box/sdf/box/model.sdf"表示的是每次在gazebo场景中生成的物体模型,这里改为自己电脑的模型地址。

4、机械臂控制python程序

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from multiprocessing import current_process
from select import select
import sys
import turtle
# sys.path.append('/home/lzw/now_work/ur_ws/src/ur_carry_box')
import rospy
from std_msgs.msg import Float64
import moveit_commander
import moveit_msgs.msg
import geometry_msgs.msg
from geometry_msgs.msg import PoseStamped,Pose
import math
from math import pi,sin,cos
import numpy as np	
import time
from moveit_commander.conversions import pose_to_list
# from pyquaternion import Quaternion
import add_box_in_sence
from std_srvs.srv import Empty

def all_close(goal, actual, tolerance):
  """
  Convenience method for testing if a list of values are within a tolerance of their counterparts in another list
  @param: goal       A list of floats, a Pose or a PoseStamped
  @param: actual     A list of floats, a Pose or a PoseStamped
  @param: tolerance  A float
  @returns: bool
  """
  all_equal = True
  if type(goal) is list:
    for index in range(len(goal)):
      if abs(actual[index] - goal[index]) > tolerance:
        return False

  elif type(goal) is geometry_msgs.msg.PoseStamped:
    return all_close(goal.pose, actual.pose, tolerance)

  elif type(goal) is geometry_msgs.msg.Pose:
    return all_close(pose_to_list(goal), pose_to_list(actual), tolerance)

  return True

def eulerAngles2rotationMat(theta, format='degree'):
  # RPY角,是ZYX欧拉角,依次绕定轴XYZ转动[rx, ry, rz]
  if format is 'degree':
      theta = [i * math.pi / 180.0 for i in theta]

  R_x = np.array([[1, 0, 0],
                  [0, math.cos(theta[0]), -math.sin(theta[0])],
                  [0, math.sin(theta[0]), math.cos(theta[0])]
                  ])

  R_y = np.array([[math.cos(theta[1]), 0, math.sin(theta[1])],
                  [0, 1, 0],
                  [-math.sin(theta[1]), 0, math.cos(theta[1])]
                  ])

  R_z = np.array([[math.cos(theta[2]), -math.sin(theta[2]), 0],
                  [math.sin(theta[2]), math.cos(theta[2]), 0],
                  [0, 0, 1]
                  ])
  R = np.dot(R_z, np.dot(R_y, R_x))
  return R

# 旋转矩阵转换为四元数
# def rotateToQuaternion(rotateMatrix):
#   q = Quaternion(matrix=rotateMatrix)
#   return q


def rpy2quaternion(roll, pitch, yaw):
  x=sin(pitch/2)*sin(yaw/2)*cos(roll/2)+cos(pitch/2)*cos(yaw/2)*sin(roll/2)
  y=sin(pitch/2)*cos(yaw/2)*cos(roll/2)+cos(pitch/2)*sin(yaw/2)*sin(roll/2)
  z=cos(pitch/2)*sin(yaw/2)*cos(roll/2)-sin(pitch/2)*cos(yaw/2)*sin(roll/2)
  w=cos(pitch/2)*cos(yaw/2)*cos(roll/2)-sin(pitch/2)*sin(yaw/2)*sin(roll/2)
  return w, x, y, z

class MoveGroupPythonIntefaceTutorial(object):
  """MoveGroupPythonIntefaceTutorial"""
  def __init__(self):
    super(MoveGroupPythonIntefaceTutorial, self).__init__()
    moveit_commander.roscpp_initialize(sys.argv)
    rospy.init_node('move_group_python_interface_tutorial',
                    anonymous=True)

    robot = moveit_commander.RobotCommander()
    scene = moveit_commander.PlanningSceneInterface()
    group_name = "arm"
    group = moveit_commander.MoveGroupCommander(group_name)
    display_trajectory_publisher = rospy.Publisher('/move_group/display_planned_path',
                                                   moveit_msgs.msg.DisplayTrajectory,
                                                   queue_size=20)

    
    planning_frame = group.get_planning_frame()
    print("============ Reference frame: %s" % planning_frame)

    # We can also print the name of the end-effector link for this group:
    eef_link = group.get_end_effector_link()
    print("============ End effector: %s" % eef_link)
    
    arm_links = robot.get_link_names(group=group_name)
    print("============ arm links: %s" % arm_links)

    # We can get a list of all the groups in the robot:
    group_names = robot.get_group_names()
    # print("============ Robot Groups:", robot.get_group_names())

    # Sometimes for debugging it is useful to print the entire state of the
    # robot:
    # print("============ Printing robot state")
    # print(robot.get_current_state())
    ## END_SUB_TUTORIAL

    # Misc variables
    self.box_name = ''
    self.robot = robot
    self.scene = scene
    self.group = group
    self.display_trajectory_publisher = display_trajectory_publisher
    self.planning_frame = planning_frame
    self.eef_link = eef_link
    self.group_names = group_names
    self.arm_links = arm_links

  def go_to_joint_state(self, joints):
    group = self.group
    joint_goal = group.get_current_joint_values()
    for i in range(6):
      print("joint "+str(i)+" angle is ", joint_goal[i])
    # joint_goal[0] = 1.57
    # joint_goal[1] = -1.57
    # joint_goal[2] = 1.57
    # joint_goal[3] = 1.57
    # joint_goal[4] = -1.57
    # joint_goal[5] = 0.0
    
    joint_goal = joints
    
    group.go(joint_goal, wait=True)
    group.stop()

    current_joints = self.group.get_current_joint_values()
    return all_close(joint_goal, current_joints, 0.01)

  
  def go_to_pose_goal(self, goal):
    '''
    goal : list  [x,y,z, R, P, Y]
    '''
    group = self.group
    current_pose = group.get_current_pose()
    print('current pose is {}'.format(current_pose.pose))
 
    group.set_start_state_to_current_state()
    group.set_pose_target(goal, self.eef_link)
    traj = group.plan()
    group.execute(traj)
    group.clear_pose_targets()
    print("============ Move success.")
  
  
  def go_to_pose_goal_interp(self, goal):
    '''
    goal : list  [x,y,z, R, P, Y]
    '''
    group = self.group
    current_pose = group.get_current_pose()
    print('current pose is {}'.format(current_pose.pose))
    
    num_step = 4
    x_step = abs(current_pose.pose.position.x-goal[0]) / num_step
    y_step = abs(current_pose.pose.position.y-goal[1]) / num_step
    z_step = abs(current_pose.pose.position.z-goal[2]) / num_step

    x_list = list(np.arange(current_pose.pose.position.x, goal[0], x_step if current_pose.pose.position.x<goal[0] else -x_step))
    y_list = list(np.arange(current_pose.pose.position.y, goal[1], y_step if current_pose.pose.position.y<goal[1] else -y_step))
    z_list = list(np.arange(current_pose.pose.position.z, goal[2], z_step if current_pose.pose.position.z<goal[2] else -z_step))
    waypoints= []
    for i in range(max([len(x_list), len(y_list), len(z_list)]) + 1):
      temp = []
      temp.append(x_list[i] if i < len(x_list) else goal[0])
      temp.append(y_list[i] if i < len(y_list) else goal[1])
      temp.append(z_list[i] if i < len(z_list) else goal[2])
      temp.append(goal[3])
      temp.append(goal[4])
      temp.append(goal[5])
      waypoints.append(temp)
    print('###current_pose={}'.format(current_pose))
    print('###target ={}'.format(goal))
    print('###waypoints={}'.format(waypoints))
    group.set_start_state_to_current_state()
    group.set_pose_targets(waypoints)
    traj = group.plan()
    print('###traj={}'.format(traj))
    group.execute(traj)
    group.clear_pose_targets()
    print("============ Move success.")
    

def main():
  try:
    tutorial = MoveGroupPythonIntefaceTutorial()
    
    rospy.wait_for_service('/vacuum_gripper/on', 1)
    rospy.wait_for_service('/vacuum_gripper/off', 1)
    _on = rospy.ServiceProxy('/vacuum_gripper/on', Empty)
    _off = rospy.ServiceProxy('/vacuum_gripper/off', Empty)

    put_position = [[1.15,-0.225],[1.15,0.225],[0.8,-0.225],[0.8,0.225],[0.45,-0.225],[0.45,0.225]]
    for i in range(len(put_position)):
      # add box
      add_box_in_sence.spawn_aruco_cubo_hover(str(i+1))
      # get box
      tutorial.go_to_joint_state(joints=[1.57,-1.57,1.57,-1.57,-1.57,0])
      tutorial.go_to_pose_goal([-0.002, 1.010, 0.368, -pi/2,0,0])
      time.sleep(1)
      _on()
      time.sleep(1)
      # put box
      tutorial.go_to_pose_goal([0.5, 0.25, 0.7, -pi/2,0,0])
      
      tutorial.go_to_pose_goal([put_position[i][0], put_position[i][1], 0.5, -pi/2,0,0])
      tutorial.go_to_pose_goal([put_position[i][0], put_position[i][1], 0.126, -pi/2,0,0])
      _off()
      time.sleep(1)
    tutorial.go_to_pose_goal([1,0,0.7, -pi/2,0,0])
    
  except rospy.ROSInterruptException:
    return
  except KeyboardInterrupt:
    return

if __name__ == '__main__':
  main()

这个没什么需要改的,贴出来供其他道友参考。

5、其他报错

大部分报错均是由于环境没有配置好,请根据报错内容仔细检查本机环境缺失内容,根据报错安装缺失项。
例如报错Could not load controller ‘arm_controller’ because controller type ‘position_controllers/JointTrajectoryController’ does not exist.,则安装:

sudo apt install ros-melodic-joint-trajectory-controller
参考:https://blog.csdn.net/gezongbo/article/details/120028916

若是ubuntu20系统,可能由于movet版本区别,则arm_control_by_moveit.py程序中,traj = group.plan()需要改为ubuntu20的moveit支持的函数输出格式,改为plan_success, traj, planning_time, error_code = arm.plan(),参考https://blog.csdn.net/LWLGZY/article/details/121106934.

6、效果视频

UR码垛

【原创不易,侵权必究。转载请标明出处】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/384119.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

单页404源码

<!doctype html> <html> <head> <meta charset"utf-8"> <title>简约 404错误页</title><link rel"shortcut icon" href"./favicon.png"><style> import url("https://fonts.googleapis.co…

Servlet验证技术

验证技术 验证是验证用户信息并确定该用户是否有权访问服务器资源的过程。用于验证用户信息的各种验证技术包括: 基本验证基于表单的验证摘要验证客户机整数验证1. 基本验证 网站可能包含两种类型的网站,即受保护和不受保护网页。默认情况下,所有用户都可以访问不受保护或者…

数据分析基础之《pandas(8)—综合案例》

一、需求 1、现在我们有一组从2006年到2016年1000部最流行的电影数据 数据来源&#xff1a;https://www.kaggle.com/damianpanek/sunday-eda/data 2、问题1 想知道这些电影数据中评分的平均分&#xff0c;导演的人数等信息&#xff0c;我们应该怎么获取&#xff1f; 3、问题…

线性代数的本质——1 向量

向量是线性代数中最为基础的概念。 何为向量&#xff1f; 从物理上看&#xff0c; 向量就是既有大小又有方向的量&#xff0c;只要这两者一定&#xff0c;就可以在空间中随便移动。 从计算机应用的角度看&#xff0c;向量和列表很接近&#xff0c;可以用来描述某对象的几个不同…

C||1.水仙花数是指一个n位数,每一位数字的n次幂的和正好等于这个数本身。2.有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数。

1.水仙花数是指一个n位数&#xff0c;每一位数字的n次幂的和正好等于这个数本身。 比如&#xff1a;153 13 53 33。 要求打印出所有三位数的水仙花数。 #include <stdio.h> #include <math.h> int main() {int i,x,y,z;for(i100;i<1000;i){xi/100%10;yi/10%…

力扣_字符串6—最小覆盖字串

题目 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串 “” 。 示例 &#xff1a; 输入&#xff1a;s “ADOBECODEBANC”, t “ABC” 输出&#xff1a;“BANC” 解释&#xff1a;…

java对象内部都有哪些东西

普通对象 对象头 markword 占8字节ClassPointer 指针 :-XX userCompressedClassPointrs 为4字节&#xff0c;不开启为 8字节实例数据 引用类型: -XX userCommpressedOops 为4字节&#xff0c;不开启8字节Padding对齐&#xff0c; 8的倍数 数组对象 对象头&#xff1a;markwor…

探索现代Web前端开发框架:选择最适合你的工具

在当今快速发展的Web开发领域&#xff0c;前端开发框架的选择显得尤为关键。这些框架可以帮助我们更高效地构建出交互性强、性能卓越的用户界面。本文将带你了解几个当前最受欢迎的Web前端开发框架&#xff0c;并帮助你根据自己的需求选择最合适的工具。 1. React React由Fac…

【java基础题型】录入3位数,求每一位是?

\t 制表符&#xff0c;用于整到8个格子 Scanner类&#xff0c;导入Scanner包(1),代码里导入Scanner类写录入&#xff0c;调用录入的对象的方法 通用求个位数&#xff0c;%10即可&#xff0c;余数不会小于除数 package java录入3位数;import java.util.Scanner; …

第五篇:MySQL常见数据类型

MySQL中的数据类型有很多&#xff0c;主要分为三类:数值类型、字符串类型、日期时间类型 三个表格都在此网盘中&#xff0c;需要者可移步自取&#xff0c;如果觉得有帮助希望点个赞~ MySQL常见数据类型表 数值类型 &#xff08;注&#xff1a;decimal类型举例&#xff0c;如1…

MATLAB Coder从入门到放弃

一、MATLAB Coder入门 1 MATLAB Coder是什么 从 MATLAB 代码生成 C 和 C 代码 MATLAB Coder™ 可从 MATLAB 代码生成适用于各种硬件平台&#xff08;从桌面计算机系统到嵌入式硬件&#xff09;的 C 和 C 代码。它支持大多数 MATLAB 语言和广泛的工具箱。您可以将生成的代码作…

通过QT制作一个模仿微信主界面的界面(不要求实现具体通信功能)

main.cpp #include "widget.h" #include "second.h"#include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();//实例化第二个界面Second s;QObject::connect(&w, &Widget::my_jump, &…

BootstrapBlazor 模板适配移动设备使用笔记

项目模板 Bootstrap Blazor App 模板 为了方便大家利用这套组件快速搭建项目&#xff0c;作者制作了 项目模板&#xff08;Project Templates&#xff09;&#xff0c;使用 dotnet new 命令行模式&#xff0c;使用步骤如下&#xff1a; 安装项目模板 dotnet new install Boo…

CSP-202312-2-因子化简(质数筛法)

CSP-202312-2-因子化简 一、质数筛法 主流的质数筛法包括埃拉托斯特尼筛法&#xff08;Sieve of Eratosthenes&#xff09;、欧拉筛法&#xff08;Sieve of Euler&#xff09;、线性筛法&#xff08;Linear Sieve&#xff09;等。这些算法都用于高效地生成一定范围内的质数。 …

Uniapp真机调试:手机端访问电脑端的后端接口解决

Uniapp真机调试&#xff1a;手机端访问电脑端的后端接口解决 1、前置操作 HBuilderX -> 运行 -> 运行到手机或模拟器 -> 运行到Android App基座 少了什么根据提示点击下载即可 使用数据线连接手机和电脑 手机端&#xff1a;打开开发者模式 -> USB调试打开手机端&…

【JAVA-Day76】Java线程解析:三态和五态

Java线程解析&#xff1a;三态和五态 《Java线程状态深度解析&#xff1a;三态和五态探秘 &#x1f60e;》摘要引言一、什么是三态 &#x1f60a;二、什么是五态 &#x1f603;三、五态之间如何转变3.1 新建状态转换到运行状态3.2 运行状态转换到阻塞状态3.3 运行状态转换到等待…

鸿蒙开发理论之页面和自定义组件生命周期

1、自定义组件和页面的关系 页面&#xff1a;即应用的UI页面。可以由一个或者多个自定义组件组成&#xff0c;Entry装饰的自定义组件为页面的入口组件&#xff0c;即页面的根节点&#xff0c;一个页面有且仅能有一个Entry。只有被Entry装饰的组件才可以调用页面的生命周期。自…

University Program VWF仿真步骤__全加器

本教程将以全加器为例&#xff0c;选择DE2-115开发板的Cyclone IV EP4CE115F29C7 FPGA&#xff0c;使用Quartus Lite v18.1&#xff0c;循序渐进的介绍如何创建Quartus工程&#xff0c;并使用Quartus Prime软件的University Program VWF工具创建波形文件&#xff0c;对全加器的…

Qt【一】:Qt3个窗口类的区别、VS与QT项目转换

一、Qt3个窗口类的区别 QMainWindow&#xff1a;包含菜单栏、工具栏、状态栏 QWidget&#xff1a;普通的一个窗口&#xff0c;什么也不包括 QDialog&#xff1a;对话框&#xff0c;常用来做登录窗口、弹出窗口&#xff08;例如设置页面&#xff09; QDialog实现简易登录界面…

DP读书:《openEuler操作系统》(九)从IPC到网卡到卡驱动程序

DP读书&#xff1a;《openEuler操作系统》从IPC到网卡到卡驱动程序&#xff09; 上章回顾_SPI上节回顾_TCP 网卡驱动程序简介1.设备驱动2.总线与设备3.网卡及其抽象 驱动程序的注册与注销1. 注册2. 注销 设备初始化1. 硬件初始化2. 软件初始化 设备的打开与关闭1. 设备的打开2.…