6 #include <Eigen/Geometry> 9 #include <ram_modify_trajectory/AddPoses.h> 10 #include <ram_modify_trajectory/DeleteSelectedPoses.h> 11 #include <ram_modify_trajectory/ModifySelectedPoses.h> 12 #include <ram_modify_trajectory/ReflectSelectedPoses.h> 13 #include <ram_modify_trajectory/ResetSelectedPoses.h> 14 #include <ram_modify_trajectory/RotateSelectedPoses.h> 15 #include <ram_modify_trajectory/ScaleSelectedPoses.h> 16 #include <ram_msgs/AdditiveManufacturingPose.h> 17 #include <ram_msgs/AdditiveManufacturingTrajectory.h> 18 #include <ram_utils/UnmodifiedTrajectory.h> 19 #include <ram_utils/AddEntryExitStrategies.h> 22 #include <uuid_msgs/UniqueID.h> 29 ram_msgs::AdditiveManufacturingTrajectory
layers;
35 bool pose_in_polygon =
false;
37 for (
auto current_pose : trajectory.poses)
39 if ((current_pose.polygon_start || current_pose.polygon_end) && (current_pose.entry_pose || current_pose.exit_pose))
42 if (current_pose.polygon_start && current_pose.polygon_end)
45 if (current_pose.polygon_start)
48 pose_in_polygon =
true;
52 if (current_pose.polygon_end)
55 pose_in_polygon =
false;
67 std::vector<ram_msgs::AdditiveManufacturingPose> poses)
69 for (
unsigned i(0); i < poses.size(); ++i)
72 bool pose_is_deleted =
false;
75 for (
unsigned j(0); j < trajectory.poses.size(); ++j)
78 if (selected_pose_uuid.compare(current_uuid) != 0)
81 trajectory.poses.erase(trajectory.poses.begin() + j);
82 pose_is_deleted =
true;
88 ROS_ERROR_STREAM(
"Pose to be deleted could not be found, UUID = " << selected_pose_uuid);
93 trajectory.similar_layers =
false;
97 bool findPose(std::string pose_uuid, std::vector<ram_msgs::AdditiveManufacturingPose> poses,
98 ram_msgs::AdditiveManufacturingPose &pose)
100 for (
auto current_pose : poses)
103 if (pose_uuid.compare(current_pose_uuid) != 0)
119 ram_modify_trajectory::ModifySelectedPoses::Response &)
125 if (req.poses.empty())
131 if (trajectory.poses.empty())
137 std::vector<ram_msgs::AdditiveManufacturingPose> strategies_to_delete;
139 std::vector<ram_msgs::AdditiveManufacturingParams::_movement_type_type> move_types;
140 for (
auto pose : req.poses)
141 move_types.push_back(pose.params.movement_type);
143 if (std::adjacent_find(move_types.begin(), move_types.end(), std::not_equal_to<int>()) != move_types.end())
148 ROS_ERROR_STREAM(
"Cannot modify speed if not all the poses have the same motion type");
154 for (
unsigned i(0); i < req.poses.size(); ++i)
157 bool pose_in_trajectory =
false;
159 for (
unsigned j(0); j < trajectory.poses.size(); ++j)
163 if (current_pose_uuid.compare(selected_pose_uuid) != 0)
167 pose_in_trajectory =
true;
180 trajectory.poses[j].pose = req.pose_reference.pose;
183 Eigen::Affine3d current_pose_eigen, reference_pose;
187 current_pose_eigen.matrix() *= reference_pose.matrix();
192 if (req.polygon_start)
194 if (trajectory.poses[j].polygon_start && !req.pose_reference.polygon_start)
197 for (
int strategy_id(j - 1); strategy_id >= 0; --strategy_id)
199 if (trajectory.poses[strategy_id].entry_pose)
200 strategies_to_delete.push_back(trajectory.poses[strategy_id]);
206 trajectory.poses[j].polygon_start = req.pose_reference.polygon_start;
212 if (trajectory.poses[j].polygon_end && !req.pose_reference.polygon_end)
214 for (
unsigned strategy_id(j + 1); strategy_id < trajectory.poses.size(); ++strategy_id)
216 if (trajectory.poses[strategy_id].exit_pose)
217 strategies_to_delete.push_back(trajectory.poses[strategy_id]);
222 trajectory.poses[j].polygon_end = req.pose_reference.polygon_end;
225 if (req.movement_type)
226 trajectory.poses[j].params.movement_type = req.pose_reference.params.movement_type;
228 if (req.approach_type)
229 trajectory.poses[j].params.approach_type = req.pose_reference.params.approach_type;
232 if (req.blend_radius)
233 trajectory.poses[j].params.blend_radius = req.pose_reference.params.blend_radius;
236 trajectory.poses[j].params.blend_radius += req.pose_reference.params.blend_radius;
238 if (trajectory.poses[j].params.blend_radius < 0)
244 if (trajectory.poses[j].params.blend_radius > 100)
252 trajectory.poses[j].params.speed = req.pose_reference.params.speed;
255 trajectory.poses[j].params.speed += req.pose_reference.params.speed;
257 if (trajectory.poses[j].params.speed < 1e-12)
265 trajectory.poses[j].params.laser_power = req.pose_reference.params.laser_power;
268 trajectory.poses[j].params.laser_power += req.pose_reference.params.laser_power;
270 if (trajectory.poses[j].params.laser_power < 0)
278 trajectory.poses[j].params.feed_rate = req.pose_reference.params.feed_rate;
281 trajectory.poses[j].params.feed_rate += req.pose_reference.params.feed_rate;
283 if (trajectory.poses[j].params.feed_rate < 0)
292 if (!pose_in_trajectory)
294 ROS_ERROR_STREAM(
"There are pose in the request that are not in the trajectory");
300 if (!
deletePoses(trajectory, strategies_to_delete))
314 ram_utils::AddEntryExitStrategies srv;
315 srv.request.poses = trajectory.poses;
316 bool success = entry_exit_strategies_client.
call(srv);
318 trajectory.poses = srv.response.poses;
322 trajectory_pub.
publish(trajectory);
329 ram_modify_trajectory::ResetSelectedPoses::Response &)
335 if (req.poses.empty())
338 if (trajectory.poses.empty())
342 ram_utils::UnmodifiedTrajectory unmodified_trajectory;
343 unmodified_trajectory.request.generated = trajectory.generated;
344 if (!unmodified_trajectory_client.
call(unmodified_trajectory))
350 std::vector<ram_msgs::AdditiveManufacturingPose> poses_to_delete;
352 for (
unsigned i(0); i < req.poses.size(); ++i)
355 bool pose_in_current_traj =
false;
356 for (
unsigned j(0); j < trajectory.poses.size(); ++j)
360 if (current_pose_uuid.compare(selected_uuid) != 0)
364 pose_in_current_traj =
true;
366 ram_msgs::AdditiveManufacturingPose unmodified_pose;
367 ram_msgs::AdditiveManufacturingPose p;
369 if (
findPose(current_pose_uuid, unmodified_trajectory.response.trajectory.poses, unmodified_pose))
372 if (trajectory.poses[j].polygon_start && !unmodified_pose.polygon_start)
375 for (
int strategy_id(j - 1); strategy_id >= 0; --strategy_id)
377 if (trajectory.poses[strategy_id].entry_pose)
380 if (!
findPose(current_pose_uuid, poses_to_delete, p))
381 poses_to_delete.push_back(trajectory.poses[strategy_id]);
388 for (
unsigned strategy_id(j + 1); strategy_id < trajectory.poses.size(); ++strategy_id)
390 if (trajectory.poses[strategy_id].exit_pose)
393 if (!
findPose(current_pose_uuid, poses_to_delete, p))
394 poses_to_delete.push_back(trajectory.poses[strategy_id]);
400 trajectory.poses[j] = unmodified_pose;
404 if (!
findPose(current_pose_uuid, poses_to_delete, p))
405 poses_to_delete.push_back(trajectory.poses[j]);
410 if (!pose_in_current_traj)
421 ram_utils::AddEntryExitStrategies srv;
422 srv.request.poses = trajectory.poses;
423 bool success = entry_exit_strategies_client.
call(srv);
425 trajectory.poses = srv.response.poses;
429 trajectory_pub.
publish(trajectory);
435 bool addPosesCallback(ram_modify_trajectory::AddPoses::Request &req, ram_modify_trajectory::AddPoses::Response &)
442 if (req.poses.empty())
445 if (trajectory.poses.empty())
449 for (
unsigned i(0); i < req.poses.size(); ++i)
453 bool pose_in_trajectory =
false;
454 for (
unsigned j(0); j < trajectory.poses.size(); ++j)
457 if (selected_uuid.compare(layers_uuid) != 0)
461 pose_in_trajectory =
true;
462 ram_msgs::AdditiveManufacturingPose new_pose = trajectory.poses[j];
466 new_pose.polygon_start =
false;
467 new_pose.polygon_end =
false;
470 if (trajectory.poses[j].polygon_end)
471 trajectory.poses[j].exit_pose =
true;
473 if ((j + 1) == trajectory.poses.size())
475 trajectory.poses.push_back(new_pose);
480 new_pose.pose.position.x = (trajectory.poses[j].pose.position.x + trajectory.poses[j + 1].pose.position.x) / 2;
481 new_pose.pose.position.y = (trajectory.poses[j].pose.position.y + trajectory.poses[j + 1].pose.position.y) / 2;
482 new_pose.pose.position.z = (trajectory.poses[j].pose.position.z + trajectory.poses[j + 1].pose.position.z) / 2;
484 trajectory.poses.insert(trajectory.poses.begin() + j + 1, new_pose);
488 if (!pose_in_trajectory)
492 trajectory.similar_layers =
false;
494 trajectory_pub.
publish(trajectory);
499 ram_modify_trajectory::DeleteSelectedPoses::Response &)
505 if (req.poses.empty())
508 if (trajectory.poses.empty())
511 std::vector<ram_msgs::AdditiveManufacturingPose> strategies_to_delete;
514 for (
unsigned i(0); i < req.poses.size(); ++i)
517 bool pose_is_deleted =
false;
520 for (
unsigned j(0); j < trajectory.poses.size(); ++j)
523 if (selected_pose_uuid.compare(current_uuid) != 0)
527 ram_msgs::AdditiveManufacturingPose p;
529 if (trajectory.poses[j].polygon_start)
532 for (
int strategy_id(j - 1); strategy_id >= 0; --strategy_id)
534 if (trajectory.poses[strategy_id].entry_pose)
539 if (!
findPose(strategy_uuid, req.poses, p))
540 if (!
findPose(strategy_uuid, strategies_to_delete, p))
541 strategies_to_delete.push_back(trajectory.poses[strategy_id]);
549 if (trajectory.poses[j].polygon_end)
552 for (
unsigned strategy_id(j + 1); strategy_id < trajectory.poses.size(); ++strategy_id)
554 if (trajectory.poses[strategy_id].exit_pose)
559 if (!
findPose(strategy_uuid, req.poses, p))
560 if (!
findPose(strategy_uuid, strategies_to_delete, p))
561 strategies_to_delete.push_back(trajectory.poses[strategy_id]);
568 if (trajectory.poses[j].polygon_start && !trajectory.poses[j].polygon_end)
570 if ((j + 1) != trajectory.poses.size())
571 trajectory.poses[j + 1].polygon_start =
true;
573 else if (trajectory.poses[j].polygon_end && !trajectory.poses[j].polygon_start)
576 trajectory.poses[j - 1].polygon_end =
true;
580 trajectory.poses.erase(trajectory.poses.begin() + j);
581 pose_is_deleted =
true;
585 if (!pose_is_deleted)
589 if (trajectory.poses.empty())
593 if (!
deletePoses(trajectory, strategies_to_delete))
596 if (trajectory.poses.empty())
599 bool trajectory_ok(
false);
600 for (
auto pose : trajectory.poses)
602 if (!pose.entry_pose && !pose.exit_pose)
604 trajectory_ok =
true;
617 ram_utils::AddEntryExitStrategies srv;
618 srv.request.poses = trajectory.poses;
619 bool success = entry_exit_strategies_client.
call(srv);
621 trajectory.poses = srv.response.poses;
624 trajectory.similar_layers =
false;
626 trajectory_pub.
publish(trajectory);
632 ram_modify_trajectory::RotateSelectedPoses::Response &)
635 if (req.poses.empty())
643 Eigen::Vector3d center_affine;
646 std::vector<ram_msgs::AdditiveManufacturingPose> selected_poses(req.poses);
652 Eigen::Affine3d translation_tf_cr(Eigen::Affine3d::Identity());
653 translation_tf_cr.translate(center_affine);
655 Eigen::Affine3d rot_z(Eigen::Affine3d::Identity());
656 rot_z.rotate(Eigen::AngleAxisd(req.rotation_angle, Eigen::Vector3d::UnitZ()));
658 Eigen::Affine3d transformation(translation_tf_cr * rot_z * translation_tf_cr.inverse());
661 for (
auto &selected_pose : req.poses)
664 bool pose_in_trajectory =
false;
666 for (
auto ¤t_pose : trajectory.poses)
671 if (current_uuid.compare(selected_uuid) != 0)
675 pose_in_trajectory =
true;
676 Eigen::Affine3d current_pose_affine;
679 Eigen::Affine3d new_pose = Eigen::Affine3d::Identity();
680 new_pose = transformation * current_pose_affine;
682 geometry_msgs::Pose new_pose_msg;
684 current_pose.pose = new_pose_msg;
688 if (!pose_in_trajectory)
693 trajectory_pub.
publish(trajectory);
700 ram_modify_trajectory::ReflectSelectedPoses::Response &)
705 if (req.poses.empty())
711 if (trajectory.poses.empty())
718 Eigen::Vector3d p_plane;
721 Eigen::Vector3d n_plane;
727 Eigen::Affine3d trans_o_plane(Eigen::Affine3d::Identity());
728 trans_o_plane.translate(p_plane);
731 Eigen::Affine3d householder(Eigen::Affine3d::Identity());
732 householder.matrix().topLeftCorner(3, 3) = Eigen::Matrix3d::Identity() - 2 * n_plane * n_plane.transpose();
734 Eigen::Affine3d reflect(trans_o_plane * householder * trans_o_plane.inverse());
737 for (
auto &selected_pose : req.poses)
740 bool pose_in_trajectory =
false;
742 for (
auto ¤t_pose : trajectory.poses)
747 if (current_uuid.compare(selected_uuid) != 0)
751 pose_in_trajectory =
true;
753 Eigen::Affine3d current_pose_affine;
757 Eigen::Affine3d new_pose = current_pose_affine;
758 new_pose.translation() = reflect * current_pose_affine.translation();
760 geometry_msgs::Pose new_pose_msg;
762 current_pose.pose = new_pose_msg;
766 if (!pose_in_trajectory)
774 trajectory_pub.
publish(trajectory);
780 ram_modify_trajectory::ScaleSelectedPoses::Response &)
785 if (req.poses.empty())
791 if (trajectory.poses.empty())
798 Eigen::Vector3d center_of_scaling;
803 Eigen::Affine3d translation(Eigen::Affine3d::Identity());
804 translation.translate(center_of_scaling);
806 Eigen::Affine3d scaling(Eigen::Affine3d::Identity());
807 scaling.scale(Eigen::Vector3d(req.scale_factor, req.scale_factor, 1));
809 Eigen::Affine3d transformation(translation * scaling * translation.inverse());
811 for (
auto &selected_pose : req.poses)
814 bool pose_in_trajectory =
false;
816 for (
auto ¤t_pose : trajectory.poses)
821 if (current_uuid.compare(selected_uuid) != 0)
825 pose_in_trajectory =
true;
827 Eigen::Affine3d current_pose_affine;
831 Eigen::Affine3d new_pose = current_pose_affine;
832 new_pose.translation() = transformation * current_pose_affine.translation();
834 geometry_msgs::Pose new_pose_msg;
836 current_pose.pose = new_pose_msg;
840 if (!pose_in_trajectory)
848 trajectory_pub.
publish(trajectory);
853 int main(
int argc,
char **argv)
855 ros::init(argc, argv,
"modify_trajectory");
859 trajectory_pub = nh.
advertise<ram_msgs::AdditiveManufacturingTrajectory>(
"ram/trajectory", 10,
true);
862 unmodified_trajectory_client = nh.
serviceClient<ram_utils::UnmodifiedTrajectory>(
863 "ram/buffer/get_unmodified_trajectory");
865 entry_exit_strategies_client = nh.
serviceClient<ram_utils::AddEntryExitStrategies>(
866 "ram/information/add_entry_exit_strategies");
static boost::uuids::uuid fromRandom(void)
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
bool addPosesCallback(ram_modify_trajectory::AddPoses::Request &req, ram_modify_trajectory::AddPoses::Response &)
void publish(const boost::shared_ptr< M > &message) const
bool modifySelectedPosesCallback(ram_modify_trajectory::ModifySelectedPoses::Request &req, ram_modify_trajectory::ModifySelectedPoses::Response &)
void poseEigenToMsg(const Eigen::Affine3d &e, geometry_msgs::Pose &m)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void poseMsgToEigen(const geometry_msgs::Pose &m, Eigen::Affine3d &e)
bool scaleSelectedPosesCallback(ram_modify_trajectory::ScaleSelectedPoses::Request &req, ram_modify_trajectory::ScaleSelectedPoses::Response &)
ros::ServiceClient entry_exit_strategies_client
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
bool call(MReq &req, MRes &res)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
std::unique_ptr< ros::NodeHandle > nh
bool deleteSelectedPosesCallback(ram_modify_trajectory::DeleteSelectedPoses::Request &req, ram_modify_trajectory::DeleteSelectedPoses::Response &)
bool resetSelectedPosesCallback(ram_modify_trajectory::ResetSelectedPoses::Request &req, ram_modify_trajectory::ResetSelectedPoses::Response &)
bool deletePoses(ram_msgs::AdditiveManufacturingTrajectory &trajectory, std::vector< ram_msgs::AdditiveManufacturingPose > poses)
void vectorMsgToEigen(const geometry_msgs::Vector3 &m, Eigen::Vector3d &e)
ros::ServiceClient unmodified_trajectory_client
int main(int argc, char **argv)
void pointMsgToEigen(const geometry_msgs::Point &m, Eigen::Vector3d &e)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool findPose(std::string pose_uuid, std::vector< ram_msgs::AdditiveManufacturingPose > poses, ram_msgs::AdditiveManufacturingPose &pose)
static std::string toHexString(boost::uuids::uuid const &uu)
void saveTrajectoryCallback(const ram_msgs::AdditiveManufacturingTrajectoryConstPtr &msg)
bool rotateSelectedPosesCallback(ram_modify_trajectory::RotateSelectedPoses::Request &req, ram_modify_trajectory::RotateSelectedPoses::Response &)
bool reflectSelectedPosesCallback(ram_modify_trajectory::ReflectSelectedPoses::Request &req, ram_modify_trajectory::ReflectSelectedPoses::Response &)
static uuid_msgs::UniqueID toMsg(boost::uuids::uuid const &uu)
ram_msgs::AdditiveManufacturingTrajectory trajectory
#define ROS_ERROR_STREAM(args)
ram_msgs::AdditiveManufacturingTrajectory layers
bool verifyPolygonLimits(ram_msgs::AdditiveManufacturingTrajectory trajectory)
ros::Publisher trajectory_pub
ROSCPP_DECL void waitForShutdown()