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"
27 
28 #include <cmath>
29 
30 #include <Eigen/Geometry>
31 
32 #include <VirtualRobot/MathTools.h>
33 
35 
37 #include <RobotAPI/interface/core/GeometryBase.h>
38 #include <RobotAPI/interface/units/PlatformUnitInterface.h>
40 
41 namespace armarx
42 {
45  {
47 
48  def->defineOptionalProperty<int>(
49  "IntervalMs",
50  10,
51  "The time in milliseconds between two calls to the simulation method.");
52  def->defineOptionalProperty<float>(
53  "InitialRotation", 0, "Initial rotation of the platform.");
54  def->defineOptionalProperty<float>(
55  "InitialPosition.x", 0, "Initial x position of the platform.");
56  def->defineOptionalProperty<float>(
57  "InitialPosition.y", 0, "Initial y position of the platform.");
58  def->defineOptionalProperty<std::string>(
59  "ReferenceFrame",
60  "Platform",
61  "Reference frame in which the platform position is reported.");
62  def->defineOptionalProperty<float>(
63  "LinearVelocity", 1000.0, "Linear velocity of the platform (default: 1000 mm/sec).");
64  def->defineOptionalProperty<float>(
65  "MaxLinearAcceleration",
66  1000.0,
67  "Linear acceleration of the platform (default: 1000 mm/sec).");
68  def->defineOptionalProperty<float>(
69  "Kp_Position", 5.0, "P value of the PID position controller");
70  def->defineOptionalProperty<float>(
71  "Kp_Velocity", 5.0, "P value of the PID velocity controller");
72  def->defineOptionalProperty<float>(
73  "AngularVelocity", 1.5, "Angular velocity of the platform (default: 1.5 rad/sec).");
74 
75  def->component(robotStateComponent);
76 
77  return def;
78  }
79 
80  void
82  {
84  referenceFrame = getProperty<std::string>("ReferenceFrame").getValue();
85  targetPositionX = currentPositionX = getProperty<float>("InitialPosition.x").getValue();
86  targetPositionY = currentPositionY = getProperty<float>("InitialPosition.y").getValue();
87  targetRotation = 0.0;
88  targetRotation = currentRotation = getProperty<float>("InitialRotation").getValue();
89 
90  maxLinearVelocity = getProperty<float>("LinearVelocity").getValue();
91  maxAngularVelocity = getProperty<float>("AngularVelocity").getValue();
92 
93  velPID.reset(
94  new MultiDimPIDController(getProperty<float>("Kp_Velocity").getValue(),
95  0,
96  0,
97  getProperty<float>("MaxLinearAcceleration").getValue()));
98  posPID.reset(
99  new MultiDimPIDController(getProperty<float>("Kp_Position").getValue(),
100  0,
101  0,
103  getProperty<float>("MaxLinearAcceleration").getValue()));
104 
105 
106  positionalAccuracy = 0.01;
107 
108  intervalMs = getProperty<int>("IntervalMs").getValue();
109  ARMARX_VERBOSE << "Starting platform unit simulation with " << intervalMs << " ms interval";
113  intervalMs,
114  false,
115  "PlatformUnitSimulation");
116  }
117 
119  PlatformUnitSimulation::currentPlatformPose() const
120  {
121  return VirtualRobot::MathTools::posrpy2eigen4f(
123  }
124 
125  void
127  {
128  agentName = robotStateComponent->getRobotName();
129  robotRootFrame = robotStateComponent->getSynchronizedRobot()->getRootNode()->getName();
130 
131  TransformStamped currentPose;
132  currentPose.header.parentFrame = GlobalFrame;
133  currentPose.header.frame = robotRootFrame;
134  currentPose.header.agent = agentName;
135  currentPose.header.timestampInMicroSeconds = TimeUtil::GetTime().toMicroSeconds();
136  currentPose.transform = currentPlatformPose();
137 
138  globalPosePrx->reportGlobalRobotPose(currentPose);
139 
140  simulationTask->start();
141  }
142 
143  void
145  {
146  if (simulationTask)
147  {
148  simulationTask->stop();
149  }
150  }
151 
152  void
154  {
155  if (simulationTask)
156  {
157  simulationTask->stop();
158  }
159  }
160 
161  void
163  {
164  // the time it took until this method was called again
165  auto now = TimeUtil::GetTime();
166  double timeDeltaInSeconds = (now - lastExecutionTime).toSecondsDouble();
167  lastExecutionTime = now;
168  std::vector<float> vel(3, 0.0f);
169  {
170  std::unique_lock lock(currentPoseMutex);
171  switch (platformMode)
172  {
173  case ePositionControl:
174  {
175  posPID->update(timeDeltaInSeconds,
176  Eigen::Vector2f(currentPositionX, currentPositionY),
177  Eigen::Vector2f(targetPositionX, targetPositionY));
178  float newXTickMotion = posPID->getControlValue()[0] * timeDeltaInSeconds;
179  currentPositionX += newXTickMotion;
180  currentPositionY += posPID->getControlValue()[1] * timeDeltaInSeconds;
181  vel[0] = posPID->getControlValue()[0];
182  vel[1] = posPID->getControlValue()[1];
183 
184  float diff = fabs(targetRotation - currentRotation);
185 
186  if (diff > orientationalAccuracy)
187  {
188  int sign = copysignf(1.0f, (targetRotation - currentRotation));
189  currentRotation +=
190  sign * std::min<float>(maxAngularVelocity * timeDeltaInSeconds, diff);
191 
192  // stay between +/- M_2_PI
193  if (currentRotation > 2 * M_PI)
194  {
195  currentRotation -= 2 * M_PI;
196  }
197 
198  if (currentRotation < -2 * M_PI)
199  {
200  currentRotation += 2 * M_PI;
201  }
202 
203  vel[2] = angularVelocity;
204  }
205  }
206  break;
207  case eVelocityControl:
208  {
209  Eigen::Vector2f targetVel(linearVelocityX, linearVelocityY);
210  Eigen::Rotation2Df rot(currentRotation);
211  targetVel = rot * targetVel;
212  velPID->update(timeDeltaInSeconds, currentTranslationVelocity, targetVel);
213  currentTranslationVelocity = timeDeltaInSeconds * velPID->getControlValue();
214  currentPositionX += timeDeltaInSeconds * currentTranslationVelocity[0];
215  currentPositionY += timeDeltaInSeconds * currentTranslationVelocity[1];
216 
217 
218  currentRotation += angularVelocity * timeDeltaInSeconds;
219 
220  // stay between +/- M_2_PI
221  if (currentRotation > 2 * M_PI)
222  {
223  currentRotation -= 2 * M_PI;
224  }
225 
226  if (currentRotation < -2 * M_PI)
227  {
228  currentRotation += 2 * M_PI;
229  }
230  vel[0] = currentTranslationVelocity[0];
231  vel[1] = currentTranslationVelocity[1];
232  vel[2] = angularVelocity;
233  }
234  break;
235  default:
236  break;
237  }
238  }
239 
240  // odom velocity is in local robot frame
241  FrameHeader odomVelocityHeader;
242  odomVelocityHeader.parentFrame = robotRootFrame;
243  odomVelocityHeader.frame = robotRootFrame;
244  odomVelocityHeader.agent = agentName;
245  odomVelocityHeader.timestampInMicroSeconds = TimeUtil::GetTime().toMicroSeconds();
246  ;
247 
248  // odom pose is in odom frame
249  FrameHeader odomPoseHeader;
250  odomPoseHeader.parentFrame = OdometryFrame;
251  odomPoseHeader.frame = robotRootFrame;
252  odomPoseHeader.agent = agentName;
253  odomPoseHeader.timestampInMicroSeconds = TimeUtil::GetTime().toMicroSeconds();
254  ;
255 
256  TransformStamped platformPose;
257  platformPose.header = odomPoseHeader;
258  platformPose.transform = currentPlatformPose();
259 
260  TwistStamped platformVelocity;
261  platformVelocity.header = odomVelocityHeader;
262  platformVelocity.twist.linear << vel[0], vel[1], 0;
263  platformVelocity.twist.angular << 0, 0, vel[2];
264 
265  odometryPrx->reportOdometryPose(platformPose);
266  odometryPrx->reportOdometryVelocity(platformVelocity);
267 
268  {
269  TransformStamped currentPose;
270  currentPose.header.parentFrame = GlobalFrame;
271  currentPose.header.frame = robotRootFrame;
272  currentPose.header.agent = agentName;
273  currentPose.header.timestampInMicroSeconds = TimeUtil::GetTime().toMicroSeconds();
274  currentPose.transform = currentPlatformPose();
275 
276  globalPosePrx->reportGlobalRobotPose(currentPose);
277  }
278 
279 
280  // legacy
281  const auto& velo = platformVelocity.twist;
282  listenerPrx->reportPlatformVelocity(velo.linear.x(), velo.linear.y(), velo.angular.z());
283  }
284 
285  void
287  Ice::Float targetPlatformPositionY,
288  Ice::Float targetPlatformRotation,
289  Ice::Float positionalAccuracy,
290  Ice::Float orientationalAccuracy,
291  const Ice::Current& c)
292  {
293  ARMARX_INFO << "new target pose : " << targetPlatformPositionX << ", "
294  << targetPlatformPositionY << " with angle " << targetPlatformRotation;
295  {
296  std::unique_lock lock(currentPoseMutex);
298  targetPositionX = targetPlatformPositionX;
299  targetPositionY = targetPlatformPositionY;
300  targetRotation = targetPlatformRotation;
301  this->positionalAccuracy = positionalAccuracy;
302  this->orientationalAccuracy = orientationalAccuracy;
303  }
304 
305  FrameHeader header;
306  header.timestampInMicroSeconds = TimeUtil::GetTime().toMicroSeconds();
307  header.parentFrame = GlobalFrame;
308  header.frame = robotRootFrame;
309  header.agent = agentName;
310 
311  TransformStamped targetPose;
312  targetPose.header = header;
313  targetPose.transform = VirtualRobot::MathTools::posrpy2eigen4f(
315  }
316 
317  void
318  armarx::PlatformUnitSimulation::move(float targetPlatformVelocityX,
319  float targetPlatformVelocityY,
320  float targetPlatformVelocityRotation,
321  const Ice::Current& c)
322  {
323  ARMARX_INFO << deactivateSpam(1) << "New velocity: " << targetPlatformVelocityX << ", "
324  << targetPlatformVelocityY
325  << " with angular velocity: " << targetPlatformVelocityRotation;
326  std::unique_lock lock(currentPoseMutex);
327  platformMode = eVelocityControl;
328  linearVelocityX = std::min(maxLinearVelocity, targetPlatformVelocityX);
329  linearVelocityY = std::min(maxLinearVelocity, targetPlatformVelocityY);
330  angularVelocity = std::min(maxAngularVelocity, targetPlatformVelocityRotation);
331  }
332 
333  void
334  PlatformUnitSimulation::moveRelative(float targetPlatformOffsetX,
335  float targetPlatformOffsetY,
336  float targetPlatformOffsetRotation,
337  float positionalAccuracy,
338  float orientationalAccuracy,
339  const Ice::Current& c)
340  {
342  {
343  std::unique_lock lock(currentPoseMutex);
344  targetPositionX = currentPositionX + targetPlatformOffsetX;
345  targetPositionY = currentPositionY + targetPlatformOffsetY;
346  targetRotation = currentRotation + targetPlatformOffsetRotation;
347  }
353  }
354 
355  void
357  float orientaionalVelocity,
358  const Ice::Current& c)
359  {
360  std::unique_lock lock(currentPoseMutex);
361  maxLinearVelocity = positionalVelocity;
362  maxAngularVelocity = orientaionalVelocity;
363  }
364 
365  void
367  {
368  move(0, 0, 0);
369  }
370 } // namespace armarx
armarx::channels::PlatformUnitObserver::platformVelocity
const PlatformUnitDatafieldCreator platformVelocity("platformVelocity")
armarx::PlatformUnitSimulation::intervalMs
int intervalMs
Definition: PlatformUnitSimulation.h:97
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
armarx::PlatformUnitSimulation::currentRotation
::Ice::Float currentRotation
Definition: PlatformUnitSimulation.h:111
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:919
armarx::PlatformUnitSimulation::targetRotation
::Ice::Float targetRotation
Definition: PlatformUnitSimulation.h:110
armarx::PlatformUnitSimulation::linearVelocityY
::Ice::Float linearVelocityY
Definition: PlatformUnitSimulation.h:114
armarx::PlatformUnitSimulation::eVelocityControl
@ eVelocityControl
Definition: PlatformUnitSimulation.h:103
armarx::PlatformUnitSimulation::velPID
MultiDimPIDControllerPtr velPID
Definition: PlatformUnitSimulation.h:123
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
armarx::PlatformUnitSimulation::onExitPlatformUnit
void onExitPlatformUnit() override
Definition: PlatformUnitSimulation.cpp:153
armarx::PlatformUnitSimulation::currentTranslationVelocity
Eigen::Vector2f currentTranslationVelocity
Definition: PlatformUnitSimulation.h:124
armarx::GlobalFrame
const std::string GlobalFrame
Definition: FramedPose.h:65
armarx::PlatformUnitSimulation::angularVelocity
::Ice::Float angularVelocity
Definition: PlatformUnitSimulation.h:116
armarx::sign
T sign(T t)
Definition: algorithm.h:214
armarx::PlatformUnit::listenerPrx
PlatformUnitListenerPrx listenerPrx
PlatformUnitListener proxy for publishing state updates.
Definition: PlatformUnit.h:134
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
armarx::PlatformUnitSimulation::platformMode
enum armarx::PlatformUnitSimulation::PlatformMode platformMode
armarx::PlatformUnitSimulation::maxLinearVelocity
::Ice::Float maxLinearVelocity
Definition: PlatformUnitSimulation.h:115
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:75
armarx::PlatformUnitSimulation::currentPositionY
::Ice::Float currentPositionY
Definition: PlatformUnitSimulation.h:109
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:286
M_PI
#define M_PI
Definition: MathTools.h:17
armarx::PlatformUnitSimulation::currentPositionX
::Ice::Float currentPositionX
Definition: PlatformUnitSimulation.h:108
FramedPose.h
armarx::PlatformUnitSimulation::linearVelocityX
::Ice::Float linearVelocityX
Definition: PlatformUnitSimulation.h:113
armarx::PlatformUnitSimulation::targetPositionX
::Ice::Float targetPositionX
Definition: PlatformUnitSimulation.h:106
armarx::PlatformUnitSimulation::onInitPlatformUnit
void onInitPlatformUnit() override
Definition: PlatformUnitSimulation.cpp:81
armarx::PlatformUnitSimulation::ePositionControl
@ ePositionControl
Definition: PlatformUnitSimulation.h:102
armarx::PlatformUnitSimulation::positionalAccuracy
::Ice::Float positionalAccuracy
Definition: PlatformUnitSimulation.h:119
armarx::PlatformUnitSimulation::simulationTask
PeriodicTask< PlatformUnitSimulation >::pointer_type simulationTask
Definition: PlatformUnitSimulation.h:126
armarx::OdometryFrame
const std::string OdometryFrame
Definition: FramedPose.h:66
armarx::MultiDimPIDController
MultiDimPIDControllerTemplate<> MultiDimPIDController
Definition: MultiDimPIDController.h:270
armarx::PlatformUnitSimulation::orientationalAccuracy
::Ice::Float orientationalAccuracy
Definition: PlatformUnitSimulation.h:120
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:107
armarx::PlatformUnitSimulation::move
void move(float targetPlatformVelocityX, float targetPlatformVelocityY, float targetPlatformVelocityRotation, const Ice::Current &c=Ice::emptyCurrent) override
Definition: PlatformUnitSimulation.cpp:318
armarx::channels::PlatformUnitObserver::platformPose
const PlatformUnitDatafieldCreator platformPose("platformPose")
armarx::PlatformUnitSimulation::currentPoseMutex
std::mutex currentPoseMutex
Definition: PlatformUnitSimulation.h:95
armarx::PlatformUnitSimulation::lastExecutionTime
IceUtil::Time lastExecutionTime
Definition: PlatformUnitSimulation.h:96
TimeUtil.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
PlatformUnit.h
armarx::PlatformUnitSimulation::eUndefined
@ eUndefined
Definition: PlatformUnitSimulation.h:101
armarx::PlatformUnit::odometryPrx
OdometryListenerPrx odometryPrx
Definition: PlatformUnit.h:137
armarx::PlatformUnitSimulation::maxAngularVelocity
::Ice::Float maxAngularVelocity
Definition: PlatformUnitSimulation.h:117
armarx::PlatformUnitSimulation::posPID
MultiDimPIDControllerPtr posPID
Definition: PlatformUnitSimulation.h:123
armarx::PeriodicTask
Definition: ArmarXManager.h:70
min
T min(T t1, T t2)
Definition: gdiam.h:44
armarx::PlatformUnitSimulation::onStartPlatformUnit
void onStartPlatformUnit() override
Definition: PlatformUnitSimulation.cpp:126
armarx::PlatformUnitSimulation::stopPlatform
void stopPlatform(const Ice::Current &c=Ice::emptyCurrent) override
Definition: PlatformUnitSimulation.cpp:366
armarx::PlatformUnitSimulation::createPropertyDefinitions
PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: PlatformUnitSimulation.cpp:44
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:35
armarx::PlatformUnitSimulation::simulationFunction
void simulationFunction()
Definition: PlatformUnitSimulation.cpp:162
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:334
armarx::PlatformUnitSimulation::onStopPlatformUnit
void onStopPlatformUnit() override
Definition: PlatformUnitSimulation.cpp:144
armarx::PlatformUnitSimulation::referenceFrame
std::string referenceFrame
Definition: PlatformUnitSimulation.h:122
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:27
armarx::PlatformUnitSimulation::setMaxVelocities
void setMaxVelocities(float positionalVelocity, float orientaionalVelocity, const Ice::Current &c=Ice::emptyCurrent) override
Definition: PlatformUnitSimulation.cpp:356
armarx::PlatformUnit::globalPosePrx
GlobalRobotPoseLocalizationListenerPrx globalPosePrx
Definition: PlatformUnit.h:136