From 3f53d6e66e5e0884ec846332dc2b9f47f1dcded0 Mon Sep 17 00:00:00 2001 From: holzheim <jan.holzheim@online.de> Date: Wed, 7 Jun 2023 08:25:20 +0200 Subject: [PATCH] Updated Arm Manipulator pick and place task --- 00_GettingStarted/docker/i2r/Dockerfile | 10 + .../docker/i2r/catkin_ws/src/image.png | Bin 0 -> 26267 bytes .../i2r/catkin_ws/src/task_2/CMakeLists.txt | 211 ++++++++++++++++++ .../i2r/catkin_ws/src/task_2/package.xml | 80 +++++++ .../catkin_ws/src/task_2/scripts/move_arm.py | 111 +++++++++ .../src/task_2/scripts/pick_excercise_v1.py | 197 ++++++++++++++++ .../src/task_2/scripts/place_excercise_v1.py | 103 +++++++++ .../docker/i2r/docker-compose.yml | 3 + 8 files changed, 715 insertions(+) create mode 100644 00_GettingStarted/docker/i2r/catkin_ws/src/image.png create mode 100644 00_GettingStarted/docker/i2r/catkin_ws/src/task_2/CMakeLists.txt create mode 100644 00_GettingStarted/docker/i2r/catkin_ws/src/task_2/package.xml create mode 100755 00_GettingStarted/docker/i2r/catkin_ws/src/task_2/scripts/move_arm.py create mode 100755 00_GettingStarted/docker/i2r/catkin_ws/src/task_2/scripts/pick_excercise_v1.py create mode 100755 00_GettingStarted/docker/i2r/catkin_ws/src/task_2/scripts/place_excercise_v1.py diff --git a/00_GettingStarted/docker/i2r/Dockerfile b/00_GettingStarted/docker/i2r/Dockerfile index 98c2b28..78e359b 100644 --- a/00_GettingStarted/docker/i2r/Dockerfile +++ b/00_GettingStarted/docker/i2r/Dockerfile @@ -11,3 +11,13 @@ RUN apt-get update && apt-get install -y \ python3-catkin-tools \ && rm -rf /var/lib/apt/lists/* +RUN rosdep update +RUN apt-get update && apt-get dist-upgrade -y \ +&& apt install -y ros-melodic-moveit \ +&& rm -rf /var/lib/apt/lists/* + +RUN cd ~/catkin_ws/src + +RUN cd ~/catkin_ws \ +&& catkin config --extend /opt/ros/${ROS_DISTRO} --cmake-args -DCMAKE_BUILD_TYPE=Release \ + diff --git a/00_GettingStarted/docker/i2r/catkin_ws/src/image.png b/00_GettingStarted/docker/i2r/catkin_ws/src/image.png new file mode 100644 index 0000000000000000000000000000000000000000..f7fb6d2bcddc62cd2dc205b748ace813060b5c60 GIT binary patch literal 26267 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 literal 0 HcmV?d00001 diff --git a/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/CMakeLists.txt b/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/CMakeLists.txt new file mode 100644 index 0000000..4abca43 --- /dev/null +++ b/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/CMakeLists.txt @@ -0,0 +1,211 @@ +cmake_minimum_required(VERSION 3.0.2) +project(task_2) + +## Compile as C++11, supported in ROS Kinetic and newer +# add_compile_options(-std=c++11) + +## Find catkin macros and libraries +## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) +## is used, also find other catkin packages +find_package(catkin REQUIRED COMPONENTS + geometry_msgs + geometry_msgs + moveit_commander + moveit_msgs + rospy + tf + tf2_ros + trajectory_msgs +) + +## System dependencies are found with CMake's conventions +# find_package(Boost REQUIRED COMPONENTS system) + + +## Uncomment this if the package has a setup.py. This macro ensures +## modules and global scripts declared therein get installed +## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html +# catkin_python_setup() + +################################################ +## Declare ROS messages, services and actions ## +################################################ + +## To declare and build messages, services or actions from within this +## package, follow these steps: +## * Let MSG_DEP_SET be the set of packages whose message types you use in +## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). +## * In the file package.xml: +## * add a build_depend tag for "message_generation" +## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET +## * If MSG_DEP_SET isn't empty the following dependency has been pulled in +## but can be declared for certainty nonetheless: +## * add a exec_depend tag for "message_runtime" +## * In this file (CMakeLists.txt): +## * add "message_generation" and every package in MSG_DEP_SET to +## find_package(catkin REQUIRED COMPONENTS ...) +## * add "message_runtime" and every package in MSG_DEP_SET to +## catkin_package(CATKIN_DEPENDS ...) +## * uncomment the add_*_files sections below as needed +## and list every .msg/.srv/.action file to be processed +## * uncomment the generate_messages entry below +## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) + +## Generate messages in the 'msg' folder +# add_message_files( +# FILES +# Message1.msg +# Message2.msg +# ) + +## Generate services in the 'srv' folder +# add_service_files( +# FILES +# Service1.srv +# Service2.srv +# ) + +## Generate actions in the 'action' folder +# add_action_files( +# FILES +# Action1.action +# Action2.action +# ) + +## Generate added messages and services with any dependencies listed here +# generate_messages( +# DEPENDENCIES +# geometry_msgs# geometry_msgs# moveit_msgs# trajectory_msgs +# ) + +################################################ +## Declare ROS dynamic reconfigure parameters ## +################################################ + +## To declare and build dynamic reconfigure parameters within this +## package, follow these steps: +## * In the file package.xml: +## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" +## * In this file (CMakeLists.txt): +## * add "dynamic_reconfigure" to +## find_package(catkin REQUIRED COMPONENTS ...) +## * uncomment the "generate_dynamic_reconfigure_options" section below +## and list every .cfg file to be processed + +## Generate dynamic reconfigure parameters in the 'cfg' folder +# generate_dynamic_reconfigure_options( +# cfg/DynReconf1.cfg +# cfg/DynReconf2.cfg +# ) + +################################### +## catkin specific configuration ## +################################### +## The catkin_package macro generates cmake config files for your package +## Declare things to be passed to dependent projects +## INCLUDE_DIRS: uncomment this if your package contains header files +## LIBRARIES: libraries you create in this project that dependent projects also need +## CATKIN_DEPENDS: catkin_packages dependent projects also need +## DEPENDS: system dependencies of this project that dependent projects also need +catkin_package( +# INCLUDE_DIRS include + LIBRARIES test_sripts_v2 + CATKIN_DEPENDS geometry_msgs geometry_msgs moveit_commander moveit_msgs rospy tf trajectory_msgs tf2_ros +# DEPENDS system_lib +) + +########### +## Build ## +########### + +## Specify additional locations of header files +## Your package locations should be listed before other locations +include_directories( +# include + ${catkin_INCLUDE_DIRS} +) + +## Declare a C++ library +# add_library(${PROJECT_NAME} +# src/${PROJECT_NAME}/test_sripts_v2.cpp +# ) + +## Add cmake target dependencies of the library +## as an example, code may need to be generated before libraries +## either from message generation or dynamic reconfigure +# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + +## Declare a C++ executable +## With catkin_make all packages are built within a single CMake context +## The recommended prefix ensures that target names across packages don't collide +# add_executable(${PROJECT_NAME}_node src/test_sripts_v2_node.cpp) + +## Rename C++ executable without prefix +## The above recommended prefix causes long target names, the following renames the +## target back to the shorter version for ease of user use +## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" +# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") + +## Add cmake target dependencies of the executable +## same as for the library above +# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + +## Specify libraries to link a library or executable target against +# target_link_libraries(${PROJECT_NAME}_node +# ${catkin_LIBRARIES} +# ) + +############# +## Install ## +############# + +# all install targets should use catkin DESTINATION variables +# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html + +# Mark executable scripts (Python etc.) for installation +# in contrast to setup.py, you can choose the destination +catkin_install_python(PROGRAMS + scripts/move_arm.py scripts/pick_excercise_v1.py scripts/place_excercise_v1.py + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +) + +## Mark executables for installation +## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html +# install(TARGETS ${PROJECT_NAME}_node +# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark libraries for installation +## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html +# install(TARGETS ${PROJECT_NAME} +# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} +# ) + +## Mark cpp header files for installation +# install(DIRECTORY include/${PROJECT_NAME}/ +# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} +# FILES_MATCHING PATTERN "*.h" +# PATTERN ".svn" EXCLUDE +# ) + +## Mark other files for installation (e.g. launch and bag files, etc.) +# install(FILES +# # myfile1 +# # myfile2 +# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +# ) + +############# +## Testing ## +############# + +## Add gtest based cpp test target and link libraries +# catkin_add_gtest(${PROJECT_NAME}-test test/test_test_sripts_v2.cpp) +# if(TARGET ${PROJECT_NAME}-test) +# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) +# endif() + +## Add folders to be run by python nosetests +# catkin_add_nosetests(test) diff --git a/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/package.xml b/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/package.xml new file mode 100644 index 0000000..dec39ce --- /dev/null +++ b/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/package.xml @@ -0,0 +1,80 @@ +<?xml version="1.0"?> +<package format="2"> + <name>task_2</name> + <version>0.0.0</version> + <description>The task_2 package</description> + + <!-- One maintainer tag required, multiple allowed, one person per tag --> + <!-- Example: --> + <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> --> + <maintainer email="robotics@todo.todo">robotics</maintainer> + + + <!-- One license tag required, multiple allowed, one license per tag --> + <!-- Commonly used license strings: --> + <!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 --> + <license>TODO</license> + + + <!-- Url tags are optional, but multiple are allowed, one per tag --> + <!-- Optional attribute type can be: website, bugtracker, or repository --> + <!-- Example: --> + <!-- <url type="website">http://wiki.ros.org/test_sripts_v2</url> --> + + + <!-- Author tags are optional, multiple are allowed, one per tag --> + <!-- Authors do not have to be maintainers, but could be --> + <!-- Example: --> + <!-- <author email="jane.doe@example.com">Jane Doe</author> --> + + + <!-- The *depend tags are used to specify dependencies --> + <!-- Dependencies can be catkin packages or system dependencies --> + <!-- Examples: --> + <!-- Use depend as a shortcut for packages that are both build and exec dependencies --> + <!-- <depend>roscpp</depend> --> + <!-- Note that this is equivalent to the following: --> + <!-- <build_depend>roscpp</build_depend> --> + <!-- <exec_depend>roscpp</exec_depend> --> + <!-- Use build_depend for packages you need at compile time: --> + <!-- <build_depend>message_generation</build_depend> --> + <!-- Use build_export_depend for packages you need in order to build against this package: --> + <!-- <build_export_depend>message_generation</build_export_depend> --> + <!-- Use buildtool_depend for build tool packages: --> + <!-- <buildtool_depend>catkin</buildtool_depend> --> + <!-- Use exec_depend for packages you need at runtime: --> + <!-- <exec_depend>message_runtime</exec_depend> --> + <!-- Use test_depend for packages you need only for testing: --> + <!-- <test_depend>gtest</test_depend> --> + <!-- Use doc_depend for packages you need only for building documentation: --> + <!-- <doc_depend>doxygen</doc_depend> --> + <buildtool_depend>catkin</buildtool_depend> + <build_depend>geometry_msgs</build_depend> + <build_depend>moveit_commander</build_depend> + <build_depend>moveit_msgs</build_depend> + <build_depend>rospy</build_depend> + <build_depend>tf</build_depend> + <build_depend>tf2_ros</build_depend> + <build_depend>trajectory_msgs</build_depend> + <build_export_depend>geometry_msgs</build_export_depend> + <build_export_depend>moveit_commander</build_export_depend> + <build_export_depend>moveit_msgs</build_export_depend> + <build_export_depend>rospy</build_export_depend> + <build_export_depend>tf</build_export_depend> + <build_export_depend>tf2_ros</build_export_depend> + <build_export_depend>trajectory_msgs</build_export_depend> + <exec_depend>geometry_msgs</exec_depend> + <exec_depend>moveit_commander</exec_depend> + <exec_depend>moveit_msgs</exec_depend> + <exec_depend>rospy</exec_depend> + <exec_depend>tf</exec_depend> + <exec_depend>tf2_ros</exec_depend> + <exec_depend>trajectory_msgs</exec_depend> + + + <!-- The export tag contains other, unspecified, tags --> + <export> + <!-- Other tools can request additional information be placed here --> + + </export> +</package> diff --git a/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/scripts/move_arm.py b/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/scripts/move_arm.py new file mode 100755 index 0000000..b2ba64d --- /dev/null +++ b/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/scripts/move_arm.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python + +#### Task 2 + +#### Imports +import sys +import rospy +import math +from moveit_commander import RobotCommander, MoveGroupCommander +from moveit_commander import PlanningSceneInterface, roscpp_initialize, roscpp_shutdown +from geometry_msgs.msg import PoseStamped, Pose +import moveit_msgs.msg +from moveit_msgs.msg import Grasp, GripperTranslation, PlaceLocation +from trajectory_msgs.msg import JointTrajectoryPoint +import geometry_msgs.msg +from tf import transformations +from copy import deepcopy + +#### Initialise a robotics node +roscpp_initialize(sys.argv) +rospy.init_node('picknplace_node', anonymous=True) +print('Pick n Place Node initialised') + +#### MoveIt APIs initialising +scene = PlanningSceneInterface() +robot = RobotCommander() +group_name="panda_arm" +move_group = MoveGroupCommander(group_name) + +#### Details +group_names = robot.get_group_names() +print('Robot groups available:',group_names) +planning_frame = move_group.get_planning_frame() +print('Reference frame:',planning_frame) +eef_link = move_group.get_end_effector_link() +print('End effector link:',planning_frame) +print('Robot current state:',robot.get_current_state()) + +#### Publisher for publishing the trajectories +display_trajectory_publisher = rospy.Publisher("/move_group/display_planned_path", moveit_msgs.msg.DisplayTrajectory, queue_size=20) + +#### Adding objects into the scene +## Q: Add the following set of objects with as per the specifications given + +table_id = 'table' +target_id = 'target' + +table_ground = 0.65 +table_size = [0.2, 0.7, 0.1] +target_size = [0.2, 0.1, 0.2] + +table_pose = PoseStamped() +table_pose.header.frame_id = planning_frame +table_pose.pose.position.x = 0.55 +table_pose.pose.position.y = 0.0 +table_pose.pose.position.z = table_ground + table_size[2] / 2.0 +table_pose.pose.orientation.w = 1.0 +scene.add_box(table_id, table_pose, table_size) + +target_pose = PoseStamped() +target_pose.header.frame_id = planning_frame +target_pose.pose.position.x = 0.55 +target_pose.pose.position.y = -0.1 +target_pose.pose.position.z = table_ground + table_size[2] + target_size[2] / 2.0 +target_pose.pose.orientation.w = 1.0 +scene.add_box(target_id, target_pose, target_size) + +#### Specifying and executing a goal in joint states +tau = 2*math.pi +joint_goal = move_group.get_current_joint_values() +joint_goal[0] = 0 +joint_goal[1] = -tau / 8 +joint_goal[2] = 0 +joint_goal[3] = -tau / 4 +joint_goal[4] = 0 +joint_goal[5] = tau / 6 # 1/6 of a turn +joint_goal[6] = 0 + +move_group.go(joint_goal, wait=True) +move_group.stop() + +#### Move the robotics arm towards a pre-defined end effector pose +## Q: Move the end-effector to the predefined locaiton with value (x,y,z)=[.4,.1,.4] & w=[1] +## Hint: A) Set pose_goal using an instace of geometry_msgs.msg.Pose() B) Use function move_group.set_pose_target(); C)Execute the pose goal using function move_group.go() +pose_goal = geometry_msgs.msg.Pose() +pose_goal.orientation.w = 1.0 +pose_goal.position.x = 0.4 +pose_goal.position.y = 0.1 +pose_goal.position.z = 0.4 + +move_group.set_pose_target(pose_goal) +move_group.go(wait=True) + +#### For stopping and clearing pose targets +move_group.stop() +move_group.clear_pose_targets() + + + + +#### Set the support surface name to the table object +move_group.set_support_surface_name(table_id) + + + + + + + + + diff --git a/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/scripts/pick_excercise_v1.py b/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/scripts/pick_excercise_v1.py new file mode 100755 index 0000000..d0c3c24 --- /dev/null +++ b/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/scripts/pick_excercise_v1.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python + +#### Task 2 + +#### Imports +import sys +import rospy +import math +from moveit_commander import RobotCommander, MoveGroupCommander +from moveit_commander import PlanningSceneInterface, roscpp_initialize, roscpp_shutdown +from geometry_msgs.msg import PoseStamped, Pose +import moveit_msgs.msg +from moveit_msgs.msg import Grasp, GripperTranslation, PlaceLocation +from trajectory_msgs.msg import JointTrajectoryPoint +import geometry_msgs.msg +from tf import transformations +from copy import deepcopy +import tf2_ros +import tf +import math + +#### Initialise a robotics node +roscpp_initialize(sys.argv) +rospy.init_node('picknplace_node', anonymous=True) +print('Pick n Place Node initialised') + +#### MoveIt APIs initialising +scene = PlanningSceneInterface() +robot = RobotCommander() +group_name="panda_arm" +move_group = MoveGroupCommander(group_name) +move_group_gripper = MoveGroupCommander("panda_hand") + +#### Open and close gripper +move_group_gripper.set_named_target("close") +move_group_gripper.go() +move_group_gripper.set_named_target("open") +move_group_gripper.go() +rospy.sleep(5) + + +#### Details +group_names = robot.get_group_names() +print('Robot groups available:',group_names) +planning_frame = move_group.get_planning_frame() +print('Reference frame:',planning_frame) +eef_link = move_group.get_end_effector_link() +print('End effector link:',planning_frame) +print('Robot current state:',robot.get_current_state()) +rospy.sleep(2) + +#### Publisher for publishing the trajectories +display_trajectory_publisher = rospy.Publisher("/move_group/display_planned_path", moveit_msgs.msg.DisplayTrajectory, queue_size=20) +rospy.sleep(2) +print("Publisher for publishing trajectories created") +#### Remove any pending objects +scene.remove_world_object("table1") +scene.remove_world_object("table2") +scene.remove_world_object("object1") +rospy.sleep(5) + +print("Removed any pending objects") + + +table_id = 'table' +box1_id = 'box1' +box2_id = 'box2' +target_id = 'target' +tool_id = 'tool' + +table_ground = 0.65 +table_size = [0.2, 0.7, 0.01] +box1_size = [0.1, 0.05, 0.05] +box2_size = [0.05, 0.05, 0.15] +target_size = [0.02, 0.01, 0.12] + + +#### Placing objects +def create_objects(): + ''' + table1 = PoseStamped() + table1.header.frame_id = planning_frame + table1.pose.position.x = 0.5 + table1.pose.position.y = 0.0 + table1.pose.position.z = 0.2 + scene.add_box("table1", table1, (0.2, 0.4, 0.4)) + + table2 = PoseStamped() + table2.header.frame_id = planning_frame + table2.pose.position.x = 0.0 + table2.pose.position.y = 0.5 + table2.pose.position.z = 0.2 + scene.add_box("table2", table2, (0.4, 0.2, 0.4)) + ''' + + table_pose = PoseStamped() + table_pose.header.frame_id = planning_frame + table_pose.pose.position.x = 0.55 + table_pose.pose.position.y = 0.1 + table_pose.pose.position.z = ( table_ground + table_size[2] / 2.0) -0.27 + table_pose.pose.orientation.w = 1.0 + scene.add_box(table_id, table_pose, table_size) + + box1_pose = PoseStamped() + box1_pose.header.frame_id = planning_frame + box1_pose.pose.position.x = 0.55 + box1_pose.pose.position.y = -0.13 + box1_pose.pose.position.z =( table_ground + table_size[2] + box1_size[2] / 2.0) -0.27 + box1_pose.pose.orientation.w = 1.0 + scene.add_box(box1_id, box1_pose, box1_size) + + box2_pose = PoseStamped() + box2_pose.header.frame_id = planning_frame + box2_pose.pose.position.x = 0.54 + box2_pose.pose.position.y = 0.33 + box2_pose.pose.position.z = (table_ground + table_size[2] + box2_size[2] / 2.0) -0.27 + box2_pose.pose.orientation.w = 1.0 + scene.add_box(box2_id, box2_pose, box2_size) + + object1 = PoseStamped() + object1.header.frame_id = planning_frame + object1.pose.position.x = 0.5 + object1.pose.position.y = 0.0 + object1.pose.position.z = 0.5 + scene.add_box("object1", object1, (0.02, 0.02, 0.2)) + + move_group.set_support_surface_name("table1") + + +create_objects() +rospy.sleep(5) + +print("Created objects") + +#### Defining a grasp +grasps=[] +g = Grasp() +g.id = "test" +grasp_pose = PoseStamped() +grasp_pose.header.frame_id = planning_frame +grasp_pose.pose.position.x = 0.55 +grasp_pose.pose.position.y = 0.0 +grasp_pose.pose.position.z = 0.5 +tau=math.pi*2 +quaternion = tf.transformations.quaternion_from_euler(-tau / 4, -tau / 8, -tau / 4) +grasp_pose.pose.orientation.x=quaternion[0] +grasp_pose.pose.orientation.y=quaternion[1] +grasp_pose.pose.orientation.z=quaternion[2] +grasp_pose.pose.orientation.w=quaternion[3] +g.grasp_pose = grasp_pose + +#### Checking grasp pose +#move_group.set_pose_target(grasp_pose) +#move_group.go() + +#### Pre-grasp approach +g.pre_grasp_approach.direction.header.frame_id = planning_frame +g.pre_grasp_approach.direction.vector.x = 1.0 +g.pre_grasp_approach.min_distance = 0.095 +g.pre_grasp_approach.desired_distance = 0.115 + + +#### set the pre-grasp posture +g.pre_grasp_posture.header.frame_id = planning_frame +g.pre_grasp_posture.joint_names = ["panda_finger_joint1","panda_finger_joint2"] + +pos_open = JointTrajectoryPoint() +pos_open.positions.append(float(0.04)) +g.pre_grasp_posture.points.append(pos_open) +#g.pre_grasp_posture.points.append(pos_open) + +#### set the post-grasp retreat +g.post_grasp_retreat.direction.header.frame_id = planning_frame +g.post_grasp_retreat.direction.vector.z = 1.0 +g.post_grasp_retreat.min_distance = 0.1 +g.post_grasp_retreat.desired_distance = 0.25 + +#### set the grasp posture +g.grasp_posture.header.frame_id = planning_frame +g.grasp_posture.joint_names = ["panda_finger_joint1","panda_finger_joint2"] + +pos_close = JointTrajectoryPoint() +pos_close.positions.append(float(0.00)) +g.grasp_posture.points.append(pos_close) +#g.grasp_posture.points.append(pos_close) + +#### Other grasp setings +g.allowed_touch_objects = ["object1"] + +#### Grasping +grasps.append(g) +move_group.pick("object1", grasps) + + + + + diff --git a/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/scripts/place_excercise_v1.py b/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/scripts/place_excercise_v1.py new file mode 100755 index 0000000..6e8065b --- /dev/null +++ b/00_GettingStarted/docker/i2r/catkin_ws/src/task_2/scripts/place_excercise_v1.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python + +#### Task 2 + +#### Imports +import sys +import rospy +import math +from moveit_commander import RobotCommander, MoveGroupCommander +from moveit_commander import PlanningSceneInterface, roscpp_initialize, roscpp_shutdown +from geometry_msgs.msg import PoseStamped, Pose +import moveit_msgs.msg +from moveit_msgs.msg import Grasp, GripperTranslation, PlaceLocation +from trajectory_msgs.msg import JointTrajectoryPoint +import geometry_msgs.msg +from tf import transformations +from copy import deepcopy +#from tf2_ros import Quaternion +import tf2_ros +import tf +import math + +tau=2*math.pi + +#### Initialise a robotics node +roscpp_initialize(sys.argv) +rospy.init_node('picknplace_node', anonymous=True) +print('Pick n Place Node initialised') + +#### MoveIt APIs initialising +scene = PlanningSceneInterface() +robot = RobotCommander() +group_name="panda_arm" +move_group = MoveGroupCommander(group_name) + + +#### Details +group_names = robot.get_group_names() +print('Robot groups available:',group_names) +planning_frame = move_group.get_planning_frame() +print('Reference frame:',planning_frame) +eef_link = move_group.get_end_effector_link() +print('End effector link:',planning_frame) +print('Robot current state:',robot.get_current_state()) +rospy.sleep(2) + +#### Remove any pending objects +scene.remove_world_object("table1") +scene.remove_world_object("table2") +rospy.sleep(5) + +#### Adding new object +table2 = PoseStamped() +table2.header.frame_id = planning_frame +table2.pose.position.x = 0.0 +table2.pose.position.y = -0.5 +table2.pose.position.z = 0.2 +scene.add_box("table2", table2, (0.4, 0.2, 0.4)) + + +#### Details +group_names = robot.get_group_names() +print('Robot groups available:',group_names) +planning_frame = move_group.get_planning_frame() +print('Reference frame:',planning_frame) +eef_link = move_group.get_end_effector_link() +print('End effector link:',planning_frame) +print('Robot current state:',robot.get_current_state()) +rospy.sleep(2) + +#### Placing pose definition +place_pose=PoseStamped() +place_pose.header.frame_id = planning_frame +quaternion = tf.transformations.quaternion_from_euler(0, 0, -tau / 4) +place_pose.pose.position.x = 0 +place_pose.pose.position.y = -0.5 +place_pose.pose.position.z = 0.5 +place_pose.pose.orientation.x=quaternion[0] +place_pose.pose.orientation.y=quaternion[1] +place_pose.pose.orientation.z=quaternion[2] +place_pose.pose.orientation.w=quaternion[3] + +#### Checking place pose +#move_group.set_pose_target(place_pose) +#move_group.go() + +place_location=PlaceLocation() +place_location.place_pose.header.frame_id = planning_frame +place_location.place_pose=place_pose + + +#### Pre-place approach +place_location.pre_place_approach.direction.header.frame_id = planning_frame +place_location.pre_place_approach.direction.vector.z = -1.0 +place_location.pre_place_approach.min_distance = 0.095 +place_location.pre_place_approach.desired_distance = 0.115 + + +#### Placing +move_group.set_support_surface_name("table2") +move_group.place("object1", place_location) + + diff --git a/00_GettingStarted/docker/i2r/docker-compose.yml b/00_GettingStarted/docker/i2r/docker-compose.yml index e90b35a..e22dd96 100644 --- a/00_GettingStarted/docker/i2r/docker-compose.yml +++ b/00_GettingStarted/docker/i2r/docker-compose.yml @@ -16,6 +16,9 @@ services: ports: - "8080:8080" environment: + # Adjust to your screen size + - DISPLAY_WIDTH=1800 + - DISPLAY_HEIGHT=1050 - RUN_XTERM=no volumes: -- GitLab