CHAPTER 15


An Object-Grabber Package


CONTENTS

15.1 Object-grabber code organization

15.2 Object manipulation query service

15.3 Generic gripper services

15.4 Object-grabber action server

15.5 Example object-grabber action client

15.6 Wrap-Up

INTRODUCTION

Control of robot arms for manipulation incorporates considerable detail. It is desirable to construct solutions that decompose the challenge into separate layers that can encapsulate detail and allow progressively more abstract interaction. ROS capabilities support logical decomposition through mechanisms of the parameter server, publish and subscribe communications between independent nodes, client–service interactions and action servers. Exploiting these capabilities for constructing a general-purpose manipulation system is described in this chapter.

15.1 Object-grabber code organization

 

Figure 15.1 shows a graphical interpretation of the code organization for the object-grabber development described here. At the top level, an object-grabber client interacts with the object-grabber action server. These nodes, which reside in the package objectgrabber, communicate via an action message objectgrabber.action, defined in the same package. At this level of abstraction, clients express goals in terms of a high-level action code, such as GRABOBJECT, together with an object identifier code and (stamped) pose of the object of interest. A grasp strategy can also be selected, if there are multiple known viable options to perform the grasp, or a default strategy can be assumed.

image

Figure 15.1 Code hierarchy for object-grabber system

From the viewpoint of the client, it is not necessary to know the type of robot to be used, how this robot is mounted (or its current pose in the world), nor what type of gripper is on the robot. Rather, the client can focus on relocating parts from initial poses to goal poses.

The node objectgrabberactionserver presents an action server named objectgrabberactionservice, which accepts goals via objectgrabber.action messages. This action server must be aware of some more of the specific detail involved in carrying out a manipulation goal request. Specifically, this action server must understand what interactions are required between the specific end-of-arm tooling (e.g. gripper) that is present on the robot and the specified object to be manipulated. For a given gripper and object, there must be one or more strategies for successful manipulation if the goal is to be achieved. How to identify an appropriate grasp strategy (given a specific object and a specific gripper) is a difficult problem in general and an ongoing area of research. However, in the code organization, this problem can be encapsulated by creating an object manipulation query service. The intent is: given an object ID and a gripper ID, reply with key gripper poses for object grasp or object placement. This presumed oracle for answering queries regarding object manipulation may be replaced with future, more sophisticated instantiations. A primitive example is provided here. Replacing this example with a more capable query service can be performed without disruption to the rest of the system, provided the same service message interface is used.

In performing object acquisition and placement, the objectgrabberactionserver must also have control over gripper actuation. A wide array of grippers is possible, e.g. a fingered hand, a parallel-jaw actuator, a vacuum gripper, or simple non-actuated tools such as a hook or spatula. For any given gripper type, the object-manipulation query service will have key poses to recommend, including a gripper-dependent pose suitable for initiating grasp. Generically, the object-grabber action server should interact with grippers by commanding whatever gripper action is suitable for grasp or release of an object of interest. A GRASP command may involve closing fingers (e.g. for the Baxter grippers), or enabling suction for a vacuum gripper, or doing nothing (for a hook or spatula). In each case, the gripper should perform the appropriate action. For this purpose, the object-grabber action server depends on a genericgrippersvc service. Service requests can be sent as defined action codes, such as GRASP or RELEASE. When launching nodes for a particular system, the appropriate gripper service should be started, where this service incorporates the specifics of how to drive the gripper used.

The object-grabber action server also interacts with (sends goals to) a Cartesian-motion action server. As described in Section 13.3, a Cartesian-motion action client can be robot agnostic. If the intent is to move a specific gripper in space, the action client can request motion planning and motion execution to achieved the desired gripper motion. The Cartesian-motion action server, however, needs to be aware of the arm being used, since this node will need to invoke inverse kinematics calls that are robot-specific. Although the Cartesian-move action server must be robot-aware, it can nonetheless present a generic interface using a common server name (cartMoveActionServer) and a common action message (objectgrabber.action).

