CartesianWaypointControlGuiWidgetController.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::CartesianWaypointControlGuiWidgetController
17 * \author Raphael Grimm ( raphael dot grimm at kit dot edu )
18 * \date 2019
19 * \copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
24
25#include <random>
26#include <string>
27
28#include <QClipboard>
29
30#include <SimoxUtility/json.h>
31
33
35
36namespace armarx
37{
39 NJointControllerGuiPluginBase("NJointCartesianWaypointController")
40 {
42 std::lock_guard g{_allMutex};
43 _ui.setupUi(getWidget());
44 connect(_ui.radioButtonWPJson, &QPushButton::clicked, this, &T::triggerParsing);
45 connect(_ui.radioButton4f, &QPushButton::clicked, this, &T::triggerParsing);
46 connect(_ui.textEditWPs, &QTextEdit::textChanged, this, &T::triggerParsing);
47
48 connect(
49 _ui.pushButtonExecute, &QPushButton::clicked, this, &T::on_pushButtonExecute_clicked);
50 connect(_ui.pushButtonZeroFT, &QPushButton::clicked, this, &T::on_pushButtonZeroFT_clicked);
51 connect(_ui.pushButtonSendSettings,
52 &QPushButton::clicked,
53 this,
54 &T::on_pushButtonSendSettings_clicked);
55 connect(_ui.pushButtonCopyCurrentPose, &QPushButton::clicked, this, &T::copyCurrentPose);
56
58 _ui.pushButtonCreateController, nullptr, _ui.pushButtonStop, nullptr);
59
60 _ui.widgetSpacer->setVisible(false);
61 _timer = startTimer(50);
62 }
63
71
72 void
78
79 void
80 CartesianWaypointControlGuiWidgetController::createController()
81 {
82 std::lock_guard g{_allMutex};
84 _supportsFT = !_ui.lineEditFTName->text().toStdString().empty();
85 }
86
87 void
88 CartesianWaypointControlGuiWidgetController::on_pushButtonSendSettings_clicked()
89 {
90 std::lock_guard g{_allMutex};
91 if (_controller)
92 {
93 ARMARX_IMPORTANT << "sending new config to " << getControllerName();
94 _controller->setConfig(readRunCfg());
95 }
96 }
97
98 void
99 CartesianWaypointControlGuiWidgetController::copyCurrentPose()
100 {
101 std::lock_guard g{_allMutex};
102 if (!_robot)
103 {
104 return;
105 }
107 const auto rns = _robot->getRobotNodeSet(_ui.comboBoxChain->currentText().toStdString());
108 if (!rns)
109 {
110 return;
111 }
112 const auto tcp = rns->getTCP();
113 if (!tcp)
114 {
115 return;
116 }
117 const auto str = simox::json::eigen4f2posquatJson(tcp->getPoseInRootFrame());
118 QApplication::clipboard()->setText(QString::fromStdString(str));
119 }
120
121 void
122 CartesianWaypointControlGuiWidgetController::on_pushButtonZeroFT_clicked()
123 {
124 std::lock_guard g{_allMutex};
125 if (_controller && _supportsFT)
126 {
127 ARMARX_IMPORTANT << "setting ft offset for " << getControllerName();
128 _controller->setCurrentFTAsOffset();
129 }
130 }
131
132 void
133 CartesianWaypointControlGuiWidgetController::on_pushButtonExecute_clicked()
134 {
135 std::lock_guard g{_allMutex};
136 if (_controller)
137 {
138 _controller->activateController();
139 ARMARX_IMPORTANT << "trigger execution of " << _lastParsedWPs.size() << " waypoints on "
141 _controller->setWaypoints(_ui.checkBoxWPReverse->isChecked() ? reverse(_lastParsedWPs)
142 : _lastParsedWPs);
143 }
144 }
145
146 void
147 CartesianWaypointControlGuiWidgetController::triggerParsing()
148 {
149 std::lock_guard g{_allMutex};
150 _lastParsedWPs.clear();
151 _ui.labelParsingSuccess->setText("<pre parsing>");
152 if (_ui.radioButtonWPJson->isChecked())
153 {
154 //parse json
155 try
156 {
157 _lastParsedWPs = simox::json::posquatArray2eigen4fVector(
158 _ui.textEditWPs->toPlainText().toStdString());
159 }
160 catch (...)
161 {
162 _ui.labelParsingSuccess->setText("Failed to parse json array!");
163 return;
164 }
165 }
166 else if (_ui.radioButton4f->isChecked())
167 {
168 //parse lines
169 ///TODO parse Matrix4f style input
170 _ui.labelParsingSuccess->setText("NYI");
171 return;
172 }
173 //test reachability
174 {
175 ///TODO test reachability and visualize
176 }
177 _ui.labelParsingSuccess->setText("Parsed " + QString::number(_lastParsedWPs.size()) +
178 " waypoints.");
179 }
180
181 NJointCartesianWaypointControllerRuntimeConfig
182 CartesianWaypointControlGuiWidgetController::readRunCfg() const
183 {
184 std::lock_guard g{_allMutex};
185 NJointCartesianWaypointControllerRuntimeConfig cfg;
186
187 cfg.wpCfg.maxPositionAcceleration = static_cast<float>(_ui.doubleSpinBoxMaxAccPos->value());
188 cfg.wpCfg.maxOrientationAcceleration =
189 static_cast<float>(_ui.doubleSpinBoxMaxAccOri->value());
190 cfg.wpCfg.maxNullspaceAcceleration =
191 static_cast<float>(_ui.doubleSpinBoxMaxAccNull->value());
192
193 cfg.wpCfg.kpJointLimitAvoidance =
194 static_cast<float>(_ui.doubleSpinBoxLimitAvoidKP->value());
195 cfg.wpCfg.jointLimitAvoidanceScale =
196 static_cast<float>(_ui.doubleSpinBoxLimitAvoidScale->value());
197
198 cfg.wpCfg.thresholdOrientationNear = static_cast<float>(_ui.doubleSpinBoxOriNear->value());
199 cfg.wpCfg.thresholdOrientationReached =
200 static_cast<float>(_ui.doubleSpinBoxOriReached->value());
201 cfg.wpCfg.thresholdPositionNear = static_cast<float>(_ui.doubleSpinBoxPosNear->value());
202 cfg.wpCfg.thresholdPositionReached =
203 static_cast<float>(_ui.doubleSpinBoxPosReached->value());
204
205 cfg.wpCfg.maxOriVel = static_cast<float>(_ui.doubleSpinBoxOriMaxVel->value());
206 cfg.wpCfg.maxPosVel = static_cast<float>(_ui.doubleSpinBoxPosMaxVel->value());
207 cfg.wpCfg.kpOri = static_cast<float>(_ui.doubleSpinBoxOriKP->value());
208 cfg.wpCfg.kpPos = static_cast<float>(_ui.doubleSpinBoxPosKP->value());
209
210 cfg.forceThreshold = static_cast<float>(_ui.doubleSpinBoxFTLimit->value());
211 cfg.optimizeNullspaceIfTargetWasReached = _ui.checkBoxKeepOptimizing->isChecked();
212 cfg.forceThresholdInRobotRootZ = _ui.checkBoxLimitinZ->isChecked();
213 cfg.skipToClosestWaypoint = _ui.checkBoxSkipWaypoints->isChecked();
214
215 return cfg;
216 }
217
218 void
219 CartesianWaypointControlGuiWidgetController::timerEvent(QTimerEvent* e)
220 {
221 std::lock_guard g{_allMutex};
222 if (_robot)
223 {
225 }
226 if (_controller)
227 {
228 ARMARX_INFO << deactivateSpam() << "setting visu gp to:\n" << _robot->getGlobalPose();
229 _controller->setVisualizationRobotGlobalPose(_robot->getGlobalPose());
230 }
231 }
232
233 void
235 {
236 bool found = false;
237 for (const auto& rnsn : _robot->getRobotNodeSetNames())
238 {
239 _ui.comboBoxChain->addItem(QString::fromStdString(rnsn));
240 if (rnsn == "RightArm")
241 {
242 _ui.comboBoxChain->setCurrentIndex(_ui.comboBoxChain->count() - 1);
243 found = true;
244 }
245 }
246 if (found && _robot->hasRobotNode("FT R"))
247 {
248 _ui.lineEditFTName->setText("FT R");
249 }
250 }
251
252 NJointControllerConfigPtr
254 {
255 NJointCartesianWaypointControllerConfigPtr cfg =
256 new NJointCartesianWaypointControllerConfig;
257 cfg->rns = _ui.comboBoxChain->currentText().toStdString();
258 cfg->ftName = _ui.lineEditFTName->text().toStdString();
259 cfg->runCfg = readRunCfg();
260 return NJointControllerConfigPtr::dynamicCast(cfg);
261 }
262} // namespace armarx
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
std::string str(const T &t)
virtual QPointer< QWidget > getWidget()
getWidget returns a pointer to the a widget of this controller.
virtual void onConnectComponent()=0
Pure virtual hook for the subclass.
bool synchronizeLocalClone(const VirtualRobot::RobotPtr &robot) const
void connectCreateAcivateDeactivateDelete(QPushButton *cr, QPushButton *ac, QPushButton *dc, QPushButton *de)
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
This file offers overloads of toIce() and fromIce() functions for STL container types.
T reverse(const T &o)
Definition container.h:33