From d24d41337a8599c8e68742f998e858682d45549c Mon Sep 17 00:00:00 2001 From: Fabian Reister <fabian.reister@kit.edu> Date: Thu, 8 Jul 2021 16:34:05 +0200 Subject: [PATCH] update --- .../Navigation/libraries/core/Trajectory.cpp | 28 ++++++--- source/Navigation/libraries/core/Trajectory.h | 8 ++- .../TrajectoryFollowingController.cpp | 5 +- .../test/trajectory_controlTest.cpp | 59 ++++++++++++++++++- 4 files changed, 88 insertions(+), 12 deletions(-) diff --git a/source/Navigation/libraries/core/Trajectory.cpp b/source/Navigation/libraries/core/Trajectory.cpp index c673e059..3f463a00 100644 --- a/source/Navigation/libraries/core/Trajectory.cpp +++ b/source/Navigation/libraries/core/Trajectory.cpp @@ -9,7 +9,9 @@ namespace armarx::nav::core { - TrajectoryPoint Trajectory::getProjection(const Pose& pose) const + TrajectoryPoint + Trajectory::getProjection(const Pose& pose, + const VelocityInterpolations& velocityInterpolation) const { const auto asPt = [](const Pose & pose) -> wykobi::point2d<float> { return wykobi::make_point<float>(pose.translation().x(), pose.translation().y()); }; @@ -20,12 +22,13 @@ namespace armarx::nav::core TrajectoryPoint bestProj; - for (size_t i = 0; i < points.size() -1; i++) + for (size_t i = 0; i < points.size() - 1; i++) { const auto& wpBefore = points.at(i); const auto& wpAfter = points.at(i + 1); - auto segment = wykobi::make_segment(asPt(wpBefore.waypoint.pose), asPt(wpAfter.waypoint.pose)); + auto segment = + wykobi::make_segment(asPt(wpBefore.waypoint.pose), asPt(wpAfter.waypoint.pose)); wykobi::point2d<float> closestPoint = wykobi::closest_point_on_segment_from_point(segment, point); @@ -35,14 +38,25 @@ namespace armarx::nav::core { const float d1 = wykobi::distance(closestPoint, asPt(wpBefore.waypoint.pose)); - const float d = wykobi::distance(asPt(wpBefore.waypoint.pose), asPt(wpAfter.waypoint.pose)); + const float d = + wykobi::distance(asPt(wpBefore.waypoint.pose), asPt(wpAfter.waypoint.pose)); const float t = d1 / d; - math::LinearInterpolatedPose ip(wpBefore.waypoint.pose.matrix(), wpAfter.waypoint.pose.matrix(), 0, 1, true); + math::LinearInterpolatedPose ip( + wpBefore.waypoint.pose.matrix(), wpAfter.waypoint.pose.matrix(), 0, 1, true); bestProj.waypoint.pose = ip.Get(t); - bestProj.twist.linear = (wpAfter.twist.linear - wpBefore.twist.linear) * t; - bestProj.twist.angular = (wpAfter.twist.angular - wpBefore.twist.angular) * t; + + switch (velocityInterpolation) + { + case VelocityInterpolations::LinearInterpolation: + bestProj.twist.linear = (wpAfter.twist.linear - wpBefore.twist.linear) * t; + bestProj.twist.angular = + (wpAfter.twist.angular - wpBefore.twist.angular) * t; + break; + case VelocityInterpolations::LastWaypoint: + bestProj.twist = wpBefore.twist; + } distance = currentDistance; } diff --git a/source/Navigation/libraries/core/Trajectory.h b/source/Navigation/libraries/core/Trajectory.h index 9a9b43a6..5f2a1c07 100644 --- a/source/Navigation/libraries/core/Trajectory.h +++ b/source/Navigation/libraries/core/Trajectory.h @@ -32,6 +32,12 @@ namespace armarx::nav::core Twist twist; }; + enum class VelocityInterpolations + { + LinearInterpolation, + LastWaypoint + }; + class Trajectory { public: @@ -39,7 +45,7 @@ namespace armarx::nav::core { } - TrajectoryPoint getProjection(const Pose& pose) const; + TrajectoryPoint getProjection(const Pose& pose, const VelocityInterpolations& velocityInterpolation) const; private: std::vector<TrajectoryPoint> points; diff --git a/source/Navigation/libraries/trajectory_control/TrajectoryFollowingController.cpp b/source/Navigation/libraries/trajectory_control/TrajectoryFollowingController.cpp index 34330e99..eda53b12 100644 --- a/source/Navigation/libraries/trajectory_control/TrajectoryFollowingController.cpp +++ b/source/Navigation/libraries/trajectory_control/TrajectoryFollowingController.cpp @@ -89,7 +89,7 @@ namespace armarx::nav::traj_ctrl const core::Pose currentPose(context.robot->getGlobalPose()); - const auto targetPose = trajectory->getProjection(currentPose); + const auto targetPose = trajectory->getProjection(currentPose, core::VelocityInterpolations::LastWaypoint); ARMARX_INFO << targetPose.waypoint.pose.translation(); @@ -107,6 +107,9 @@ namespace armarx::nav::traj_ctrl pidPos.update(mat4f_to_pos(currentPose.matrix()), mat4f_to_pos(targetPose.waypoint.pose.matrix())); pidOri.update(mat4f_to_rpy(currentPose.matrix()), mat4f_to_rpy(targetPose.waypoint.pose.matrix())); + ARMARX_INFO << "Feed forward velocity " << targetPose.twist.linear; + ARMARX_INFO << "Control value " << pidPos.getControlValue(); + // TODO: better handling if feed forward velocity is not set. need movement direction ... core::Twist twist = { diff --git a/source/Navigation/libraries/trajectory_control/test/trajectory_controlTest.cpp b/source/Navigation/libraries/trajectory_control/test/trajectory_controlTest.cpp index 4b30e427..a9cda016 100644 --- a/source/Navigation/libraries/trajectory_control/test/trajectory_controlTest.cpp +++ b/source/Navigation/libraries/trajectory_control/test/trajectory_controlTest.cpp @@ -20,8 +20,14 @@ * GNU General Public License */ +#include <limits> + #include <Eigen/Geometry> +#include <Eigen/src/Geometry/Transform.h> +#include <Eigen/src/Geometry/Translation.h> + #include <VirtualRobot/Robot.h> + #include "Navigation/libraries/core/Trajectory.h" #define BOOST_TEST_MODULE Navigation::ArmarXLibraries::trajectory_control @@ -37,29 +43,76 @@ using namespace armarx::nav; -BOOST_AUTO_TEST_CASE(testTrajectoryFollowingController) +BOOST_AUTO_TEST_CASE(testTrajectoryFollowingControllerOnTrajectory) { core::Scene scene; scene.robot = std::make_shared<VirtualRobot::LocalRobot>("foo", "bar"); scene.robot->setGlobalPose(Eigen::Matrix4f::Identity(), false); - traj_ctrl::TrajectoryFollowingController controller(traj_ctrl::TrajectoryFollowingControllerParams(), - scene); + traj_ctrl::TrajectoryFollowingControllerParams params; + params.pidPos = {1, 0, 0}; + params.pidOri = {1, 0, 0}; + params.limits.linearVelocity = std::numeric_limits<float>::max(); + params.limits.angularVelocity = std::numeric_limits<float>::max(); + + traj_ctrl::TrajectoryFollowingController controller(params, scene); core::TrajectoryPoint wpBefore; wpBefore.waypoint.pose = Eigen::Affine3f::Identity(); + wpBefore.waypoint.pose.translation().x() -= 100.F; wpBefore.twist.linear = Eigen::Vector3f::UnitX(); wpBefore.twist.angular = Eigen::Vector3f::Zero(); core::TrajectoryPoint wpAfter = wpBefore; wpAfter.waypoint.pose.translation().x() += 2000.F; + core::TrajectoryPtr traj(new core::Trajectory({wpBefore, wpAfter})); + + core::Twist controlVal = controller.control(traj); + + ARMARX_DEBUG << "Control val " << controlVal.linear; + + // only feed-forward velocity needs to be considered + BOOST_CHECK_EQUAL(controlVal.linear.x(), 1.0); + + BOOST_CHECK_EQUAL(true, true); +} + + +/** + * @brief Tests the control + * + */ +BOOST_AUTO_TEST_CASE(testTrajectoryFollowingControllerNextToTrajectory) +{ + core::Scene scene; + scene.robot = std::make_shared<VirtualRobot::LocalRobot>("foo", "bar"); + scene.robot->setGlobalPose(Eigen::Matrix4f::Identity() * Eigen::Affine3f(Eigen::Translation3f(0, 100, 0)).matrix(), false); + + traj_ctrl::TrajectoryFollowingControllerParams params; + params.pidPos = {1, 0, 0}; + params.pidOri = {1, 0, 0}; + params.limits.linearVelocity = std::numeric_limits<float>::max(); + params.limits.angularVelocity = std::numeric_limits<float>::max(); + + traj_ctrl::TrajectoryFollowingController controller(params, scene); + + core::TrajectoryPoint wpBefore; + wpBefore.waypoint.pose = Eigen::Affine3f::Identity(); + wpBefore.waypoint.pose.translation().x() -= 100.F; + wpBefore.twist.linear = Eigen::Vector3f::UnitX(); + wpBefore.twist.angular = Eigen::Vector3f::Zero(); + + core::TrajectoryPoint wpAfter = wpBefore; + wpAfter.waypoint.pose.translation().x() += 2000.F; core::TrajectoryPtr traj(new core::Trajectory({wpBefore, wpAfter})); core::Twist controlVal = controller.control(traj); + ARMARX_DEBUG << "Control val " << controlVal.linear; + // only feed-forward velocity needs to be considered BOOST_CHECK_EQUAL(controlVal.linear.x(), 1.0); -- GitLab