To invoke planned trajectories, the Cartesian-planner action server bundles planned trajectories into messages of type trajectorymsgs/JointTrajectory and sends these to a lower-level interaction server to be executed. For the right arm of the Baxter robot, this can be either the provided roscontroller action service, robot/limb/right/followjointtrajectory or the simple, custom joint trajectory action server described herein, rtarmas (in the baxtertrajectorystreamer package). These action servers have direct control over the robot’s joint commands, and thus they are also specific to a robot design and its ROS interface.

The action servers cartMoveActionServer and below were introduced previously. Descriptions of the objectmanipquerysvc, genericgrippersvc, objectgrabberactionservice and an example object-grabber action client are offered in this chapter.

15.2 Object manipulation query service

 

The code objectmanipulationquerysvc.cpp in package objectmanipulationproperties offers a service, objectmanipquerysvc, that communicates via service message objectManipulationQuery.srv, defined in the same package. Use of this service is illustrated via an example client in the same package, exampleobjectmanipqueryclient.cpp. The intent of this service is to provide recommendations and options for how a specific gripper can acquire or place a specific object.

In this service, manipulation actions are abstracted in terms of key gripper poses associated with steps of acquiring and placing objects. Providing such advice can be quite complex, since there are myriad grasp options and strategies. For some simple robots, such as four-DOF SCARA 1 designs, manipulation is limited to approaching objects from above. If the gripper is a vacuum gripper, grasp options are constrained by supporting features on the object, e.g. horizontal, planar surfaces that are sufficiently wide, smooth and flat to provide a seal with a suction cup. Further, such features must be located close enough to the object’s center of mass that the part will not fall due to excessive moments about the vacuum gripper. As a result, the options for successful grasp in such cases may be quite limited, corresponding to an (xyz) location on the part’s surface relative to the part’s reference frame. To recommend this grasp strategy, the object-manipulation query service would respond to an inquiry (which specifies gripper ID and object ID) by specifying a (stamped) pose of the object’s frame relative to the gripper frame. (As noted earlier, the gripper frame may be referred to as genericgripperframe, provided a static transform publisher makes this frame known to tf).

In addition to specifying a relative grasp pose (object frame with respect to gripper frame), approach and depart strategies must also be specified. For the simple case of a vacuum gripper grasping from above, a typical strategy would be to move the gripper to a pose directly above the intended grasp pose; descend vertically to the desired grasp pose; enable the vacuum gripper to grasp the object; and depart from the work surface with a pure z translation upward. The strategy for grasping a part can thus be specified succinctly in terms of three key poses: the gripper pose (relative to the object frame) for approach, grasp, and depart. If Cartesian motions are executed from approach to grasp to depart, acquisition should be successful. The part would not be disturbed before grasp, and it would not be bumped out of grasp when the part is lifted. Similarly, for placement, three key gripper poses can be expressed, including the gripper pose required to achieve the desired part placement pose, and the corresponding approach and depart poses.

If multiple viable grasp sites are available, the object-manipulation query service should offer these as alternatives. A default (preferred) grasp option should be presented as the first option. But if this option is not possible (e.g. is out of reach of the robot or is occluded), alternative grasp options may be considered for successful manipulation.

For a six-DOF arm with a parallel-jaw gripper, more manipulation options are possible. For example, a cylinder sitting upright on a horizontal surface (e.g. a can or water bottle) could be grasped from above or from the side. If the intent is to pour from a bottle, grasp from the side would be preferred. If the object is a peg to be inserted in a hole, grasp from above may be necessary. Further, symmetry of the object in this case would leave a degree of freedom available for any one grasp strategy. For example, an upright cylinder could be approached sideways, with the gripper’s z axis pointing radially toward the object’s centerline. However, such radial approaches could be used at an arbitrary polar angle, providing a degree of freedom of approach and grasp options. Multiple options may need to be explored to find an approach that is kinematically reachable.

