From 1a5754e5323a0c095b56977fa7d895c3ffa07c4e Mon Sep 17 00:00:00 2001 From: Fabian Reister <fabian.reister@kit.edu> Date: Fri, 11 Jun 2021 15:51:41 +0200 Subject: [PATCH] bugfix: platform position controller is turning into wrong direction Tested: from orientation -1.3 to 1.5 --- ...onomicPlatformGlobalPositionController.cpp | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.cpp index bc246422b..249520b76 100755 --- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.cpp +++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.cpp @@ -22,6 +22,8 @@ * GNU General Public License */ #include "NJointHolonomicPlatformGlobalPositionController.h" +#include <cmath> +#include <SimoxUtility/math/periodic/periodic_clamp.h> namespace armarx { @@ -34,7 +36,7 @@ namespace armarx const NJointHolonomicPlatformGlobalPositionControllerConfigPtr& cfg, const VirtualRobot::RobotPtr&) : pid(cfg->p, cfg->i, cfg->d, cfg->maxVelocity, cfg->maxAcceleration), - opid(cfg->p_rot, cfg->i_rot, cfg->d_rot, cfg->maxRotationVelocity, cfg->maxRotationAcceleration) + opid(cfg->p_rot, cfg->i_rot, cfg->d_rot, cfg->maxRotationVelocity, cfg->maxRotationAcceleration, true) { const SensorValueBase* sv = useSensorValue(cfg->platformName); @@ -78,24 +80,28 @@ namespace armarx return; } - float relativeOrientation = currentOrientation - rtGetControlStruct().startOrientation; - Eigen::Vector2f relativeCurrentPosition = currentPosition - rtGetControlStruct().startPosition; - Eigen::Vector2f updatedPosition = rtGetControlStruct().globalPosition;// + relativeCurrentPosition; - float updatedOrientation = rtGetControlStruct().globalOrientation;//+ relativeOrientation; + const Eigen::Vector2f measuredPosition = rtGetControlStruct().globalPosition;// + relativeCurrentPosition; + const float measuredOrientation = rtGetControlStruct().globalOrientation;//+ relativeOrientation; - float relativeGlobalOrientation = rtGetControlStruct().globalOrientation - getWriterControlStruct().startOrientation; - relativeGlobalOrientation = std::atan2(std::sin(relativeGlobalOrientation), std::cos(relativeGlobalOrientation)); + const float targetOrientation = rtGetControlStruct().targetOrientation; - float relativeTargetOrientation = rtGetControlStruct().targetOrientation - getWriterControlStruct().startOrientation; - relativeTargetOrientation = std::atan2(std::sin(relativeTargetOrientation), std::cos(relativeTargetOrientation)); + // measured and target orientation are now within bounds [-pi, pi] + // in which orientation to rotate? => angleBetween is not reliable yet! + // float angleBetween = targetOrientation - measuredOrientation; - pid.update(timeSinceLastIteration.toSecondsDouble(), updatedPosition, rtGetControlStruct().target); + // angleBetween = simox::math::periodic_clamp(angleBetween, -M_PIf32, M_PIf32); + // targetOrientation = measuredOrientation + angleBetween; + // -> now angleBetween is reliable + + pid.update(timeSinceLastIteration.toSecondsDouble(), measuredPosition, rtGetControlStruct().target); //opid.update(timeSinceLastIteration.toSecondsDouble(), static_cast<double>(updatedOrientation), rtGetControlStruct().targetOrientation); - opid.update(timeSinceLastIteration.toSecondsDouble(), static_cast<double>(relativeGlobalOrientation), relativeTargetOrientation); + opid.update(timeSinceLastIteration.toSecondsDouble(), static_cast<double>(measuredOrientation), targetOrientation); + + const Eigen::Rotation2Df global_R_local(-measuredOrientation); - Eigen::Vector2f velocities = Eigen::Rotation2Df(-updatedOrientation) * Eigen::Vector2f(pid.getControlValue()[0], pid.getControlValue()[1]); + Eigen::Vector2f velocities = global_R_local * Eigen::Vector2f(pid.getControlValue()[0], pid.getControlValue()[1]); target->velocityX = velocities.x(); target->velocityY = velocities.y(); target->velocityRotation = static_cast<float>(opid.getControlValue()); @@ -112,7 +118,7 @@ namespace armarx std::lock_guard<std::recursive_mutex> lock(controlDataMutex); getWriterControlStruct().target << x, y; - getWriterControlStruct().targetOrientation = std::atan2(std::sin(yaw), std::cos(yaw)); + getWriterControlStruct().targetOrientation = simox::math::periodic_clamp(yaw, -M_PIf32, M_PIf32); getWriterControlStruct().translationAccuracy = translationAccuracy; getWriterControlStruct().rotationAccuracy = rotationAccuracy; getWriterControlStruct().newTargetSet = true; @@ -125,7 +131,7 @@ namespace armarx // ..todo: check if norm is too large getWriterControlStruct().globalPosition << currentPose.x, currentPose.y; - getWriterControlStruct().globalOrientation = currentPose.rotationAroundZ; + getWriterControlStruct().globalOrientation = simox::math::periodic_clamp(currentPose.rotationAroundZ, -M_PIf32, M_PIf32); getWriterControlStruct().startPosition = currentPosition; getWriterControlStruct().startOrientation = currentOrientation; -- GitLab