ROS MoveIt的同步和异步

xiaoxiao2025-09-17  32

ROS MoveIt的同步和异步

flyfish

当调用MoveIt的同步运动或者异步运动 异步:asyncMove 同步:move

move_group_interface.cpp

moveit::planning_interface::MoveItErrorCode moveit::planning_interface::MoveGroupInterface::asyncMove() { return impl_->move(false); } moveit::planning_interface::MoveItErrorCode moveit::planning_interface::MoveGroupInterface::move() { return impl_->move(true); }

impl_的声明在move_group_interface.h文件中

class MoveGroupInterfaceImpl; MoveGroupInterfaceImpl* impl_;

move_group_interface和MoveGroupInterfaceImpl主要是使用了C++ pimp惯用法以保持接口不变,可移植,最小依赖 class MoveGroupInterface::MoveGroupInterfaceImpl

就像这样

// my_class.h class my_class { // ... all public and protected stuff goes here ... private: class impl; unique_ptr<impl> pimpl; // opaque type here }; // my_class.cpp class my_class::impl { // defined privately here // ... all private data and functions: all of these // can now change without recompiling callers ... }; my_class::my_class(): pimpl( new impl ) { // ... set impl values ... }

namespace moveit { namespace planning_interface { } } moveit,planning_interface都是命名空间

move的实现

MoveItErrorCode move(bool wait) { if (!move_action_client_) { return MoveItErrorCode(moveit_msgs::MoveItErrorCodes::FAILURE); } if (!move_action_client_->isServerConnected()) { return MoveItErrorCode(moveit_msgs::MoveItErrorCodes::FAILURE); } moveit_msgs::MoveGroupGoal goal; constructGoal(goal); goal.planning_options.plan_only = false; goal.planning_options.look_around = can_look_; goal.planning_options.replan = can_replan_; goal.planning_options.replan_delay = replan_delay_; goal.planning_options.planning_scene_diff.is_diff = true; goal.planning_options.planning_scene_diff.robot_state.is_diff = true; move_action_client_->sendGoal(goal); if (!wait) { return MoveItErrorCode(moveit_msgs::MoveItErrorCodes::SUCCESS); } if (!move_action_client_->waitForResult()) { ROS_INFO_STREAM_NAMED("move_group_interface", "MoveGroup action returned early"); } if (move_action_client_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED) { return MoveItErrorCode(move_action_client_->getResult()->error_code); } else { ROS_INFO_STREAM_NAMED("move_group_interface", move_action_client_->getState().toString() << ": " << move_action_client_->getState().getText()); return MoveItErrorCode(move_action_client_->getResult()->error_code); } }

MoveGroupInterface以action的形式(move_action_client_)来接受move_goup的规划结果,

它的类型是 std::unique_ptr<actionlib::SimpleActionClient<moveit_msgs::MoveGroupAction> > move_action_client_;

如果是异步 move_action_client_->sendGoal(goal);之后就返回 如果同步就要等待执行 完成actionlib::SimpleClientGoalState::SUCCEEDED后返回 代码如下.问题到此解决.

simple_action_client.h

template<class ActionSpec> bool SimpleActionClient<ActionSpec>::waitForResult(const ros::Duration & timeout) { if (gh_.isExpired()) { ROS_ERROR_NAMED("actionlib", "Trying to waitForGoalToFinish() when no goal is running. You are incorrectly using SimpleActionClient"); return false; } if (timeout < ros::Duration(0, 0)) { ROS_WARN_NAMED("actionlib", "Timeouts can't be negative. Timeout is [%.2fs]", timeout.toSec()); } ros::Time timeout_time = ros::Time::now() + timeout; boost::mutex::scoped_lock lock(done_mutex_); // Hardcode how often we check for node.ok() ros::Duration loop_period = ros::Duration().fromSec(.1); while (nh_.ok()) { // Determine how long we should wait ros::Duration time_left = timeout_time - ros::Time::now(); // Check if we're past the timeout time if (timeout > ros::Duration(0, 0) && time_left <= ros::Duration(0, 0) ) { break; } if (cur_simple_state_ == SimpleGoalState::DONE) { break; } // Truncate the time left if (time_left > loop_period || timeout == ros::Duration()) { time_left = loop_period; } done_condition_.timed_wait(lock, boost::posix_time::milliseconds(time_left.toSec() * 1000.0f)); } return cur_simple_state_ == SimpleGoalState::DONE; }
转载请注明原文地址: https://www.6miu.com/read-5036485.html

最新回复(0)