27 #include <VirtualRobot/Robot.h>
28 #include <VirtualRobot/RobotNodeSet.h>
32 #define DEFAULT_TCP_STRING "default TCP"
37 NJointControllerRegistration<NJointCartesianVelocityController>
39 "NJointCartesianVelocityController");
44 return "NJointCartesianVelocityController";
49 const NJointCartesianVelocityControllerConfigPtr& config,
54 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(config->nodeSetName);
56 for (
size_t i = 0; i < rns->getSize(); ++i)
58 std::string jointName = rns->getNode(i)->getName();
61 targets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
63 const SensorValue1DoFActuatorTorque* torqueSensor =
64 sv->
asA<SensorValue1DoFActuatorTorque>();
65 const SensorValue1DoFGravityTorque* gravityTorqueSensor =
66 sv->
asA<SensorValue1DoFGravityTorque>();
71 if (!gravityTorqueSensor)
73 ARMARX_WARNING <<
"No Gravity Torque sensor available for " << jointName;
75 torqueSensors.push_back(torqueSensor);
76 gravityTorqueSensors.push_back(gravityTorqueSensor);
79 VirtualRobot::RobotNodePtr tcp =
86 nodeSetName = config->nodeSetName;
88 torquePIDs.resize(tcpController->rns->getSize(),
SimplePID());
92 initData.
torqueKp.resize(tcpController->rns->getSize(), 0);
93 initData.
torqueKd.resize(tcpController->rns->getSize(), 0);
110 if (mode == VirtualRobot::IKSolver::All)
134 Eigen::VectorXf jnv = Eigen::VectorXf::Zero(tcpController->rns->getSize());
136 if (jointLimitAvoidanceKp > 0)
138 jnv += jointLimitAvoidanceKp * tcpController->calculateJointLimitAvoidance();
140 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
143 if (torqueSensors.at(i) && gravityTorqueSensors.at(i) &&
148 jnv(i) += torquePIDs.at(i).update(timeSinceLastIteration.toSecondsDouble(),
149 torqueSensors.at(i)->torque -
150 gravityTorqueSensors.at(i)->gravityTorque);
155 torquePIDs.at(i).lastError = 0;
159 Eigen::VectorXf jointTargetVelocities = tcpController->calculate(x, jnv, mode);
160 for (
size_t i = 0; i < targets.size(); ++i)
162 targets.at(i)->velocity = jointTargetVelocities(i);
166 ::armarx::WidgetDescription::WidgetSeq
170 ::armarx::WidgetDescription::WidgetSeq widgets;
171 auto addSlider = [&](
const std::string& label,
float limit)
173 widgets.emplace_back(
new Label(
false, label));
178 c_x->defaultValue = 0.0f;
180 widgets.emplace_back(c_x);
187 addSlider(
"roll", 0.5);
188 addSlider(
"pitch", 0.5);
189 addSlider(
"yaw", 0.5);
190 addSlider(
"avoidJointLimitsKp", 1);
194 WidgetDescription::HBoxLayoutPtr
197 float defaultValue)
const
201 auto addSlider = [&](
const std::string& label)
203 layout->children.emplace_back(
new Label(
false, label));
205 floatSlider->name = label;
206 floatSlider->min =
min;
207 floatSlider->defaultValue = defaultValue;
208 floatSlider->max =
max;
209 layout->children.emplace_back(floatSlider);
212 for (
const VirtualRobot::RobotNodePtr& rn : tcpController->rns->getAllRobotNodes())
214 addSlider(rn->getName());
223 const std::map<std::string, ConstControlDevicePtr>& controlDevices,
224 const std::map<std::string, ConstSensorDevicePtr>&)
229 LabelPtr label =
new Label;
230 label->text =
"nodeset name";
231 layout->children.emplace_back(label);
232 StringComboBoxPtr box =
new StringComboBox;
233 box->defaultIndex = 0;
235 box->options = robot->getRobotNodeSetNames();
236 box->name =
"nodeSetName";
237 layout->children.emplace_back(box);
239 LabelPtr labelTCP =
new Label;
240 labelTCP->text =
"tcp name";
241 layout->children.emplace_back(labelTCP);
242 StringComboBoxPtr boxTCP =
new StringComboBox;
243 boxTCP->defaultIndex = 0;
245 boxTCP->options = robot->getRobotNodeNames();
247 boxTCP->name =
"tcpName";
248 layout->children.emplace_back(boxTCP);
250 LabelPtr labelMode =
new Label;
251 labelMode->text =
"mode";
252 layout->children.emplace_back(labelMode);
253 StringComboBoxPtr boxMode =
new StringComboBox;
254 boxMode->defaultIndex = 0;
256 boxMode->options = {
"Position",
"Orientation",
"Both"};
257 boxMode->name =
"mode";
258 layout->children.emplace_back(boxMode);
265 layout->children.emplace_back(
new HSpacer);
269 NJointCartesianVelocityControllerConfigPtr
273 return new NJointCartesianVelocityControllerConfig(
274 values.at(
"nodeSetName")->getString(),
275 values.at(
"tcpName")->getString(),
283 if (mode ==
"Position")
287 if (mode ==
"Orientation")
293 return VirtualRobot::IKSolver::CartesianSelection::All;
302 if (mode ==
"Position")
306 if (mode ==
"Orientation")
332 return VirtualRobot::IKSolver::CartesianSelection::All;
384 layout->children.insert(layout->children.end(), sliders.begin(), sliders.end());
386 return {{
"ControllerTarget", layout},
397 if (name ==
"ControllerTarget")
407 valueMap.at(
"avoidJointLimitsKp")->getFloat();
410 else if (name ==
"TorqueKp")
413 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
416 valueMap.at(tcpController->rns->getNode(i)->getName())->getFloat();
420 else if (name ==
"TorqueKd")
423 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
426 valueMap.at(tcpController->rns->getNode(i)->getName())->getFloat();
430 else if (name ==
"NullspaceJointVelocities")
433 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
436 valueMap.at(tcpController->rns->getNode(i)->getName())->getFloat();
449 float derivative = (error - lastError) /
dt;
450 float retVal = Kp * error + Kd * derivative;
465 float avoidJointLimitsKp,
486 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
489 torqueKp.at(tcpController->rns->getNode(i)->getName());
496 const StringFloatDictionary& nullspaceJointVelocities,
500 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
503 nullspaceJointVelocities.at(tcpController->rns->getNode(i)->getName());