43 #include <planner_cspace_msgs/PlannerStatus.h> 44 #include <trajectory_msgs/JointTrajectory.h> 45 #include <sensor_msgs/JointState.h> 55 namespace planner_2dof_serial_joints
61 using Ptr = std::shared_ptr<Planner2dofSerialJointsNode>;
76 Astar::Gridmap<char, 0x40>
cm_;
107 return std::hypot(b.
x_ - x_, b.
y_ - y_);
136 auto end0 =
end(th0);
137 auto end1 = b.
end(th1);
138 auto& end0r = radius_[1];
142 auto& origin0r = radius_[0];
145 if (end0.dist(end1) < end0r + end1r)
147 if (end0.dist(origin1) < end0r + origin1r)
149 if (end1.dist(origin0) < end1r + origin0r)
165 void cbJoint(
const sensor_msgs::JointState::ConstPtr& msg)
167 int id[2] = { -1, -1 };
168 for (
size_t i = 0; i < msg->name.size(); i++)
170 if (msg->name[i].compare(links_[0].
name_) == 0)
172 else if (msg->name[i].compare(links_[1].
name_) == 0)
175 if (
id[0] == -1 ||
id[1] == -1)
177 ROS_ERROR(
"joint_state does not contain link group %s.", group_.c_str());
182 has_joint_states_ =
true;
191 std::pair<ros::Duration, std::pair<float, float>>
cmd_prev_;
194 void cbTrajectory(
const trajectory_msgs::JointTrajectory::ConstPtr& msg)
198 for (
size_t i = 0; i < msg->joint_names.size(); i++)
200 if (msg->joint_names[i].compare(links_[0].
name_) == 0)
202 else if (msg->joint_names[i].compare(links_[1].
name_) == 0)
205 if (id_[0] == -1 || id_[1] == -1)
207 ROS_ERROR(
"joint_trajectory does not contains link group %s.", group_.c_str());
210 if (msg->points.size() != 1)
212 ROS_ERROR(
"single trajectory point required.");
214 decltype(cmd_prev_) cmd;
215 cmd.first = msg->points[0].time_from_start;
216 cmd.second.first = msg->points[0].positions[id_[0]];
217 cmd.second.second = msg->points[0].positions[id_[1]];
218 if (cmd_prev_ == cmd)
228 if (!has_joint_states_)
232 if (id_[0] == -1 || id_[1] == -1)
237 links_[1].current_th_);
239 static_cast<float>(traj_prev_.points[0].positions[id_[0]]),
240 static_cast<float>(traj_prev_.points[0].positions[id_[1]]));
242 ROS_INFO(
"link %s: %0.3f, %0.3f", group_.c_str(),
243 traj_prev_.points[0].positions[id_[0]],
244 traj_prev_.points[0].positions[id_[1]]);
247 std::list<Astar::Vecf> path;
250 ROS_INFO(
"Trajectory found");
255 for (
auto it = path.begin(); it != path.end(); it++)
259 if (it_next != path.end())
261 float diff[2], diff_max;
262 diff[0] = std::abs((*it_next)[0] - (*it)[0]);
263 diff[1] = std::abs((*it_next)[1] - (*it)[1]);
264 diff_max = std::max(diff[0], diff[1]);
268 if (traj_prev_.points[0].time_from_start <=
ros::Duration(0))
270 avg_vel_ = std::min(links_[0].
vmax_, links_[1].vmax_);
274 avg_vel_ = pos_sum / traj_prev_.points[0].time_from_start.toSec();
275 if (avg_vel_ > links_[0].
vmax_)
276 avg_vel_ = links_[0].
vmax_;
277 if (avg_vel_ > links_[1].vmax_)
278 avg_vel_ = links_[1].
vmax_;
282 trajectory_msgs::JointTrajectory out;
283 out.header = traj_prev_.header;
285 out.joint_names.resize(2);
286 out.joint_names[0] = links_[0].
name_;
287 out.joint_names[1] = links_[1].
name_;
289 for (
auto it = path.begin(); it != path.end(); it++)
291 if (it == path.begin())
294 trajectory_msgs::JointTrajectoryPoint p;
295 p.positions.resize(2);
296 p.velocities.resize(2);
303 float diff[2], diff_max;
304 diff[0] = std::abs((*it)[0] - (*it_prev)[0]);
305 diff[1] = std::abs((*it)[1] - (*it_prev)[1]);
306 diff_max = std::max(diff[0], diff[1]);
309 if (it_next == path.end())
311 p.velocities[0] = 0.0;
312 p.velocities[1] = 0.0;
316 float dir[2], dir_max;
321 dir[0] = ((*it)[0] - (*it_prev)[0]);
322 dir[1] = ((*it)[1] - (*it_prev)[1]);
325 dir[0] = ((*it_next)[0] - (*it)[0]);
326 dir[1] = ((*it_next)[1] - (*it)[1]);
329 dir[0] = ((*it_next)[0] - (*it_prev)[0]);
330 dir[1] = ((*it_next)[1] - (*it_prev)[1]);
333 dir_max = std::max(std::abs(dir[0]), std::abs(dir[1]));
336 p.velocities[0] = dir[0] / t;
337 p.velocities[1] = dir[1] / t;
340 p.positions[0] = (*it)[0];
341 p.positions[1] = (*it)[1];
342 out.points.push_back(p);
348 trajectory_msgs::JointTrajectory out;
349 out.header = traj_prev_.header;
351 out.joint_names.resize(2);
352 out.joint_names[0] = links_[0].
name_;
353 out.joint_names[1] = links_[1].
name_;
354 trajectory_msgs::JointTrajectoryPoint p;
355 p.positions.resize(2);
358 p.velocities.resize(2);
359 out.points.push_back(p);
373 , has_joint_states_(false)
379 pub_trajectory_ = neonavigation_common::compat::advertise<trajectory_msgs::JointTrajectory>(
380 nh_,
"joint_trajectory",
381 pnh_,
"trajectory_out", 1,
true);
383 nh_,
"trajectory_in",
389 pub_status_ = nh_group.
advertise<planner_cspace_msgs::PlannerStatus>(
"status", 1,
true);
391 nh_group.
param(
"resolution", resolution_, 128);
392 pnh_.param(
"debug_aa", debug_aa_,
false);
395 pnh_.param(
"replan_interval", interval, 0.2);
399 int queue_size_limit;
400 nh_group.
param(
"queue_size_limit", queue_size_limit, 0);
403 status_.status = planner_cspace_msgs::PlannerStatus::DONE;
405 cm_.reset(
Astar::Vec(resolution_ * 2, resolution_ * 2));
409 nh_group.
param(
"link0_name", links_[0].
name_, std::string(
"link0"));
410 nh_group.
param(
"link0_joint_radius", links_[0].
radius_[0], 0.07
f);
411 nh_group.
param(
"link0_end_radius", links_[0].radius_[1], 0.07
f);
417 nh_group.
param(
"link0_vmax", links_[0].
vmax_, 0.5
f);
418 nh_group.
param(
"link1_name", links_[1].name_, std::string(
"link1"));
419 nh_group.
param(
"link1_joint_radius", links_[1].radius_[0], 0.07
f);
420 nh_group.
param(
"link1_end_radius", links_[1].radius_[1], 0.07
f);
421 nh_group.
param(
"link1_length", links_[1].length_, 0.27
f);
426 nh_group.
param(
"link1_vmax", links_[1].vmax_, 0.5
f);
433 ROS_INFO(
"link group: %s", group_.c_str());
434 ROS_INFO(
" - link0: %s", links_[0].name_.c_str());
435 ROS_INFO(
" - link1: %s", links_[1].name_.c_str());
438 nh_group.
param(
"link0_coef", euclid_cost_coef[0], 1.0
f);
439 nh_group.
param(
"link1_coef", euclid_cost_coef[1], 1.5
f);
445 std::string point_vel_mode;
446 nh_group.
param(
"point_vel_mode", point_vel_mode, std::string(
"prev"));
447 std::transform(point_vel_mode.begin(), point_vel_mode.end(), point_vel_mode.begin(), ::tolower);
448 if (point_vel_mode.compare(
"prev") == 0)
450 else if (point_vel_mode.compare(
"next") == 0)
452 else if (point_vel_mode.compare(
"avg") == 0)
455 ROS_ERROR(
"point_vel_mode must be prev/next/avg");
457 ROS_INFO(
"Resolution: %d", resolution_);
459 for (p[0] = 0; p[0] < resolution_ * 2; p[0]++)
461 for (p[1] = 0; p[1] < resolution_ * 2; p[1]++)
466 if (links_[0].
isCollide(links_[1], pf[0], pf[1]))
474 for (p[0] = 0; p[0] < resolution_ * 2; p[0]++)
476 for (p[1] = 0; p[1] < resolution_ * 2; p[1]++)
482 int range = std::lround(cc.
expand_ * resolution_ / (2.0 * M_PI));
483 for (d[0] = -range; d[0] <= range; d[0]++)
485 for (d[1] = -range; d[1] <= range; d[1]++)
488 if ((
unsigned int)p2[0] >= (
unsigned int)resolution_ * 2 ||
489 (
unsigned int)p2[1] >= (
unsigned int)resolution_ * 2)
491 int dist = std::max(std::abs(d[0]),
abs(d[1]));
492 int c = std::floor(100.0 * (range - dist) / range);
501 nh_group.
param(
"range", range, 8);
511 nh_group.
param(
"num_threads", num_threads, 1);
512 omp_set_num_threads(num_threads);
517 const int t0,
const int t1,
518 float& gt0,
float& gt1)
520 gt0 = (t0 -
resolution_) * 2.0 * M_PI / static_cast<float>(resolution_);
521 gt1 = (t1 -
resolution_) * 2.0 * M_PI / static_cast<float>(resolution_);
525 const float gt0,
const float gt1)
527 t0 = std::lround(gt0 * resolution_ / (2.0 * M_PI)) +
resolution_;
528 t1 = std::lround(gt1 * resolution_ / (2.0 * M_PI)) +
resolution_;
547 ROS_INFO(
"Planning from (%d, %d) to (%d, %d)",
548 s[0], s[1], e[0], e[1]);
552 ROS_WARN(
"Path plan failed (current status is in collision)");
553 status_.error = planner_cspace_msgs::PlannerStatus::PATH_NOT_FOUND;
558 ROS_WARN(
"Path plan failed (goal status is in collision)");
559 status_.error = planner_cspace_msgs::PlannerStatus::PATH_NOT_FOUND;
563 d.
cycle(resolution_, resolution_);
565 std::vector<Astar::VecWithCost> starts;
566 starts.emplace_back(s);
568 if (model_->cost(s, e, starts, e) >= model_->euclidCost(d))
578 std::list<Astar::Vec> path_grid;
580 float cancel = std::numeric_limits<float>::max();
582 cancel = replan_interval_.
toSec();
584 starts, e, path_grid, model_,
588 ROS_WARN(
"Path plan failed (goal unreachable)");
589 status_.error = planner_cspace_msgs::PlannerStatus::PATH_NOT_FOUND;
600 for (
auto& n : path_grid)
608 ROS_INFO(
" next: %d, %d", n[0], n[1]);
610 n_diff.
cycle(resolution_, resolution_);
619 float prec = 2.0 * M_PI /
static_cast<float>(
resolution_);
622 egp[0] += std::ceil(-egp[0] / M_PI * 2.0) * M_PI * 2.0;
624 egp[1] += std::ceil(-egp[1] / M_PI * 2.0) * M_PI * 2.0;
625 path.back()[0] += fmod(egp[0] + prec / 2.0, prec) - prec / 2.0;
626 path.back()[1] += fmod(egp[1] + prec / 2.0, prec) - prec / 2.0;
631 for (p[0] = resolution_ / 2; p[0] < resolution_ * 3 / 2; p[0]++)
633 for (p[1] = resolution_ / 2; p[1] < resolution_ * 3 / 2; p[1]++)
636 for (
auto& g : path_grid)
642 printf(
"\033[31ms\033[0m");
644 printf(
"\033[31me\033[0m");
646 printf(
"\033[34m*\033[0m");
648 printf(
"%d", cm_[p] / 11);
665 int main(
int argc,
char* argv[])
667 ros::init(argc, argv,
"planner_2dof_serial_joints");
670 std::vector<planner_cspace::planner_2dof_serial_joints::Planner2dofSerialJointsNode::Ptr> jys;
672 pnh.
param(
"num_groups", n, 1);
673 for (
int i = 0; i < n; i++)
676 pnh.
param(
"group" + std::to_string(i) +
"_name",
677 name, std::string(
"group") + std::to_string(i));
tf2_ros::TransformListener tfl_
void cbTrajectory(const trajectory_msgs::JointTrajectory::ConstPtr &msg)
void cycle(const int res, const ArgList &...rest)
void grid2Metric(const int t0, const int t1, float >0, float >1)
std::shared_ptr< GridAstarModel2DoFSerialJoint > Ptr
void publish(const boost::shared_ptr< M > &message) const
ros::Publisher pub_trajectory_
sensor_msgs::JointState joint_
GridAstarModel2DoFSerialJoint::Ptr model_
bool search(const std::vector< VecWithCost > &ss, const Vec &e, std::list< Vec > &path, const typename GridAstarModelBase< DIM, NONCYCLIC >::Ptr &model, ProgressCallback cb_progress, const float cost_leave, const float progress_interval, const bool return_best=false)
Vec3dof end(const float th) const
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
IMETHOD Vector diff(const Vector &p_w_a, const Vector &p_w_b, double dt=1)
void setQueueSizeLimit(const size_t size)
ros::Subscriber subscribe(ros::NodeHandle &nh_new, const std::string &topic_new, ros::NodeHandle &nh_old, const std::string &topic_old, uint32_t queue_size, void(*fp)(M), const ros::TransportHints &transport_hints=ros::TransportHints())
planner_cspace_msgs::PlannerStatus status_
geometry_msgs::TransformStamped t
std::shared_ptr< Planner2dofSerialJointsNode > Ptr
ROSCPP_DECL void spin(Spinner &spinner)
int main(int argc, char *argv[])
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
void reset(const Vec size)
Astar::Gridmap< char, 0x40 > cm_
std::pair< ros::Duration, std::pair< float, float > > cmd_prev_
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool cbProgress(const std::list< Astar::Vec > &, const SearchStats &)
void grid2Metric(const Astar::Vec t, Astar::Vecf >)
ros::Subscriber sub_joint_
ros::Publisher pub_status_
trajectory_msgs::JointTrajectory traj_prev_
INLINE Rall1d< T, V, S > abs(const Rall1d< T, V, S > &x)
ros::Duration replan_interval_
float dist(const Vec3dof &b)
Planner2dofSerialJointsNode(const std::string group_name)
ros::Subscriber sub_trajectory_
bool isCollide(const LinkBody b, const float th0, const float th1)
void cbJoint(const sensor_msgs::JointState::ConstPtr &msg)
void metric2Grid(Astar::Vec &t, const Astar::Vecf gt)
bool makePlan(const Astar::Vecf sg, const Astar::Vecf eg, std::list< Astar::Vecf > &path)
void metric2Grid(int &t0, int &t1, const float gt0, const float gt1)