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);
109 const IceUtil::Time& timeSinceLastIteration)
114 if (mode == VirtualRobot::IKSolver::All)
121 else if (mode == VirtualRobot::IKSolver::Position)
126 else if (mode == VirtualRobot::IKSolver::Orientation)
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(),
283 VirtualRobot::IKSolver::CartesianSelection
287 if (mode ==
"Position")
289 return VirtualRobot::IKSolver::CartesianSelection::Position;
291 if (mode ==
"Orientation")
293 return VirtualRobot::IKSolver::CartesianSelection::Orientation;
297 return VirtualRobot::IKSolver::CartesianSelection::All;
300 return (VirtualRobot::IKSolver::CartesianSelection)0;
303 NJointCartesianVelocityControllerMode::CartesianSelection
306 if (mode ==
"Position")
308 return NJointCartesianVelocityControllerMode::CartesianSelection::ePosition;
310 if (mode ==
"Orientation")
312 return NJointCartesianVelocityControllerMode::CartesianSelection::eOrientation;
316 return NJointCartesianVelocityControllerMode::CartesianSelection::eAll;
319 return (NJointCartesianVelocityControllerMode::CartesianSelection)0;
322 VirtualRobot::IKSolver::CartesianSelection
324 const NJointCartesianVelocityControllerMode::CartesianSelection mode)
326 if (mode == NJointCartesianVelocityControllerMode::CartesianSelection::ePosition)
328 return VirtualRobot::IKSolver::CartesianSelection::Position;
330 if (mode == NJointCartesianVelocityControllerMode::CartesianSelection::eOrientation)
332 return VirtualRobot::IKSolver::CartesianSelection::Orientation;
334 if (mode == NJointCartesianVelocityControllerMode::CartesianSelection::eAll)
336 return VirtualRobot::IKSolver::CartesianSelection::All;
339 return (VirtualRobot::IKSolver::CartesianSelection)0;
350 VirtualRobot::IKSolver::CartesianSelection mode)
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();
454 float retVal =
Kp * error +
Kd * derivative;
469 float avoidJointLimitsKp,
470 NJointCartesianVelocityControllerMode::CartesianSelection mode,
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());
int Label(int n[], int size, int *curLabel, MiscLib::Vector< std::pair< int, size_t > > *labels)
#define DEFAULT_TCP_STRING
Brief description of class JointControlTargetBase.
VirtualRobot::IKSolver::CartesianSelection mode
std::vector< float > torqueKd
std::vector< float > torqueKp
std::vector< float > nullspaceJointVelocities
void setTorqueKp(const StringFloatDictionary &torqueKp, const Ice::Current &) override
static NJointCartesianVelocityControllerMode::CartesianSelection IceModeFromString(const std::string mode)
static WidgetDescription::WidgetPtr GenerateConfigDescription(const VirtualRobot::RobotPtr &, const std::map< std::string, ConstControlDevicePtr > &, const std::map< std::string, ConstSensorDevicePtr > &)
void setNullspaceJointVelocities(const StringFloatDictionary &nullspaceJointVelocities, const Ice::Current &) override
WidgetDescription::StringWidgetDictionary getFunctionDescriptions(const Ice::Current &) const override
NJointCartesianVelocityController(RobotUnit *prov, const NJointCartesianVelocityControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
WidgetDescription::HBoxLayoutPtr createJointSlidersLayout(float min, float max, float defaultValue) const
std::string getNodeSetName() const
static NJointCartesianVelocityControllerConfigPtr GenerateConfigFromVariants(const StringVariantBaseMap &values)
static VirtualRobot::IKSolver::CartesianSelection ModeFromString(const std::string mode)
void setControllerTarget(float x, float y, float z, float roll, float pitch, float yaw, float avoidJointLimitsKp, NJointCartesianVelocityControllerMode::CartesianSelection mode, const Ice::Current &) override
::armarx::WidgetDescription::WidgetSeq createSliders()
static VirtualRobot::IKSolver::CartesianSelection ModeFromIce(const NJointCartesianVelocityControllerMode::CartesianSelection mode)
void rtPostDeactivateController() override
This function is called after the controller is deactivated.
void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration) override
TODO make protected and use attorneys.
void setVelocities(float xVel, float yVel, float zVel, float rollVel, float pitchVel, float yawVel, VirtualRobot::IKSolver::CartesianSelection mode)
void setAvoidJointLimitsKp(float kp)
std::string getClassName(const Ice::Current &) const override
void callDescribedFunction(const std::string &name, const StringVariantBaseMap &valueMap, const Ice::Current &) override
void rtPreActivateController() override
This function is called before the controller is activated.
const SensorValueBase * useSensorValue(const std::string &sensorDeviceName) const
Get a const ptr to the given SensorDevice's SensorValue.
const VirtualRobot::RobotPtr & useSynchronizedRtRobot(bool updateCollisionModel=false)
Requests a VirtualRobot for use in rtRun *.
const VirtualRobot::RobotPtr & rtGetRobot()
TODO make protected and use attorneys.
ControlTargetBase * useControlTarget(const std::string &deviceName, const std::string &controlMode)
Declares to calculate the ControlTarget for the given ControlDevice in the given ControlMode when rtR...
const NJointCartesianVelocityControllerControlData & rtGetControlStruct() const
MutexType controlDataMutex
std::lock_guard< std::recursive_mutex > LockGuardType
void writeControlStruct()
NJointCartesianVelocityControllerControlData & getWriterControlStruct()
void reinitTripleBuffer(const NJointCartesianVelocityControllerControlData &initial)
The RobotUnit class manages a robot and its controllers.
The SensorValueBase class.
float update(float dt, float error)
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_ERROR_S
The logging level for unexpected behaviour, that must be fixed.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
std::shared_ptr< class Robot > RobotPtr
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::map< std::string, VariantBasePtr > StringVariantBaseMap
std::vector< T > max(const std::vector< T > &v1, const std::vector< T > &v2)
std::vector< T > min(const std::vector< T > &v1, const std::vector< T > &v2)
NJointControllerRegistration< NJointCartesianVelocityController > registrationControllerNJointCartesianVelocityController("NJointCartesianVelocityController")