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 
36 using namespace armarx;
37 using namespace MotionControlGroup;
38 
39 // DO NOT EDIT NEXT LINE
40 MoveJoints::SubClassRegistry MoveJoints::Registry(MoveJoints::GetName(),
42 
44  XMLStateTemplate<MoveJoints>(stateData), MoveJointsGeneratedBase<MoveJoints>(stateData)
45 {
46 }
47 
48 void
50 {
51  timeoutEvent = setTimeoutEvent(in.gettimeoutInMs(), createEventEvTimeout());
52  ARMARX_DEBUG << "timeout installed" << std::endl;
53 }
54 
55 void
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 
164  DataFieldIdentifierBaseList jointList;
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  {
182  TimeUtil::MSSleep(10);
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 
260 void
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>();
271  DataFieldIdentifierBaseList jointList;
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
296 std::string
298 {
299  return "MoveJoints";
300 }
301 
302 // DO NOT EDIT NEXT FUNCTION
305 {
306  return XMLStateFactoryBasePtr(new MoveJoints(stateData));
307 }
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
armarx::MotionControlGroup::MotionControlGroupStatechartContext::getKinematicUnitObserverName
std::string getKinematicUnitObserverName()
Definition: MotionControlGroupStatechartContext.h:132
armarx::MotionControlGroup::MotionControlGroupStatechartContext
Definition: MotionControlGroupStatechartContext.h:75
armarx::MotionControlGroup::MoveJoints::run
void run() override
Definition: MoveJoints.cpp:56
armarx::MotionControlGroup::MoveJoints::GetName
static std::string GetName()
Definition: MoveJoints.cpp:297
armarx::TimeUtil::MSSleep
static void MSSleep(int durationMS)
lock the calling thread for a given duration (like usleep(...) but using Timeserver time)
Definition: TimeUtil.cpp:100
armarx::XMLStateConstructorParams
Definition: XMLState.h:49
armarx::MotionControlGroup::MoveJoints::CreateInstance
static XMLStateFactoryBasePtr CreateInstance(XMLStateConstructorParams stateData)
Definition: MoveJoints.cpp:304
armarx::Term
Definition: Term.h:111
armarx::XMLStateFactoryBasePtr
IceInternal::Handle< XMLStateFactoryBase > XMLStateFactoryBasePtr
Definition: XMLState.h:64
IceInternal::Handle< SingleTypeVariantList >
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:75
armarx::MotionControlGroup::MotionControlGroupStatechartContext::getRobot
const std::shared_ptr< RemoteRobot > getRobot()
Definition: MotionControlGroupStatechartContext.h:90
armarx::MotionControlGroup::MoveJoints::onExit
void onExit() override
Definition: MoveJoints.cpp:261
armarx::MotionControlGroup::MoveJoints::targetReachedCondition
ConditionIdentifier targetReachedCondition
Definition: MoveJoints.h:54
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
armarx::XMLStateTemplate
Class for legacy to stay compatible with old statecharts.
Definition: XMLState.h:146
armarx::flush
const LogSender::manipulator flush
Definition: LogSender.h:251
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:184
MoveJoints.h
armarx::MotionControlGroup::MoveJoints
Definition: MoveJoints.h:39
max
T max(T t1, T t2)
Definition: gdiam.h:51
armarx::MotionControlGroup::MoveJoints::onEnter
void onEnter() override
Definition: MoveJoints.cpp:49
MotionControlGroupStatechartContext.h
armarx::MotionControlGroup::MoveJoints::Registry
static SubClassRegistry Registry
Definition: MoveJoints.h:52
armarx::TimeUtil::GetTime
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Definition: TimeUtil.cpp:42
armarx::control::njoint_controller::platform::platform_follower_controller::NameValueMap
std::map< std::string, float > NameValueMap
Definition: PlatformFollowerController.h:88
armarx::MotionControlGroup::MotionControlGroupStatechartContext::getKinematicUnit
KinematicUnitInterfacePrx getKinematicUnit()
Definition: MotionControlGroupStatechartContext.h:120
TimeUtil.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:198
armarx::Literal
Definition: Term.h:208
min
T min(T t1, T t2)
Definition: gdiam.h:44
armarx::DataFieldIdentifierBaseList
::std::vector<::armarx::DataFieldIdentifierBasePtr > DataFieldIdentifierBaseList
Definition: StatechartContextInterface.h:43
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::MotionControlGroup::MoveJoints::timeoutEvent
ActionEventIdentifier timeoutEvent
Definition: MoveJoints.h:55
armarx::MotionControlGroup::MoveJoints::MoveJoints
MoveJoints(XMLStateConstructorParams stateData)
Definition: MoveJoints.cpp:43