RobotIKGuiPlugin.cpp
Go to the documentation of this file.
1 /*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package ArmarX::
17 * @author Philipp Schmidt
18 * @date 2015
19 * @license http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 
22 */
23 
24 #include "RobotIKGuiPlugin.h"
25 #include "RobotViewer.h"
26 
27 /* ArmarX includes */
34 
35 /* Virtual Robot includes */
36 #include <VirtualRobot/XML/RobotIO.h>
37 #include <VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h>
38 
39 /* Coin includes */
40 #include <Inventor/actions/SoGetMatrixAction.h>
41 #include <Inventor/actions/SoSearchAction.h>
42 #include <Inventor/SbViewportRegion.h>
44 #include <QClipboard>
45 
46 // Gui Includes
47 #include "SetDesiredPoseDialog.h"
48 
49 #define ROBOT_UPDATE_TIMER_MS 33
50 #define TEXTFIELD_UPDATE_TIMER_MS 200
51 #define AUTO_FOLLOW_UPDATE 333
52 #define CARTESIAN_CONTROLLER_LOOP_AMOUNT 100
53 
55 {
56  addWidget<RobotIKWidgetController>();
57 }
58 
59 armarx::RobotIKWidgetController::RobotIKWidgetController() : manipulatorMoved(false), startUpCameraPositioningFlag(true)
60 {
61 
62 
63  //Component names
64  robotStateComponentName = "";
65  robotIKComponentName = "";
66  kinematicUnitComponentName = "";
67 
68  visualization = NULL;
69  robotUpdateSensor = NULL;
70  textFieldUpdateSensor = NULL;
71 }
72 
74 {
75  ARMARX_INFO << "RobotIKWidgetController on init";
76  QMetaObject::invokeMethod(this, "initWidget");
77  //Prepare proxies
78  usingProxy(robotStateComponentName);
79  usingProxy(robotIKComponentName);
80  usingProxy(kinematicUnitComponentName);
81 }
82 
84 {
85  //Get all proxies
86  robotStateComponentPrx = getProxy<RobotStateComponentInterfacePrx>(robotStateComponentName);
87  kinematicUnitInterfacePrx = getProxy<KinematicUnitInterfacePrx>(kinematicUnitComponentName);
88  robotIKPrx = getProxy<RobotIKInterfacePrx>(robotIKComponentName);
89 
90  //Load robot
91  robot = loadRobot(getIncludePaths());
92  ARMARX_INFO << VAROUT(robot->getName());
93 
94  if (!robot)
95  {
96  getObjectScheduler()->terminate();
97 
98  if (getWidget()->parentWidget())
99  {
100  getWidget()->parentWidget()->close();
101  }
102 
103  ARMARX_ERROR << "RobotIKPlugin: Unable to load robot file! Terminating." << std::endl;
104  return;
105  }
106 
107  //Add in our visualization for manipulators
108  visualization = new ManipulatorVisualization;
109  this->ui.robotViewer->getRobotViewer()->getRootNode()->addChild((SoNode*)visualization);
110 
111  //Get visualization for our robot and add it to scene graph
112  currentRobotVisualization = robot->getVisualization<VirtualRobot::CoinVisualization>();
113  this->ui.robotViewer->getRobotViewer()->getRootNode()->addChild(currentRobotVisualization->getCoinVisualization());
114 
115  // Get visualization for preview robot
116  previewRobot = loadRobot(getIncludePaths());
117  previewRobotVisualization = previewRobot->getVisualization<VirtualRobot::CoinVisualization>();
118 
119  // Setup cartesianControlRobot
120  cartesianControlRobot = previewRobot->clone();
121 
122  //Make a timer update robo pose every time tick
123  SoSensorManager* sensor_mgr = SoDB::getSensorManager();
124  robotUpdateSensor = new SoTimerSensor(robotUpdateTimerCB, this);
125  robotUpdateSensor->setInterval(SbTime(ROBOT_UPDATE_TIMER_MS / 1000.0f));
126  sensor_mgr->insertTimerSensor(robotUpdateSensor);
127 
128  //And a timer to update the labels
129  textFieldUpdateSensor = new SoTimerSensor(textFieldUpdateTimerCB, this);
130  textFieldUpdateSensor->setInterval(SbTime(TEXTFIELD_UPDATE_TIMER_MS / 1000.0f));
131  sensor_mgr->insertTimerSensor(textFieldUpdateSensor);
132 
133  //Get all kinematic chain descriptions and add them to the combo box
134  auto robotNodeSets = robot->getRobotNodeSets();
135 
136  for (VirtualRobot::RobotNodeSetPtr s : robotNodeSets)
137  {
138  this->ui.comboBox->addItem(QString::fromStdString(s->getName()));
139  }
140 
141  //Make sure comboBox is enabled so you can select a kinematic chain
142  this->ui.comboBox->setEnabled(true);
143  this->ui.cartesianselection->clear();
144  //Get all caertesian selections and add them
145  this->ui.cartesianselection->addItem(QString::fromStdString("Orientation and Position"));
146  this->ui.cartesianselection->addItem(QString::fromStdString("Position"));
147  this->ui.cartesianselection->addItem(QString::fromStdString("Orientation"));
148  this->ui.cartesianselection->addItem(QString::fromStdString("X position"));
149  this->ui.cartesianselection->addItem(QString::fromStdString("Y position"));
150  this->ui.cartesianselection->addItem(QString::fromStdString("Z position"));
151 
152  //Make sure it is enabled
153  this->ui.cartesianselection->setEnabled(true);
154  this->ui.cartesianselection->setCurrentIndex(0);
155 
156  connectSlots();
157  enableMainWidgetAsync(true);
158 }
159 
160 void armarx::RobotIKWidgetController::onDisconnect()
161 {
162  //Stop timers
163  SoSensorManager* sensor_mgr = SoDB::getSensorManager();
164  sensor_mgr->removeTimerSensor(textFieldUpdateSensor);
165  sensor_mgr->removeTimerSensor(robotUpdateSensor);
166 
167  //Remove all options in comboBox
168  this->ui.comboBox->clear();
169 
170  //Disable ui controls
171  this->ui.comboBox->setEnabled(false);
172  this->ui.moveTCP->setEnabled(false);
173  this->ui.reachableLabel->setEnabled(false);
174  this->ui.reachableLabel->setText(QString::fromStdString("No kinematic chain selected"));
175  this->ui.reachableLabel->setStyleSheet("QLabel { color : red; }");
176  this->ui.errorValue->setEnabled(false);
177  this->ui.errorValue->setText(QString::fromStdString("Calculated error: 0"));
178  this->ui.errorValue->setEnabled(false);
179  this->ui.pushButton->setEnabled(false);
180  this->ui.checkBox->setChecked(false);
181  this->ui.checkBox->setEnabled(false);
182  this->ui.currentPose->setEnabled(false);
183  this->ui.currentPoseMatrix->setEnabled(false);
184  this->ui.desiredPose->setEnabled(false);
185  this->ui.desiredPoseMatrix->setEnabled(false);
186  this->ui.resetManip->setEnabled(false);
187  this->ui.btnCopyCurrentPoseToClipboard->setEnabled(false);
188  this->ui.pushButton_setDesiredPose->setEnabled(false);
189 
190  //Remove all visualization
191  this->ui.robotViewer->getRobotViewer()->getRootNode()->removeAllChildren();
192 
193  visualization = NULL;
194  robotUpdateSensor = NULL;
195  textFieldUpdateSensor = NULL;
196 }
197 
199 {
200  QMetaObject::invokeMethod(this, "onDisconnect");
201 }
202 
204 {
205  // enableMainWidgetAsync(false);
206 }
207 
208 QPointer<QDialog> armarx::RobotIKWidgetController::getConfigDialog(QWidget* parent)
209 {
210  if (!dialog)
211  {
212  dialog = new SimpleConfigDialog(parent);
213  dialog->addProxyFinder<RobotStateComponentInterfacePrx>({"RobotStateComponent", "", "RobotState*"});
214  dialog->addProxyFinder<KinematicUnitInterfacePrx>({"KinematicUnit", "", "*KinematicUnit|KinematicUnit*"});
215  dialog->addProxyFinder<RobotIKInterfacePrx>({"RobotIK", "", "RobotIK*"});
216  }
217  return qobject_cast<SimpleConfigDialog*>(dialog);
218 }
219 
221 {
222  robotStateComponentName = settings->value("robotStateComponentName").toString().toStdString();
223  robotIKComponentName = settings->value("robotIKComponentName").toString().toStdString();
224  kinematicUnitComponentName = settings->value("kinematicUnitComponentName").toString().toStdString();
225 }
226 
228 {
229  settings->setValue("robotStateComponentName", robotStateComponentName.c_str());
230  settings->setValue("robotIKComponentName", robotIKComponentName.c_str());
231  settings->setValue("kinematicUnitComponentName", kinematicUnitComponentName.c_str());
232 }
233 
235 {
236  robotStateComponentName = dialog->getProxyName("RobotStateComponent");
237  robotIKComponentName = dialog->getProxyName("RobotIK");
238  kinematicUnitComponentName = dialog->getProxyName("KinematicUnit");
239 }
240 
242 {
243  ARMARX_INFO << "RobotIKWidgetController initWidget";
244  //Initialize Gui
245  ui.setupUi(getWidget());
246  getWidget()->setEnabled(false);
247  //Alignment for ui
248  this->ui.gridLayout->setAlignment(Qt::AlignTop);
249 
250  //Label color can not be set in designer, so we do it here
251  this->ui.reachableLabel->setStyleSheet("QLabel { color : red; }");
252 }
253 
255 {
256  robotIKPrx->begin_computeExtendedIKGlobalPose(this->ui.comboBox->currentText().toStdString(), new armarx::Pose(visualization->getUserDesiredPose()),
257  convertOption(this->ui.cartesianselection->currentText().toStdString()),
258  Ice::newCallback(this, &RobotIKWidgetController::ikCallbackExecuteMotion));
259 }
260 
261 void armarx::RobotIKWidgetController::ikCallbackExecuteMotion(const Ice::AsyncResultPtr& r)
262 {
263  RobotIKInterfacePrx prx = RobotIKInterfacePrx::uncheckedCast(r->getProxy());
264  ExtendedIKResult solution = prx->end_computeExtendedIKGlobalPose(r);
265  {
266  ScopedLock lock(solutionMutex);
267  currentSolution = improveCurrentSolution(solution);
268  }
269  QMetaObject::invokeMethod(this, "updateSolutionDisplay");
270  QMetaObject::invokeMethod(this, "executeMotion");
271 }
272 void armarx::RobotIKWidgetController::ikCallbackDisplaySolution(const Ice::AsyncResultPtr& r)
273 
274 {
275  RobotIKInterfacePrx prx = RobotIKInterfacePrx::uncheckedCast(r->getProxy());
276  ExtendedIKResult solution = prx->end_computeExtendedIKGlobalPose(r);
277  {
278  ScopedLock lock(solutionMutex);
279  currentSolution = improveCurrentSolution(solution);
280  if (currentSolution.isReachable)
281  {
282  updatePreviewRobot();
283  }
284  }
285  QMetaObject::invokeMethod(this, "updateSolutionDisplay");
286 }
287 
288 
289 
291 {
292  //An item has been selected, so we can allow the user to use the ui now
293  //The manipulator will be set to the position of the current tcp, so this pose
294  //has to be reachable!
295  this->ui.moveTCP->setEnabled(true);
296  this->ui.reachableLabel->setEnabled(true);
297  this->ui.reachableLabel->setText(QString::fromStdString("Pose reachable!"));
298  this->ui.reachableLabel->setStyleSheet("QLabel { color : green; }");
299  this->ui.errorValue->setText(QString::fromStdString("Calculated error: 0"));
300  this->ui.errorValue->setEnabled(true);
301  this->ui.pushButton->setEnabled(true);
302  this->ui.currentPose->setEnabled(true);
303  this->ui.currentPoseMatrix->setEnabled(true);
304  this->ui.desiredPose->setEnabled(true);
305  this->ui.desiredPoseMatrix->setEnabled(true);
306  this->ui.resetManip->setEnabled(true);
307  this->ui.checkBox->setEnabled(true);
308  this->ui.btnCopyCurrentPoseToClipboard->setEnabled(true);
309  this->ui.pushButton_setDesiredPose->setEnabled(true);
310 
311  //Add visualization
312  if (visualization && robot->hasRobotNodeSet(arg1.toStdString()))
313  {
314  visualization->setVisualization(robot, robot->getRobotNodeSet(arg1.toStdString()));
315  //Add callbacks
316  visualization->addManipFinishCallback(manipFinishCallback, this);
317  visualization->addManipMovedCallback(manipMovedCallback, this);
318  }
319 
320  armarx::RemoteRobot::synchronizeLocalClone(previewRobot, robotStateComponentPrx);
321 }
322 
324 {
325  //If there is a manip in the scene we pretend it just moved to update color etc.
326  if (visualization->getIsVisualizing())
327  {
328  manipFinishCallback(this, NULL);
329  }
330 }
331 
333 {
334  //Triggers reset of manipulator in kinematicChainChanged
335  kinematicChainChanged(this->ui.comboBox->currentText());
336 }
337 
339 {
340  if (getState() != eManagedIceObjectStarted)
341  {
342  return;
343  }
344 
345 
346  ScopedLock lock(solutionMutex);
347 
348  if (currentSolution.isReachable)
349  {
350  //Green
351  ui.reachableLabel->setText(QString::fromStdString("Pose reachable!"));
352  ui.reachableLabel->setStyleSheet("QLabel { color : green; }");
353  visualization->setColor(0, 1, 0);
354  }
355  else
356  {
357  //Red
358  ui.reachableLabel->setText(QString::fromStdString("Pose unreachable!"));
359  ui.reachableLabel->setStyleSheet("QLabel { color : red; }");
360  visualization->setColor(1, 0, 0);
361  }
362 
363  //Display calculated error
364  ui.errorValue->setText("Calculated error: " + QString::number(currentSolution.errorPosition, 'f', 1)
365  + " mm " + QString::number(currentSolution.errorOrientation * 180 / M_PI, 'f', 2) + " deg");
366 
367 }
368 
370 {
371  auto visualizationRoot = this->ui.robotViewer->getRobotViewer()->getRootNode();
372  if (checked)
373  {
374  if (visualizationRoot->findChild(currentRobotVisualization->getCoinVisualization()) == -1)
375  {
376  visualizationRoot->addChild(currentRobotVisualization->getCoinVisualization());
377  }
378  }
379  else
380  {
381  if (visualizationRoot->findChild(currentRobotVisualization->getCoinVisualization()) != -1)
382  {
383  visualizationRoot->removeChild(currentRobotVisualization->getCoinVisualization());
384  }
385  }
386 }
387 
389 {
390  auto visualizationRoot = this->ui.robotViewer->getRobotViewer()->getRootNode();
391  if (checked)
392  {
393  if (visualizationRoot->findChild(previewRobotVisualization->getCoinVisualization()) == -1)
394  {
395  visualizationRoot->addChild(previewRobotVisualization->getCoinVisualization());
396  }
397  }
398  else
399  {
400  if (visualizationRoot->findChild(previewRobotVisualization->getCoinVisualization()) != -1)
401  {
402  visualizationRoot->removeChild(previewRobotVisualization->getCoinVisualization());
403  }
404  }
405 }
406 
407 void armarx::RobotIKWidgetController::connectSlots()
408 {
409  connect(ui.resetManip, SIGNAL(clicked()), this, SLOT(resetManip()), Qt::UniqueConnection);
410  connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(executeMotion()), Qt::UniqueConnection);
411  connect(ui.comboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(kinematicChainChanged(QString)), Qt::UniqueConnection);
412  connect(ui.cartesianselection, SIGNAL(currentIndexChanged(QString)), this, SLOT(caertesianSelectionChanged(QString)), Qt::UniqueConnection);
413  connect(ui.checkBox, SIGNAL(toggled(bool)), this, SLOT(autoFollowChanged(bool)), Qt::UniqueConnection);
414  connect(ui.btnCopyCurrentPoseToClipboard, SIGNAL(clicked()), this, SLOT(on_btnCopyCurrentPoseToClipboard_clicked()), Qt::UniqueConnection);
415  connect(ui.checkBox_showCurrentRobot, SIGNAL(toggled(bool)), this, SLOT(showCurrentRobotChanged(bool)), Qt::UniqueConnection);
416  connect(ui.checkBox_showPreviewRobot, SIGNAL(toggled(bool)), this, SLOT(showPreviewRobotChanged(bool)), Qt::UniqueConnection);
417  connect(ui.pushButton_setDesiredPose, SIGNAL(clicked()), this, SLOT(on_btnSetDesiredPose_clicked()), Qt::UniqueConnection);
418 }
419 
420 Ice::StringSeq armarx::RobotIKWidgetController::getIncludePaths() const
421 {
422  Ice::StringSeq includePaths;
423 
424  try
425  {
426  Ice::StringSeq packages = robotStateComponentPrx->getArmarXPackages();
427  packages.push_back(Application::GetProjectName());
428 
429  for (const std::string& projectName : packages)
430  {
431  if (projectName.empty())
432  {
433  continue;
434  }
435 
436  CMakePackageFinder project(projectName);
437  auto pathsString = project.getDataDir();
438  Ice::StringSeq projectIncludePaths = armarx::Split(pathsString, ",;", true, true);
439  includePaths.insert(includePaths.end(), projectIncludePaths.begin(), projectIncludePaths.end());
440  }
441  }
442  catch (...)
443  {
444  ARMARX_ERROR << "Unable to retrieve robot filename." << std::endl;
445  }
446 
447  return includePaths;
448 }
449 
450 VirtualRobot::RobotPtr armarx::RobotIKWidgetController::loadRobot(Ice::StringSeq includePaths)
451 {
452  try
453  {
454  std::string rfile = robotStateComponentPrx->getRobotFilename();
455  ArmarXDataPath::getAbsolutePath(rfile, rfile, includePaths);
456  return VirtualRobot::RobotIO::loadRobot(rfile);
457  }
458  catch (...)
459  {
460  ARMARX_ERROR << "Unable to load robot from file" << std::endl;
461  return VirtualRobot::RobotPtr();
462  }
463 }
464 
465 void armarx::RobotIKWidgetController::manipFinishCallback(void* data, SoDragger* dragger)
466 {
467  RobotIKWidgetController* controller = static_cast<RobotIKWidgetController*>(data);
468  if (controller)
469  {
470  startIKSolving(controller);
471  }
472 }
473 
474 void armarx::RobotIKWidgetController::manipMovedCallback(void* data, SoDragger* dragger)
475 {
476  RobotIKWidgetController* controller = static_cast<RobotIKWidgetController*>(data);
477 
478  if (controller)
479  {
480  controller->manipulatorMoved = true;
481  QMetaObject::invokeMethod(controller, "showPreviewRobotChanged", Qt::QueuedConnection, Q_ARG(bool, false));
482  }
483 }
484 
485 void armarx::RobotIKWidgetController::robotUpdateTimerCB(void* data, SoSensor* sensor)
486 {
487  RobotIKWidgetController* controller = static_cast<RobotIKWidgetController*>(data);
488 
489  if (!controller || !controller->robotStateComponentPrx || !controller->robot)
490  {
491  return;
492  }
493 
494  try
495  {
496  armarx::RemoteRobot::synchronizeLocalClone(controller->robot, controller->robotStateComponentPrx);
497 
498  if (controller->startUpCameraPositioningFlag)
499  {
500  controller->ui.robotViewer->getRobotViewer()->cameraViewAll();
501  controller->startUpCameraPositioningFlag = false;
502  }
503  }
504  catch (...) {};
505 }
506 
507 void armarx::RobotIKWidgetController::textFieldUpdateTimerCB(void* data, SoSensor* sensor)
508 {
509  RobotIKWidgetController* controller = static_cast<RobotIKWidgetController*>(data);
510 
511  if (!controller)
512  {
513  return;
514  }
515 
516  if (controller->visualization->getIsVisualizing())
517  {
518  Eigen::Matrix4f tcpMatrix = controller->robot->getRobotNodeSet(controller->ui.comboBox->currentText().toStdString())->getTCP()->getPoseInRootFrame();
519  FramedPose actualPose(tcpMatrix,
520  controller->robot->getRootNode()->getName(),
521  controller->robot->getName());
522  //Set text label to tcp matrix
523  controller->ui.currentPoseMatrix->setText(QString::fromStdString(actualPose.output()));
524 
525  //Set text label for desired tcp pose
526  FramedPose desired(controller->robot->getRootNode()->toLocalCoordinateSystem(controller->visualization->getUserDesiredPose()),
527  controller->robot->getRootNode()->getName(),
528  controller->robot->getName());
529  controller->ui.desiredPoseMatrix->setText(QString::fromStdString(desired.output()));
530  }
531 }
532 
533 void armarx::RobotIKWidgetController::autoFollowSensorTimerCB(void* data, SoSensor* sensor)
534 {
535  RobotIKWidgetController* controller = static_cast<RobotIKWidgetController*>(data);
536 
537  if (controller && controller->manipulatorMoved)
538  {
539  controller->solveIK();
540  controller->manipulatorMoved = false;
541  }
542 }
543 
544 void armarx::RobotIKWidgetController::startIKSolving(RobotIKWidgetController* controller)
545 {
546  if (controller)
547  {
548  controller->ui.reachableLabel->setText(QString::fromStdString("Calculating..."));
549  controller->ui.reachableLabel->setStyleSheet("QLabel { color : black; }");
550  controller->robotIKPrx->begin_computeExtendedIKGlobalPose(controller->ui.comboBox->currentText().toStdString(),
551  new armarx::Pose(controller->visualization->getUserDesiredPose()),
552  controller->convertOption(controller->ui.cartesianselection->currentText().toStdString()),
553  Ice::newCallback(controller, &RobotIKWidgetController::ikCallbackDisplaySolution));
554  }
555 }
556 
557 armarx::ExtendedIKResult armarx::RobotIKWidgetController::improveCurrentSolution(armarx::ExtendedIKResult& solution)
558 {
559  if (!ui.checkBox_cartesianControl->isChecked())
560  {
561  return solution;
562  }
563 
564  if (!solution.isReachable)
565  {
566  return solution;
567  }
568 
570  armarx::CartesianSelection mode = convertOption(ui.cartesianselection->currentText().toStdString());
571  if (mode == CartesianSelection::eAll)
572  {
573  vrmode = VirtualRobot::IKSolver::CartesianSelection::All;
574  }
575  else if (mode == CartesianSelection::ePosition)
576  {
578  }
579  else if (mode == CartesianSelection::eOrientation)
580  {
582  }
583  else
584  {
585  return solution;
586  }
587 
588  armarx::RemoteRobot::synchronizeLocalClone(cartesianControlRobot, robotStateComponentPrx);
589  cartesianControlRobot->setJointValues(solution.jointAngles);
590  VirtualRobot::RobotNodeSetPtr kc = cartesianControlRobot->getRobotNodeSet(ui.comboBox->currentText().toStdString());
591  VirtualRobot::RobotNodePtr tcp = kc->getTCP();
592  Eigen::Matrix4f globalTargetTCPPose = visualization->getUserDesiredPose();
593  Eigen::Matrix4f localTarget = cartesianControlRobot->getRootNode()->toLocalCoordinateSystem(globalTargetTCPPose);
594 
595  CartesianPositionControllerPtr cartesianPositionController;
596  cartesianPositionController.reset(new CartesianPositionController(tcp));
597 
598  CartesianVelocityControllerPtr cartesianVelocityController;
599  cartesianVelocityController.reset(new CartesianVelocityController(kc, tcp, VirtualRobot::JacobiProvider::eSVD));
600 
601 
602  float errorOriInitial = cartesianPositionController->getOrientationError(localTarget);
603  float errorPosInitial = cartesianPositionController->getPositionError(localTarget);
604 
605  float stepLength = 0.05f;
606  float eps = 0.001;
607 
608  for (int i = 0; i < CARTESIAN_CONTROLLER_LOOP_AMOUNT; i++)
609  {
610  Eigen::VectorXf tcpVelocities = cartesianPositionController->calculate(localTarget, vrmode);
611  Eigen::VectorXf nullspaceVel = cartesianVelocityController->calculateJointLimitAvoidance(); // calculateNullspaceVelocity(tcpVelocities, 1.0f, vrmode);
612  float nullspaceLen = nullspaceVel.norm();
613  if (nullspaceLen > stepLength)
614  {
615  nullspaceVel = nullspaceVel / nullspaceLen * stepLength;
616  }
617  Eigen::VectorXf jointVelocities = cartesianVelocityController->calculate(tcpVelocities, nullspaceVel, vrmode);
618 
619  //jointVelocities = jointVelocities * stepLength;
620  float len = jointVelocities.norm();
621  if (len > stepLength)
622  {
623  jointVelocities = jointVelocities / len * stepLength;
624  }
625 
626  for (size_t n = 0; n < kc->getSize(); n++)
627  {
628  kc->getNode(n)->setJointValue(kc->getNode(n)->getJointValue() + jointVelocities(n));
629  }
630  if (len < eps)
631  {
632  break;
633  }
634  }
635 
636  float errorOriAfter = cartesianPositionController->getOrientationError(localTarget);
637  float errorPosAfter = cartesianPositionController->getPositionError(localTarget);
638  if (errorOriAfter < errorOriInitial + 1.f / 180 * M_PI && errorPosAfter < errorPosInitial + 1.f)
639  {
640  solution.jointAngles = kc->getJointValueMap();
641  solution.errorOrientation = errorOriAfter;
642  solution.errorPosition = errorPosAfter;
643  }
644 
645  return solution;
646 }
647 
648 armarx::ExtendedIKResult armarx::RobotIKWidgetController::getIKSolution() const
649 {
650  return ExtendedIKResult();
651 }
652 
653 armarx::CartesianSelection armarx::RobotIKWidgetController::convertOption(std::string option) const
654 {
655  if (option == "Orientation and Position")
656  {
657  return eAll;
658  }
659  else if (option == "Position")
660  {
661  return ePosition;
662  }
663  else if (option == "Orientation")
664  {
665  return eOrientation;
666  }
667  else if (option == "X position")
668  {
669  return eX;
670  }
671  else if (option == "Y position")
672  {
673  return eY;
674  }
675  else if (option == "Z position")
676  {
677  return eZ;
678  }
679 
680  return eAll;
681 }
682 
683 void armarx::RobotIKWidgetController::updatePreviewRobot()
684 {
685  armarx::RemoteRobot::synchronizeLocalClone(previewRobot, robotStateComponentPrx);
686  previewRobot->setJointValues(currentSolution.jointAngles);
687  showPreviewRobotChanged(ui.checkBox_showPreviewRobot->isChecked());
688 }
689 
690 void armarx::RobotIKWidgetController::on_btnSetDesiredPose_clicked()
691 {
693 
694  if (d.exec() == QDialog::Accepted)
695  {
696  FramedPosePtr newDesiredPose = d.getDesiredPose();
697  if (newDesiredPose->frame.empty())
698  {
699  ARMARX_WARNING << "Frame of a FramedPose cannot be empty!";
700  }
701  else if (newDesiredPose->agent.empty())
702  {
703  ARMARX_WARNING << "Agent of a FramedPose cannot be empty!";
704 
705  }
706  else
707  {
708  try
709  {
710  visualization->setUserDesiredPose(newDesiredPose->toGlobalEigen(robot));
711  startIKSolving(this);
712  }
713  catch (...)
714  {
716  }
717  }
718  }
719 }
720 
721 void armarx::RobotIKWidgetController::executeMotion()
722 {
723  if (currentSolution.isReachable)
724  {
725  //Switch all control modes to ePositionControl
726  std::vector<VirtualRobot::RobotNodePtr> rn = robot->getRobotNodeSet(this->ui.comboBox->currentText().toStdString())->getAllRobotNodes();
727  NameControlModeMap jointModes;
729 
730  for (unsigned int i = 0; i < rn.size(); i++)
731  {
732  jointModes[rn[i]->getName()] = ePositionControl;
733  jointAngles[rn[i]->getName()] = 0.0f;
734  }
735 
736  kinematicUnitInterfacePrx->switchControlMode(jointModes);
737  kinematicUnitInterfacePrx->setJointAngles(currentSolution.jointAngles);
738  }
739 }
740 
742 {
743  if (checked)
744  {
745  //Make a timer update robo pose every time tick
746  SoSensorManager* sensor_mgr = SoDB::getSensorManager();
747  autoFollowSensor = new SoTimerSensor(autoFollowSensorTimerCB, this);
748  autoFollowSensor->setInterval(SbTime(AUTO_FOLLOW_UPDATE / 1000.0f));
749  sensor_mgr->insertTimerSensor(autoFollowSensor);
750  }
751  else
752  {
753  SoSensorManager* sensor_mgr = SoDB::getSensorManager();
754  sensor_mgr->removeTimerSensor(autoFollowSensor);
755  }
756 }
757 
758 void armarx::RobotIKWidgetController::on_btnCopyCurrentPoseToClipboard_clicked()
759 {
760 
761  if (visualization->getIsVisualizing())
762  {
763 
764  Eigen::Matrix4f tcpMatrix = robot->getRobotNodeSet(ui.comboBox->currentText().toStdString())->getTCP()->getPoseInRootFrame();
765  FramedPosePtr pose = new FramedPose(tcpMatrix, robot->getRootNode()->getName(), robot->getName());
766  JSONObjectPtr obj = new JSONObject();
767  obj->serializeIceObject(pose);
768 
769 
770  QClipboard* clipboard = QApplication::clipboard();
771  clipboard->setText(QString::fromStdString(obj->asString(true)));
772  }
773 }
774 
775 
armarx::RobotIKGuiPlugin::RobotIKGuiPlugin
RobotIKGuiPlugin()
Definition: RobotIKGuiPlugin.cpp:54
armarx::RobotIKWidgetController::showPreviewRobotChanged
void showPreviewRobotChanged(bool checked)
Definition: RobotIKGuiPlugin.cpp:388
armarx::Application::GetProjectName
static const std::string & GetProjectName()
Definition: Application.cpp:863
armarx::RobotIKWidgetController::getConfigDialog
QPointer< QDialog > getConfigDialog(QWidget *parent=0) override
getConfigDialog returns a pointer to the a configuration widget of this controller.
Definition: RobotIKGuiPlugin.cpp:208
armarx::RobotIKWidgetController::RobotIKWidgetController
RobotIKWidgetController()
Definition: RobotIKGuiPlugin.cpp:59
SetDesiredPoseDialog
Definition: SetDesiredPoseDialog.h:13
armarx::RobotIKWidgetController::initWidget
void initWidget()
Definition: RobotIKGuiPlugin.cpp:241
GfxTL::Orientation
ScalarT Orientation(const VectorXD< 2, ScalarT > &p1, const VectorXD< 2, ScalarT > &p2, const VectorXD< 2, ScalarT > &c)
Definition: Orientation.h:9
JSONObject.h
armarx::RobotIKWidgetController::onExitComponent
void onExitComponent() override
Hook for subclass.
Definition: RobotIKGuiPlugin.cpp:203
armarx::RemoteRobot::synchronizeLocalClone
static bool synchronizeLocalClone(VirtualRobot::RobotPtr robot, RobotStateComponentInterfacePrx robotStatePrx)
Definition: RemoteRobot.cpp:448
armarx::VariantType::FramedPose
const VariantTypeId FramedPose
Definition: FramedPose.h:37
armarx::JSONObject
The JSONObject class is used to represent and (de)serialize JSON objects.
Definition: JSONObject.h:43
armarx::FramedPosePtr
IceInternal::Handle< FramedPose > FramedPosePtr
Definition: FramedPose.h:250
armarx::Split
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelperTemplates.h:35
ROBOT_UPDATE_TIMER_MS
#define ROBOT_UPDATE_TIMER_MS
Definition: RobotIKGuiPlugin.cpp:49
armarx::RobotIKWidgetController::showCurrentRobotChanged
void showCurrentRobotChanged(bool checked)
Definition: RobotIKGuiPlugin.cpp:369
armarx::RobotIKWidgetController::saveSettings
void saveSettings(QSettings *settings) override
Implement to save the settings as part of the GUI configuration.
Definition: RobotIKGuiPlugin.cpp:227
armarx::NJointTaskSpaceDMPControllerMode::ePosition
@ ePosition
Definition: ControllerInterface.ice:36
armarx::CartesianPositionControllerPtr
std::shared_ptr< CartesianPositionController > CartesianPositionControllerPtr
Definition: CartesianPositionController.h:38
TEXTFIELD_UPDATE_TIMER_MS
#define TEXTFIELD_UPDATE_TIMER_MS
Definition: RobotIKGuiPlugin.cpp:50
armarx::RobotIKWidgetController::caertesianSelectionChanged
void caertesianSelectionChanged(const QString &arg1)
Definition: RobotIKGuiPlugin.cpp:323
armarx::ScopedLock
Mutex::scoped_lock ScopedLock
Definition: Synchronization.h:132
RobotIKGuiPlugin.h
armarx::CartesianVelocityControllerPtr
std::shared_ptr< CartesianVelocityController > CartesianVelocityControllerPtr
Definition: CartesianVelocityController.h:34
armarx::RobotIKWidgetController::kinematicChainChanged
void kinematicChainChanged(const QString &arg1)
Definition: RobotIKGuiPlugin.cpp:290
project
std::string project
Definition: VisualizationRobot.cpp:82
armarx::RobotIKWidgetController::loadSettings
void loadSettings(QSettings *settings) override
Implement to load the settings that are part of the GUI configuration.
Definition: RobotIKGuiPlugin.cpp:220
IceInternal::Handle< FramedPose >
armarx::RobotIKWidgetController::resetManip
void resetManip()
Definition: RobotIKGuiPlugin.cpp:332
controller
Definition: AddOperation.h:39
M_PI
#define M_PI
Definition: MathTools.h:17
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
armarx::NJointTaskSpaceDMPControllerMode::CartesianSelection
CartesianSelection
Definition: ControllerInterface.ice:34
armarx::RobotIKWidgetController::configured
void configured() override
This function must be implemented by the user, if he supplies a config dialog.
Definition: RobotIKGuiPlugin.cpp:234
ArmarXObjectScheduler.h
armarx::channels::KinematicUnitObserver::jointVelocities
const KinematicUnitDatafieldCreator jointVelocities("jointVelocities")
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
SetDesiredPoseDialog::getDesiredPose
armarx::FramedPosePtr getDesiredPose()
Definition: SetDesiredPoseDialog.cpp:29
CARTESIAN_CONTROLLER_LOOP_AMOUNT
#define CARTESIAN_CONTROLLER_LOOP_AMOUNT
Definition: RobotIKGuiPlugin.cpp:52
CartesianVelocityController.h
CartesianPositionController.h
RobotViewer.h
armarx::control::njoint_controller::platform::platform_follower_controller::NameValueMap
std::map< std::string, float > NameValueMap
Definition: PlatformFollowerController.h:91
armarx::channels::KinematicUnitObserver::jointAngles
const KinematicUnitDatafieldCreator jointAngles("jointAngles")
CMakePackageFinder.h
option
#define option(type, fn)
SetDesiredPoseDialog.h
armarx::Pose
The Pose class.
Definition: Pose.h:242
armarx::RobotIKWidgetController::onDisconnectComponent
void onDisconnectComponent() override
Hook for subclass.
Definition: RobotIKGuiPlugin.cpp:198
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:601
armarx::RobotIKWidgetController::solveIK
void solveIK()
Definition: RobotIKGuiPlugin.cpp:254
armarx::NJointTaskSpaceDMPControllerMode::eAll
@ eAll
Definition: ControllerInterface.ice:38
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
armarx::NJointTaskSpaceDMPControllerMode::eOrientation
@ eOrientation
Definition: ControllerInterface.ice:37
IceInternal::ProxyHandle<::IceProxy::armarx::RobotStateComponentInterface >
armarx::ManipulatorVisualization
Definition: ManipulatorVisualization.h:51
armarx::RobotIKWidgetController::onConnectComponent
void onConnectComponent() override
Pure virtual hook for the subclass.
Definition: RobotIKGuiPlugin.cpp:83
armarx::RobotIKWidgetController::autoFollowChanged
void autoFollowChanged(bool checked)
Definition: RobotIKGuiPlugin.cpp:741
armarx::ArmarXDataPath::getAbsolutePath
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
Definition: ArmarXDataPath.cpp:111
armarx::navigation::core::Position
Eigen::Vector3f Position
Definition: basic_types.h:36
armarx::handleExceptions
void handleExceptions()
Definition: Exception.cpp:141
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::RobotIKWidgetController::updateSolutionDisplay
void updateSolutionDisplay()
Definition: RobotIKGuiPlugin.cpp:338
ArmarXDataPath.h
AUTO_FOLLOW_UPDATE
#define AUTO_FOLLOW_UPDATE
Definition: RobotIKGuiPlugin.cpp:51
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
armarx::RobotIKWidgetController::onInitComponent
void onInitComponent() override
Pure virtual hook for the subclass.
Definition: RobotIKGuiPlugin.cpp:73
Application.h
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18
armarx::SimpleConfigDialog
A config-dialog containing one (or multiple) proxy finders.
Definition: SimpleConfigDialog.h:84