diff --git a/source/RobotAPI/libraries/RobotStatechartHelpers/ObstacleAvoidingPlatformUnitHelper.cpp b/source/RobotAPI/libraries/RobotStatechartHelpers/ObstacleAvoidingPlatformUnitHelper.cpp index 03ed255120ccf8a5084ea824f7d8e2d790c1c485..595bdf0ddd20cd91ee5452ea168fcb670821a17a 100644 --- a/source/RobotAPI/libraries/RobotStatechartHelpers/ObstacleAvoidingPlatformUnitHelper.cpp +++ b/source/RobotAPI/libraries/RobotStatechartHelpers/ObstacleAvoidingPlatformUnitHelper.cpp @@ -24,26 +24,28 @@ #include <RobotAPI/libraries/RobotStatechartHelpers/ObstacleAvoidingPlatformUnitHelper.h> -// STD/STL -#include <limits> - // Simox #include <SimoxUtility/math.h> +armarx::ObstacleAvoidingPlatformUnitHelper::ObstacleAvoidingPlatformUnitHelper( + armarx::PlatformUnitInterfacePrx platform_unit, + VirtualRobot::RobotPtr robot) : + ObstacleAvoidingPlatformUnitHelper{platform_unit, robot, Config{}} +{ + // pass +} + + armarx::ObstacleAvoidingPlatformUnitHelper::ObstacleAvoidingPlatformUnitHelper( armarx::PlatformUnitInterfacePrx platform_unit, VirtualRobot::RobotPtr robot, - const float pos_reached_threshold, - const float ori_reached_threshold) : + const Config& cfg) : m_platform_unit{platform_unit}, m_robot{robot}, - m_pos_reached_threshold{pos_reached_threshold}, - m_ori_reached_threshold{ori_reached_threshold} + m_cfg{cfg} { - const float inf = std::numeric_limits<float>::infinity(); - m_target.pos = Eigen::Vector2f{inf, inf}; - m_target.ori = inf; + // pass } @@ -58,36 +60,113 @@ armarx::ObstacleAvoidingPlatformUnitHelper::setTarget( const Eigen::Vector2f& target_pos, const float target_ori) { - m_target.pos = target_pos; - m_target.ori = target_ori; + setTarget(Target{target_pos, target_ori}); +} + + +void +armarx::ObstacleAvoidingPlatformUnitHelper::setTarget(const Target& target) +{ + m_waypoints.clear(); + m_waypoints.push_back(target); + m_current_waypoint_index = 0; + m_waypoint_changed = true; +} + + +armarx::ObstacleAvoidingPlatformUnitHelper::Target +armarx::ObstacleAvoidingPlatformUnitHelper::getCurrentTarget() +const +{ + return m_waypoints.at(m_current_waypoint_index); } void armarx::ObstacleAvoidingPlatformUnitHelper::update() { - m_platform_unit->moveTo(m_target.pos.x(), m_target.pos.y(), m_target.ori, - m_pos_reached_threshold, m_ori_reached_threshold); + // Skip to next waypoint if in proximity. + if (isCurrentTargetNear() and not isLastWaypoint()) + { + m_current_waypoint_index++; + m_waypoint_changed = true; + } + + if (m_waypoint_changed) + { + // Get thresholds depending on waypoint or final target (last waypoint). + const float pos_thresh = m_cfg.pos_reached_threshold; + const float ori_thresh = m_cfg.ori_reached_threshold; + + // Control. + const Target target = getCurrentTarget(); + m_platform_unit->moveTo(target.pos.x(), target.pos.y(), target.ori, pos_thresh, ori_thresh); + + m_waypoint_changed = false; + } +} + + +void +armarx::ObstacleAvoidingPlatformUnitHelper::addWaypoint(const Eigen::Vector2f& waypoint_pos, float waypoint_ori) +{ + addWaypoint(Target{waypoint_pos, waypoint_ori}); +} + + +void +armarx::ObstacleAvoidingPlatformUnitHelper::setWaypoints(const std::vector<Target>& waypoints) +{ + m_waypoints = waypoints; + m_current_waypoint_index = 0; + m_waypoint_changed = true; +} + + +void +armarx::ObstacleAvoidingPlatformUnitHelper::addWaypoint(const Target& waypoint) +{ + m_waypoints.push_back(waypoint); } bool -armarx::ObstacleAvoidingPlatformUnitHelper::isFinalTargetReached() +armarx::ObstacleAvoidingPlatformUnitHelper::isLastWaypoint() const { - using namespace simox::math; + return m_current_waypoint_index + 1 >= m_waypoints.size(); +} - // Determine agent position. - const Eigen::Vector2f agent_pos = m_robot->getGlobalPosition().head<2>(); - const float agent_ori = - periodic_clamp<float>(mat4f_to_rpy(m_robot->getGlobalPose()).z(), -M_PI, M_PI); - // Determine distance and angular distance to goal position and orientation. - const float target_dist = (m_target.pos - agent_pos).norm(); - const float target_angular_dist = periodic_clamp<float>(m_target.ori - agent_ori, -M_PI, M_PI); +bool +armarx::ObstacleAvoidingPlatformUnitHelper::isCurrentTargetNear() +const +{ + return getPositionError() < m_cfg.pos_near_threshold and getOrientationError() < m_cfg.ori_near_threshold; +} + - return target_dist < m_pos_reached_threshold and - std::fabs(target_angular_dist) < m_ori_reached_threshold; +bool +armarx::ObstacleAvoidingPlatformUnitHelper::isCurrentTargetReached() +const +{ + return getPositionError() < m_cfg.pos_reached_threshold and getOrientationError() < m_cfg.ori_reached_threshold; +} + + +bool +armarx::ObstacleAvoidingPlatformUnitHelper::isFinalTargetNear() +const +{ + return isLastWaypoint() and isCurrentTargetNear(); +} + + +bool +armarx::ObstacleAvoidingPlatformUnitHelper::isFinalTargetReached() +const +{ + return isLastWaypoint() and isCurrentTargetReached(); } @@ -96,3 +175,24 @@ armarx::ObstacleAvoidingPlatformUnitHelper::setMaxVelocities(float max_vel, floa { m_platform_unit->setMaxVelocities(max_vel, max_angular_vel); } + + +float +armarx::ObstacleAvoidingPlatformUnitHelper::getPositionError() +const +{ + const Eigen::Vector2f agent_pos = m_robot->getGlobalPosition().head<2>(); + return (getCurrentTarget().pos - agent_pos).norm(); +} + + +float +armarx::ObstacleAvoidingPlatformUnitHelper::getOrientationError() +const +{ + using namespace simox::math; + + const float agent_ori = + periodic_clamp<float>(mat4f_to_rpy(m_robot->getGlobalPose()).z(), -M_PI, M_PI); + return std::fabs(periodic_clamp<float>(getCurrentTarget().ori - agent_ori, -M_PI, M_PI)); +} diff --git a/source/RobotAPI/libraries/RobotStatechartHelpers/ObstacleAvoidingPlatformUnitHelper.h b/source/RobotAPI/libraries/RobotStatechartHelpers/ObstacleAvoidingPlatformUnitHelper.h index 12d7100f997eeb818f6cf0aff989e42a92059df5..85d7543c956369817a0bb4df0c3dbda9fd22a576 100644 --- a/source/RobotAPI/libraries/RobotStatechartHelpers/ObstacleAvoidingPlatformUnitHelper.h +++ b/source/RobotAPI/libraries/RobotStatechartHelpers/ObstacleAvoidingPlatformUnitHelper.h @@ -42,11 +42,30 @@ namespace armarx public: + struct Config + { + float pos_reached_threshold = 10; // [mm] + float ori_reached_threshold = 0.1; // [rad] + float pos_near_threshold = 50; // [mm] + float ori_near_threshold = 0.2; // [rad] + }; + + struct Target + { + Eigen::Vector2f pos; + float ori; + }; + + public: + + ObstacleAvoidingPlatformUnitHelper( + armarx::PlatformUnitInterfacePrx platform_unit, + VirtualRobot::RobotPtr robot); + ObstacleAvoidingPlatformUnitHelper( armarx::PlatformUnitInterfacePrx platform_unit, VirtualRobot::RobotPtr robot, - float pos_reached_threshold, - float ori_reached_threshold); + const Config& cfg); virtual ~ObstacleAvoidingPlatformUnitHelper(); @@ -54,9 +73,40 @@ namespace armarx void setTarget(const Eigen::Vector2f& target_pos, float target_ori); + void + setTarget(const Target& target); + + Target + getCurrentTarget() const; + void update(); + void + setWaypoints(const std::vector<Target>& waypoints); + + void + addWaypoint(const Eigen::Vector2f& waypoint_pos, float waypoint_ori); + + void + addWaypoint(const Target& waypoint); + + bool + isLastWaypoint() + const; + + bool + isCurrentTargetNear() + const; + + bool + isCurrentTargetReached() + const; + + bool + isFinalTargetNear() + const; + bool isFinalTargetReached() const; @@ -64,22 +114,25 @@ namespace armarx void setMaxVelocities(float max_vel, float max_angular_vel); - private: + float + getPositionError() + const; - struct target - { - Eigen::Vector2f pos; - float ori; - }; + float + getOrientationError() + const; + + private: armarx::PlatformUnitInterfacePrx m_platform_unit; VirtualRobot::RobotPtr m_robot; - target m_target; + std::vector<Target> m_waypoints; + unsigned int m_current_waypoint_index = 0; + bool m_waypoint_changed = false; - float m_pos_reached_threshold; - float m_ori_reached_threshold; + Config m_cfg; };