Even when the grasp pose is chosen, approach and depart poses have options. For example, an upright cylinder in a power grasp (with the gripper z axis horizontal) could be achieved by approaching the object along the gripper’s z axis (i.e. by sliding the gripper parallel to the table surface). Alternatively, the same grasp pose could be achieved by orienting the gripper in the grasp orientation, but starting from a position above the cylinder and descending in the -z direction. In either case, the desired strategy can be described in terms of 3 key poses: pose of the gripper frame relative to the object frame at the grasp pose, pose of the gripper frame relative to the object at the approach pose, and pose of the gripper frame relative to the (original pose of) the object for departure. Having established a grasp strategy, it is only necessary to specify these 3 key poses. (Note: in this implementation, key poses are expressed as pose of the object frame relative to the gripper frame).

Use of the object-manipulation query service requires reference to gripper ID and object ID. In the present implementation, these are specified in the objectmanipulationproperties package in the include sub-directory in files gripperIDcodes.h and objectIDcodes.h. The grippers and objects included are extremely sparse, at present, but these are placeholders for a future, more general knowledge database.

Use of the query service for grasping an object is illustrated in objectgrabber.cpp in the objectgrabber package. This code includes the function getdefaultgrabposes(), which is displayed in part in Listing 15.2.

image

This function populates a query message with a gripper ID code, an object ID code and the action code GRASPSTRATEGYOPTIONSQUERY. The client calls the query service with this request message and receives a reply. The function examines how many grasp strategies have been returned, and if there are no known grasp solutions, the function returns with failure. Otherwise, the function chooses the first available strategy, which (by design) is the default preferred grasp strategy.

The function getdefaultgrabposes() then specifies use of this grasp option in the service request and specifies the action code GETGRASPPOSETRANSFORMS. In the response, the field geometrymsgs/Pose[] gripperposeoptions will be populated with candidate grasp poses for the chosen grasp strategy. The first option in this function is selected by default. More generally, alternatives may be examined if the default pose is unreachable.

The getdefaultgrabposes() repeats this process twice more to obtain approach poses and depart poses for the default grasp strategy.

The object-manipulation query service returns poses corresponding to the object frame with respect to the (generic) gripper frame. These poses must be converted into desired gripper poses with respect to some reference frame (e.g. sensor frame, torso, world frame or generic systemrefframe). Lines of code from getdefaultgrabposes() that perform this transformation for the grasp transform are:

image

image

In this process, representations are converted to transform objects for use in performing transformations, with the help of utility functions in the XformUtils package. First, the object’s location in space is specified as a poseStamped. That is, a pose is expressed with respect to a named frameid, but the pose does not specify a child frame. To convert the poseStamped to a StampedTransform, a childframeid is named objectframe. Note that the parent frame in which the object pose is expressed is arbitrary. It could be a sensor frame, world frame, or any other relevant frame. It will be referred to here as objectparentframe.

The desired grasp pose, as recommended by the object-manipulation service, is provided merely as a geometrymsgs/Pose. This is converted to a StampedTransform by providing a parent frameid (genericgripperframe) and a childframeid (objectframe). The resulting transform of object frame with respect to the gripper frame is inverted to obtain the gripper frame with respect to the object frame. This inversion is post-multiplied times the StampedTransform object to obtain the StampedTransform corresponding to the genericgripperframe with respect to the objectparentframe. At this point, one of the key frames for object acquisition is known and expressed as a StampedTransform of the generic gripper frame with respect to some named frame (objectparentframe). Later, this will be transformed to express the corresponding tool-flange pose with respect to the robot’s base link, which will then be suitable for use of the inverse kinematics functions.

Corresponding transformations of the approach and depart poses are computed as well.

