From edb57a895bc47313f1274ef6bf073a36462eefce Mon Sep 17 00:00:00 2001 From: Erdal Pekel <info@erdalpekel.de> Date: Tue, 12 Mar 2019 05:13:36 -0700 Subject: [PATCH] Added simple box publisher for Gazebo --- CMakeLists.txt | 4 ++- README.md | 4 +++ launch/box.launch | 9 ++++++ models/box.xacro | 40 ++++++++++++++++++++++++ src/box_publisher.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 launch/box.launch create mode 100644 models/box.xacro create mode 100644 src/box_publisher.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f59073..bc6fad6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,5 +57,7 @@ include_directories( ) add_executable(robot_control_node src/robot_control_node.cpp) +add_executable(box_publisher_node src/box_publisher.cpp) -target_link_libraries(robot_control_node ${catkin_LIBRARIES} boost_filesystem ${JSONCPP_LIBRARIES}) \ No newline at end of file +target_link_libraries(robot_control_node ${catkin_LIBRARIES} boost_filesystem ${JSONCPP_LIBRARIES}) +target_link_libraries(box_publisher_node ${catkin_LIBRARIES}) \ No newline at end of file diff --git a/README.md b/README.md index 0aaa6a3..fea7f65 100644 --- a/README.md +++ b/README.md @@ -29,3 +29,7 @@ You can see the full explanation in my [blog post](https://erdalpekel.de/?p=55). ## Extension: _MoveIt!_ constraint-aware planning This repository was extended with a ROS node that communicates with the _MoveIt!_ Planning Scene API. It makes sure that the motion planning pipeline avoids collision objects in the environment specified by the user in a separate directory (`~/.panda_simulation`) as _JSON_ files. You can read more about it in the accompanying [blog post](https://erdalpekel.de/?p=123). + +## Extension: Publishing a box at Panda's hand in _Gazebo_ + +This repository was extended with a node that publishes a simple box object in the _Gazebo_ simulation at the hand of the robot. The position of this box will get updated as soon as the robot moves. You can read more about it in the accompanying [blog post](https://erdalpekel.de/?p=178). \ No newline at end of file diff --git a/launch/box.launch b/launch/box.launch new file mode 100644 index 0000000..5e57917 --- /dev/null +++ b/launch/box.launch @@ -0,0 +1,9 @@ +<launch> + <param name="box_description" command="$(find xacro)/xacro --inorder $(find panda_simulation)/models/box.xacro"/> + <node name="box_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" args="robot_description:=box_description" /> + <node name="spawn_object" pkg="gazebo_ros" type="spawn_model" args="-param box_description -urdf -model box"/> + + + <!-- launch node --> + <node pkg="panda_simulation" type="box_publisher_node" name="box_publisher_node" /> +</launch> \ No newline at end of file diff --git a/models/box.xacro b/models/box.xacro new file mode 100644 index 0000000..4cfb076 --- /dev/null +++ b/models/box.xacro @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="simple_box"> + <link name="object_base_link"> + </link> + + <joint name="object_base_joint" type="fixed"> + <parent link="object_base_link"/> + <child link="object_link"/> + <axis xyz="0 0 1" /> + <origin xyz="0 0 0" rpy="0 0 0"/> + </joint> + + <link name="object_link"> + <inertial> + <origin xyz="0 0 0" /> + <mass value="1.0" /> + <inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="100.0" iyz="0.0" izz="1.0" /> + </inertial> + <visual> + <origin xyz="0 0 0"/> + <geometry> + <box size="0.04 0.04 0.08" /> + </geometry> + </visual> + <collision> + <origin xyz="0 0 0"/> + <geometry> + <box size="0.04 0.04 0.08" /> + </geometry> + </collision> + </link> + + <gazebo reference="object_base_link"> + <gravity>0</gravity> + </gazebo> + + <gazebo reference="object_link"> + <material>Gazebo/Blue</material> + </gazebo> +</robot> \ No newline at end of file diff --git a/src/box_publisher.cpp b/src/box_publisher.cpp new file mode 100644 index 0000000..339f3f2 --- /dev/null +++ b/src/box_publisher.cpp @@ -0,0 +1,71 @@ +#include <gazebo_msgs/SetModelState.h> +#include <moveit/move_group_interface/move_group_interface.h> +#include <moveit/robot_model_loader/robot_model_loader.h> +#include <ros/ros.h> +#include <sensor_msgs/JointState.h> + +static const std::string PLANNING_GROUP_ARM = "panda_arm"; +static const double PANDA_ARM_TO_HAND_OFFSET = 0.12; +static const double PANDA_HAND_TO_FINGER_OFFSET = 0.04; +ros::Publisher gazebo_model_state_pub; +robot_model::RobotModelPtr kinematic_model; +robot_state::RobotStatePtr kinematic_state; + +void jointStatesCallback(const sensor_msgs::JointState &joint_states_current) +{ + const robot_state::JointModelGroup *joint_model_group = kinematic_model->getJointModelGroup("panda_arm"); + const std::vector<std::string> &joint_names = joint_model_group->getJointModelNames(); + + std::vector<double> joint_states; + for (size_t i = 0; i < joint_states_current.position.size() - 2; ++i) + { + joint_states.push_back(joint_states_current.position[i + 2]); + } + kinematic_state->setJointGroupPositions(joint_model_group, joint_states); + + const Eigen::Affine3d &end_effector_state = kinematic_state->getGlobalLinkTransform("panda_link8"); + + double end_effector_z_offset = PANDA_ARM_TO_HAND_OFFSET + PANDA_HAND_TO_FINGER_OFFSET; + Eigen::Affine3d tmp_transform(Eigen::Translation3d(Eigen::Vector3d(0.0, 0.0, end_effector_z_offset))); + + Eigen::Affine3d newState = end_effector_state * tmp_transform; + + geometry_msgs::Pose pose; + pose.position.x = newState.translation().x(); + pose.position.y = newState.translation().y(); + pose.position.z = newState.translation().z(); + + Eigen::Quaterniond quat(newState.rotation()); + pose.orientation.w = quat.w(); + pose.orientation.x = quat.x(); + pose.orientation.y = quat.y(); + pose.orientation.z = quat.z(); + + ROS_DEBUG_STREAM("translation" << std::endl << newState.translation()); + ROS_DEBUG_STREAM("rotation" << std::endl << newState.rotation()); + + gazebo_msgs::ModelState model_state; + // This string results from the spawn_urdf call in the box.launch file argument: -model box + model_state.model_name = std::string("box"); + model_state.pose = pose; + model_state.reference_frame = std::string("world"); + + gazebo_model_state_pub.publish(model_state); +} + +int main(int argc, char **argv) +{ + ros::init(argc, argv, "box_publisher_node"); + ros::NodeHandle node_handle; + + ros::Subscriber joint_states_sub = node_handle.subscribe("/joint_states", 1, jointStatesCallback); + + robot_model_loader::RobotModelLoader robot_model_loader("robot_description"); + kinematic_model = robot_model_loader.getModel(); + kinematic_state = robot_state::RobotStatePtr(new robot_state::RobotState(kinematic_model)); + + gazebo_model_state_pub = node_handle.advertise<gazebo_msgs::ModelState>("/gazebo/set_model_state", 1); + + ros::spin(); + return 0; +} \ No newline at end of file -- GitLab