MovePlatformRelative.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2014-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 RobotSkillTemplates::PlatformGroup
19  * @author Mirko Waechter ( mirko dot waechter at kit dot edu )
20  * @date 2015
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
25 #include "MovePlatformRelative.h"
26 
28 
30 
31 #include "PlatformContext.h"
32 
33 using namespace armarx;
34 using namespace PlatformGroup;
35 
36 // DO NOT EDIT NEXT LINE
37 MovePlatformRelative::SubClassRegistry
38  MovePlatformRelative::Registry(MovePlatformRelative::GetName(),
40 
43  MovePlatformRelativeGeneratedBase<MovePlatformRelative>(stateData)
44 {
45 }
46 
47 void
49 {
50  if (!in.getUsePlatformNativeController())
51  {
52  // put your user code for the enter-point here
53  // execution time should be short (<100ms)
54  PlatformContext* c = getContext<PlatformContext>();
55  auto pose = in.getRelativePose();
56 
57  DatafieldRefPtr posXRef =
58  new DatafieldRef(c->platformUnitObserverPrx, "platformPose", "positionX");
59  DatafieldRefPtr posYRef =
60  new DatafieldRef(c->platformUnitObserverPrx, "platformPose", "positionY");
61  DatafieldRefPtr oriRef =
62  new DatafieldRef(c->platformUnitObserverPrx, "platformPose", "rotation");
63  float posX = posXRef->getDataField()->getFloat();
64  float posY = posYRef->getDataField()->getFloat();
65  float ori = oriRef->getDataField()->getFloat();
66 
67  Eigen::Vector3f localPos{pose->x, pose->y, 0};
69  m = Eigen::AngleAxisf(ori, Eigen::Vector3f::UnitZ());
70  Eigen::Vector3f globalPos = m * localPos;
71 
72  if (pose->z > M_PI)
73  {
74  pose->z -= M_PI * 2.0;
75  }
76 
77  if (pose->z < -M_PI)
78  {
79  pose->z += M_PI * 2.0;
80  }
81 
82  float targetX = posX + globalPos[0];
83  float targetY = posY + globalPos[1];
84  float targetOri = ori + pose->z;
85 
86  while (targetOri < 0)
87  {
88  targetOri += M_PI * 2.0;
89  }
90 
91  while (targetOri > M_PI * 2.0)
92  {
93  targetOri -= M_PI * 2.0;
94  }
95 
96  ARMARX_INFO << "Relative target pose: " << pose->toEigen().transpose();
97  ARMARX_INFO << "Global target pose: " << targetX << " " << targetY << " " << targetOri;
98  local.setAbsoluteTargetPosition(new Vector3(targetX, targetY, targetOri));
99  }
100  else
101  {
102  cancelSubstates();
103  PlatformContext* context = getContext<PlatformContext>();
104  std::string platformDatafieldName = in.getPlatformPoseDatafieldName();
106  context->platformUnitObserverName + "." + platformDatafieldName + ".positionX");
108  context->platformUnitObserverName + "." + platformDatafieldName + ".positionY");
110  context->platformUnitObserverName + "." + platformDatafieldName + ".rotation");
111  auto datafields = context->platformUnitObserverPrx->getDataFields({posXId, posYId, rotId});
112  auto relativeTargetPose = in.getRelativePose();
113 
114  Vector3Ptr target = new Vector3(
115  datafields.at(0)->getFloat() + relativeTargetPose->x,
116  datafields.at(1)->getFloat() + relativeTargetPose->y,
117  math::MathUtils::angleMod2PI(datafields.at(2)->getFloat() + relativeTargetPose->z));
118 
119 
120  Literal checkX(*posXId, checks::approx, {target->x, in.getPositionalAccuracy()});
121  Literal checkY(*posYId, checks::approx, {target->y, in.getPositionalAccuracy()});
122 
123  Literal checkAngle(*rotId, checks::approx, {target->z, in.getOrientationalAccuracy()});
124  // for special case of orientations around 2*PI
125  float checkAngleValueOffset;
126 
127  if (target->z > M_PI)
128  {
129  checkAngleValueOffset = -2 * M_PI;
130  }
131  else
132  {
133  checkAngleValueOffset = 2 * M_PI;
134  }
135 
136  Literal checkAngle2(
137  rotId,
138  checks::approx,
139  {(float)(target->z + checkAngleValueOffset), in.getOrientationalAccuracy()});
140 
141  installConditionForTargetReached(checkX && checkY && (checkAngle || checkAngle2));
142  setTimeoutEvent(in.getTimeout(), this->createEventTimeout());
143  // usleep(20000);
144  }
145 }
146 
147 void
149 {
150  std::string platformDatafieldName = in.getPlatformPoseDatafieldName();
151  if (in.getUsePlatformNativeController())
152  {
153  PlatformContext* context = getContext<PlatformContext>();
155  context->platformUnitObserverName + "." + platformDatafieldName + ".positionX");
157  context->platformUnitObserverName + "." + platformDatafieldName + ".positionY");
159  context->platformUnitObserverName + "." + platformDatafieldName + ".rotation");
160  auto datafields = context->platformUnitObserverPrx->getDataFields({posXId, posYId, rotId});
161  auto relativeTargetPose = in.getRelativePose();
162  Vector3Ptr target = new Vector3(
163  datafields.at(0)->getFloat() + relativeTargetPose->x,
164  datafields.at(1)->getFloat() + relativeTargetPose->y,
165  math::MathUtils::angleMod2PI(datafields.at(2)->getFloat() + relativeTargetPose->z));
166  context->platformUnitPrx->moveRelative(relativeTargetPose->x,
167  relativeTargetPose->y,
168  relativeTargetPose->z,
169  in.getPositionalAccuracy(),
170  in.getOrientationalAccuracy());
171  auto getError = [&]()
172  {
173  auto datafields =
174  context->platformUnitObserverPrx->getDataFields({posXId, posYId, rotId});
175 
176  Eigen::Vector2f currentPos(datafields.at(0)->getFloat(), datafields.at(1)->getFloat());
177  float yaw = datafields.at(2)->getFloat();
178  Eigen::Vector2f posError = currentPos - target->toEigen().head(2);
179  float yawError = yaw - target->z;
180  return Vector3Ptr(new Vector3(posError(0), posError(1), yawError));
181  };
182  while (!isRunningTaskStopped())
183  {
184  auto error = getError();
185  ARMARX_INFO << deactivateSpam(1) << VAROUT(*error);
186 
187  usleep(20000);
188  }
189  auto error = getError();
190  ARMARX_INFO << "remaining error: " << *error;
191  out.setRemainingError(error);
192  }
193 }
194 
195 void
197 {
198  // put your user code for the exit point here
199  // execution time should be short (<100ms)
200  waitForRunningTaskToFinish();
201 }
202 
203 // DO NOT EDIT NEXT FUNCTION
206 {
207  return XMLStateFactoryBasePtr(new MovePlatformRelative(stateData));
208 }
armarx::PlatformGroup::MovePlatformRelative::run
void run() override
Definition: MovePlatformRelative.cpp:148
MathUtils.h
armarx::XMLStateConstructorParams
Definition: XMLState.h:49
boost::target
Vertex target(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:668
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
armarx::control::common::getError
void getError(Eigen::Matrix4f &currentPose, Eigen::Vector3d &targetPosition, Eigen::Quaterniond &targetQuaternion, double &posiError, double &oriError)
Definition: utils.cpp:94
armarx::XMLStateFactoryBasePtr
IceInternal::Handle< XMLStateFactoryBase > XMLStateFactoryBasePtr
Definition: XMLState.h:64
IceInternal::Handle< DatafieldRef >
armarx::math::MathUtils::angleMod2PI
static float angleMod2PI(float value)
Definition: MathUtils.h:167
armarx::PlatformGroup::MovePlatformRelative::CreateInstance
static XMLStateFactoryBasePtr CreateInstance(XMLStateConstructorParams stateData)
Definition: MovePlatformRelative.cpp:205
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:75
DatafieldRef.h
MovePlatformRelative.h
armarx::PlatformGroup::MovePlatformRelative::Registry
static SubClassRegistry Registry
Definition: MovePlatformRelative.h:43
armarx::XMLStateTemplate
Class for legacy to stay compatible with old statecharts.
Definition: XMLState.h:146
armarx::PlatformGroup::MovePlatformRelative
Definition: MovePlatformRelative.h:31
M_PI
#define M_PI
Definition: MathTools.h:17
armarx::PlatformGroup::MovePlatformRelative::onExit
void onExit() override
Definition: MovePlatformRelative.cpp:196
armarx::PlatformContext::platformUnitObserverName
std::string platformUnitObserverName
Definition: PlatformContext.h:147
armarx::VariantType::DatafieldRef
const VariantTypeId DatafieldRef
Definition: DatafieldRef.h:197
armarx::PlatformGroup::MovePlatformRelative::MovePlatformRelative
MovePlatformRelative(XMLStateConstructorParams stateData)
Definition: MovePlatformRelative.cpp:41
PlatformContext.h
armarx::PlatformGroup::MovePlatformRelative::onEnter
void onEnter() override
Definition: MovePlatformRelative.cpp:48
float
#define float
Definition: 16_Level.h:22
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:198
memoryx::KBM::Vector3
Eigen::Vector3d Vector3
Definition: kbm.h:43
armarx::PlatformContext::platformUnitPrx
PlatformUnitInterfacePrx platformUnitPrx
Definition: PlatformContext.h:143
armarx::Vector3Ptr
IceInternal::Handle< Vector3 > Vector3Ptr
Definition: Pose.h:165
armarx::Literal
Definition: Term.h:208
armarx::PlatformContext
Definition: PlatformContext.h:77
GfxTL::Matrix3f
MatrixXX< 3, 3, float > Matrix3f
Definition: MatrixXX.h:649
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::DataFieldIdentifier
DataFieldIdentifier provide the basis to identify data field within a distributed ArmarX scenario.
Definition: DataFieldIdentifier.h:48
armarx::PlatformContext::platformUnitObserverPrx
PlatformUnitObserverInterfacePrx platformUnitObserverPrx
Definition: PlatformContext.h:144