The function getdefaultdropoffposes() invokes the same process, yielding three key poses. However, these poses are specialized for part placement rather than part acquisition. They are transformed to express desired gripper poses with respect to a named frameid.

Having obtained the key poses, the remaining step is to compute trajectories that will achieve these poses in sequence, and these trajectories should be Cartesian motions from approach to grasp to depart poses.

It is anticipated that this simple example object-manipulation query service will be replaced in the future with increasingly competent nodes. Notably, this oracle should be able to grow its knowledge base by multiple means, including manually visualized and coded grasp options, computed grasp options, and grasps that are discovered by online robotic experimentation and learning. The present implementation is intended merely for illustrative purposes in a simple context. Nonetheless, this implementation is already suitable for a variety of relatively simple factory automation tasks.

15.3 Generic gripper services

 

It is intended that an object-grabber client be independent of any specific arm or gripper. Rather, its focus should be on the task level, specifying desired object motions. To carry out such requests, the object-grabber action server must be aware of how to control the actual gripper being used. To keep the object-grabber action server general, the system refers to generic grippers. A generic gripper interface was described in Section 14.3, specifically for the ReThink gripper on the right arm of the Baxter simulator. The node rethinkrtgripperservice.cpp in the package genericgripperservices provides a wrapper for this gripper. Requests to this service use a generic service message, defined in genericGripperInterface.srv. Generic command codes, such as GRASP, can be sent using this service message to a service named genericgrippersvc. Within the genericgripperservices package are multiple nodes that host a service by this name and use the genericGripperInterface service message. Only one of these should be launched for use with a given robot system and should correspond to the actual gripper in use. Although the various generic gripper services accept common commands, any specific gripper service node should map these commands onto the appropriate actuations for a specific gripper.

The node virtualvacuumgripperservice in the genericgripperservices package simulates a vacuum gripper. This service communicates with a custom Gazebo plug-in, called stickyfingers, that behaves like a vacuum gripper (but lacking in pneumatic or fluid-flow details). The sticky-fingers plug-in is defined in the stickyfingers package within the complementary repository learningrosexternalpackages. This package creates a library from source code stickyfingers.cpp, which compiles to libstickyfingers.so. This library is used as a Gazebo plug-in. An illustration is in ur10launch (a package within Part5 of the accompanying learningros repository), in the model file ur10onpedestalwstickyfingers.xacro. This model file appears in Listing 15.1.

image

Listing 15.1 ur10_on_pedestal_w_sticky_fingers.xacro

Within Listing 15.1, lines 6 and 7 import the UR10 model as installed from ROS (from package urdescription, referred to via included file ur10robot.urdf.xacro). Line 10 brings in a simple model of a pedestal. Lines 14 through 19 specify a joint to attach the UR10 model to the pedestal, and lines 22 through 27 attach the pedestal to the world frame.

Lines 30 through 49 describe a simple, cylindrical link that will emulate the body of the virtual vacuum gripper. Importantly, within the description of the collision model, a name is assigned to the collision model: vvgcollision. This link is attached to the tool flange of the robot with a link, specified in lines 52 through 56.

Lines 59 through 64 bring in the sticky-fingers plug-in within a Gazebo tag. The sticky-fingers library limits the load capacity of the virtual gripper to a value set (in this case) to 10 kg. The sticky-fingers plug-in behaves as follows. The stickiness of the vvg link is enabled or disabled via a call to the service /stickyfinger/wrist3link, which merely sets the status to true or false. When status is set to true, the plug-in consults Gazebo to determine whether there is contact between the vvgcollision boundary and some object in the environment with mass less than 10 kg (a value set in the capacity tag). If so, a new, temporary joint is created to attach the

identified object to a distal link of the robot model (the final wrist link). Thereafter, as the robot moves, it will also carry the contacted object and will experience the gravity, inertial and collision effects of carrying this object.

