ManipulatorVisualization.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-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
19 * @author
20 * @date
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
25
26//Virtual Robot includes
27#include <VirtualRobot/RobotNodeSet.h>
28#include <VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h>
29#include <VirtualRobot/XML/RobotIO.h>
30
32
33/* Coin includes */
34#include <iostream>
35
36#include <Inventor/SbViewportRegion.h>
37#include <Inventor/actions/SoGetMatrixAction.h>
38#include <Inventor/actions/SoSearchAction.h>
39#include <Inventor/nodes/SoCube.h>
40
42 isVisualizing(false),
43 hasEndEffectorVisualizer(false),
44 localTransformation(Eigen::Matrix4f::Identity())
45{
46 //Im gonna live forever :)
47 this->ref();
48}
49
51{
52 //Life makes no sense anymore
53 this->unref();
54}
55
56void
58 VirtualRobot::RobotNodeSetPtr nodeSet)
59{
60 //Completely forget anything we displayed earlier
61 //This also works when this is the first time we display something
62 this->removeVisualization();
63
64 //First of all add the end effector
65 VirtualRobot::EndEffectorPtr endEffector = robot->getEndEffector(nodeSet->getTCP()->getName());
66 if (!endEffector)
67 {
68 std::vector<VirtualRobot::EndEffectorPtr> eefs;
69 robot->getEndEffectors(eefs);
70 for (auto eef : eefs)
71 {
72 if (eef->getTcp() == nodeSet->getTCP())
73 {
74 endEffector = eef;
75 break;
76 }
77 }
78 }
79 this->hasEndEffectorVisualizer = endEffector ? true : false;
80
81 //Display all indicators in the same color and with transparency
82 this->material = new SoMaterial();
83 this->material->transparency = 0.5;
84 this->material->setOverride(true);
85 this->addChild(material);
86
87 //if no end effector is defined for the chain, just add a placeholder
88 if (this->hasEndEffectorVisualizer)
89 {
90 VirtualRobot::RobotPtr endEffectorRobot = endEffector->createEefRobot("", "");
91 VirtualRobot::CoinVisualizationPtr endEffectorVisualization =
92 endEffectorRobot->getVisualization();
93 this->addChild(endEffectorVisualization->getCoinVisualization());
94 }
95 else
96 {
97 SoCube* cube = new SoCube();
98 cube->width = 0.1;
99 cube->height = 0.1;
100 cube->depth = 0.1;
101
102 this->addChild(cube);
103 }
104
105 //And now wrap this bad boy with our manipulator
106 this->manip.reset(new SoTransformerManip());
107
108 //We need this null separator to remove the scale knobs
109 //This won't lead to memory leak, because this separator
110 //will be deleted when the manipulator itself gets removed
111 //from the scene graph
112 SoSeparator* nullSep = new SoSeparator;
113
114 //Make all scale knobs disappear
115 manip->getDragger()->setPart("scale1", nullSep);
116 manip->getDragger()->setPart("scale2", nullSep);
117 manip->getDragger()->setPart("scale3", nullSep);
118 manip->getDragger()->setPart("scale4", nullSep);
119 manip->getDragger()->setPart("scale5", nullSep);
120 manip->getDragger()->setPart("scale6", nullSep);
121 manip->getDragger()->setPart("scale7", nullSep);
122 manip->getDragger()->setPart("scale8", nullSep);
123
124 //Stores the global position and pose of tcp
125 Eigen::Matrix4f globalMat = nodeSet->getTCP()->getGlobalPose();
126
127 if (this->hasEndEffectorVisualizer)
128 {
129 //Stores the local transformation from the endeffector base to the TCP node
130 this->localTransformation = endEffector->getBase()->getTransformationTo(nodeSet->getTCP());
131
132 globalMat = endEffector->getBase()->getGlobalPose();
133 }
134
135 //Now go ahead and set new position
136 //Factor 1000 to match coin unit system
137 globalMat(0, 3) /= 1000;
138 globalMat(1, 3) /= 1000;
139 globalMat(2, 3) /= 1000;
140 manip->setMatrix(VirtualRobot::CoinVisualizationFactory::getSbMatrix(globalMat));
141
142 this->insertChild(manip.get(), 0);
143
144 this->isVisualizing = true;
145}
146
147void
149{
150 //Remove all children and reset manip pointer
151 //This should bring ref counter of Inventor down to zero and free memory
152 this->removeAllChildren();
153 manip.reset();
154
155 this->isVisualizing = false;
156 this->hasEndEffectorVisualizer = false;
157 this->localTransformation = Eigen::Matrix4f::Identity();
158}
159
160void
161ManipulatorVisualization::setColor(float r, float g, float b)
162{
163 if (this->getIsVisualizing())
164 {
165 this->material->ambientColor.setValue(r, g, b);
166 }
167}
168
169void
171{
172 if (this->getIsVisualizing())
173 {
174 this->manip->getDragger()->addFinishCallback(func, data);
175 }
176}
177
178void
180{
181 if (this->getIsVisualizing())
182 {
183 this->manip->getDragger()->addMotionCallback(func, data);
184 }
185}
186
187Eigen::Matrix4f
189{
190 if (this->getIsVisualizing())
191 {
192 SoGetMatrixAction* action = new SoGetMatrixAction(SbViewportRegion());
193 SoSearchAction sa;
194 sa.setNode(manip.get());
195 sa.setSearchingAll(TRUE); // Search all nodes
196 SoBaseKit::setSearchingChildren(TRUE); // Even inside nodekits
197 sa.apply(this);
198
199 action->apply(sa.getPath());
200
201 SbMatrix matrix = action->getMatrix();
202
203 Eigen::Matrix4f mat = Eigen::Matrix4f::Identity();
204 mat(0, 0) = matrix[0][0];
205 mat(0, 1) = matrix[1][0];
206 mat(0, 2) = matrix[2][0];
207 mat(0, 3) = matrix[3][0] * 1000;
208
209 mat(1, 0) = matrix[0][1];
210 mat(1, 1) = matrix[1][1];
211 mat(1, 2) = matrix[2][1];
212 mat(1, 3) = matrix[3][1] * 1000;
213
214 mat(2, 0) = matrix[0][2];
215 mat(2, 1) = matrix[1][2];
216 mat(2, 2) = matrix[2][2];
217 mat(2, 3) = matrix[3][2] * 1000;
218
219 mat(3, 0) = matrix[0][3];
220 mat(3, 1) = matrix[1][3];
221 mat(3, 2) = matrix[2][3];
222 mat(3, 3) = matrix[3][3];
223
224 //We need to take local transformation into account, because otherwise the visualizer
225 //shows a wrong position for tcp (offset equals local transformation of tcp in node set then)
226 //Just apply local transformation to fix this
227 if (this->hasEndEffectorVisualizer)
228 {
229 mat = mat * this->localTransformation;
230 }
231
232 return mat;
233 }
234
235 return Eigen::Matrix4f::Identity();
236}
237
238std::string
240{
241 Eigen::Matrix4f mat = this->getUserDesiredPose();
242
243 //Convert to string
244 std::stringstream buffer;
245 buffer << mat;
246 return buffer.str();
247}
248
249void
251{
252 if (this->hasEndEffectorVisualizer)
253 {
254 globalPose = globalPose * this->localTransformation.inverse();
255 }
256 globalPose(0, 3) /= 1000;
257 globalPose(1, 3) /= 1000;
258 globalPose(2, 3) /= 1000;
259 manip->setMatrix(VirtualRobot::CoinVisualizationFactory::getSbMatrix(globalPose));
260}
uint8_t data[1]
void addManipFinishCallback(SoDraggerCB *func, void *data)
void addManipMovedCallback(SoDraggerCB *func, void *data)
void setUserDesiredPose(Eigen::Matrix4f globalPose)
void setVisualization(VirtualRobot::RobotPtr robot, VirtualRobot::RobotNodeSetPtr nodeSet)
void setColor(float r, float g, float b)
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19