ign gazebo moveit2 示例 panda

Posted zhangrelay

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ign gazebo moveit2 示例 panda相关的知识,希望对你有一定的参考价值。

参考:github.com/AndrejOrsula/ign_moveit2


ros2 launch ign_moveit2 example_throw.launch.py


 


 


github ign moveit2 案例越来越全。gazebo webots 等都支持。


cpp示例:example_ign_moveit2.cpp

/// C++ MoveIt2 interface for Ignition Gazebo that utilises move_group API to generate JointTrajectory, which is then
/// subsequently published in order to be executed by JointTrajectoryController Ignition plugin.
/// This set of node currently serves as an example and is configured for Franka Emika Panda robot.


/// DEPENDENCIES ///


// ROS 2
#include <rclcpp/rclcpp.hpp>

// ROS 2 Interface
#include <trajectory_msgs/msg/joint_trajectory.hpp>

// MoveIt2
#include <moveit/moveit_cpp/moveit_cpp.h>
#include <moveit/moveit_cpp/planning_component.h>
#include <moveit/robot_state/conversions.h>
#include <moveit/move_group_interface/move_group_interface.h>
#include <moveit/planning_scene_interface/planning_scene_interface.h>

//
/// NAMESPACES ///
//

using namespace std::chrono_literals;

/
/// CONSTANTS ///
/

/// The name of the primary node
const std::string NODE_NAME = "ign_moveit2";
/// The name of node responsible for MoveIt2, separated to keep at individual thread
const std::string NODE_NAME_MOVEIT2_HANDLER = "ign_moveit2_handler";
/// Identifier of the planning group
const std::string PLANNING_GROUP = "panda_arm";
/// Topic that planned trajectory will be published to
const std::string JOINT_TRAJECTORY_TOPIC = "joint_trajectory";

/
/// Node - MoveIt2Handler ///
/

class MoveIt2Handler : public rclcpp::Node
{
public:
  /// Constructor
  MoveIt2Handler();

  /// Publisher of the trajectories
  rclcpp::Publisher<trajectory_msgs::msg::JointTrajectory>::SharedPtr trajectory_publisher_;
  /// Planning scene interface
  moveit::planning_interface::PlanningSceneInterface planning_scene_interface_;
  /// Move group interface for the robot
  moveit::planning_interface::MoveGroupInterface move_group_;

  /// Set goal to target joint values
  bool set_joint_goal(const std::vector<double, std::allocator<double>> &_target_joint_state);
  /// Set goal to target pose
  bool set_pose_goal(const geometry_msgs::msg::PoseStamped &_target_pose);
  /// Set goal to named target
  bool set_named_target_goal(const std::string &_named_target);
  /// Plan trajectory with previously set target
  bool plan_trajectory();
};

MoveIt2Handler::MoveIt2Handler() : Node(NODE_NAME_MOVEIT2_HANDLER, rclcpp::NodeOptions().automatically_declare_parameters_from_overrides(true)),
                                   trajectory_publisher_(this->create_publisher<trajectory_msgs::msg::JointTrajectory>(JOINT_TRAJECTORY_TOPIC, 1)),
                                   planning_scene_interface_(this->get_name()),
                                   move_group_(std::shared_ptr<rclcpp::Node>(std::move(this)), PLANNING_GROUP)
{
  // Various trajectory parameters can be set here
  this->move_group_.setMaxAccelerationScalingFactor(0.5);
  this->move_group_.setMaxVelocityScalingFactor(0.5);
  RCLCPP_INFO(this->get_logger(), "Node initialised successfuly");
}

bool MoveIt2Handler::set_joint_goal(const std::vector<double, std::allocator<double>> &_target_joint_state)
{
  RCLCPP_INFO(this->get_logger(), "Setting goal to a custom joint values");
  return this->move_group_.setJointValueTarget(_target_joint_state);
}

bool MoveIt2Handler::set_pose_goal(const geometry_msgs::msg::PoseStamped &_target_pose)
{
  RCLCPP_INFO(this->get_logger(), "Setting goal to a custom pose");
  return this->move_group_.setPoseTarget(_target_pose);
}

bool MoveIt2Handler::set_named_target_goal(const std::string &_named_target)
{
  RCLCPP_INFO(this->get_logger(), ("Setting goal to named target \\"" + _named_target + "\\"").c_str());
  return this->move_group_.setNamedTarget(_named_target);
}

bool MoveIt2Handler::plan_trajectory()
{
  moveit::planning_interface::MoveGroupInterface::Plan plan;

  if (this->move_group_.plan(plan) == moveit::planning_interface::MoveItErrorCode::SUCCESS)
  {
    RCLCPP_INFO(this->get_logger(), "Planning successful");
    trajectory_publisher_->publish(plan.trajectory_.joint_trajectory);
    return true;
  }
  else
  {
    RCLCPP_WARN(this->get_logger(), "Planning failed");
    return false;
  }
}