When the sticky-fingers status is set to false, the temporary link is removed. In this state, the virtual gripper will not attach to any objects and an object that was formerly held will be released.

Communication with the sticky-fingers state is via a corresponding service and service message defined within the stickyfingers package. The node virtualvacuumgripperservice abstracts use of the vacuum gripper by creating another service with the generic service name genericgrippersvc, which uses the generic service message genericGripperInterface.srv defined in the genericgripperservices package. By running the node virtualvacuumgripperservice, one can send generic commands such as GRASP and RELEASE using the generic service name and generic service message. As a result, an object-grabber action client can command grasp and release without needing to know what type of gripper is used.

Use of the virtual vacuum gripper also requires that the corresponding static transform publisher specify a generic gripper frame at the desired location—the face of the virtual vacuum gripper link. The virtual vacuum gripper will be illustrated in the context of the object-grabber action server–action client operation.

15.4 Object-grabber action server

 

The object-grabber action server (in package objectgrabber) accepts manipulation goals from an action client (without reference to any specific arm or gripper) and generates plans and commands to achieve the desired manipulation goals.

Performing a successful grasp requires several steps. For example, consider grasping an object on a table surface from above using a parallel-jaw gripper. One must command the chosen arm to open the gripper; move the arm sufficiently high above the table surface (without bumping the table); orient the gripper for a suitable approach pose; perform a Cartesian move to approach the object, resulting in gripper fingers surrounding the object; close the gripper fingers to an appropriate finger separation; and perform a Cartesian move to depart from the table top (ideally, normal to the table surface).

These steps are accomplished with the help of two services and an action server. The generic gripper service translates GRASP and RELEASE commands into corresponding actuation commands appropriate for the target gripper (e.g. fingers versus vacuum gripper). The object-manipulation query service provides recommendations for key gripper poses, given an object ID and a gripper ID. Cartesian moves among the key poses (approach, grasp, depart) achieve appropriate approach and departure, such that gripper components do not interfere with the object before grasp, and the grasped object does not interfere with the support surface as it is withdrawn.

The object-grabber action service does not receive a gripper ID from its client. Rather, this service must be aware of what type of gripper is on the arm being controlled. This is accomplished using the parameter server. When launching the object-grabber nodes, one of the nodes should perform the action of placing the gripper ID on the parameter server. For example, the node setbaxtergripperparam.cpp in the objectgrabber package contains:

image

Running this node results in setting the parameter gripperID to code RETHINKELECTRICGRIPPERRT (which is defined in the header file objectmanipulationproperties/gripperIDcodes.h).

Upon start-up, the object-grabber node consults the parameter server to obtain the gripper ID that is used subsequently in sending queries to the object-manipulation query service to obtain key gripper poses. Also on start-up, the object-grabber node establishes connections with a generic gripper service, an object-manipulation query service, and a Cartesian motion action server. While the object-grabber action server does need to be aware of the gripper to be used for manipulation, it does not need to be aware of the type of robot arm being used. Rather, goal gripper poses are specified to a Cartesian motion action server, and this server is responsible for computing and executing coordinated joint motions that achieve the desired gripper motions.

The object-grabber code is long, but it has a style that is largely repetitive. The executeCallback function parses the goal message to extract the action code within the goal message. It uses this action code in a switch–case statement to direct computation appropriately. For the code GRABOBJECT, the corresponding case is as follows:

image

The key line in this case is rtnval = grabobject(objectid,objectposestamped), which uses the objectid field of the goal message and the corresponding stamped pose within the goal message. These are used as arguments to the function grabobject().

The grabobject() function is presented below. This function first invokes getdefaultgrabposes(objectid,objectposestamped), from which three key gripper poses are obtained: approachpose, grasppose, and departpose. The gripper is put in a state appropriate for object approach with the lines:

image

In the case of a fingered gripper, the fingers are opened; for a vacuum gripper, the suction is disabled.

