27 #include <VirtualRobot/IK/DifferentialIK.h>
28 #include <VirtualRobot/Nodes/RobotNode.h>
29 #include <VirtualRobot/Robot.h>
30 #include <VirtualRobot/RobotNodeSet.h>
36 #define DEFAULT_TCP_STRING "default TCP"
41 NJointControllerRegistration<NJointCartesianVelocityController>
43 "NJointCartesianVelocityController");
48 return "NJointCartesianVelocityController";
53 const NJointCartesianVelocityControllerConfigPtr& config,
58 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(config->nodeSetName);
60 for (
size_t i = 0; i < rns->getSize(); ++i)
62 std::string jointName = rns->getNode(i)->getName();
65 targets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
67 const SensorValue1DoFActuatorTorque* torqueSensor =
68 sv->
asA<SensorValue1DoFActuatorTorque>();
69 const SensorValue1DoFGravityTorque* gravityTorqueSensor =
70 sv->
asA<SensorValue1DoFGravityTorque>();
75 if (!gravityTorqueSensor)
77 ARMARX_WARNING <<
"No Gravity Torque sensor available for " << jointName;
79 torqueSensors.push_back(torqueSensor);
80 gravityTorqueSensors.push_back(gravityTorqueSensor);
83 VirtualRobot::RobotNodePtr tcp =
90 nodeSetName = config->nodeSetName;
92 torquePIDs.resize(tcpController->rns->getSize(),
SimplePID());
96 initData.
torqueKp.resize(tcpController->rns->getSize(), 0);
97 initData.
torqueKd.resize(tcpController->rns->getSize(), 0);
114 if (mode == VirtualRobot::IKSolver::All)
138 Eigen::VectorXf jnv = Eigen::VectorXf::Zero(tcpController->rns->getSize());
140 if (jointLimitAvoidanceKp > 0)
142 jnv += jointLimitAvoidanceKp * tcpController->calculateJointLimitAvoidance();
144 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
147 if (torqueSensors.at(i) && gravityTorqueSensors.at(i) &&
152 jnv(i) += torquePIDs.at(i).update(timeSinceLastIteration.toSecondsDouble(),
153 torqueSensors.at(i)->torque -
154 gravityTorqueSensors.at(i)->gravityTorque);
159 torquePIDs.at(i).lastError = 0;
163 Eigen::VectorXf jointTargetVelocities = tcpController->calculate(x, jnv, mode);
164 for (
size_t i = 0; i < targets.size(); ++i)
166 targets.at(i)->velocity = jointTargetVelocities(i);
170 ::armarx::WidgetDescription::WidgetSeq
174 ::armarx::WidgetDescription::WidgetSeq widgets;
175 auto addSlider = [&](
const std::string& label,
float limit)
177 widgets.emplace_back(
new Label(
false, label));
182 c_x->defaultValue = 0.0f;
184 widgets.emplace_back(c_x);
191 addSlider(
"roll", 0.5);
192 addSlider(
"pitch", 0.5);
193 addSlider(
"yaw", 0.5);
194 addSlider(
"avoidJointLimitsKp", 1);
198 WidgetDescription::HBoxLayoutPtr
201 float defaultValue)
const
205 auto addSlider = [&](
const std::string& label)
207 layout->children.emplace_back(
new Label(
false, label));
209 floatSlider->name = label;
210 floatSlider->min =
min;
211 floatSlider->defaultValue = defaultValue;
212 floatSlider->max =
max;
213 layout->children.emplace_back(floatSlider);
216 for (
const VirtualRobot::RobotNodePtr& rn : tcpController->rns->getAllRobotNodes())
218 addSlider(rn->getName());
227 const std::map<std::string, ConstControlDevicePtr>& controlDevices,
228 const std::map<std::string, ConstSensorDevicePtr>&)
233 LabelPtr label =
new Label;
234 label->text =
"nodeset name";
235 layout->children.emplace_back(label);
236 StringComboBoxPtr box =
new StringComboBox;
237 box->defaultIndex = 0;
239 box->options = robot->getRobotNodeSetNames();
240 box->name =
"nodeSetName";
241 layout->children.emplace_back(box);
243 LabelPtr labelTCP =
new Label;
244 labelTCP->text =
"tcp name";
245 layout->children.emplace_back(labelTCP);
246 StringComboBoxPtr boxTCP =
new StringComboBox;
247 boxTCP->defaultIndex = 0;
249 boxTCP->options = robot->getRobotNodeNames();
251 boxTCP->name =
"tcpName";
252 layout->children.emplace_back(boxTCP);
254 LabelPtr labelMode =
new Label;
255 labelMode->text =
"mode";
256 layout->children.emplace_back(labelMode);
257 StringComboBoxPtr boxMode =
new StringComboBox;
258 boxMode->defaultIndex = 0;
260 boxMode->options = {
"Position",
"Orientation",
"Both"};
261 boxMode->name =
"mode";
262 layout->children.emplace_back(boxMode);
269 layout->children.emplace_back(
new HSpacer);
273 NJointCartesianVelocityControllerConfigPtr
277 return new NJointCartesianVelocityControllerConfig(
278 values.at(
"nodeSetName")->getString(),
279 values.at(
"tcpName")->getString(),
287 if (mode ==
"Position")
291 if (mode ==
"Orientation")
297 return VirtualRobot::IKSolver::CartesianSelection::All;
306 if (mode ==
"Position")
310 if (mode ==
"Orientation")
336 return VirtualRobot::IKSolver::CartesianSelection::All;
388 layout->children.insert(layout->children.end(), sliders.begin(), sliders.end());
390 return {{
"ControllerTarget", layout},
401 if (name ==
"ControllerTarget")
411 valueMap.at(
"avoidJointLimitsKp")->getFloat();
414 else if (name ==
"TorqueKp")
417 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
420 valueMap.at(tcpController->rns->getNode(i)->getName())->getFloat();
424 else if (name ==
"TorqueKd")
427 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
430 valueMap.at(tcpController->rns->getNode(i)->getName())->getFloat();
434 else if (name ==
"NullspaceJointVelocities")
437 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
440 valueMap.at(tcpController->rns->getNode(i)->getName())->getFloat();
453 float derivative = (error - lastError) /
dt;
454 float retVal = Kp * error + Kd * derivative;
469 float avoidJointLimitsKp,
490 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
493 torqueKp.at(tcpController->rns->getNode(i)->getName());
500 const StringFloatDictionary& nullspaceJointVelocities,
504 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
507 nullspaceJointVelocities.at(tcpController->rns->getNode(i)->getName());