//
/// Node - IgnitionMoveIt2 ///
//

class IgnitionMoveIt2 : public rclcpp::Node
{
public:
  /// Constructor
  IgnitionMoveIt2(std::shared_ptr<MoveIt2Handler> &moveit2_handler_);

private:
  /// Pointer to a node handling the interfacing with MoveIt2
  std::shared_ptr<MoveIt2Handler> moveit2_handler_;

  void run_example();
};

IgnitionMoveIt2::IgnitionMoveIt2(std::shared_ptr<MoveIt2Handler> &_moveit2_handler) : Node(NODE_NAME),
                                                                                      moveit2_handler_(_moveit2_handler)
{
  RCLCPP_INFO(this->get_logger(), "Node initialised successfuly");

  // Example
  this->run_example();
}

void IgnitionMoveIt2::run_example()
{
  auto target_joints = this->moveit2_handler_->move_group_.getCurrentJointValues();
  target_joints[0] = 1.5707963;
  target_joints[1] = -0.78539816;
  target_joints[2] = 1.5707963;
  target_joints[3] = 0.78539816;
  target_joints[4] = -1.5707963;
  target_joints[5] = 1.5707963;
  target_joints[6] = 0.78539816;
  this->moveit2_handler_->set_joint_goal(target_joints);
  RCLCPP_INFO(this->get_logger(), "Moving to joint goal");
  this->moveit2_handler_->plan_trajectory();

  // Wait until finished
  rclcpp::sleep_for(5s);

  auto target_pose = this->moveit2_handler_->move_group_.getCurrentPose();
  target_pose.pose.position.x = 0.5;
  target_pose.pose.position.y = 0.25;
  target_pose.pose.position.z = 0.75;
  target_pose.pose.orientation.x = 0.0;
  target_pose.pose.orientation.y = 0.0;
  target_pose.pose.orientation.z = 0.0;
  target_pose.pose.orientation.w = 1.0;
  this->moveit2_handler_->set_pose_goal(target_pose);
  RCLCPP_INFO(this->get_logger(), "Moving to pose goal");
  this->moveit2_handler_->plan_trajectory();
}


/// MAIN ///


/// Main function that initiates nodes of this process
/// Multi-threaded executor is utilised such that MoveIt2 thread is separated
int main(int argc, char *argv[])
{
  rclcpp::init(argc, argv);

  auto moveit2_handler = std::make_shared<MoveIt2Handler>();
  auto ign_moveit2 = std::make_shared<IgnitionMoveIt2>(moveit2_handler);

  rclcpp::executors::MultiThreadedExecutor executor;
  executor.add_node(moveit2_handler);
  executor.add_node(ign_moveit2);
  executor.spin();

  rclcpp::shutdown();
  return EXIT_SUCCESS;
}

扔个球的python示例:example_throw.py

#!/usr/bin/env python3

from geometry_msgs.msg import Pose
from moveit2 import MoveIt2Interface
from rclpy.node import Node
import rclpy
import time