With assistance from the class ArmMotionCommander, which encapsulates some of the detail of communication with a Cartesian motion action server, an arm motion plan is computed for a joint-space motion from the current pose to the computed approach pose using:

image

The return value is inspected to see whether a motion plan was successfully computed. If so, the Cartesian motion action server is instructed to execute this motion plan through the function call:

image

image

A Cartesian motion plan to move the arm from the approach pose to the grasp pose is then computed via the function call:

image

This function sends a corresponding planner action code in a goal message to the Cartesian-motion action server. Due to separation of the object-grabber action server node from the motion planner–action server node, the object-grabber node can be robot-agnostic, whereas the motion planner must be customized for a specific robot design.

The grabobject() function proceeds with additional calls to invoke grasp, then plans and executes a departure trajectory with the grasped object.

15.5 Example object-grabber action client

 

The intent of the object-grabber action service is to allow higher-level code to focus on the task level, independently of robot or gripper specifics. An example of this approach is described here with an action client of the object-grabber action service.

The node exampleobjectgrabberactionclient contained in the objectgrabber package appears in Listings 15.2 through 15.4.

image

Listing 15.2 example_object_grabber_action_client.cpp: example use of object-grabber action server, preamble and functions

image

Listing 15.3 example_object_grabber_action_client.cpp: example use of object-grabber action server, manipulation functions

image

Listing 15.4 example_object_grabber_action_client.cpp: example use of object-grabber action server, main program

In this program, the function setexampleobjectframes(), lines 48 through 66, merely hard-code poses for pick-up and placement of an object. More generally, these poses would come from a database or a perceptual system.

The action client establishes connection with the objectgrabberactionservice (lines 111 through 121). This action client is made available to external functions through the global pointer gobjectgrabberacptr. The main program then uses the function movetowaitingpose() (defined in lines 68 through 74) to move the arm to a pre-defined pose above a presumptive table.

Next, the main program calls grabobject(objectpickupposeStamped), which is defined in lines 76 through 97. This function populates a goal message with an object ID, a pick-up pose, and a code to specify use of the default grasp strategy. When this goal is sent to the object-grabber service, the intended result is that the specified object is grasped by the robot’s gripper from the specified pick-up location.

After the object is grasped, the main program calls dropoffobject(objectdropoffposeStamped), which is defined in lines 89 through 99. This function populates and sends a goal to perform the complementary operation of placing the grasped object at a defined location.

All coordinates specified refer to the object’s frame, independent of any gripper or arm.

This example object-grabber action client can be run using different target robotic systems. It is only necessary that the named object actually be located at the prescribed pose. The action client is first illustrated with respect to the Baxter robot.

Figure 15.2 shows the frame named rightgripper, which is oriented with the z axis pointing out from the wrist and the y axis pointing from the right fingertip to the left fingertip. The origin is on the gripper-frame z axis, level with the tips of the fingers. Using the static-transform launch file baxterstatictransforms.launch, this frame is synonymous with a frame named genericgripperframe. Additionally, the torso frame used by Baxter’s kinematics library is defined to be related to the systemrefframe, which is located at the ground-plane level, 0.91 m directly beneath the torso frame.

image

Figure 15.2 Torso frame and right_gripper frame for Baxter

For an object of interest, we will again consider the toy block used in Section 8.5. To introduce the table and block within reach of Baxter, first start Baxter in an empty world with:

image

Next, add a table and a toy block by launching:

image

In launch operations, there is no guarantee on timing. Thus, it can happen that the block model is spawned into Gazebo before the table model is spawned. In this case, the block will fall to the floor. There are two ways to reset the block. Within the Gazebo window, from the top menu, use the edit item and select reset model poses. The block will be reset to its originally defined pose. From the Gazebo window, one can see the result by opening the models item, selecting the toy-block model, and clicking on its pose item. As shown in Fig 15.3, the block’s origin is at (x,y,z)=(0.5,-0.35,0.792) . Note that these are the coordinates hard-coded in the example object-grabber client code.

