15 std::map<std::string, float>
16 MoveJointsToPosition::filterJointTargetValues(
17 const NameValueMap& jointsTargetValues,
18 const std::vector<std::string>& disabledJoints)
const
20 std::map<std::string, float> filtered;
21 for (
const auto& [jointName, v] : jointsTargetValues)
23 if (std::find(disabledJoints.begin(), disabledJoints.end(), jointName) !=
27 <<
" because it was explictly disabled in skill params.";
30 filtered[jointName] = v;
38 auto filtered = this->filterJointTargetValues(in.parameters.jointsTargetValues,
39 in.parameters.disabledJoints);
41 auto jointNames = simox::alg::get_keys(filtered);
47 ::armarx::skills::Skill::MainResult
50 auto filtered = this->filterJointTargetValues(in.parameters.jointsTargetValues,
51 in.parameters.disabledJoints);
53 auto jointNames = simox::alg::get_keys(filtered);
57 srv_.virtualRobotReader.getRobot(srv_.robotName);
60 ARMARX_ERROR <<
"Could not get robot '" << srv_.robotName <<
"'";
65 if (not checkJointsTargetValuesValid(in.parameters.jointsTargetValues, virtualRobot))
74 srv_.kinematicUnit->requestJoints(jointNames);
76 catch (
const armarx::KinematicUnitUnavailable& e)
78 ARMARX_IMPORTANT <<
"Failed to request joints. Terminating. Joints unavailable:"
86 switchControlMode(filtered, ePositionControl);
88 if (in.parameters.inSimulation)
92 moveJointsSimulation(filtered,
93 in.parameters.simulationJointSpeed,
94 in.parameters.simulationJointSpeedOverride,
102 in.parameters.accuracy,
103 in.parameters.accuracyOverride,
104 in.parameters.timeoutMS,
105 in.parameters.timeoutOverrideMS,
112 MoveJointsToPosition::checkJointsTargetValuesValid(
const NameValueMap& jointsTargetValues,
115 for (
const auto& [jointName, targetValue] : jointsTargetValues)
117 if (not virtualRobot->hasRobotNode(jointName))
119 ARMARX_ERROR <<
"Robot has no joint '" << jointName <<
"'";
122 const VirtualRobot::RobotNodePtr robotNode = virtualRobot->getRobotNode(jointName);
123 if (not robotNode->checkJointLimits(targetValue))
125 ARMARX_ERROR <<
"Target value '" << targetValue <<
"' for joint '" << jointName
126 <<
"' out of limits (" << robotNode->getJointLimitLo() <<
" - "
127 << robotNode->getJointLimitHi() <<
")";
135 MoveJointsToPosition::switchControlMode(
const NameValueMap& jointsTargetValues,
136 const ControlMode controlMode)
138 armarx::NameControlModeMap modeMap;
139 for (
const auto& [jointName, _] : jointsTargetValues)
141 modeMap[jointName] = controlMode;
143 srv_.kinematicUnit->switchControlMode(modeMap);
147 MoveJointsToPosition::moveJoints(
const NameValueMap& jointsTargetValues,
148 const float accuracyDefault,
149 const NameValueMap& accuracyOverride,
150 const float timeoutDefault,
151 NameValueMap timeoutOverride,
154 srv_.kinematicUnit->setJointAngles(jointsTargetValues);
157 ARMARX_INFO <<
"Waiting until target values are reached";
162 auto do_if_terminate_and_not_reached = [&]()
164 ARMARX_INFO <<
"Skill got aborted, stopping movement";
165 ARMARX_CHECK(srv_.virtualRobotReader.synchronizeRobotJoints(*virtualRobot,
167 <<
"Robot state synchronization failed";
170 switchControlMode(jointsTargetValues, eVelocityControl);
173 for (
auto& [jointName, _] : jointsTargetValues)
175 targetJointVelocities[jointName] = 0;
177 srv_.kinematicUnit->setJointVelocities(targetJointVelocities);
184 bool reachedOrTimedOut =
false;
188 for (
const auto& [jointName, _] : jointsTargetValues)
190 if (timeoutOverride.find(jointName) == timeoutOverride.end())
192 timeoutOverride[jointName] = timeoutDefault;
197 std::map<std::string, bool> timeoutedJoints;
198 for (
const auto& [jointName, _] : jointsTargetValues)
200 timeoutedJoints[jointName] =
false;
204 NameValueMap pastJointAngles = srv_.kinematicUnit->getJointAngles();
207 std::map<std::string, armarx::DateTime> lastMotion;
208 for (
const auto& [jointName, _] : jointsTargetValues)
213 while (not reachedOrTimedOut)
216 ARMARX_CHECK(srv_.virtualRobotReader.synchronizeRobotJoints(*virtualRobot,
218 <<
"Robot state synchronization failed";
220 reachedOrTimedOut =
true;
221 for (
const auto& [jointName, targetValue] : jointsTargetValues)
223 if (not timeoutedJoints[jointName])
226 const float currentValue =
227 virtualRobot->getRobotNode(jointName)->getJointValue();
228 const float accuracy = accuracyOverride.count(jointName) > 0
229 ? accuracyOverride.at(jointName)
233 <<
"' is: " << std::abs(targetValue - currentValue);
236 if (std::abs(currentValue - pastJointAngles[jointName]) > accuracy)
239 pastJointAngles[jointName] = currentValue;
244 if ((timeoutOverride[jointName] >= 0) &&
245 ((
DateTime::Now() - lastMotion[jointName]).toMilliSecondsDouble() >=
246 timeoutOverride[jointName]))
248 timeoutedJoints[jointName] =
true;
249 ARMARX_INFO <<
"Joint " << jointName <<
" has reached its timeout.";
252 if (std::abs(targetValue - currentValue) > accuracy)
256 <<
"' is higer than accuracy: " << std::abs(targetValue - currentValue)
257 <<
" > " << accuracy <<
"(accuracy)";
258 reachedOrTimedOut =
false;
264 clock.waitFor(sleepTime);
269 MoveJointsToPosition::moveJointsSimulation(
const NameValueMap& jointsTargetValues,
270 const float speedDefault,
271 const NameValueMap& speedOverride,
276 <<
"Robot state synchronization failed";
279 armarx::trajectory::Trajectory trajectory;
280 double maxDuration = 0;
282 for (
const auto& [jointName, targetValue] : jointsTargetValues)
285 speedOverride.count(jointName) > 0 ? speedOverride.at(jointName) : speedDefault;
287 const float currentValue = virtualRobot->getRobotNode(jointName)->getJointValue();
288 const double duration = std::abs(targetValue - currentValue) / speed;
291 track[0] = currentValue;
292 track[duration] = targetValue;
294 maxDuration = std::max(maxDuration, duration);
297 ARMARX_INFO <<
"Simulating trajectory (duration: " << maxDuration <<
"s)";
305 while (t < maxDuration)
311 for (
const auto& [name, _] : jointsTargetValues)
313 const float value = std::get<float>(trajectory[name].at(t));
314 nextValues[name] =
value;
317 srv_.kinematicUnit->setJointAngles(nextValues);
319 clock.waitFor(sleepTime);
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
::armarx::skills::SkillDescription GetSkillDescription()
MoveJointsToPosition(const Services &)
arondto::MoveJointsToPositionParams ParamType
static MainResult MakeSucceededResult(aron::data::DictPtr data=nullptr)
virtual MainResult main()
Override this method with the actual implementation.
void throwIfSkillShouldTerminate(const std::string &abortedMessage="") const
virtual ExitResult exit()
Override this method with the actual implementation.
static MainResult MakeFailedResult(aron::data::DictPtr data=nullptr)
VariantTrack & addTrack(const TrackID &id)
Add track with the given ID (and no update function).
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_INFO
The normal logging level.
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
std::shared_ptr< class Robot > RobotPtr
armarx::core::time::Duration Duration
Track< VariantValue > VariantTrack
A track with value type TValue.
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::shared_ptr< Value > value()
This file is part of ArmarX.
std::chrono::system_clock Clock
::armarx::KinematicUnitInterfacePrx kinematicUnit
A result struct for skill exit function.