NJointTCPController.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 */
24#include "NJointTCPController.h"
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<NJointTCPController>
42
43 std::string
44 NJointTCPController::getClassName(const Ice::Current&) const
45 {
46 return "NJointTCPController";
47 }
48
49 void
54
55 void
56 NJointTCPController::rtRun(const IceUtil::Time& sensorValuesTimestamp,
57 const IceUtil::Time& timeSinceLastIteration)
58 {
59 auto mode = rtGetControlStruct().mode;
60
61 Eigen::VectorXf x;
62 if (mode == VirtualRobot::IKSolver::All)
63 {
64 x.resize(6);
68 }
69 else if (mode == VirtualRobot::IKSolver::Position)
70 {
71 x.resize(3);
73 }
74 else if (mode == VirtualRobot::IKSolver::Orientation)
75 {
76 x.resize(3);
79 }
80 else
81 {
82 // No mode has been set
83 return;
84 }
85
86 Eigen::MatrixXf jacobiInv = ik->getPseudoInverseJacobianMatrix(tcp, mode);
87 Eigen::VectorXf jointTargetVelocities = jacobiInv * x;
88
89 for (size_t i = 0; i < targets.size(); ++i)
90 {
91 targets.at(i)->velocity = jointTargetVelocities(i);
92 }
93 }
94
95 ::armarx::WidgetDescription::WidgetSeq
97 {
98 using namespace armarx::WidgetDescription;
99 ::armarx::WidgetDescription::WidgetSeq widgets;
100 auto addSlider = [&](const std::string& label, float limit)
101 {
102 widgets.emplace_back(new Label(false, label));
103 {
104 FloatSliderPtr c_x = new FloatSlider;
105 c_x->name = label;
106 c_x->min = -limit;
107 c_x->defaultValue = 0.0f;
108 c_x->max = limit;
109 widgets.emplace_back(c_x);
110 }
111 };
112
113 addSlider("x", 100);
114 addSlider("y", 100);
115 addSlider("z", 100);
116 addSlider("roll", 0.5);
117 addSlider("pitch", 0.5);
118 addSlider("yaw", 0.5);
119 return widgets;
120 }
121
124 const VirtualRobot::RobotPtr& robot,
125 const std::map<std::string, ConstControlDevicePtr>& controlDevices,
126 const std::map<std::string, ConstSensorDevicePtr>&)
127 {
128 using namespace armarx::WidgetDescription;
129 HBoxLayoutPtr layout = new HBoxLayout;
130
131 LabelPtr label = new Label;
132 label->text = "nodeset name";
133 layout->children.emplace_back(label);
134 StringComboBoxPtr box = new StringComboBox;
135 box->defaultIndex = 0;
136
137 box->options = robot->getRobotNodeSetNames();
138 box->name = "nodeSetName";
139 layout->children.emplace_back(box);
140
141 LabelPtr labelTCP = new Label;
142 labelTCP->text = "tcp name";
143 layout->children.emplace_back(labelTCP);
144 StringComboBoxPtr boxTCP = new StringComboBox;
145 boxTCP->defaultIndex = 0;
146
147 boxTCP->options = robot->getRobotNodeNames();
148 boxTCP->options.insert(boxTCP->options.begin(), DEFAULT_TCP_STRING);
149 boxTCP->name = "tcpName";
150 layout->children.emplace_back(boxTCP);
151
152 LabelPtr labelMode = new Label;
153 labelMode->text = "mode";
154 layout->children.emplace_back(labelMode);
155 StringComboBoxPtr boxMode = new StringComboBox;
156 boxMode->defaultIndex = 0;
157
158 boxMode->options = {"Position", "Orientation", "Both"};
159 boxMode->name = "mode";
160 layout->children.emplace_back(boxMode);
161
162
163 // auto sliders = createSliders();
164 // layout->children.insert(layout->children.end(),
165 // sliders.begin(),
166 // sliders.end());
167 layout->children.emplace_back(new HSpacer);
168 return layout;
169 }
170
171 NJointTCPControllerConfigPtr
173 {
174 return new NJointTCPControllerConfig{values.at("nodeSetName")->getString(),
175 values.at("tcpName")->getString()};
176 }
177
179 const NJointTCPControllerConfigPtr& config,
180 const VirtualRobot::RobotPtr& r)
181 {
182 ARMARX_CHECK_EXPRESSION(robotUnit);
183 ARMARX_CHECK_EXPRESSION(!config->nodeSetName.empty());
185 auto nodeset = rtGetRobot()->getRobotNodeSet(config->nodeSetName);
186 ARMARX_CHECK_EXPRESSION(nodeset) << config->nodeSetName;
187 for (size_t i = 0; i < nodeset->getSize(); ++i)
188 {
189 auto jointName = nodeset->getNode(i)->getName();
190 ControlTargetBase* ct = useControlTarget(jointName, ControlModes::Velocity1DoF);
191 const SensorValueBase* sv = useSensorValue(jointName);
192 targets.push_back(ct->asA<ControlTarget1DoFActuatorVelocity>());
193 sensors.push_back(sv->asA<SensorValue1DoFActuatorPosition>());
194 };
195 ik.reset(new VirtualRobot::DifferentialIK(
196 nodeset, rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
197 tcp = (config->tcpName.empty() || config->tcpName == DEFAULT_TCP_STRING)
198 ? nodeset->getTCP()
199 : rtGetRobot()->getRobotNode(config->tcpName);
200 ARMARX_CHECK_EXPRESSION(tcp) << config->tcpName;
201
202 nodeSetName = config->nodeSetName;
203 }
204
205 void
207 float yVel,
208 float zVel,
209 float rollVel,
210 float pitchVel,
211 float yawVel,
212 VirtualRobot::IKSolver::CartesianSelection mode)
213 {
219 getWriterControlStruct().pitchVel = pitchVel;
223 }
224
225 std::string
227 {
228 return nodeSetName;
229 }
230
231 void
235
238 {
239 using namespace armarx::WidgetDescription;
240 HBoxLayoutPtr layout = new HBoxLayout;
241 auto sliders = createSliders();
242 layout->children.insert(layout->children.end(), sliders.begin(), sliders.end());
243 return {{"ControllerTarget", layout}};
244 }
245
246 void
248 const StringVariantBaseMap& valueMap,
249 const Ice::Current&)
250 {
251 if (name == "ControllerTarget")
252 {
254 getWriterControlStruct().xVel = valueMap.at("x")->getFloat();
255 getWriterControlStruct().yVel = valueMap.at("y")->getFloat();
256 getWriterControlStruct().zVel = valueMap.at("z")->getFloat();
257 getWriterControlStruct().rollVel = valueMap.at("roll")->getFloat();
258 getWriterControlStruct().pitchVel = valueMap.at("pitch")->getFloat();
259 getWriterControlStruct().yawVel = valueMap.at("yaw")->getFloat();
261 }
262 else
263 {
264 ARMARX_WARNING << "Unknown function name called: " << name;
265 }
266 }
267} // namespace armarx
int Label(int n[], int size, int *curLabel, MiscLib::Vector< std::pair< int, size_t > > *labels)
Definition Bitmap.cpp:801
Brief description of class JointControlTargetBase.
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...
VirtualRobot::IKSolver::CartesianSelection mode
static WidgetDescription::WidgetPtr GenerateConfigDescription(const VirtualRobot::RobotPtr &, const std::map< std::string, ConstControlDevicePtr > &, const std::map< std::string, ConstSensorDevicePtr > &)
NJointTCPController(RobotUnit *prov, const NJointTCPControllerConfigPtr &config, const VirtualRobot::RobotPtr &r)
WidgetDescription::StringWidgetDictionary getFunctionDescriptions(const Ice::Current &) const override
::armarx::WidgetDescription::WidgetSeq createSliders()
static NJointTCPControllerConfigPtr GenerateConfigFromVariants(const StringVariantBaseMap &values)
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)
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.
The RobotUnit class manages a robot and its controllers.
Definition RobotUnit.h:192
The SensorValueBase class.
const T * asA() const
#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_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.
std::map< std::string, VariantBasePtr > StringVariantBaseMap
NJointControllerRegistration< NJointTCPController > registrationControllerNJointTCPController("NJointTCPController")