An alternative way to reset the block pose is:

image

This node includes code that interacts directly with Gazebo to set a named model to a specified pose (as introduced in Section 3.4).

image

Figure 15.3 Model coordinates obtained from Gazebo

After launching the Baxter simulator (or real robot), wait until the robot is ready to be enabled, then run:

image

This launch file starts 12 different nodes. Three of these nodes perform actions that run to completion and terminate. These nodes enable the robot’s actuators, set the gripper ID on the parameter server, and run a playfile to move the arms to a defined waiting pose.

This launch file also starts up rviz with reference to a saved configuration file. It also includes (and runs) a launch file that starts two static-transform publishers that define the frames genericgripperframe and systemrefframe.

Three services are started: a playfile service (which is not required for the object grabber, but can be useful); the object-manipulation properties service, and a generic gripper service that abstracts control of Baxter’s right gripper.

Finally, four action servers are started. Right and left arm joint trajectory action servers are started; they can receive trajectories as goals and execute them with fine interpolation. (Alternatively, ReThink’s joint trajectory action servers could be launched and used, although this would require modifying the Cartesian motion action server to use these.) The action server baxterrtarmcartmoveas is launched, which provides Cartesian motion planning and execution capabilities specific to Baxter’s right arm, but presents an interface to action clients that is robot-agnostic. The final action server launched is the objectgrabberactionserver, which assumes use of a robot-independent Cartesian motion action server (which is baxterrtarmcartmoveas, in this case). The objectgrabberactionserver presents an action server interface to clients that enables clients to specify manipulation goals that are independent of specific robots or grippers.

The result of running this launch file is to command Baxter’s arms to move to the defined waiting pose, then the object-grabber awaits goals. This initial state is shown in Fig 15.4. The example object-grabber action client program has a hard-coded object ID with a hard-coded pose, consistent with the toy block on the cafe table spawned in Gazebo, as shown in Fig 15.3. The example client program can be run with:

image

Figure 15.4 rviz view of Baxter simulator in pre-pose, illustrating right hand and right gripper frames

image

Running this node results in the robot picking up the block, rotating it, and setting it back down. The first step of this is sending a GRABOBJECT goal to the object-grabber action server. This invokes a sequence of actions enabling the robot to move its gripper to a recommended approach pose, open the gripper fingers, descend to a recommended grasp pose, close the fingers, and ascend to a recommended depart pose.

Execution of the default-strategy approach pose results in the scene in Fig 15.5, with the gripper 0.1 m directly above the block, and with gripper fingers open and aligned in preparation for descending to the grasp pose.

image

Figure 15.5 Approach pose from action client object_grabber_action_client, with pre-positioned block at known precise coordinates

image

Figure 15.6 Grasp pose used by action client object_grabber_action_client

image

Figure 15.7 Depart pose used by action client object_grabber_action_client

Figure 15.6 shows the result of moving to the grasp pose prescribed by the object-manipulation query service. The generic gripper frame, with origin defined between the fingertips, is positioned such that its origin is coincident with the block frame origin. The gripper frame orientation is specified to have the gripper z axis anti-parallel to the block frame z axis, and have the gripper frame x axis parallel to the major axis of the block (the block frame x axis). In this recommended grasp pose, the fingertips straddle the block near its center, preparing to grasp the block. After descending to the grasp pose and closing the gripper, the robot moves to its depart pose, presumably with the object successfully grasped, resulting in the pose shown in Fig 15.7. This concludes the GRABOBJECT action. The object-grabber action client next commands DROPOFFOBJECT. In this sequence, the robot moves to an approach pose above the drop-off coordinates, descends to the destination pose, opens the gripper, then withdraws the gripper. Figure 15.8 shows the state of the robot just after the block has been placed at its destination coordinates and the gripper fingers have been opened, in preparation for withdrawing the gripper.

