RobotVisualizationController.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 ArmarXGuiPlugins::RobotTrajectoryDesigner::Visualization
17 * @author Timo Birr
18 * @date 2018
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
23
24#include <QGridLayout>
25
27
30
31#include "../Environment.h"
32#include "../KinematicSolver.h"
35#include "VirtualRobot/RobotNodeSet.h"
36#include "VirtualRobot/XML/RobotIO.h"
37
38#define ROBOT_UPDATE_TIMER_MS 33
39
40
41using namespace armarx;
42using namespace VirtualRobot;
43
44/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
45/// INITIALIZATION
46/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
52
56
57void
59{
60 //initialize Attributes
61 this->cs = IKSolver::CartesianSelection::All;
62 this->selectedWayPoint = 0;
63 this->selectedTransition = -1;
64 this->iKCallback = true;
65 this->playerRunning = false;
66
67
68 //Initialize Viewer Widget
69 QWidget* viewerParent = new QWidget();
70 this->viewer = RobotVisualizationPtr(new CoinRobotViewerAdapter(viewerParent));
71 this->viewSplitter = new RobotVisualizationWidget(0, viewerParent, viewer);
72 dynamic_cast<QGridLayout*>(parent->layout())
73 ->addWidget(viewSplitter,
74 0,
75 0,
76 1,
77 3); //this needs to be done in order to let Toolbar and view overlap
78 if (environment != NULL && environment->getRobot())
79 {
80 robotChanged(environment->getRobot());
81 }
82 this->setCamera(0);
83 ARMARX_INFO << "RobotTrajectoryDesigner: RobotVisualizationController on init component";
84}
85
86void
88{
89 ARMARX_INFO << "RobotTrajectoryDesigner: RobotVisualizationController on connect component";
90}
91
92void
94{
95 ARMARX_INFO << "RobotTrajectoryDesigner: RobotVisualizationController on disconnect";
96}
97
98void
100{
101 ARMARX_INFO << "RobotTrajectoryDesigner: RobotVisualizationController on exit components";
102}
103
104void
106{
107 //UPDATE WAYPOINT SELECTION
108 if (selectedWayPoint != this->viewer->getSelectedWaypoint())
109 {
110 selectedWayPoint = this->viewer->getSelectedWaypoint();
111 emit wayPointSelected(selectedWayPoint);
112 if (currentTrajectory && static_cast<unsigned>(viewer->getSelectedWaypoint()) <
113 currentTrajectory->getAllUserWaypoints().size())
114 {
115 std::vector<double> angles =
116 currentTrajectory->getUserWaypoint(viewer->getSelectedWaypoint())->getJointAngles();
117 viewer->setManipulator(currentTrajectory->getRns(),
118 std::vector<float>(angles.begin(), angles.end()));
119 }
120 }
121 //UPDATE MANIPULATOR MOVEMENT
122 if (!selectedKinematicChain)
123 {
124 return;
125 }
126 emit manipulatorChanged(viewer->getManipulatorPose());
128 PoseBasePtr destination = PoseBasePtr(new Pose(viewer->getManipulatorPose()));
129 std::string currentRnsName = selectedKinematicChain->getName();
130 std::vector<float> jointAngles =
131 ks->solveRecursiveIK(this->robot->getRobotNodeSet(currentRnsName),
132 robot->getRobotNodeSet(currentRnsName)->getJointValues(),
133 destination,
134 cs);
135 if (jointAngles.size() != 0 && iKCallback)
136 {
137 robot->getRobotNodeSet(currentRnsName)->setJointValues(jointAngles);
138 emit poseReachable(true);
139 emit tcpPoseChanged(robot->getRobotNodeSet(currentRnsName)->getTCP()->getGlobalPose());
140 }
141 else
142 {
143 emit poseReachable(false);
144 }
145}
146
147void
152
153/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
154/// PARALLEL VIEWS
155/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
156void
158{
159 this->viewSplitter->addWidget();
160}
161
162void
164{
165 this->viewSplitter->removeWidget();
166}
167
168/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
169/// UPDATING OF VISUALIZATION
170/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
171
172void
174{
175 this->environment = environment;
176 robotChanged(environment->getRobot());
177}
178
179void
181{
182 this->robot = robot;
183 if (viewer)
184 {
185 viewer->addRobotVisualization(this->robot, "");
186 }
188 this->currentTrajectory = NULL;
189 this->selectedWayPoint = 0;
190 this->selectedTransition = -1;
191 this->setCamera(0);
192}
193
194void
196{
197 /*for (RobotVisualizationPtr visu : viewers)
198 {
199 visu->clearTrajectory();
200 }*/
201 viewer->clearTrajectory();
202
203
204 if (!trajectory)
205 {
206 return;
207 }
208
209 this->currentTrajectory = trajectory;
210 this->kinematicChainChanged(currentTrajectory->getRns());
211 //clearViewers
212
213
214 //Add all UserWayPoints
215 int i = 0;
216 if (currentTrajectory->getAllUserWaypoints().size() == 0)
217 {
218 return;
219 }
220 for (UserWaypointPtr currentPoint : currentTrajectory->getAllUserWaypoints())
221 {
222
223 VirtualRobot::EndEffectorPtr endEffector =
224 robot->getEndEffector(trajectory->getRns()->getTCP()->getName());
225 if (!endEffector)
226 {
227 std::vector<VirtualRobot::EndEffectorPtr> eefs;
228 robot->getEndEffectors(eefs);
229 for (auto eef : eefs)
230 {
231 if (eef->getTcp() == trajectory->getRns()->getTCP())
232 {
233 endEffector = eef;
234 break;
235 }
236 }
237 }
238 Pose localPose =
239 Pose(currentPoint->getPose()->position, currentPoint->getPose()->orientation);
240 if (endEffector)
241 {
242
243 viewer->addWaypointVisualization(
244 i,
245 PosePtr(new Pose(trajectory->getRns()->getKinematicRoot()->toGlobalCoordinateSystem(
246 localPose.toEigen()))),
247 endEffector);
248 //visu->addWaypointVisualization(i, currentPoint->getPose(), robot->getEndEffector(robot->getRobotNodeSet(trajectory->getRns()->getName())->getTCP()->getName()));
249 }
250 else
251 {
252 viewer->addWaypointVisualization(
253 i,
254 PosePtr(new Pose(trajectory->getRns()->getKinematicRoot()->toGlobalCoordinateSystem(
255 localPose.toEigen()))),
256 NULL);
257 }
258 i++;
259 }
260
261
262 //Add all Transitions
263 if (currentTrajectory->getAllUserWaypoints().size() == 1)
264 {
265 return;
266 }
268 for (unsigned int k = 0; k < currentTrajectory->getNrOfUserWaypoints() - 1; k++)
269 {
270 TrajectoryPtr currentTransition = currentTrajectory->getTransition(k)->getTrajectory();
271 std::vector<PoseBasePtr> curve = std::vector<PoseBasePtr>();
272 for (const Trajectory::TrajData& element : *currentTransition)
273 {
274 std::vector<double> jointValues = element.getPositions();
275 PoseBasePtr pose = ks->doForwardKinematic(currentTrajectory->getRns(), jointValues);
276 curve.push_back(pose);
277 }
278 viewer->addTransitionVisualization(k, curve);
279 if (static_cast<signed>(k) == selectedTransition)
280 {
281 viewer->highlightTransitionVisualization(k, curve);
282 }
283 }
284 //ARMARX_INFO << "DEBUG END";
285}
286
287void
289{
290 //TODO find out sphere size
291}
292
293void
295{
297 TrajectoryPtr selectedTransition = currentTrajectory->getTransition(index)->getTrajectory();
298
299 std::vector<PoseBasePtr> curve = std::vector<PoseBasePtr>();
300
301 for (const Trajectory::TrajData& element : *selectedTransition)
302 {
303 std::vector<double> jointValues = element.getPositions();
304 PoseBasePtr pose = ks->doForwardKinematic(currentTrajectory->getRns(), jointValues);
305 curve.push_back(pose);
306 }
307 /*for (RobotVisualizationPtr visu : viewers)*/
308 {
309
310 if (currentTrajectory->getNrOfUserWaypoints() >
311 static_cast<unsigned>(this->selectedTransition + 1) &&
312 this->selectedTransition >= 0)
313 {
314 TrajectoryPtr deselectedTransition =
315 currentTrajectory->getTransition(this->selectedTransition)->getTrajectory();
316 std::vector<PoseBasePtr> oldCurve = std::vector<PoseBasePtr>();
317
318 for (const Trajectory::TrajData& element : *deselectedTransition)
319 {
320
321 std::vector<double> jointValues = element.getPositions();
322 PoseBasePtr pose = ks->doForwardKinematic(currentTrajectory->getRns(), jointValues);
323 oldCurve.push_back(pose);
324 }
325 viewer->removeTransitionVisualization(this->selectedTransition);
326 viewer->addTransitionVisualization(this->selectedTransition, oldCurve);
327 }
328 viewer->highlightTransitionVisualization(index, curve);
329 }
330 this->selectedTransition = index;
331}
332
333void
335{
336 viewer->clearTrajectory();
337 this->currentTrajectory = NULL;
338}
339
340/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
341/// IK CALLBACK METHODS
342/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
343void
345 VirtualRobot::IKSolver::CartesianSelection cs)
346{
347 this->cs = IKSolver::CartesianSelection::All;
348 refresh();
349}
350
351void
353{
354 viewer->removeAllWaypointVisualizations();
355 //IKCallback
356
357 this->selectedKinematicChain = rns;
358
359 if (selectedKinematicChain)
360 {
361 std::vector<float> jointAngles;
362 jointAngles = std::vector<float>(
363 robot->getRobotNodeSet(this->selectedKinematicChain->getName())->getJointValues());
364 viewer->setManipulator(this->selectedKinematicChain, jointAngles);
365 }
366 this->updateViews(NULL);
367}
368
369void
371{
372 iKCallback = enabled;
373}
374
375/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
376/// CAMERA UPDATING METHODS
377/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
378void
383
384void
386{
387 Eigen::Vector3f position;
388 Eigen::Vector3f pointAtA = Eigen::Vector3f(0, 0, 0);
389 Eigen::Vector3f pointAtB;
390
391 switch (perspective)
392 {
393 case 0:
394 //HIGH ANGLE
395 position = Eigen::Vector3f(0, 2, 3.5);
396 pointAtB = Eigen::Vector3f(0, 0, 5);
397 break;
398
399 case 1:
400 //TOP
401 position = Eigen::Vector3f(0, 0, 4);
402 pointAtB = Eigen::Vector3f(0, -360, 0);
403 break;
404
405 case 2:
406 //FRONT
407 position = Eigen::Vector3f(0, 5, 2);
408 pointAtB = Eigen::Vector3f(0, 0, 2);
409 break;
410 case 3:
411 //BACK
412 position = Eigen::Vector3f(0, -5, 2);
413 pointAtB = Eigen::Vector3f(0, 0, 2);
414 break;
415
416 case 4:
417 //LEFT
418 position = Eigen::Vector3f(5, 0, 2);
419 pointAtB = Eigen::Vector3f(0, 0, 2);
420 break;
421 case 5:
422 //RIGHT
423 position = Eigen::Vector3f(-5, 0, 2);
424 pointAtB = Eigen::Vector3f(0, 0, 2);
425 break;
426 default:
427 position = Eigen::Vector3f(0, 2, 3.5);
428 pointAtB = Eigen::Vector3f(0, 0, 5);
429 }
430 this->viewSplitter->setCameraOfFocused(position, pointAtA, pointAtB);
431 /*RobotVisualizationPtr expectedViewer = viewers[0];
432 expectedViewer->setCamera(position, pointAtA, pointAtB);
433 expectedViewer->updateRobotVisualization();*/
434}
435
436void
438{
439 viewer->setSelectedWaypoint(index);
440 if (currentTrajectory)
441 {
442 ARMARX_WARNING << "robot visualisation controller trying to update selected waypoint";
443 std::vector<double> jA = currentTrajectory->getUserWaypoint(index)->getJointAngles();
444 std::vector<float> jointAngles = std::vector<float>(jA.begin(), jA.end());
445 viewer->setManipulator(currentTrajectory->getRns(), jointAngles);
447 currentTrajectory->getUserWaypoint(index)->getIKSelection());
448 }
449}
450
451/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
452/// PLAY TRAJECTORY
453/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
454
455void
457{
458 player = DesignerTrajectoryPlayerPtr(new DesignerTrajectoryPlayer(this->viewer, this->robot));
459 player->addTrajectory(currentTrajectory);
460 this->playerStarter();
461}
462
463void
464RobotVisualizationController::playTrajectories(std::vector<DesignerTrajectoryPtr> trajectories)
465{
466 player = DesignerTrajectoryPlayerPtr(new DesignerTrajectoryPlayer(this->viewer, this->robot));
467 for (DesignerTrajectoryPtr current : trajectories)
468 {
469 player->addTrajectory(current);
470 }
471 this->playerStarter();
472}
473
474void
476{
477 player = NULL;
478 KinematicSolver::getInstance(NULL, NULL)->syncRobotPrx();
479 updateViews(currentTrajectory);
481 viewer->setManipulator(
482 selectedKinematicChain,
483 robot->getRobotNodeSet(selectedKinematicChain->getName())->getJointValues());
484 playerRunning = false;
485 emit trajectoryPlayerNotPlaying(!playerRunning);
486 emit trajectoryPlayerPlaying(playerRunning);
487}
488
489void
490RobotVisualizationController::playerStarter()
491{
492 if (playerRunning || !selectedKinematicChain)
493 {
494 return;
495 }
496 playerRunning = true;
497 emit trajectoryPlayerNotPlaying(!playerRunning);
498 emit trajectoryPlayerPlaying(playerRunning);
499 connect(player.get(), SIGNAL(finishedPlayback()), this, SLOT(trajectoryPlayerStopped()));
500 viewer->clearTrajectory();
501 viewer->setManipulator(NULL, std::vector<float>());
503 player->startPlayback();
504}
uint8_t index
The CoinRobotViewerAdapter class.
static std::shared_ptr< KinematicSolver > getInstance(VirtualRobot::ScenePtr scenario, VirtualRobot::RobotPtr robot)
SINGLETON-FEATURES///////////////////////////////////////////////////////////////////////////////////...
The Pose class.
Definition Pose.h:243
virtual Eigen::Matrix4f toEigen() const
Definition Pose.cpp:334
void environmentChanged(EnvironmentPtr environment)
environmentChanged updates the environment that is currently visualized
void onInitComponent() override
Initializes the controller.
void tcpPoseChanged(Eigen::Matrix4f globalPose)
tcpPoseChanged informs all releveant controllers about the new global pose of the manipulator
void addConnection(std::shared_ptr< RobotVisualizationController > ctr)
void wayPointSelected(int index)
wayPointSelected informs all relevant controllers that the currently selected Waypoit has been change...
void removeView()
removeView removes RobotViewer with index
void cartesianSelectionChanged(VirtualRobot::IKSolver::CartesianSelection cs)
IK CALLBACK METHODS.
void onDisconnectComponent() override
Called whenever a component is disconnected.
void selectedTransitionChanged(int index)
selectedTransitionChanged highlights the Transition with index
void displayAllWayPoints(bool display)
displayAllWayPoints Enables Visualization and threfore selection of all waypoints of the current Traj...
void refresh() override
refresh gets all relevant data from subject an updates itself accoringly should be called by subject ...
void poseReachable(bool reachable)
poseReachable informs all relevant controllers whether the pose of the manipulator is reachable
void kinematicChainChanged(VirtualRobot::RobotNodeSetPtr rns)
kinematicChainChanged removes all visualization from the previously selected Trajectory and changes t...
void manipulatorChanged(Eigen::Matrix4f globalPose)
manipulatorChanged informs all relevant controllers that the pose of the manipulator has changed and ...
void trajectoryPlayerPlaying(bool playing)
void updateViews(DesignerTrajectoryPtr trajectory)
UPDATING OF VISUALIZATION.
void setIKCallbackEnabled(bool enabled)
setIKCallbackEnabled sets whther the robot Model tries to reach the Pose determined by the Manipulato...
RobotVisualizationController(QWidget *parent)
RobotVisualizationController creates a new RobotVisualizationController.
void playTrajectories(std::vector< DesignerTrajectoryPtr > trajectories)
playTrajectories plays all trajectories at the same time
void selectedWayPointChanged(int index)
selectedWayPointChanged highlights the waypoint with index and moves the manipulator to its Pose
void onConnectComponent() override
Connects all signals and slots of the controller.
void trajectoryPlayerNotPlaying(bool playing)
trajectoryPlayerNotPlaying
void robotChanged(VirtualRobot::RobotPtr robot)
robotChanged updates the robot model that is currently visualized Removes the robot that is visualize...
void onExitComponent() override
Called on exit, cleans.
void trajectoryPlayerStopped()
trajectoryPlayerStopped restarts the visualization of the whole scene after the debug drawer does not...
The RobotVisualizationWidget class Holds the original viewer and reproduces it tosupport parallel vie...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::shared_ptr< KinematicSolver > KinematicSolverPtr
std::shared_ptr< DesignerTrajectoryPlayer > DesignerTrajectoryPlayerPtr
IceInternal::Handle< Trajectory > TrajectoryPtr
Definition Trajectory.h:52
IceInternal::Handle< Pose > PosePtr
Definition Pose.h:306
std::shared_ptr< Environment > EnvironmentPtr
Definition Environment.h:29
std::shared_ptr< RobotVisualizationController > RobotVisualizationControllerPtr
std::shared_ptr< DesignerTrajectory > DesignerTrajectoryPtr
std::shared_ptr< UserWaypoint > UserWaypointPtr
std::shared_ptr< RobotVisualization > RobotVisualizationPtr