4 #include <VirtualRobot/IK/GazeIK.h>
5 #include <VirtualRobot/Nodes/RobotNode.h>
6 #include <VirtualRobot/Nodes/RobotNodePrismatic.h>
7 #include <VirtualRobot/Robot.h>
8 #include <VirtualRobot/RobotNodeSet.h>
9 #include <VirtualRobot/VirtualRobot.h>
15 #include <ArmarXCore/interface/observers/VariantBase.h>
26 #include <armarx/view_selection/gaze_controller/gaze_ik/aron/ControllerConfig.aron.generated.h>
29 #include <range/v3/range/conversion.hpp>
30 #include <range/v3/view/zip.hpp>
39 const NJointControllerConfigPtr& config,
44 ConfigPtrT cfg = ConfigPtrT::dynamicCast(config);
50 const auto configData = arondto::Config::FromAron(cfg->config);
57 _rtRobot->setThreadsafe(
false);
59 _robotAdditionalTask = _rtRobot->clone();
60 _robotAdditionalTask->setThreadsafe(
false);
61 RobotState initialState;
62 initialState.globalRobotPose = _rtRobot->getGlobalPose();
64 ARMARX_INFO <<
"Using nodeset `" << configData.params.nodeSetName <<
"`.";
65 _headNodeSet = _robotAdditionalTask->getRobotNodeSet(configData.params.nodeSetName);
69 for (
const auto& [name,
value] : _robotAdditionalTask->getJointValues())
71 initialState.jointValues.push_back(
value);
73 const auto node = _rtRobot->getRobotNode(name);
75 _rtRobotNodes.push_back(node);
77 _additionalTaskRobotNodeNames.push_back(name);
86 if (initialConfig.
target.has_value())
98 const auto tcpNode = _headNodeSet->getTCP();
99 _virtualPrismaticJoint =
100 std::dynamic_pointer_cast<VirtualRobot::RobotNodePrismatic>(tcpNode);
104 _gazeIK = std::make_unique<VirtualRobot::GazeIK>(_headNodeSet, _virtualPrismaticJoint);
105 _gazeIK->enableJointLimitAvoidance(configData.params.enableJointLimitAvoidance);
106 _gazeIK->setup(configData.params.maxPositionError,
107 configData.params.maxLoops,
108 configData.params.maxGradientDecentSteps);
109 _gazeIK->setVerbose(
false);
115 std::vector<float> controlTargets;
117 for (
const auto& nodeName : _headNodeSet->getNodeNames())
119 if (nodeName == _virtualPrismaticJoint->getName())
124 ARMARX_INFO <<
"Using control target `" << nodeName <<
"`.";
125 auto&
target = _rtCtrlTargets.emplace_back(
126 useControlTarget<armarx::ControlTarget1DoFActuatorPosition>(
127 nodeName, ControlModes::Position1DoF));
131 const auto node = _headNodeSet->getNode(nodeName);
134 controlTargets.emplace_back(0);
147 const Ice::Current& )
151 auto updateConfigDto = arondto::Config::FromAron(dto);
156 if (config.
target.has_value())
161 _configBuffer_updateConfigToAdditionalTask.
getWriteBuffer() = config;
162 _configBuffer_updateConfigToAdditionalTask.
commitWrite();
168 runTask(
"GazeControllerAdditionalTask",
173 ARMARX_IMPORTANT <<
"Create a new thread alone PlatformTrajectory controller";
174 while (
getState() == eManagedIceObjectStarted)
181 c.waitForCycleDuration();
205 for (std::size_t i = 0; i < _rtCtrlTargets.size(); i++)
211 _robotStateBuffer_rtToAdditionalTask.
getWriteBuffer().globalRobotPose =
215 _rtRobotNodes.size());
216 for (std::size_t i = 0; i < _rtRobotNodes.size(); i++)
219 _robotStateBuffer_rtToAdditionalTask.
getWriteBuffer().jointValues.at(i) =
220 _rtRobotNodes.at(i)->getJointValue();
223 _robotStateBuffer_rtToAdditionalTask.
commitWrite();
235 rtReady.store(
false);
244 const float currentPitchAngle = _publishCurrentPitchAngle;
245 const float currentYawAngle = _publishCurrentYawAngle;
246 const float targetPitchAngle = _publishTargetPitchAngle;
247 const float targetYawAngle = _publishTargetYawAngle;
250 datafields[
"currentPitchAngle"] =
new Variant(currentPitchAngle);
251 datafields[
"currentYawAngle"] =
new Variant(currentYawAngle);
252 datafields[
"targetPitchAngle"] =
new Variant(targetPitchAngle);
253 datafields[
"targetYawAngle"] =
new Variant(targetYawAngle);
263 GazeController::additionalTask()
265 const auto& configBuffer =
270 _robotAdditionalTask->setGlobalPose(robotStateBuffer.globalRobotPose);
273 robotStateBuffer.jointValues.size());
274 const std::map<std::string, float> jointPositions =
275 ranges::views::zip(_additionalTaskRobotNodeNames, robotStateBuffer.jointValues) |
276 ranges::to<std::map>();
278 _robotAdditionalTask->setJointValues(jointPositions);
280 if (not configBuffer.target.has_value())
284 std::fill(w.begin(), w.end(), 0);
293 const Eigen::Vector3f globalPosition =
294 configBuffer.target->position.toGlobalEigen(_robotAdditionalTask);
297 const bool solutionFound = _gazeIK->solve(globalPosition);
302 for (std::size_t i = 0; i < _headNodeSet->getSize(); i++)
304 if (
auto node = _headNodeSet->getNode(i); node != _headNodeSet->getTCP())
309 ARMARX_DEBUG << _headNodeSet->getNode(i)->getName() <<
": "
310 << _headNodeSet->getNode(i)->getJointValue();
316 <<
"No IK solution found for Gaze IK to global target "