image

Figure 15.8 Drop-off pose used by action client object_grabber_action_client

To illustrate the generality of the action client program, the same operation can be executed by a UR10 robot. First, start the UR10 robot on a pedestal with a virtual vacuum gripper added:

image

Next, add a table and block and start the nodes needed for the object-grabber service:

image

This launch file is similar to the corresponding Baxter launch file. (One addition is that the UR10 launch file incorporates spawning the table and block.) It sets a gripper ID on the parameter server (in this case, a virtual vacuum gripper). It includes a launch file that starts static transform publishers for a generic gripper frame and a system reference frame relative to respective UR10 frames. It also starts rviz with reference to a pre-defined configuration file.

A gripper service is started that controls the virtual vacuum gripper, but it still presents a generic interface for defined GRASP and RELEASE command codes.

A Cartesian motion action server, ur10cartmoveas, is started. This action server presents a generic interface to action clients, but its implementation is specific to the UR10 robot.

The object-manipulation query service is started. This service is identical to that used in the Baxter example. The object-grabber action service is started, identical to that used in the Baxter example.

The result of launching these nodes is as shown in Fig 15.9.

image

Figure 15.9 Initial state after launching UR10 object-grabber nodes

With the object-grabber action server (and supporting nodes) running, one can run an action client. The object-grabber action client demonstrated for the Baxter example can be run verbatim for the UR10 example:

image

In performing the GRABOBJECT action, the UR10 is first sent to an approach pose, as shown in Fig 15.10. This approach pose is recommended by the object-manipulation query service as appropriate for the emulated vacuum gripper relative to the toy-block part.

image

Figure 15.10 UR10 block approach pose

Figure 15.11 shows the result of moving to the grasp pose prescribed by the object-manipulation query service specific for this gripper and object. The generic gripper frame, with origin defined at the center of the face of the vacuum gripper, is positioned such that its origin is coincident with the top face of the block. The gripper frame orientation is specified to have the gripper z axis anti-parallel to the block frame z axis. (The gripper frame x axis direction is arbitrary, but constrained to be perpendicular to the z axis.) In this recommended grasp pose, the vacuum gripper may be expected to form a seal with the top face of the toy-block object.

image

Figure 15.11 Grasp pose used by action client object_grabber_action_client

After descending to the grasp pose and commanding the gripper to GRASP, the robot moves to its depart pose, presumably with the object successfully grasped, resulting in the pose shown in Fig 15.12

image

Figure 15.12 UR10 depart pose

This concludes the GRABOBJECT action. The object-grabber action client next commands DROPOFFOBJECT. In this sequence, the robot moves to an approach pose above the drop-off coordinates, descends to the destination pose, invokes a RELEASE command to the gripper, then withdraws the gripper. Figure 15.13 shows the state of the robot just after the block has been placed at its destination coordinates but before the gripper has released the part.

image

Figure 15.13 Drop-off pose used by action client object_grabber_action_client

The example object-grabber action client can successfully achieve the desired effect of moving a part from a specified initial pose to a desired destination pose. The same action client can be used with very different robot arms and grippers.

15.6 Wrap-Up

 

The object-grabber action service described in this chapter is an example of how we can use ROS to make software more re-usable. The object-grabber action service is independent of any specific robot arm. For object-manipulation commands, the system must know what type of gripper is being used, and the approach taken here is to provide this information via the parameter server.

It was shown that an action client of the object-grabber action server can be composed in a manner that allows the programmer to focus on task properties rather than robot properties. In the simple example provided, an object was to be relocated from a specified initial pose to a specified destination pose. This was accomplished using two very different robot arms with very different grippers, yet the same action client program could be used with both systems to accomplish the task goals.

In the final section of this text, we consider issues of system integration incorporating perception, mobility and manipulation.

1 Selective Comp;iance Assembly Robot Arm

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.139.50