imarker_end_effector.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2016, University of Colorado, Boulder
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of PickNik LLC nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 /* Author: Dave Coleman
36  Desc: Class to encapsule a visualized robot state that can be controlled using an interactive marker
37 */
38 
39 // Boost
40 #include <boost/filesystem.hpp>
41 
42 // C++
43 #include <string>
44 
45 // Conversions
46 #include <tf2_eigen/tf2_eigen.h>
47 
48 // this package
51 
52 namespace
53 {
54 bool isStateValid(const planning_scene::PlanningScene* planning_scene, bool verbose, bool only_check_self_collision,
56  const moveit::core::JointModelGroup* group, const double* ik_solution)
57 {
58  // Apply IK solution to robot state
59  robot_state->setJointGroupPositions(group, ik_solution);
60  robot_state->update();
61 
62 #if 0 // Ensure there are objects in the planning scene
63  const std::size_t num_collision_objects = planning_scene->getCollisionEnv()->getWorld()->size();
64  if (num_collision_objects == 0)
65  {
66  ROS_ERROR_STREAM_NAMED("cart_path_planner", "No collision objects exist in world, you need at least a table "
67  "modeled for the controller to work");
68  ROS_ERROR_STREAM_NAMED("cart_path_planner", "To fix this, relaunch the teleop/head tracking/whatever MoveIt "
69  "node to publish the collision objects");
70  return false;
71  }
72 #endif
73 
74  if (!planning_scene)
75  {
76  ROS_ERROR_STREAM_NAMED("cart_path_planner", "No planning scene provided");
77  return false;
78  }
79  if (only_check_self_collision)
80  {
81  // No easy API exists for only checking self-collision, so we do it here.
82  // TODO(davetcoleman): move this into planning_scene.cpp
84  req.verbose = verbose;
85  req.group_name = group->getName();
87  planning_scene->checkSelfCollision(req, res, *robot_state);
88  if (!res.collision)
89  return true; // not in collision
90  }
91  else if (!planning_scene->isStateColliding(*robot_state, group->getName()))
92  return true; // not in collision
93 
94  // Display more info about the collision
95  if (verbose)
96  {
97  visual_tools->publishRobotState(*robot_state, rviz_visual_tools::RED);
98  planning_scene->isStateColliding(*robot_state, group->getName(), true);
99  visual_tools->publishContactPoints(*robot_state, planning_scene);
100  }
101  ROS_WARN_STREAM_THROTTLE_NAMED(2.0, "cart_path_planner", "Collision");
102  return false;
103 }
104 
105 } // namespace
106 
107 namespace moveit_visual_tools
108 {
109 IMarkerEndEffector::IMarkerEndEffector(IMarkerRobotState* imarker_parent, const std::string& imarker_name,
110  ArmData arm_data, rviz_visual_tools::colors color)
111  : name_(imarker_name)
112  , imarker_parent_(imarker_parent)
113  , imarker_state_(imarker_parent_->imarker_state_)
114  , psm_(imarker_parent_->psm_)
115  , visual_tools_(imarker_parent_->visual_tools_)
116  , arm_data_(arm_data)
117  , color_(color)
118  , imarker_server_(imarker_parent_->imarker_server_)
119 {
120  // Get pose from robot state
121  imarker_pose_ = imarker_state_->getGlobalLinkTransform(arm_data_.ee_link_);
122 
123  // Create imarker
125 
126  ROS_INFO_STREAM_NAMED(name_, "IMarkerEndEffector '" << name_ << "' tracking ee link '"
127  << arm_data_.ee_link_->getName() << "' ready.");
128 }
129 
130 void IMarkerEndEffector::getPose(Eigen::Isometry3d& pose)
131 {
132  pose = imarker_pose_;
133 }
134 
136 {
137  imarker_pose_ = imarker_state_->getGlobalLinkTransform(arm_data_.ee_link_);
138 
140 
141  return true;
142 }
143 
144 void IMarkerEndEffector::iMarkerCallback(const visualization_msgs::InteractiveMarkerFeedbackConstPtr& feedback)
145 {
146  if (feedback->event_type == visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP)
147  {
148  // Save pose to file if its been long enough
149  double save_every_sec = 0.1;
150  if (time_since_last_save_ < ros::Time::now() - ros::Duration(save_every_sec))
151  {
154  }
155  return;
156  }
157 
158  // Ignore if not pose update
159  if (feedback->event_type != visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE)
160  return;
161 
162  // Only allow one feedback to be processed at a time
163  {
164  // boost::unique_lock<boost::mutex> scoped_lock(imarker_mutex_);
166  {
167  return;
168  }
170  }
171 
172  // Convert
173  Eigen::Isometry3d robot_ee_pose;
174  tf2::fromMsg(feedback->pose, robot_ee_pose);
175 
176  // Update robot
177  solveIK(robot_ee_pose);
178 
179  // Redirect to base class
180  if (imarker_callback_)
181  imarker_callback_(feedback, robot_ee_pose);
182 
183  // Allow next feedback to be processed
184  {
185  // boost::unique_lock<boost::mutex> scoped_lock(imarker_mutex_);
187  }
188 }
189 
190 void IMarkerEndEffector::solveIK(Eigen::Isometry3d& pose)
191 {
192  // Cartesian settings
193  const double timeout = 1.0 / 30.0; // 30 fps
194 
195  // Optionally collision check
198  {
199  // TODO(davetcoleman): this is currently not working, the locking seems to cause segfaults
200  boost::scoped_ptr<planning_scene_monitor::LockedPlanningSceneRO> ls;
202  constraint_fn = boost::bind(&isStateValid, static_cast<const planning_scene::PlanningSceneConstPtr&>(*ls).get(),
204  boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3);
205  }
206 
207  // Attempt to set robot to new pose
208  if (imarker_state_->setFromIK(arm_data_.jmg_, pose, arm_data_.ee_link_->getName(), timeout, constraint_fn))
209  {
210  imarker_state_->update();
211  // if (psm_->getPlanningScene()->isStateValid(*imarker_state_))
212  //{
213  // ROS_INFO_STREAM_NAMED(name_, "Solved IK");
215  //}
216  // else
217  // {
218  // visual_tools_->publishRobotState(imarker_state_, rviz_visual_tools::RED);
219  // exit(0);
220  // }
221  }
222 }
223 
225 {
226  // Convert
227  const geometry_msgs::Pose pose_msg = tf2::toMsg(imarker_pose_);
228 
229  // marker
230  make6DofMarker(pose_msg);
231 }
232 
233 void IMarkerEndEffector::updateIMarkerPose(const Eigen::Isometry3d& /*pose*/)
234 {
235  // Move marker to tip of fingers
236  // imarker_pose_ = pose * imarker_offset_.inverse();
238 }
239 
241 {
242  // Convert
243  const geometry_msgs::Pose pose_msg = tf2::toMsg(imarker_pose_);
244 
245  imarker_server_->setPose(int_marker_.name, pose_msg);
246  imarker_server_->applyChanges();
247 }
248 
249 void IMarkerEndEffector::make6DofMarker(const geometry_msgs::Pose& pose)
250 {
251  ROS_DEBUG_STREAM_NAMED(name_, "Making 6dof interactive marker named " << name_);
252 
253  int_marker_.header.frame_id = "world";
254  int_marker_.pose = pose;
255  int_marker_.scale = 0.2;
256 
257  int_marker_.name = name_;
258  // int_marker_.description = "imarker_" + name_; // TODO: unsure, but I think this causes a caption in Rviz that I
259  // don't want
260 
261  // insert a box
262  // makeBoxControl(int_marker_);
263 
264  // int_marker_.controls[0].interaction_mode = InteractiveMarkerControl::MENU;
265 
266  InteractiveMarkerControl control;
267  control.orientation.w = 1;
268  control.orientation.x = 1;
269  control.orientation.y = 0;
270  control.orientation.z = 0;
271  control.name = "rotate_x";
272  control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
273  int_marker_.controls.push_back(control);
274  control.name = "move_x";
275  control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
276  int_marker_.controls.push_back(control);
277 
278  control.orientation.w = 1;
279  control.orientation.x = 0;
280  control.orientation.y = 1;
281  control.orientation.z = 0;
282  control.name = "rotate_z";
283  control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
284  int_marker_.controls.push_back(control);
285  control.name = "move_z";
286  control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
287  int_marker_.controls.push_back(control);
288 
289  control.orientation.w = 1;
290  control.orientation.x = 0;
291  control.orientation.y = 0;
292  control.orientation.z = 1;
293  control.name = "rotate_y";
294  control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
295  int_marker_.controls.push_back(control);
296  control.name = "move_y";
297  control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
298  int_marker_.controls.push_back(control);
299 
300  imarker_server_->insert(int_marker_);
301  imarker_server_->setCallback(int_marker_.name,
302  boost::bind(&IMarkerEndEffector::iMarkerCallback, this, boost::placeholders::_1));
303  // menu_handler_.apply(*imarker_server_, int_marker_.name);
304 }
305 
306 visualization_msgs::InteractiveMarkerControl&
307 IMarkerEndEffector::makeBoxControl(visualization_msgs::InteractiveMarker& msg)
308 {
309  visualization_msgs::InteractiveMarkerControl control;
310  control.always_visible = true;
311 
312  visualization_msgs::Marker marker;
313  marker.type = visualization_msgs::Marker::CUBE;
314  marker.scale.x = msg.scale * 0.3; // x direction
315  marker.scale.y = msg.scale * 0.10; // y direction
316  marker.scale.z = msg.scale * 0.10; // height
317  marker.color = visual_tools_->getColor(color_);
318 
319  control.markers.push_back(marker);
320  msg.controls.push_back(control);
321 
322  return msg.controls.back();
323 }
324 
325 } // namespace moveit_visual_tools
ROS_WARN_STREAM_THROTTLE_NAMED
#define ROS_WARN_STREAM_THROTTLE_NAMED(period, name, args)
moveit::core::GroupStateValidityCallbackFn
boost::function< bool(RobotState *robot_state, const JointModelGroup *joint_group, const double *joint_group_variable_values)> GroupStateValidityCallbackFn
imarker_end_effector.h
moveit_visual_tools::IMarkerEndEffector::psm_
planning_scene_monitor::PlanningSceneMonitorPtr psm_
Definition: imarker_end_effector.h:175
moveit_visual_tools::IMarkerEndEffector::imarker_parent_
IMarkerRobotState * imarker_parent_
Definition: imarker_end_effector.h:168
moveit_visual_tools::IMarkerEndEffector::updateIMarkerPose
void updateIMarkerPose(const Eigen::Isometry3d &pose)
Definition: imarker_end_effector.cpp:233
tf2_eigen.h
tf2::fromMsg
void fromMsg(const A &, B &b)
ROS_DEBUG_STREAM_NAMED
#define ROS_DEBUG_STREAM_NAMED(name, args)
moveit_visual_tools::IMarkerEndEffector::collision_checking_verbose_
bool collision_checking_verbose_
Definition: imarker_end_effector.h:196
moveit_visual_tools::IMarkerEndEffector::imarker_callback_
IMarkerCallback imarker_callback_
Definition: imarker_end_effector.h:201
moveit_visual_tools::ArmData::jmg_
moveit::core::JointModelGroup * jmg_
Definition: imarker_robot_state.h:106
planning_scene::PlanningScene
moveit_visual_tools::IMarkerEndEffector::getPose
void getPose(Eigen::Isometry3d &pose)
Get the current end effector pose.
Definition: imarker_end_effector.cpp:130
moveit_visual_tools::ArmData::ee_link_
moveit::core::LinkModel * ee_link_
Definition: imarker_robot_state.h:109
moveit::core::RobotState
moveit_visual_tools::IMarkerEndEffector::int_marker_
visualization_msgs::InteractiveMarker int_marker_
Definition: imarker_end_effector.h:189
moveit_visual_tools::IMarkerEndEffector::color_
rviz_visual_tools::colors color_
Definition: imarker_end_effector.h:182
collision_detection::CollisionRequest
moveit_visual_tools::IMarkerEndEffector::initializeInteractiveMarkers
void initializeInteractiveMarkers()
Definition: imarker_end_effector.cpp:224
moveit::core::JointModelGroup::getName
const std::string & getName() const
moveit_visual_tools::IMarkerEndEffector::makeBoxControl
visualization_msgs::InteractiveMarkerControl & makeBoxControl(visualization_msgs::InteractiveMarker &msg)
Definition: imarker_end_effector.cpp:307
moveit_visual_tools::IMarkerEndEffector::name_
std::string name_
Definition: imarker_end_effector.h:165
moveit_visual_tools::MoveItVisualToolsPtr
std::shared_ptr< MoveItVisualTools > MoveItVisualToolsPtr
Definition: moveit_visual_tools.h:782
moveit::core::RobotState::update
void update(bool force=false)
moveit_visual_tools::IMarkerEndEffector::iMarkerCallback
void iMarkerCallback(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
Definition: imarker_end_effector.cpp:144
moveit_visual_tools::IMarkerEndEffector::imarker_ready_to_process_
bool imarker_ready_to_process_
Definition: imarker_end_effector.h:190
collision_detection::CollisionResult
ROS_ERROR_STREAM_NAMED
#define ROS_ERROR_STREAM_NAMED(name, args)
moveit_visual_tools::IMarkerEndEffector::imarker_pose_
Eigen::Isometry3d imarker_pose_
Definition: imarker_end_effector.h:172
collision_detection::CollisionRequest::verbose
bool verbose
collision_detection::CollisionRequest::group_name
std::string group_name
moveit_visual_tools::IMarkerEndEffector::visual_tools_
moveit_visual_tools::MoveItVisualToolsPtr visual_tools_
Definition: imarker_end_effector.h:178
moveit_visual_tools::IMarkerEndEffector::setPoseFromRobotState
bool setPoseFromRobotState()
Definition: imarker_end_effector.cpp:135
moveit_visual_tools::IMarkerEndEffector::time_since_last_save_
ros::Time time_since_last_save_
Definition: imarker_end_effector.h:185
moveit_visual_tools::IMarkerEndEffector::only_check_self_collision_
bool only_check_self_collision_
Definition: imarker_end_effector.h:197
moveit_visual_tools::ArmData
I wish this struct wasn't necessary, but the SRDF does not seem to support choosing one particular li...
Definition: imarker_robot_state.h:104
moveit_visual_tools::IMarkerEndEffector::use_collision_checking_
bool use_collision_checking_
Definition: imarker_end_effector.h:198
rviz_visual_tools::RED
RED
imarker_robot_state.h
rviz_visual_tools::colors
colors
moveit_visual_tools::IMarkerEndEffector::arm_data_
ArmData arm_data_
Definition: imarker_end_effector.h:181
moveit_visual_tools::IMarkerRobotState::publishRobotState
void publishRobotState()
Show current state in Rviz.
Definition: imarker_robot_state.cpp:300
moveit_visual_tools::IMarkerEndEffector::sendUpdatedIMarkerPose
void sendUpdatedIMarkerPose()
Definition: imarker_end_effector.cpp:240
moveit_visual_tools::IMarkerEndEffector::imarker_server_
InteractiveMarkerServerPtr imarker_server_
Definition: imarker_end_effector.h:193
moveit_visual_tools::IMarkerEndEffector::IMarkerEndEffector
IMarkerEndEffector(IMarkerRobotState *imarker_parent, const std::string &imarker_name, ArmData arm_data, rviz_visual_tools::colors color=rviz_visual_tools::PURPLE)
Constructor.
Definition: imarker_end_effector.cpp:109
moveit_visual_tools::IMarkerRobotState
Definition: imarker_robot_state.h:112
planning_scene_monitor::LockedPlanningSceneRO
moveit::core::JointModelGroup
moveit_visual_tools::IMarkerEndEffector::make6DofMarker
void make6DofMarker(const geometry_msgs::Pose &pose)
Definition: imarker_end_effector.cpp:249
ROS_INFO_STREAM_NAMED
#define ROS_INFO_STREAM_NAMED(name, args)
tf2::toMsg
B toMsg(const A &a)
collision_detection::CollisionResult::collision
bool collision
moveit_visual_tools::IMarkerRobotState::saveToFile
bool saveToFile()
Definition: imarker_robot_state.cpp:197
moveit::core::LinkModel::getName
const std::string & getName() const
moveit::core::RobotState::setJointGroupPositions
void setJointGroupPositions(const std::string &joint_group_name, const double *gstate)
planning_scene
moveit_visual_tools
Definition: imarker_end_effector.h:62
moveit_visual_tools::IMarkerEndEffector::imarker_state_
moveit::core::RobotStatePtr imarker_state_
Definition: imarker_end_effector.h:171
ros::Duration
moveit_visual_tools::IMarkerEndEffector::solveIK
void solveIK(Eigen::Isometry3d &pose)
Definition: imarker_end_effector.cpp:190
ros::Time::now
static Time now()
verbose
bool verbose


moveit_visual_tools
Author(s): Dave Coleman
autogenerated on Fri May 19 2023 02:14:04