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