NJointHolonomicPlatformVelocityControllerWithRamp.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package RobotAPI::ArmarXObjects::NJointHolonomicPlatformUnitVelocityPassThroughController
17 * @author Raphael Grimm ( raphael dot grimm at kit dot edu )
18 * @date 2017
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
24
25#include <VirtualRobot/Robot.h>
26
28
33
35
36namespace armarx
37{
40 ConfigPtrT cfg,
42 ramp(cfg->maxPositionAcceleration, cfg->maxOrientationAcceleration)
43 {
44 target = useControlTarget(cfg->platformName, ControlModes::HolonomicPlatformVelocity)
47 << "The actuator " << cfg->platformName << " has no control mode "
48 << ControlModes::HolonomicPlatformVelocity;
49
50 const auto sensor = useSensorValue(cfg->platformName);
51 ARMARX_CHECK_EXPRESSION(sensor) << "No sensor value for " << cfg->platformName;
54 << "Sensor value for " << cfg->platformName << " has invalid type";
55 }
56
57 void
59 {
60 activationVelocity(0) = velocitySensor->velocityX;
61 activationVelocity(1) = velocitySensor->velocityY;
62 activationVelocity(2) = velocitySensor->velocityRotation;
63 activationTime = IceUtil::Time::now();
64
65 // init velocity ramp
67 }
68
69 void
71 const IceUtil::Time& sensorValuesTimestamp,
72 const IceUtil::Time& timeSinceLastIteration)
73 {
74 auto commandAge = sensorValuesTimestamp - rtGetControlStruct().commandTimestamp;
75
76 if (commandAge > maxCommandDelay && // command must be recent
77 (rtGetControlStruct().velocityX != 0.0f || rtGetControlStruct().velocityY != 0.0f ||
78 rtGetControlStruct().velocityRotation !=
79 0.0f)) // only throw error if any command is not zero
80 {
81 ARMARX_RT_LOGF_WARNING("Platform target velocity was not set for a too long time: "
82 "delay: %f, s, max allowed delay: %f s",
83 commandAge.toSecondsDouble(),
84 maxCommandDelay.toSecondsDouble())
85 .deactivateSpam(0.5);
86 // << deactivateSpam(0.5)
87 // << "Platform target velocity was not set for a too long time: delay: "
88 // << commandAge.toSecondsDouble()
89 // << " s, max allowed delay: " << maxCommandDelay.toSecondsDouble() << " s";
90 const Eigen::Vector3f targetVelocity = Eigen::Vector3f::Zero();
91 Eigen::Vector3f result =
92 ramp.update(targetVelocity, timeSinceLastIteration.toSecondsDouble());
93 target->velocityX = result(0);
94 target->velocityY = result(1);
95 target->velocityRotation = result(2);
96 }
97 else
98 {
99 Eigen::Vector3f result;
100 if (activationTime > rtGetControlStruct().commandTimestamp)
101 {
102 // No valid command has been specified. Sane default: come to rest.
103 const Eigen::Vector3f targetVelocity = Eigen::Vector3f::Zero();
104 result = ramp.update(targetVelocity, timeSinceLastIteration.toSecondsDouble());
105 }
106 else
107 {
108 Eigen::Vector3f x(rtGetControlStruct().velocityX,
109 rtGetControlStruct().velocityY,
110 rtGetControlStruct().velocityRotation);
111 result = ramp.update(x, timeSinceLastIteration.toSecondsDouble());
112 }
113
114 target->velocityX = result(0);
115 target->velocityY = result(1);
116 target->velocityRotation = result(2);
117 }
118 }
119
120 void
122 float maxPositionAcceleration,
123 float maxOrientationAcceleration)
124 {
125 ramp.setMaxPositionAcceleration(maxPositionAcceleration);
126 ramp.setMaxOrientationAcceleration(maxOrientationAcceleration);
127 }
128
131 "NJointHolonomicPlatformVelocityControllerWithRamp");
132
133 Cartesian2DimVelocityRamp ::Cartesian2DimVelocityRamp(float maxPositionAcceleration,
134 float maxOrientationAcceleration) :
135 maxPositionAcceleration(maxPositionAcceleration),
136 maxOrientationAcceleration(maxOrientationAcceleration)
137 {
138 }
139
140 void
141 Cartesian2DimVelocityRamp::init(const Eigen::Vector3f& state)
142 {
143 this->state = state;
144 }
145
146 Eigen::Vector3f
147 Cartesian2DimVelocityRamp::update(const Eigen::Vector3f& target, float dt)
148 {
149 if (dt <= 0)
150 {
151 return state;
152 }
153 Eigen::Vector3f delta = target - state;
154 float factor = 1;
155
156 Eigen::Vector2f posDelta = delta.block<2, 1>(0, 0);
157 float posFactor = posDelta.norm() / maxPositionAcceleration / dt;
158 factor = std::max(factor, posFactor);
159
160 float oriFactor = std::abs(delta(2)) / maxOrientationAcceleration / dt;
161 factor = std::max(factor, oriFactor);
162
163 state += delta / factor;
164 return state;
165 }
166
167 void
169 {
170 this->maxPositionAcceleration = maxPositionAcceleration;
171 }
172
173 void
175 {
176 this->maxOrientationAcceleration = maxOrientationAcceleration;
177 }
178
179} // namespace armarx
#define ARMARX_RT_LOGF_WARNING(...)
constexpr T dt
Eigen::Vector3f update(const Eigen::Vector3f &target, float dt)
Brief description of class ControlTargetHolonomicPlatformVelocity.
const SensorValueBase * useSensorValue(const std::string &sensorDeviceName) const
Get a const ptr to the given SensorDevice's SensorValue.
ControlTargetBase * useControlTarget(const std::string &deviceName, const std::string &controlMode)
Declares to calculate the ControlTarget for the given ControlDevice in the given ControlMode when rtR...
void setMaxAccelerations(float maxPositionAcceleration, float maxOrientationAcceleration)
void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration) override
TODO make protected and use attorneys.
NJointHolonomicPlatformVelocityControllerWithRamp(RobotUnit *prov, ConfigPtrT config, const VirtualRobot::RobotPtr &)
void rtPreActivateController() override
This function is called before the controller is activated.
The RobotUnit class manages a robot and its controllers.
Definition RobotUnit.h:192
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
This file offers overloads of toIce() and fromIce() functions for STL container types.
NJointControllerRegistration< NJointHolonomicPlatformVelocityControllerWithRamp > registrationNJointHolonomicPlatformVelocityControllerWithRamp("NJointHolonomicPlatformVelocityControllerWithRamp")