NJointCartesianTorqueController.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2017, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarX
19 * @author Mirko Waechter( mirko.waechter at kit dot edu)
20 * @date 2017
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
25
26#include <VirtualRobot/IK/DifferentialIK.h>
27#include <VirtualRobot/Robot.h>
28#include <VirtualRobot/RobotNodeSet.h>
29
31
32#include "../RobotUnit.h"
33
34
35#define DEFAULT_TCP_STRING "default TCP"
36
37namespace armarx
38{
39
40 NJointControllerRegistration<NJointCartesianTorqueController>
42
43 std::string
45 {
46 return "NJointCartesianTorqueController";
47 }
48
50 RobotUnit*,
51 NJointCartesianTorqueControllerConfigPtr config,
53 {
54 ARMARX_CHECK_EXPRESSION(!config->nodeSetName.empty());
56 VirtualRobot::RobotNodeSetPtr rns = rtGetRobot()->getRobotNodeSet(config->nodeSetName);
57 ARMARX_CHECK_EXPRESSION(rns) << config->nodeSetName;
58 for (size_t i = 0; i < rns->getSize(); ++i)
59 {
60 std::string jointName = rns->getNode(i)->getName();
61 ControlTargetBase* ct = useControlTarget(jointName, ControlModes::Torque1DoF);
62 //const SensorValueBase* sv = useSensorValue(jointName);
63 targets.push_back(ct->asA<ControlTarget1DoFActuatorTorque>());
64
65 /*const SensorValue1DoFActuatorTorque* torqueSensor = sv->asA<SensorValue1DoFActuatorTorque>();
66 const SensorValue1DoFGravityTorque* gravityTorqueSensor = sv->asA<SensorValue1DoFGravityTorque>();
67 if (!torqueSensor)
68 {
69 ARMARX_WARNING << "No Torque sensor available for " << jointName;
70 }
71 if (!gravityTorqueSensor)
72 {
73 ARMARX_WARNING << "No Gravity Torque sensor available for " << jointName;
74 }
75 torqueSensors.push_back(torqueSensor);
76 gravityTorqueSensors.push_back(gravityTorqueSensor);*/
77 };
78
79 tcp = (config->tcpName.empty() || config->tcpName == DEFAULT_TCP_STRING)
80 ? rns->getTCP()
81 : rtGetRobot()->getRobotNode(config->tcpName);
82 ARMARX_CHECK_EXPRESSION(tcp) << config->tcpName;
83
84 nodeSetName = config->nodeSetName;
85
86 ik.reset(new VirtualRobot::DifferentialIK(
87 rns, rns->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
88
89
90 /*NJointCartesianTorqueControllerControlData initData;
91 initData.nullspaceJointVelocities.resize(tcpController->rns->getSize(), 0);
92 initData.torqueKp.resize(tcpController->rns->getSize(), 0);
93 initData.mode = ModeFromIce(config->mode);
94 reinitTripleBuffer(initData);*/
95 }
96
97 void
101
102 void
103 NJointCartesianTorqueController::rtRun(const IceUtil::Time& sensorValuesTimestamp,
104 const IceUtil::Time& timeSinceLastIteration)
105 {
106 Eigen::VectorXf cartesianFT(6);
107 cartesianFT << rtGetControlStruct().forceX / 1000, rtGetControlStruct().forceY / 1000,
110
111 Eigen::MatrixXf jacobi =
112 ik->getJacobianMatrix(tcp, VirtualRobot::IKSolver::CartesianSelection::All);
113 Eigen::MatrixXf jacobiT = jacobi.transpose();
114
115
116 Eigen::VectorXf jointTargetTorques = jacobiT * cartesianFT;
117
118 ARMARX_IMPORTANT << deactivateSpam(0.5) << VAROUT(jointTargetTorques.transpose());
119
120 for (size_t i = 0; i < targets.size(); ++i)
121 {
122 targets.at(i)->torque = jointTargetTorques(i);
123 }
124 }
125
126 WidgetDescription::HBoxLayoutPtr
128 {
129 using namespace armarx::WidgetDescription;
130 HBoxLayoutPtr layout = new HBoxLayout;
131 auto addSlider = [&](const std::string& label, float min, float max, float defaultValue)
132 {
133 layout->children.emplace_back(new Label(false, label));
134 FloatSliderPtr floatSlider = new FloatSlider;
135 floatSlider->name = label;
136 floatSlider->min = min;
137 floatSlider->defaultValue = defaultValue;
138 floatSlider->max = max;
139 layout->children.emplace_back(floatSlider);
140 };
141
142 addSlider("forceX", -10, 10, 0);
143 addSlider("forceY", -10, 10, 0);
144 addSlider("forceZ", -10, 10, 0);
145 addSlider("torqueX", -1, 1, 0);
146 addSlider("torqueY", -1, 1, 0);
147 addSlider("torqueZ", -1, 1, 0);
148
149 return layout;
150 }
151
152 /*WidgetDescription::HBoxLayoutPtr NJointCartesianTorqueController::createJointSlidersLayout(float min, float max, float defaultValue) const
153 {
154 using namespace armarx::WidgetDescription;
155 HBoxLayoutPtr layout = new HBoxLayout;
156 auto addSlider = [&](const std::string & label)
157 {
158 layout->children.emplace_back(new Label(false, label));
159 FloatSliderPtr floatSlider = new FloatSlider;
160 floatSlider->name = label;
161 floatSlider->min = min;
162 floatSlider->defaultValue = defaultValue;
163 floatSlider->max = max;
164 layout->children.emplace_back(floatSlider);
165 };
166
167 for (const VirtualRobot::RobotNodePtr& rn : tcpController->rns->getAllRobotNodes())
168 {
169 addSlider(rn->getName());
170 }
171
172 return layout;
173 }*/
174
177 const VirtualRobot::RobotPtr& robot,
178 const std::map<std::string, ConstControlDevicePtr>& controlDevices,
179 const std::map<std::string, ConstSensorDevicePtr>&)
180 {
181 using namespace armarx::WidgetDescription;
182 HBoxLayoutPtr layout = new HBoxLayout;
183
184 LabelPtr label = new Label;
185 label->text = "nodeset name";
186 layout->children.emplace_back(label);
187 StringComboBoxPtr box = new StringComboBox;
188 box->defaultIndex = 0;
189
190 box->options = robot->getRobotNodeSetNames();
191 box->name = "nodeSetName";
192 layout->children.emplace_back(box);
193
194 LabelPtr labelTCP = new Label;
195 labelTCP->text = "tcp name";
196 layout->children.emplace_back(labelTCP);
197 StringComboBoxPtr boxTCP = new StringComboBox;
198 boxTCP->defaultIndex = 0;
199
200 boxTCP->options = robot->getRobotNodeNames();
201 boxTCP->options.insert(boxTCP->options.begin(), DEFAULT_TCP_STRING);
202 boxTCP->name = "tcpName";
203 layout->children.emplace_back(boxTCP);
204
205 //LabelPtr labelMode = new Label;
206 //labelMode->text = "mode";
207 //layout->children.emplace_back(labelMode);
208 //StringComboBoxPtr boxMode = new StringComboBox;
209 //boxMode->defaultIndex = 0;
210 //
211 //boxMode->options = {"Position", "Orientation", "Both"};
212 //boxMode->name = "mode";
213 //layout->children.emplace_back(boxMode);
214
215
216 layout->children.emplace_back(new HSpacer);
217 return layout;
218 }
219
220 NJointCartesianTorqueControllerConfigPtr
222 {
223 return new NJointCartesianTorqueControllerConfig(values.at("nodeSetName")->getString(),
224 values.at("tcpName")->getString());
225 }
226
227 std::string
229 {
230 return nodeSetName;
231 }
232
233 void
237
240 {
241 using namespace armarx::WidgetDescription;
242 HBoxLayoutPtr layout = createSliders();
243
244 return {{"ControllerTarget", layout}};
245 }
246
247 void
249 const StringVariantBaseMap& valueMap,
250 const Ice::Current&)
251 {
252 if (name == "ControllerTarget")
253 {
255 getWriterControlStruct().forceX = valueMap.at("forceX")->getFloat();
256 getWriterControlStruct().forceY = valueMap.at("forceY")->getFloat();
257 getWriterControlStruct().forceZ = valueMap.at("forceZ")->getFloat();
258 getWriterControlStruct().torqueX = valueMap.at("torqueX")->getFloat();
259 getWriterControlStruct().torqueY = valueMap.at("torqueY")->getFloat();
260 getWriterControlStruct().torqueZ = valueMap.at("torqueZ")->getFloat();
262 }
263 else
264 {
265 ARMARX_WARNING << "Unknown function name called: " << name;
266 }
267 }
268} // namespace armarx
269
270void
272 float forceY,
273 float forceZ,
274 float torqueX,
275 float torqueY,
276 float torqueZ,
277 const Ice::Current&)
278{
287}
int Label(int n[], int size, int *curLabel, MiscLib::Vector< std::pair< int, size_t > > *labels)
Definition Bitmap.cpp:801
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
#define VAROUT(x)
Brief description of class JointControlTargetBase.
static WidgetDescription::WidgetPtr GenerateConfigDescription(const VirtualRobot::RobotPtr &, const std::map< std::string, ConstControlDevicePtr > &, const std::map< std::string, ConstSensorDevicePtr > &)
WidgetDescription::StringWidgetDictionary getFunctionDescriptions(const Ice::Current &) const override
NJointCartesianTorqueController(RobotUnit *prov, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
void setControllerTarget(float forceX, float forceY, float forceZ, float torqueX, float torqueY, float torqueZ, const Ice::Current &) override
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.
static NJointCartesianTorqueControllerConfigPtr GenerateConfigFromVariants(const StringVariantBaseMap &values)
::armarx::WidgetDescription::HBoxLayoutPtr createSliders()
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 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...
The RobotUnit class manages a robot and its controllers.
Definition RobotUnit.h:192
#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_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
::IceInternal::Handle<::armarx::WidgetDescription::Widget > WidgetPtr
::std::map<::std::string, ::armarx::WidgetDescription::WidgetPtr > StringWidgetDictionary
This file offers overloads of toIce() and fromIce() functions for STL container types.
NJointControllerRegistration< NJointCartesianTorqueController > registrationControllerNJointCartesianTorqueController("NJointCartesianTorqueController")
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)