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
26
28
30
31#include "PlatformContext.h"
32
33using namespace armarx;
34using namespace PlatformGroup;
35
36// DO NOT EDIT NEXT LINE
37MovePlatformRelative::SubClassRegistry
38 MovePlatformRelative::Registry(MovePlatformRelative::GetName(),
40
43 MovePlatformRelativeGeneratedBase<MovePlatformRelative>(stateData)
44{
45}
46
47void
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};
68 Eigen::Matrix3f m;
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
147void
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
195void
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
#define float
Definition 16_Level.h:22
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
#define M_PI
Definition MathTools.h:17
#define VAROUT(x)
constexpr T c
DataFieldIdentifier provide the basis to identify data field within a distributed ArmarX scenario.
The DatafieldRef class is similar to the ChannelRef, but points to a specific Datafield instead of to...
Literals are part of the user front end of the ArmarX condition mechanism.
Definition Term.h:209
std::string platformUnitObserverName
PlatformUnitObserverInterfacePrx platformUnitObserverPrx
PlatformUnitInterfacePrx platformUnitPrx
MovePlatformRelative(XMLStateConstructorParams stateData)
static XMLStateFactoryBasePtr CreateInstance(XMLStateConstructorParams stateData)
The Vector3 class.
Definition Pose.h:113
Class for legacy to stay compatible with old statecharts.
Definition XMLState.h:147
static float angleMod2PI(float value)
Definition MathUtils.h:167
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< Vector3 > Vector3Ptr
Definition Pose.h:165
IceInternal::Handle< DatafieldRef > DatafieldRefPtr
Definition Observer.h:43
IceInternal::Handle< DataFieldIdentifier > DataFieldIdentifierPtr
Typedef of DataFieldIdentifierPtr as IceInternal::Handle<DataFieldIdentifier> for convenience.
IceInternal::Handle< XMLStateFactoryBase > XMLStateFactoryBasePtr
Definition XMLState.h:64