CartesianImpedanceControllerWidgetController.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 RobotAPI::gui-plugins::CartesianImpedanceControllerWidgetController
17 * \author Raphael Grimm ( raphael dot grimm at kit dot edu )
18 * \date 2020
19 * \copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
24
25#include <string>
26
27#include <SimoxUtility/math/convert/mat4f_to_pos.h>
28#include <SimoxUtility/math/convert/mat4f_to_rpy.h>
29#include <SimoxUtility/math/convert/rpy_to_quat.h>
30
32
33namespace armarx
34{
36 NJointControllerGuiPluginBase("NJointTaskSpaceImpedanceController")
37 {
38 _ui.setupUi(getWidget());
39 connectCreateAcivateDeactivateDelete(_ui.pushButtonCreate,
40 _ui.pushButtonActivate,
41 _ui.pushButtonDeactivate,
42 _ui.pushButtonDelete);
44 _ui.gridLayoutSettings->addWidget(_settings);
45
46 _targ.setXYZWidgets(
47 _ui.doubleSpinBoxTargTX, _ui.doubleSpinBoxTargTY, _ui.doubleSpinBoxTargTZ);
48
49 _targ.setRPYWidgets(
50 _ui.doubleSpinBoxTargRX, _ui.doubleSpinBoxTargRY, _ui.doubleSpinBoxTargRZ);
51
52 _targ.setDefaultLimits();
53 _timer = startTimer(10);
54 }
55
63
64 void
66 {
68 std::lock_guard g{_allMutex};
70 ARMARX_INFO << "setup comboBoxRNS";
71 for (const auto& rnsName : _robot->getRobotNodeSetNames())
72 {
73 _ui.comboBoxRNS->addItem(QString::fromStdString(rnsName));
74 }
76 for (const auto& nodeName : _robot->getRobotNodeNames())
77 {
78 _ui.comboBoxLockY->addItem(QString::fromStdString(nodeName));
79 _ui.comboBoxLockZ->addItem(QString::fromStdString(nodeName));
80 }
81
83 connect(
84 _ui.pushButtonTargGet, &QPushButton::clicked, this, &T::on_pushButtonTargGet_clicked);
85 connect(
86 _ui.pushButtonTargAdd, &QPushButton::clicked, this, &T::on_pushButtonTargAdd_clicked);
87 connect(
88 _ui.pushButtonTargSet, &QPushButton::clicked, this, &T::on_pushButtonTargSet_clicked);
89 connect(_ui.comboBoxRNS,
90 SIGNAL(currentIndexChanged(const QString&)),
91 this,
92 SLOT(on_comboBoxRNS_currentIndexChanged(const QString&)));
93 connect(_ui.radioButtonSelectLeft,
94 &QRadioButton::clicked,
95 this,
96 &T::on_radioButtonSelect_clicked);
97 connect(_ui.radioButtonSelectRight,
98 &QRadioButton::clicked,
99 this,
100 &T::on_radioButtonSelect_clicked);
101 connect(_ui.radioButtonSelectRNS,
102 &QRadioButton::clicked,
103 this,
104 &T::on_radioButtonSelect_clicked);
105
106 _ui.groupBoxAdvanced->setChecked(false);
107 _ui.radioButtonSelectLeft->setChecked(true);
108 }
109
110 void
112 {
114 std::lock_guard g{_allMutex};
115 _left = getRobotNameHelper().getArm("Left");
116 _right = getRobotNameHelper().getArm("Right");
117 }
118
119 void
121 {
123 std::lock_guard g{_allMutex};
124 if (_robot)
125 {
127 }
128 if (_ui.checkBoxAutoUpdatePose->isChecked())
129 {
131 on_pushButtonTargSet_clicked();
132 }
133 const bool lockY = _ui.checkBoxLockY->isChecked();
134 const bool lockZ = _ui.checkBoxLockZ->isChecked();
135 bool anyTracking = lockY || lockZ;
136 _ui.widgetTarget->setEnabled(!anyTracking);
137 if (_rns && (lockY || lockZ))
138 {
140 Eigen::Matrix4f pose = _rns->getTCP()->getPoseInRootFrame();
141 if (lockY)
142 {
143 pose(1, 3) = _robot->getRobotNode(_ui.comboBoxLockY->currentText().toStdString())
144 ->getPositionInRootFrame()(1);
145 }
146 if (lockZ)
147 {
148 pose(2, 3) = _robot->getRobotNode(_ui.comboBoxLockZ->currentText().toStdString())
149 ->getPositionInRootFrame()(2);
150 }
151 if (_controller)
152 {
153 _controller->setPosition(pose.topRightCorner<3, 1>());
154 }
155 visuHandAtPose(pose);
156 ARMARX_INFO << "set Target pose to\n" << pose;
157 }
158 else if (!(lockY || lockZ))
159 {
160 const Eigen::Matrix4f rootTcpTarg =
161 _ui.radioButtonVisuSet ? _targ.getMat4()
162 : _rns->getTCP()->getPoseInRootFrame() * _targ.getMat4();
163 visuHandAtPose(rootTcpTarg);
164 }
165 }
166
167 void
169 {
171 std::lock_guard g{_allMutex};
172 if (_visuHandRobotFile.empty() || !_robot || !arviz.topic())
173 {
174 if (arviz.topic())
175 {
176 arviz.commitLayerContaining("hand");
177 }
178 return;
179 }
180
181 arviz.commitLayerContaining("hand",
182 viz::Robot{"Hand"}
183 .file(_visuHandRobotProject, _visuHandRobotFile)
184 .useFullModel()
185 .pose(_robot->getGlobalPose() * tcpInRoot * _tcpToBase)
186 .overrideColor(viz::Color::green()));
187 }
188} // namespace armarx
189
190//read config
191namespace armarx
192{
193 NJointControllerConfigPtr
194 CartesianImpedanceControllerWidgetController::readFullCFG() const
195 {
197 auto [pos, quat] = readTargetCFG();
198 return NJointControllerConfigPtr::dynamicCast(_settings->readFullCFG(pos, quat));
199 }
200
201 std::tuple<Eigen::Vector3f, Eigen::Quaternionf>
202 CartesianImpedanceControllerWidgetController::readTargetCFG() const
203 {
205 return {_targ.getPos(), _targ.getQuat()};
206 }
207} // namespace armarx
208
209//push buttons
210namespace armarx
211{
212 void
213 CartesianImpedanceControllerWidgetController::createController()
214 {
217 _ui.widgetRNSSelect->setEnabled(false);
218 _settings->setController(_controller);
219 }
220
221 void
222 CartesianImpedanceControllerWidgetController::deleteController()
223 {
226 _ui.widgetRNSSelect->setEnabled(true);
227 _settings->setController(nullptr);
228 }
229
230 void
231 CartesianImpedanceControllerWidgetController::on_pushButtonTargSet_clicked()
232 {
234 std::lock_guard g{_allMutex};
235 if (!_controller)
236 {
237 return;
238 }
239 const Eigen::Matrix4f pose = _targ.getMat4();
240 _controller->setPose(pose);
241 ARMARX_INFO << "set Target pose to\n" << pose;
242 }
243
244 void
245 CartesianImpedanceControllerWidgetController::on_pushButtonTargAdd_clicked()
246 {
248 std::lock_guard g{_allMutex};
249 if (!_controller || !_rns)
250 {
251 return;
252 }
253 const Eigen::Matrix4f pose = _rns->getTCP()->getPoseInRootFrame() * _targ.getMat4();
254 _controller->setPose(pose);
255 ARMARX_INFO << "set Target pose to\n" << pose;
256 }
257
258 void
259 CartesianImpedanceControllerWidgetController::on_pushButtonTargGet_clicked()
260 {
262 std::lock_guard g{_allMutex};
263 if (!_rns)
264 {
265 return;
266 }
267 const Eigen::Matrix4f pose = _rns->getTCP()->getPoseInRootFrame();
268 const Eigen::Vector3f pos = simox::math::mat4f_to_pos(pose);
269 const Eigen::Vector3f rpy = simox::math::mat4f_to_rpy(pose);
270
271 _ui.doubleSpinBoxTargTX->setValue(pos(0));
272 _ui.doubleSpinBoxTargTY->setValue(pos(1));
273 _ui.doubleSpinBoxTargTZ->setValue(pos(2));
274
275 _ui.doubleSpinBoxTargRX->setValue(rpy(0));
276 _ui.doubleSpinBoxTargRY->setValue(rpy(1));
277 _ui.doubleSpinBoxTargRZ->setValue(rpy(2));
278 }
279
280 void
281 CartesianImpedanceControllerWidgetController::on_comboBoxRNS_currentIndexChanged(
282 const QString& arg1)
283 {
285 std::lock_guard g{_allMutex};
286 if (!_robot || _controller)
287 {
288 return;
289 }
290 const std::string rnsName = arg1.toStdString();
291 _rns = _robot->getRobotNodeSet(rnsName);
292 _settings->setRNS(_rns);
293 auto checkSide = [&](const RobotNameHelper::Arm& side)
294 {
295 if (!_rns->getTCP() || side.getTCP() != _rns->getTCP()->getName() ||
296 !side.getRobotNameHelper())
297 {
298 return;
299 }
300 const auto arm = side.addRobot(_robot);
301 _tcpToBase = arm.getTcp2HandRootTransform();
302 _visuHandRobotFile = side.getHandModelPath();
303 _visuHandRobotProject = side.getHandModelPackage();
304 };
305 if (_left.getRobotNameHelper())
306 {
307 checkSide(_left);
308 }
309 if (_right.getRobotNameHelper())
310 {
311 checkSide(_right);
312 }
313
314 on_pushButtonTargGet_clicked();
315 }
316
317 void
318 CartesianImpedanceControllerWidgetController::on_radioButtonSelect_clicked()
319 {
321 std::lock_guard g{_allMutex};
322 if (_ui.radioButtonSelectLeft->isChecked())
323 {
324 on_comboBoxRNS_currentIndexChanged(QString::fromStdString(_left.getKinematicChain()));
325 }
326 else if (_ui.radioButtonSelectRight->isChecked())
327 {
328 on_comboBoxRNS_currentIndexChanged(QString::fromStdString(_right.getKinematicChain()));
329 }
330 else
331 {
332 on_comboBoxRNS_currentIndexChanged(_ui.comboBoxRNS->currentText());
333 }
334 }
335} // namespace armarx
virtual QPointer< QWidget > getWidget()
getWidget returns a pointer to the a widget of this controller.
NJointTaskSpaceImpedanceControlConfigPtr readFullCFG(const Eigen::Vector3f &targPos, const Eigen::Quaternionf &targOri) const
void visuHandAtPose(const Eigen::Matrix4f &tcpInRoot=Eigen::Matrix4f::Identity())
bool synchronizeLocalClone(const VirtualRobot::RobotPtr &robot) const
void connectCreateAcivateDeactivateDelete(QPushButton *cr, QPushButton *ac, QPushButton *dc, QPushButton *de)
Robot & file(std::string const &project, std::string const &filename)
Definition Robot.h:16
Robot & overrideColor(Color c)
Definition Robot.h:50
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
This file offers overloads of toIce() and fromIce() functions for STL container types.
#define ARMARX_TRACE
Definition trace.h:77