Robowflex  v0.1
Making MoveIt Easy
shadowhand_ik.cpp
Go to the documentation of this file.
1 /* Author: Zachary Kingston */
2 
3 #include <sensor_msgs/JointState.h>
4 
5 // Robowflex
11 #include <robowflex_library/util.h>
12 
13 using namespace robowflex;
14 
15 /* \file shadowhand_ik.cpp
16  * Example of multi-target IK using BioIK for the shadowhand. This script also uses some of the more advanced
17  * features of Robot::IKQuery and setFromIK() that allow for approximate solutions and higher thresholds on IK
18  * solution tolerance.
19  * This script also visualizes the query and result using RViz. See
20  * https://kavrakilab.github.io/robowflex/rviz.html for RViz visualization.
21  */
22 
23 // Tip links of each of the shadowhand's fingers (from forefinger to thumb).
24 const std::vector<std::string> tips = {"fftip", "mftip", "rftip", "lftip", "thtip"};
25 
26 int main(int argc, char **argv)
27 {
28  // Startup ROS
29  ROS ros(argc, argv);
30 
31  // Create a Shadowhand robot and initialize.
32  auto shadowhand = std::make_shared<Robot>("shadowhand");
33  shadowhand->initializeFromYAML("package://robowflex_resources/shadowhand.yml");
34  shadowhand->loadKinematics("all_fingers", false);
35  shadowhand->setState({"kuka_arm_1_joint", "kuka_arm_3_joint", "kuka_arm_5_joint"}, {1, 2, 1});
36 
37  auto scene = std::make_shared<Scene>(shadowhand);
38  scene->updateCollisionObject("rod_1", Geometry::makeCylinder(0.1, 1),
39  TF::createPoseXYZ(0, 0, 0.5, constants::pi / 2, 0, 0));
40  scene->updateCollisionObject("rod_2", Geometry::makeCylinder(0.1, 1),
41  TF::createPoseXYZ(-0.2, 0.2, 0.5, 0, 0, 0));
42  scene->updateCollisionObject("rod_3", Geometry::makeCylinder(0.01, 0.25),
43  TF::createPoseXYZ(0, -0.04, 0.95, 0, constants::pi / 2, 0));
44 
45  // Save initial state.
46  auto start = *shadowhand->getScratchState();
47 
48  // Visualize the Shadowhand robot.
49  IO::RVIZHelper rviz(shadowhand);
50  rviz.updateScene(scene);
51 
52  // Set the shadowhand to a default grasp and save that state.
53  shadowhand->setStateFromYAMLFile("package://robowflex_resources/shadowhand/poses/grasp.yml");
54  auto grasp = *shadowhand->getScratchState();
55 
56  // Visualize desired grasp state.
57  rviz.visualizeCurrentState();
58  RBX_INFO("Desired Grasp Displayed, Press Enter to Continue...");
59  std::cin.ignore();
60 
61  // Extract poses of the tip links.
62  RobotPoseVector poses;
63  for (const auto &tip : tips)
64  {
65  auto pose = shadowhand->getLinkTF(tip);
66  poses.emplace_back(pose);
67 
68  // Create a marker at each tip frame.
69  rviz.addTransformMarker(tip + "_goal", "map", pose, 0.3);
70  }
71 
72  // Reset state to the initial start state.
73  *shadowhand->getScratchState() = start;
74 
75  // Visualize starting state and goal markers.
76  rviz.visualizeCurrentState();
77  rviz.updateMarkers();
78  RBX_INFO("Initial State and Goal Displayed, Press Enter to Continue...");
79  std::cin.ignore();
80 
81  // Configure query for shadowhand
82  Robot::IKQuery query("all_fingers", poses, tips);
83  query.scene = scene;
84  query.verbose = true; // If verbose is true, debugging output for constraints and collisions is output.
85 
86  query.timeout = 0.05;
87  query.attempts = 50;
88 
89  // Need approximate solutions as multi-target BioIK will only return approximate solutions.
91  query.validate = true; // Need external validation to verify approximate solutions are within tolerance.
92  query.valid_distance = 0.01; // Tuned distance threshold that is appropriate for query.
93 
94  // By adding metrics to the IKQuery, every attempt is used to find the best configuration (according to
95  // the sum of the metrics). A weighting factor is added to balance the metrics.
96  query.addDistanceMetric(); // Distance to IKQuery
97  query.addCenteringMetric(0.01); // Distance of joints from their center
98  query.addClearanceMetric(0.01); // Distance of robot to collision
99 
100  if (not shadowhand->setFromIK(query))
101  RBX_ERROR("IK query failed!");
102 
103  // Visualize resulting state.
104  rviz.visualizeCurrentState();
105  RBX_INFO("Solution to IK is visualized. Press enter to exit...");
106  std::cin.ignore();
107 
108  rviz.removeAllMarkers();
109  rviz.updateMarkers();
110 
111  return 0;
112 }
static GeometryPtr makeCylinder(double radius, double length)
Create a cylinder.
Definition: geometry.cpp:58
RVIZ visualization helper. See Live Visualization with RViz for more information.
Definition: visualization.h:38
void removeAllMarkers()
Removes all markers that were added through addMarker().
void updateMarkers()
Displays the managed list of markers. Keeps track of whether markers have already been displayed and ...
void visualizeCurrentState()
Visualize the current state of the robot.
void updateScene(const SceneConstPtr &scene)
Updates the scene being visualized.
void addTransformMarker(const std::string &name, const std::string &base_frame, const RobotPose &pose, double scale=1)
Add a transform marker to the managed list of markers. Displayed after an updateMarkers() call.
RAII-pattern for starting up ROS.
Definition: util.h:52
T emplace_back(T... args)
#define RBX_ERROR(fmt,...)
Output a error logging message.
Definition: log.h:102
#define RBX_INFO(fmt,...)
Output a info logging message.
Definition: log.h:118
RobotPose createPoseXYZ(double x, double y, double z)
Creates a robot pose from a linear component and zero orientation.
Definition: tf.cpp:14
static const double pi
Definition: constants.h:21
Main namespace. Contains all library classes and functions.
Definition: scene.cpp:25
Functions for loading and animating scenes in Blender.
int main(int argc, char **argv)
const std::vector< std::string > tips
Robot IK Query options. IK queries in Robowflex consist of: a) A position specified by some geometric...
kinematics::KinematicsQueryOptions options
Other query options.
void addCenteringMetric(double weight=1.)
Add a metric to the query to evaluate how "centered" the joints of the robot are (from their 0 positi...
bool verbose
Verbose output of collision checking.
void addClearanceMetric(double weight=1.)
Add a metric to the query to evaluate clearance from provided scene.
SceneConstPtr scene
If provided, use this scene for collision checking.
std::size_t attempts
IK attempts (samples within regions).
void addDistanceMetric(double weight=1.)
Add a metric to the query to evaluate distance to constraint.