PlatformUnitSimulation.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package ArmarXCore::units
19  * @author Christian Boege (boege at kit dot edu)
20  * @date 2011
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
25 
26 #include "PlatformUnitSimulation.h"
28 
29 #include <RobotAPI/interface/core/GeometryBase.h>
30 #include <cmath>
31 
32 #include <Eigen/Geometry>
33 
35 
36 #include <RobotAPI/interface/units/PlatformUnitInterface.h>
38 
39 #include <VirtualRobot/MathTools.h>
40 
41 namespace armarx
42 {
44  {
46 
47  def->defineOptionalProperty<int>("IntervalMs", 10, "The time in milliseconds between two calls to the simulation method.");
48  def->defineOptionalProperty<float>("InitialRotation", 0, "Initial rotation of the platform.");
49  def->defineOptionalProperty<float>("InitialPosition.x", 0, "Initial x position of the platform.");
50  def->defineOptionalProperty<float>("InitialPosition.y", 0, "Initial y position of the platform.");
51  def->defineOptionalProperty<std::string>("ReferenceFrame", "Platform", "Reference frame in which the platform position is reported.");
52  def->defineOptionalProperty<float>("LinearVelocity", 1000.0, "Linear velocity of the platform (default: 1000 mm/sec).");
53  def->defineOptionalProperty<float>("MaxLinearAcceleration", 1000.0, "Linear acceleration of the platform (default: 1000 mm/sec).");
54  def->defineOptionalProperty<float>("Kp_Position", 5.0, "P value of the PID position controller");
55  def->defineOptionalProperty<float>("Kp_Velocity", 5.0, "P value of the PID velocity controller");
56  def->defineOptionalProperty<float>("AngularVelocity", 1.5, "Angular velocity of the platform (default: 1.5 rad/sec).");
57 
58  def->component(robotStateComponent);
59 
60  return def;
61  }
62 
64  {
66  referenceFrame = getProperty<std::string>("ReferenceFrame").getValue();
67  targetPositionX = currentPositionX = getProperty<float>("InitialPosition.x").getValue();
68  targetPositionY = currentPositionY = getProperty<float>("InitialPosition.y").getValue();
69  targetRotation = 0.0;
70  targetRotation = currentRotation = getProperty<float>("InitialRotation").getValue();
71 
72  maxLinearVelocity = getProperty<float>("LinearVelocity").getValue();
73  maxAngularVelocity = getProperty<float>("AngularVelocity").getValue();
74 
75  velPID.reset(new MultiDimPIDController(getProperty<float>("Kp_Velocity").getValue(), 0, 0, getProperty<float>("MaxLinearAcceleration").getValue()));
76  posPID.reset(new MultiDimPIDController(getProperty<float>("Kp_Position").getValue(), 0, 0, maxLinearVelocity, getProperty<float>("MaxLinearAcceleration").getValue()));
77 
78 
79  positionalAccuracy = 0.01;
80 
81  intervalMs = getProperty<int>("IntervalMs").getValue();
82  ARMARX_VERBOSE << "Starting platform unit simulation with " << intervalMs << " ms interval";
84 
85  }
86 
87  Eigen::Matrix4f PlatformUnitSimulation::currentPlatformPose() const
88  {
89  return VirtualRobot::MathTools::posrpy2eigen4f(currentPositionX, currentPositionY, 0, 0, 0, currentRotation);
90  }
91 
93  {
94  agentName = robotStateComponent->getRobotName();
95  robotRootFrame = robotStateComponent->getSynchronizedRobot()->getRootNode()->getName();
96 
97  TransformStamped currentPose;
98  currentPose.header.parentFrame = GlobalFrame;
99  currentPose.header.frame = robotRootFrame;
100  currentPose.header.agent = agentName;
101  currentPose.header.timestampInMicroSeconds = TimeUtil::GetTime().toMicroSeconds();
102  currentPose.transform = currentPlatformPose();
103 
104  globalPosePrx->reportGlobalRobotPose(currentPose);
105 
106  simulationTask->start();
107  }
108 
110  {
111  if (simulationTask)
112  {
113  simulationTask->stop();
114  }
115  }
116 
117 
119  {
120  if (simulationTask)
121  {
122  simulationTask->stop();
123  }
124  }
125 
127  {
128  // the time it took until this method was called again
129  auto now = TimeUtil::GetTime();
130  double timeDeltaInSeconds = (now - lastExecutionTime).toSecondsDouble();
131  lastExecutionTime = now;
132  std::vector<float> vel(3, 0.0f);
133  {
134  std::unique_lock lock(currentPoseMutex);
135  switch (platformMode)
136  {
137  case ePositionControl:
138  {
139  posPID->update(timeDeltaInSeconds,
140  Eigen::Vector2f(currentPositionX, currentPositionY),
141  Eigen::Vector2f(targetPositionX, targetPositionY));
142  float newXTickMotion = posPID->getControlValue()[0] * timeDeltaInSeconds;
143  currentPositionX += newXTickMotion;
144  currentPositionY += posPID->getControlValue()[1] * timeDeltaInSeconds;
145  vel[0] = posPID->getControlValue()[0];
146  vel[1] = posPID->getControlValue()[1];
147 
148  float diff = fabs(targetRotation - currentRotation);
149 
150  if (diff > orientationalAccuracy)
151  {
152  int sign = copysignf(1.0f, (targetRotation - currentRotation));
153  currentRotation += sign * std::min<float>(maxAngularVelocity * timeDeltaInSeconds, diff);
154 
155  // stay between +/- M_2_PI
156  if (currentRotation > 2 * M_PI)
157  {
158  currentRotation -= 2 * M_PI;
159  }
160 
161  if (currentRotation < -2 * M_PI)
162  {
163  currentRotation += 2 * M_PI;
164  }
165 
166  vel[2] = angularVelocity;
167 
168  }
169  }
170  break;
171  case eVelocityControl:
172  {
173  Eigen::Vector2f targetVel(linearVelocityX, linearVelocityY);
174  Eigen::Rotation2Df rot(currentRotation);
175  targetVel = rot * targetVel;
176  velPID->update(timeDeltaInSeconds, currentTranslationVelocity, targetVel);
177  currentTranslationVelocity = timeDeltaInSeconds * velPID->getControlValue();
178  currentPositionX += timeDeltaInSeconds * currentTranslationVelocity[0];
179  currentPositionY += timeDeltaInSeconds * currentTranslationVelocity[1];
180 
181 
182  currentRotation += angularVelocity * timeDeltaInSeconds;
183 
184  // stay between +/- M_2_PI
185  if (currentRotation > 2 * M_PI)
186  {
187  currentRotation -= 2 * M_PI;
188  }
189 
190  if (currentRotation < -2 * M_PI)
191  {
192  currentRotation += 2 * M_PI;
193  }
194  vel[0] = currentTranslationVelocity[0];
195  vel[1] = currentTranslationVelocity[1];
196  vel[2] = angularVelocity;
197  }
198  break;
199  default:
200  break;
201  }
202  }
203 
204  // odom velocity is in local robot frame
205  FrameHeader odomVelocityHeader;
206  odomVelocityHeader.parentFrame = robotRootFrame;
207  odomVelocityHeader.frame = robotRootFrame;
208  odomVelocityHeader.agent = agentName;
209  odomVelocityHeader.timestampInMicroSeconds = TimeUtil::GetTime().toMicroSeconds();;
210 
211  // odom pose is in odom frame
212  FrameHeader odomPoseHeader;
213  odomPoseHeader.parentFrame = OdometryFrame;
214  odomPoseHeader.frame = robotRootFrame;
215  odomPoseHeader.agent = agentName;
216  odomPoseHeader.timestampInMicroSeconds = TimeUtil::GetTime().toMicroSeconds();;
217 
218  TransformStamped platformPose;
219  platformPose.header = odomPoseHeader;
220  platformPose.transform = currentPlatformPose();
221 
222  TwistStamped platformVelocity;
223  platformVelocity.header = odomVelocityHeader;
224  platformVelocity.twist.linear << vel[0], vel[1], 0;
225  platformVelocity.twist.angular << 0, 0, vel[2];
226 
227  odometryPrx->reportOdometryPose(platformPose);
228  odometryPrx->reportOdometryVelocity(platformVelocity);
229 
230  {
231  TransformStamped currentPose;
232  currentPose.header.parentFrame = GlobalFrame;
233  currentPose.header.frame = robotRootFrame;
234  currentPose.header.agent = agentName;
235  currentPose.header.timestampInMicroSeconds = TimeUtil::GetTime().toMicroSeconds();
236  currentPose.transform = currentPlatformPose();
237 
238  globalPosePrx->reportGlobalRobotPose(currentPose);
239  }
240 
241 
242  // legacy
243  const auto& velo = platformVelocity.twist;
244  listenerPrx->reportPlatformVelocity(velo.linear.x(), velo.linear.y(), velo.angular.z());
245  }
246 
247  void PlatformUnitSimulation::moveTo(Ice::Float targetPlatformPositionX, Ice::Float targetPlatformPositionY, Ice::Float targetPlatformRotation, Ice::Float positionalAccuracy, Ice::Float orientationalAccuracy, const Ice::Current& c)
248  {
249  ARMARX_INFO << "new target pose : " << targetPlatformPositionX << ", " << targetPlatformPositionY << " with angle " << targetPlatformRotation;
250  {
251  std::unique_lock lock(currentPoseMutex);
253  targetPositionX = targetPlatformPositionX;
254  targetPositionY = targetPlatformPositionY;
255  targetRotation = targetPlatformRotation;
256  this->positionalAccuracy = positionalAccuracy;
257  this->orientationalAccuracy = orientationalAccuracy;
258  }
259 
260  FrameHeader header;
261  header.timestampInMicroSeconds = TimeUtil::GetTime().toMicroSeconds();
262  header.parentFrame = GlobalFrame;
263  header.frame = robotRootFrame;
264  header.agent = agentName;
265 
266  TransformStamped targetPose;
267  targetPose.header = header;
268  targetPose.transform = VirtualRobot::MathTools::posrpy2eigen4f(targetPositionX, targetPositionY, 0, 0, 0, targetRotation);
269  }
270 
271  void armarx::PlatformUnitSimulation::move(float targetPlatformVelocityX, float targetPlatformVelocityY, float targetPlatformVelocityRotation, const Ice::Current& c)
272  {
273  ARMARX_INFO << deactivateSpam(1) << "New velocity: " << targetPlatformVelocityX << ", " << targetPlatformVelocityY << " with angular velocity: " << targetPlatformVelocityRotation;
274  std::unique_lock lock(currentPoseMutex);
275  platformMode = eVelocityControl;
276  linearVelocityX = std::min(maxLinearVelocity, targetPlatformVelocityX);
277  linearVelocityY = std::min(maxLinearVelocity, targetPlatformVelocityY);
278  angularVelocity = std::min(maxAngularVelocity, targetPlatformVelocityRotation);
279 
280  }
281 
282  void PlatformUnitSimulation::moveRelative(float targetPlatformOffsetX, float targetPlatformOffsetY, float targetPlatformOffsetRotation, float positionalAccuracy, float orientationalAccuracy, const Ice::Current& c)
283  {
285  {
286  std::unique_lock lock(currentPoseMutex);
287  targetPositionX = currentPositionX + targetPlatformOffsetX;
288  targetPositionY = currentPositionY + targetPlatformOffsetY;
289  targetRotation = currentRotation + targetPlatformOffsetRotation;
290  }
292  }
293 
294  void PlatformUnitSimulation::setMaxVelocities(float positionalVelocity, float orientaionalVelocity, const Ice::Current& c)
295  {
296  std::unique_lock lock(currentPoseMutex);
297  maxLinearVelocity = positionalVelocity;
298  maxAngularVelocity = orientaionalVelocity;
299  }
300 
301  void PlatformUnitSimulation::stopPlatform(const Ice::Current& c)
302  {
303  move(0, 0, 0);
304  }
305 }
armarx::channels::PlatformUnitObserver::platformVelocity
const PlatformUnitDatafieldCreator platformVelocity("platformVelocity")
armarx::PlatformUnitSimulation::intervalMs
int intervalMs
Definition: PlatformUnitSimulation.h:81
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::PlatformUnitSimulation::currentRotation
::Ice::Float currentRotation
Definition: PlatformUnitSimulation.h:96
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:918
armarx::PlatformUnitSimulation::targetRotation
::Ice::Float targetRotation
Definition: PlatformUnitSimulation.h:95
armarx::PlatformUnitSimulation::linearVelocityY
::Ice::Float linearVelocityY
Definition: PlatformUnitSimulation.h:99
armarx::PlatformUnitSimulation::eVelocityControl
@ eVelocityControl
Definition: PlatformUnitSimulation.h:87
armarx::PlatformUnitSimulation::velPID
MultiDimPIDControllerPtr velPID
Definition: PlatformUnitSimulation.h:108
armarx::PlatformUnitSimulation::onExitPlatformUnit
void onExitPlatformUnit() override
Definition: PlatformUnitSimulation.cpp:118
armarx::PlatformUnitSimulation::currentTranslationVelocity
Eigen::Vector2f currentTranslationVelocity
Definition: PlatformUnitSimulation.h:109
armarx::GlobalFrame
const std::string GlobalFrame
Definition: FramedPose.h:62
armarx::PlatformUnitSimulation::angularVelocity
::Ice::Float angularVelocity
Definition: PlatformUnitSimulation.h:101
armarx::sign
T sign(T t)
Definition: algorithm.h:194
armarx::PlatformUnit::listenerPrx
PlatformUnitListenerPrx listenerPrx
PlatformUnitListener proxy for publishing state updates.
Definition: PlatformUnit.h:124
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::PlatformUnitSimulation::platformMode
enum armarx::PlatformUnitSimulation::PlatformMode platformMode
armarx::PlatformUnitSimulation::maxLinearVelocity
::Ice::Float maxLinearVelocity
Definition: PlatformUnitSimulation.h:100
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:72
armarx::PlatformUnitSimulation::currentPositionY
::Ice::Float currentPositionY
Definition: PlatformUnitSimulation.h:94
armarx::PlatformUnitSimulation::moveTo
void moveTo(Ice::Float targetPlatformPositionX, Ice::Float targetPlatformPositionY, Ice::Float targetPlatformRotation, Ice::Float positionalAccuracy, Ice::Float orientationalAccuracy, const Ice::Current &c=Ice::emptyCurrent) override
Definition: PlatformUnitSimulation.cpp:247
M_PI
#define M_PI
Definition: MathTools.h:17
armarx::PlatformUnitSimulation::currentPositionX
::Ice::Float currentPositionX
Definition: PlatformUnitSimulation.h:93
FramedPose.h
armarx::PlatformUnitSimulation::linearVelocityX
::Ice::Float linearVelocityX
Definition: PlatformUnitSimulation.h:98
armarx::PlatformUnitSimulation::targetPositionX
::Ice::Float targetPositionX
Definition: PlatformUnitSimulation.h:91
armarx::PlatformUnitSimulation::onInitPlatformUnit
void onInitPlatformUnit() override
Definition: PlatformUnitSimulation.cpp:63
armarx::PlatformUnitSimulation::ePositionControl
@ ePositionControl
Definition: PlatformUnitSimulation.h:86
armarx::PlatformUnitSimulation::positionalAccuracy
::Ice::Float positionalAccuracy
Definition: PlatformUnitSimulation.h:104
armarx::PlatformUnitSimulation::simulationTask
PeriodicTask< PlatformUnitSimulation >::pointer_type simulationTask
Definition: PlatformUnitSimulation.h:111
armarx::OdometryFrame
const std::string OdometryFrame
Definition: FramedPose.h:63
armarx::MultiDimPIDController
MultiDimPIDControllerTemplate<> MultiDimPIDController
Definition: MultiDimPIDController.h:250
armarx::PlatformUnitSimulation::orientationalAccuracy
::Ice::Float orientationalAccuracy
Definition: PlatformUnitSimulation.h:105
PlatformUnitSimulation.h
armarx::TimeUtil::GetTime
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Definition: TimeUtil.cpp:42
armarx::PlatformUnitSimulation::targetPositionY
::Ice::Float targetPositionY
Definition: PlatformUnitSimulation.h:92
armarx::PlatformUnitSimulation::move
void move(float targetPlatformVelocityX, float targetPlatformVelocityY, float targetPlatformVelocityRotation, const Ice::Current &c=Ice::emptyCurrent) override
Definition: PlatformUnitSimulation.cpp:271
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:601
armarx::channels::PlatformUnitObserver::platformPose
const PlatformUnitDatafieldCreator platformPose("platformPose")
armarx::PlatformUnitSimulation::currentPoseMutex
std::mutex currentPoseMutex
Definition: PlatformUnitSimulation.h:79
armarx::PlatformUnitSimulation::lastExecutionTime
IceUtil::Time lastExecutionTime
Definition: PlatformUnitSimulation.h:80
TimeUtil.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
PlatformUnit.h
armarx::PlatformUnitSimulation::eUndefined
@ eUndefined
Definition: PlatformUnitSimulation.h:85
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::PlatformUnit::odometryPrx
OdometryListenerPrx odometryPrx
Definition: PlatformUnit.h:127
armarx::PlatformUnitSimulation::maxAngularVelocity
::Ice::Float maxAngularVelocity
Definition: PlatformUnitSimulation.h:102
armarx::PlatformUnitSimulation::posPID
MultiDimPIDControllerPtr posPID
Definition: PlatformUnitSimulation.h:108
armarx::PeriodicTask
Definition: ArmarXManager.h:70
min
T min(T t1, T t2)
Definition: gdiam.h:42
armarx::PlatformUnitSimulation::onStartPlatformUnit
void onStartPlatformUnit() override
Definition: PlatformUnitSimulation.cpp:92
armarx::PlatformUnitSimulation::stopPlatform
void stopPlatform(const Ice::Current &c=Ice::emptyCurrent) override
Definition: PlatformUnitSimulation.cpp:301
armarx::PlatformUnitSimulation::createPropertyDefinitions
PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: PlatformUnitSimulation.cpp:43
armarx::PlatformUnitSimulation::simulationFunction
void simulationFunction()
Definition: PlatformUnitSimulation.cpp:126
armarx::PlatformUnitSimulation::moveRelative
void moveRelative(float targetPlatformOffsetX, float targetPlatformOffsetY, float targetPlatformOffsetRotation, float positionalAccuracy, float orientationalAccuracy, const Ice::Current &c=Ice::emptyCurrent) override
Definition: PlatformUnitSimulation.cpp:282
armarx::PlatformUnitSimulation::onStopPlatformUnit
void onStopPlatformUnit() override
Definition: PlatformUnitSimulation.cpp:109
armarx::PlatformUnitSimulation::referenceFrame
std::string referenceFrame
Definition: PlatformUnitSimulation.h:107
armarx::PlatformUnit::createPropertyDefinitions
PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: PlatformUnit.cpp:35
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::PlatformUnitSimulation::setMaxVelocities
void setMaxVelocities(float positionalVelocity, float orientaionalVelocity, const Ice::Current &c=Ice::emptyCurrent) override
Definition: PlatformUnitSimulation.cpp:294
armarx::PlatformUnit::globalPosePrx
GlobalRobotPoseLocalizationListenerPrx globalPosePrx
Definition: PlatformUnit.h:126