class Thrower(Node):

    def __init__(self):
        super().__init__("thrower")
        # Create a subscriber for object pose
        self._object_pose_sub = self.create_subscription(Pose, '/model/throwing_object/pose',
                                                         self.object_pose_callback, 1)

        # Create MoveIt2 interface node
        self._moveit2 = MoveIt2Interface()

        # Create multi-threaded executor
        self._executor = rclpy.executors.MultiThreadedExecutor(2)
        self._executor.add_node(self)
        self._executor.add_node(self._moveit2)

        # Wait a couple of seconds until Ignition is ready and spin up the executor
        time.sleep(2)
        self._executor.spin()

    def object_pose_callback(self, pose_msg):
        self.throw(pose_msg.position)
        self.destroy_subscription(self._object_pose_sub)
        rclpy.shutdown()
        exit(0)

    def throw(self, object_position):
        # Open gripper
        self._moveit2.gripper_open()
        self._moveit2.wait_until_executed()

        # Move above object
        position = [object_position.x,
                    object_position.y, object_position.z + 0.1]
        quaternion = [1.0, 0.0, 0.0, 0.0]
        self._moveit2.set_pose_goal(position, quaternion)
        self._moveit2.plan_kinematic_path()
        self._moveit2.execute()
        self._moveit2.wait_until_executed()

        self._moveit2.set_max_velocity(0.5)
        self._moveit2.set_max_acceleration(0.5)

        # Move to grasp position
        position = [object_position.x,
                    object_position.y, object_position.z]
        quaternion = [1.0, 0.0, 0.0, 0.0]
        self._moveit2.set_pose_goal(position, quaternion)
        self._moveit2.plan_kinematic_path()
        self._moveit2.execute()
        self._moveit2.wait_until_executed()

        # Close gripper
        self._moveit2.gripper_close(width=0.05, speed=0.2, force=20.0)
        self._moveit2.wait_until_executed()

        # Move above object again
        position = [object_position.x,
                    object_position.y, object_position.z + 0.1]
        quaternion = [1.0, 0.0, 0.0, 0.0]
        self._moveit2.set_pose_goal(position, quaternion)
        self._moveit2.plan_kinematic_path()
        self._moveit2.execute()
        self._moveit2.wait_until_executed()

        # Move to pre-throw configuration
        joint_positions = [0.0,
                           -1.75,
                           0.0,
                           -0.1,
                           0.0,
                           3.6,
                           0.8]
        self._moveit2.set_joint_goal(joint_positions)
        self._moveit2.plan_kinematic_path()
        self._moveit2.execute()
        self._moveit2.wait_until_executed()

        # Throw
        self._moveit2.set_max_velocity(1.0)
        self._moveit2.set_max_acceleration(1.0)

        # Arm trajectory
        joint_positions = [0.0,
                           1.0,
                           0.0,
                           -1.1,
                           0.0,
                           1.9,
                           0.8]
        self._moveit2.set_joint_goal(joint_positions)
        trajectory = self._moveit2.plan_kinematic_path(
        ).motion_plan_response.trajectory.joint_trajectory

        # Hand opening trajectory
        hand_trajectory = self._moveit2.gripper_plan_path(0.08, 0.2)

        # Merge hand opening into arm trajectory, such that it is timed for release (at 50%)
        release_index = round(0.5*len(trajectory.points))
        for finger_joint in hand_trajectory.joint_names:
            trajectory.joint_names.append(finger_joint)
        while len(trajectory.points[release_index].effort) < 9:
            trajectory.points[release_index].effort.append(0.0)
        for finger_index in range(2):
            trajectory.points[release_index].positions.append(
                hand_trajectory.points[-1].positions[finger_index])
            trajectory.points[release_index].velocities.append(
                hand_trajectory.points[-1].velocities[finger_index])
            trajectory.points[release_index].accelerations.append(
                hand_trajectory.points[-1].accelerations[finger_index])

        self._moveit2.execute(trajectory)
        self._moveit2.wait_until_executed()

        # Move to default position
        joint_positions = [0.0,
                           0.0,
                           0.0,
                           -1.57,
                           0.0,
                           1.57,
                           0.79]
        self._moveit2.set_joint_goal(joint_positions)
        self._moveit2.plan_kinematic_path()
        self._moveit2.execute()
        self._moveit2.wait_until_executed()


def main(args=None):
    rclpy.init(args=args)

    _thrower = Thrower()

    rclpy.shutdown()


if __name__ == "__main__":
    main()

launch文件示例:

"""Launch example (Python) of throwing an object"""

import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch_ros.actions import Node
from launch.substitutions import LaunchConfiguration
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource


def generate_launch_description():
    # Launch Arguments
    use_sim_time = LaunchConfiguration('use_sim_time', default=True)
    config_rviz2 = LaunchConfiguration('config_rviz2', default=os.path.join(get_package_share_directory('ign_moveit2'),
                                                                            'launch', 'rviz.rviz'))

    return LaunchDescription([
        # Launch Arguments
        DeclareLaunchArgument(
            'use_sim_time',
            default_value=use_sim_time,
            description="If true, use simulated clock"),
        DeclareLaunchArgument(
            'config_rviz2',
            default_value=config_rviz2,
            description="Path to config for RViz2"),

        # MoveIt2 move_group action server with necessary ROS2 <-> Ignition bridges
        IncludeLaunchDescription(
            PythonLaunchDescriptionSource(
                [os.path.join(get_package_share_directory('ign_moveit2'),
                              'launch', 'ign_moveit2.launch.py')]),
            launch_arguments=[('use_sim_time', use_sim_time),
                              ('config_rviz2', config_rviz2)]),

        # Launch world
        IncludeLaunchDescription(
            PythonLaunchDescriptionSource(
                [os.path.join(get_package_share_directory('ign_moveit2'),
                              'launch', 'examples', 'worlds', 'world_panda_throw.launch.py')]),
            launch_arguments=[('use_sim_time', use_sim_time)]),

        # Python example script (object throwing)
        Node(name='ign_moveit2_example_throw',
             package='ign_moveit2',
             executable='example_throw.py',
             output='screen',
             parameters=[{'use_sim_time': use_sim_time}])
    ])

 

以上是关于ign gazebo moveit2 示例 panda的主要内容,如果未能解决你的问题,请参考以下文章

ROS2极简总结-MoveIt2

ROS2机器人实验报告提示06➡抓阄⬅MoveIt2

ROS2机器人实验报告提示06➡抓阄⬅MoveIt2

尝试对MoveIt2的轨迹进行插值控制舵机机械手

ROS2 Humble路线图 MoveIt2 Nav2 - 机器翻译

gazebo gazebo组成