MoveJoints.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::MotionControlGroup
19 * @author Mirko Waechter ( mirko dot waechter at kit dot edu )
20 * @date 2014
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25#include "MoveJoints.h"
26
28
29#include <RobotAPI/interface/units/KinematicUnitInterface.h>
30
32
33//#include <RobotAPI/libraries/core/RobotStatechartContext.h>
34#include <VirtualRobot/RobotConfig.h>
35
36using namespace armarx;
37using namespace MotionControlGroup;
38
39// DO NOT EDIT NEXT LINE
40MoveJoints::SubClassRegistry MoveJoints::Registry(MoveJoints::GetName(),
41 &MoveJoints::CreateInstance);
42
44 XMLStateTemplate<MoveJoints>(stateData), MoveJointsGeneratedBase<MoveJoints>(stateData)
45{
46}
47
48void
50{
51 timeoutEvent = setTimeoutEvent(in.gettimeoutInMs(), createEventEvTimeout());
52 ARMARX_DEBUG << "timeout installed" << std::endl;
53}
54
55void
57{
58 // put your user code for the enter-point here
59 // execution time should be short (<100ms)
60
62 getContext<MotionControlGroupStatechartContext>();
63
64 NameValueMap targetJointAngles;
65 NameValueMap targetJointVelocities;
66 std::vector<std::string> jointNames;
67 std::vector<float> targetJointValues;
68
69 if (in.isjointNamesSet() && in.istargetJointValuesSet())
70 {
71 jointNames = in.getjointNames();
72 targetJointValues = in.gettargetJointValues();
73 }
74 else if (in.isalternativeJointMapSet())
75 {
76 auto map = in.getalternativeJointMap();
77
78 for (const auto& elem : map)
79 {
80 jointNames.push_back(elem.first);
81 targetJointValues.push_back(elem.second);
82 }
83 }
84 else
85 {
86 throw LocalException("You must either specify the alternativeJointMap param or the "
87 "targetJointValues and jointNames params.");
88 }
89
90 if (jointNames.size() != targetJointValues.size())
91 {
92 throw LocalException("Sizes of joint name list and joint value list do not match!");
93 }
94
95 if (jointNames.size() == 0)
96 {
97 emitEvJointTargetReached();
98 local.setCommandedJoints(NameValueMap());
99 return;
100 }
101
102 ARMARX_VERBOSE << "number of joints that will be set: " << jointNames.size() << flush;
103 NameControlModeMap controlModes;
104 bool useNativeController = in.getUseNativePositionControl();
105 for (size_t i = 0; i < jointNames.size(); i++)
106 {
107 targetJointAngles[jointNames.at(i)] = targetJointValues.at(i);
108 controlModes[jointNames.at(i)] = useNativeController ? ePositionControl : eVelocityControl;
109 ARMARX_DEBUG << "setting joint angle for joint '" << jointNames.at(i) << "' to "
110 << targetJointValues.at(i) << std::endl;
111 }
112
113 // TODO: Set Max Velocities
114 if (in.isjointMaxSpeedsSet() &&
115 getInput<SingleTypeVariantList>("jointMaxSpeeds")->getSize() == (int)jointNames.size())
116 {
117 SingleTypeVariantListPtr maxJointValues = getInput<SingleTypeVariantList>("jointMaxSpeeds");
118
119 for (size_t i = 0; i < jointNames.size(); i++)
120 {
121 targetJointVelocities[jointNames.at(i)] = maxJointValues->getVariant(i)->getFloat();
122 }
123 }
124 else
125 {
126 float maxVel = in.getjointMaxSpeed();
127
128 for (size_t i = 0; i < jointNames.size(); i++)
129 {
130 targetJointVelocities[jointNames.at(i)] = maxVel;
131 }
132 }
133
134 // now install the condition
135 Term cond;
136 float tolerance = getInput<float>("jointTargetTolerance");
137 NameValueMap jointValueMap;
138
139 for (size_t i = 0; i < jointNames.size(); i++)
140 {
141 ARMARX_DEBUG << "creating condition (" << i << " of " << jointNames.size() << ") for value "
142 << targetJointValues.at(i) << flush;
144 "jointangles",
145 jointNames.at(i)),
146 checks::approx,
147 {targetJointValues.at(i), tolerance});
148 cond = cond && approx;
149 jointValueMap[jointNames.at(i)] = targetJointValues.at(i);
150 }
151 local.setCommandedJoints(jointValueMap);
152 ARMARX_DEBUG << "installing condition: EvJointTargetReached" << std::endl;
153 targetReachedCondition = installCondition<EvJointTargetReached>(cond);
154 ARMARX_DEBUG << "condition installed: EvJointTargetReached" << std::endl;
155
156 context->getKinematicUnit()->switchControlMode(controlModes);
157 if (useNativeController)
158 {
159 context->getKinematicUnit()->setJointVelocities(targetJointVelocities);
160 context->getKinematicUnit()->setJointAngles(targetJointAngles);
161 return;
162 }
163
165 for (auto& joint : jointValueMap)
166 {
167 jointList.push_back(new DataFieldIdentifier(
168 context->getKinematicUnitObserverName(), "jointangles", joint.first));
169 }
170 ARMARX_INFO << "Joint targets: " << jointValueMap;
171 auto currentValues = context->getRobot()->getConfig()->getRobotNodeJointValueMap();
172
173 ARMARX_INFO << "Joint target tolerance: " << tolerance;
174
175
176 NameValueMap currentTargetJointVelocities;
177 auto start = TimeUtil::GetTime();
178 float accelerationTime = in.getAccelerationTime();
179 float maxVel = in.getjointMaxSpeed();
180 while (!isRunningTaskStopped())
181 {
183
184 currentValues = context->getRobot()->getConfig()->getRobotNodeJointValueMap();
185 ; //context->getKinematicUnitObserver()->getDataFields(jointList);
186 float maxDelta = 0;
187 size_t i = 0;
188 for (auto& value : jointValueMap)
189 {
190 float delta = fabs((value.second - currentValues[value.first]));
191 maxDelta = std::max(delta, maxDelta);
192 // ARMARX_INFO << deactivateSpam(1, value.first) << value.first << ": Difference : " << delta;
193 i++;
194 }
195 if (maxDelta > 0)
196 {
197 float motionDuration = maxDelta / maxVel;
198 ARMARX_INFO << deactivateSpam(1) << VAROUT(maxDelta) << VAROUT(motionDuration);
199 targetJointVelocities.clear();
200 i = 0;
201 for (auto& value : jointValueMap)
202 {
203 float delta = (value.second - currentValues[value.first]);
204 targetJointVelocities[value.first] = delta / motionDuration;
205 i++;
206 }
207 ARMARX_INFO << deactivateSpam(1) << VAROUT(targetJointVelocities);
208
209 i = 0;
210 NameValueMap currentDeltas;
211 for (auto& value : jointValueMap)
212 {
213 float delta = ((value.second - currentValues[value.first]));
214 currentDeltas[value.first] = delta;
215 float slowdownFactor =
216 (1 / (1 + exp(-(fabs(delta) - 0.1) / 0.04))); //sigmoid function
217 float newVel = std::min(fabs(targetJointVelocities[value.first]),
218 fabs(delta) * slowdownFactor * 10); // slowdown at end
219 if (newVel * delta < 0)
220 {
221 newVel *= -1;
222 }
223 newVel *= std::min(1.0,
224 (TimeUtil::GetTime() - start).toMilliSecondsDouble() /
225 accelerationTime); // time to accelerate to fullspeed
226 currentTargetJointVelocities[value.first] = newVel;
227 i++;
228 }
230 << "Current joint target velocities: " << currentTargetJointVelocities;
231 ARMARX_INFO << deactivateSpam(1) << "Current joint deltas to target: " << currentDeltas;
232 context->getKinematicUnit()->setJointVelocities(currentTargetJointVelocities);
233 }
234 }
235 if (in.getSetVelocitiesToZeroAtEnd())
236 {
237 for (auto& joint : jointValueMap)
238 {
239 targetJointVelocities[joint.first] = 0.0f;
240 }
241 context->getKinematicUnit()->setJointVelocities(targetJointVelocities);
242 }
243
244
245 if (in.getHoldPositionAfterwards())
246 {
247 currentValues = context->getRobot()->getConfig()->getRobotNodeJointValueMap();
248 int i = 0;
249 for (auto& joint : jointValueMap)
250 {
251 controlModes[joint.first] = ePositionControl;
252 //targetJointAngles[joint.first] = currentValues.at(i)->getFloat();
253 i++;
254 }
255 context->getKinematicUnit()->switchControlMode(controlModes);
256 context->getKinematicUnit()->setJointAngles(targetJointAngles);
257 }
258}
259
260void
262{
263 // put your user code for the exit point here
264 // execution time should be short (<100ms)
265 while (!isRunningTaskFinished())
266 {
268 }
270 getContext<MotionControlGroupStatechartContext>();
272 auto jointValueMap = local.getCommandedJoints();
273 NameValueMap targetJointVelocities;
274 for (auto& joint : jointValueMap)
275 {
276 jointList.push_back(new DataFieldIdentifier(
277 context->getKinematicUnitObserverName(), "jointangles", joint.first));
278 targetJointVelocities[joint.first] = 0.0f;
279 }
280
281 auto currentValues = context->getRobot()->getConfig()->getRobotNodeJointValueMap();
282 size_t i = 0;
283
284 float tolerance = getInput<float>("jointTargetTolerance");
285 ARMARX_INFO << "Joint target tolerance: " << tolerance;
286 NameValueMap differences;
287 for (auto& value : jointValueMap)
288 {
289 differences[value.first] = (value.second - currentValues[value.first]);
290 i++;
291 }
292 ARMARX_VERBOSE << VAROUT(differences);
293}
294
295// DO NOT EDIT NEXT FUNCTION
296std::string
298{
299 return "MoveJoints";
300}
301
302// DO NOT EDIT NEXT FUNCTION
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
#define VAROUT(x)
DataFieldIdentifier provide the basis to identify data field within a distributed ArmarX scenario.
Literals are part of the user front end of the ArmarX condition mechanism.
Definition Term.h:209
custom implementation of the StatechartContext for a statechart
MoveJoints(XMLStateConstructorParams stateData)
ConditionIdentifier targetReachedCondition
Definition MoveJoints.h:54
ActionEventIdentifier timeoutEvent
Definition MoveJoints.h:55
static XMLStateFactoryBasePtr CreateInstance(XMLStateConstructorParams stateData)
Terms are part of the user front end of the ArmarX condition mechanism.
Definition Term.h:112
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Definition TimeUtil.cpp:42
static void MSSleep(int durationMS)
lock the calling thread for a given duration (like usleep(...) but using Timeserver time)
Definition TimeUtil.cpp:100
Class for legacy to stay compatible with old statecharts.
Definition XMLState.h:147
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< SingleTypeVariantList > SingleTypeVariantListPtr
::std::vector<::armarx::DataFieldIdentifierBasePtr > DataFieldIdentifierBaseList
const LogSender::manipulator flush
Definition LogSender.h:251
IceInternal::Handle< XMLStateFactoryBase > XMLStateFactoryBasePtr
Definition XMLState.h:64