NJointJointSpaceDMPController.cpp
Go to the documentation of this file.
2
3#include <VirtualRobot/Robot.h>
4
9
10#include <dmp/representation/dmp/umidmp.h>
11
12// control
13#include <armarx/control/deprecated_njoint_mp_controller/joint_space/ControllerInterface.h>
14
16{
17
20
21 std::string
23 {
24 return "NJointJointSpaceDMPController";
25 }
26
29 const armarx::NJointControllerConfigPtr& config,
31 {
32 NJointJointSpaceDMPControllerConfigPtr cfg =
33 NJointJointSpaceDMPControllerConfigPtr::dynamicCast(config);
34 ARMARX_CHECK_EXPRESSION_W_HINT(cfg, "Needed type: NJointJointSpaceDMPControllerConfigPtr");
35
36 for (std::string jointName : cfg->jointNames)
37 {
38 ControlTargetBase* ct = useControlTarget(jointName, ControlModes::Velocity1DoF);
39 const SensorValueBase* sv = useSensorValue(jointName);
40 targets.insert(std::make_pair(jointName, ct->asA<ControlTarget1DoFActuatorVelocity>()));
41 positionSensors.insert(
42 std::make_pair(jointName, sv->asA<SensorValue1DoFActuatorPosition>()));
43 torqueSensors.insert(
44 std::make_pair(jointName, sv->asA<SensorValue1DoFActuatorTorque>()));
45 gravityTorqueSensors.insert(
46 std::make_pair(jointName, sv->asA<SensorValue1DoFGravityTorque>()));
47 velocitySensors.insert(
48 std::make_pair(jointName, sv->asA<SensorValue1DoFActuatorVelocity>()));
49 }
50 if (cfg->jointNames.size() == 0)
51 {
52 ARMARX_ERROR << "cfg->jointNames.size() == 0";
53 }
54
55 dmpPtr.reset(new DMP::UMIDMP(cfg->kernelSize, cfg->DMPKd, cfg->baseMode, cfg->tau));
56 timeDuration = cfg->timeDuration;
57 canVal = timeDuration;
58 finished = false;
59 phaseL = cfg->phaseL;
60 phaseK = cfg->phaseK;
61 phaseDist0 = cfg->phaseDist0;
62 phaseDist1 = cfg->phaseDist1;
63 phaseKp = cfg->phaseKp;
64
65 isDisturbance = false;
66
68 initData.tau = 1.0;
69 initData.isStart = false;
70 reinitTripleBuffer(initData);
71 }
72
73 void
74 NJointJointSpaceDMPController::rtRun(const IceUtil::Time& sensorValuesTimestamp,
75 const IceUtil::Time& timeSinceLastIteration)
76 {
77 if (rtGetControlStruct().isStart && !finished)
78 {
79 currentState.clear();
80 double phaseStop = 0;
81 double error = 0;
82 std::vector<double> currentPosition;
83 std::vector<double> currentVelocity;
84 for (size_t i = 0; i < dimNames.size(); i++)
85 {
86 const auto& jointName = dimNames.at(i);
87 DMP::DMPState currentPos;
88 currentPos.pos = (positionSensors.count(jointName) == 1)
89 ? positionSensors[jointName]->position
90 : 0.0f;
91 currentPos.vel = (velocitySensors.count(jointName) == 1)
92 ? velocitySensors[jointName]->velocity
93 : 0.0f;
94 currentPos.vel *= timeDuration;
95 currentState.push_back(currentPos);
96 currentPosition.push_back(currentPos.pos);
97 currentVelocity.push_back(currentPos.vel);
98
99 error += pow(currentPos.pos - targetState[i], 2);
100 }
101
102 double phaseDist;
103
104 if (isDisturbance)
105 {
106 phaseDist = phaseDist1;
107 }
108 else
109 {
110 phaseDist = phaseDist0;
111 }
112
113 error = sqrt(error);
114 phaseStop = phaseL / (1 + exp(-phaseK * (error - phaseDist)));
115 mpcFactor = 1 - (phaseStop / phaseL);
116
117 if (mpcFactor < 0.1)
118 {
119 isDisturbance = true;
120 }
121
122 if (mpcFactor > 0.9)
123 {
124 isDisturbance = false;
125 }
126
127 double tau = rtGetControlStruct().tau;
128 double deltaT = timeSinceLastIteration.toSecondsDouble();
129 canVal -= 1 / tau * deltaT * 1 / (1 + phaseStop);
130 double dmpDeltaT = deltaT / timeDuration;
131 dmpPtr->setTemporalFactor(tau);
132
133 currentState = dmpPtr->calculateDirectlyVelocity(
134 currentState, canVal / timeDuration, dmpDeltaT, targetState);
135
136 if (canVal < 1e-8)
137 {
138 finished = true;
139 }
140
141 for (size_t i = 0; i < dimNames.size(); ++i)
142 {
143 const auto& jointName = dimNames.at(i);
144 if (targets.count(jointName) == 1)
145 {
146 double vel0 = currentState[i].vel / timeDuration;
147 double vel1 = phaseKp * (targetState[i] - currentPosition[i]);
148 double vel = mpcFactor * vel0 + (1 - mpcFactor) * vel1;
149 targets[jointName]->velocity = finished ? 0.0f : vel;
150
151 std::string targetVelstr = jointName + "_targetvel";
152 std::string targetStatestr = jointName + "_dmpTarget";
153 debugOutputData.getWriteBuffer().latestTargetVelocities[jointName] = vel;
154 debugOutputData.getWriteBuffer().dmpTargetState[jointName] = targetState[i];
155 }
156 }
157
158 debugOutputData.getWriteBuffer().currentCanVal = canVal;
159 debugOutputData.getWriteBuffer().mpcFactor = mpcFactor;
160 debugOutputData.commitWrite();
161 }
162 else
163 {
164 for (size_t i = 0; i < dimNames.size(); ++i)
165 {
166 const auto& jointName = dimNames.at(i);
167 if (targets.count(jointName) == 1)
168 {
169 targets[jointName]->velocity = 0.0f;
170 }
171 }
172 }
173 }
174
175 void
177 const Ice::Current&)
178 {
179 DMP::Vec<DMP::SampledTrajectoryV2> trajs;
180
181 DMP::DVec ratios;
182 for (size_t i = 0; i < fileNames.size(); ++i)
183 {
184 DMP::SampledTrajectoryV2 traj;
185 traj.readFromCSVFile(fileNames.at(i));
186 dimNames = traj.getDimensionNames();
187 traj = DMP::SampledTrajectoryV2::normalizeTimestamps(traj, 0, 1);
188 trajs.push_back(traj);
189
190 if (i == 0)
191 {
192 ratios.push_back(1.0);
193 }
194 else
195 {
196 ratios.push_back(0.0);
197 }
198 }
199 dmpPtr->learnFromTrajectories(trajs);
200 dmpPtr->setOneStepMPC(true);
201 dmpPtr->styleParas = dmpPtr->getStyleParasWithRatio(ratios);
202
203 ARMARX_INFO << "Learned DMP ... ";
204 }
205
206 void
207 NJointJointSpaceDMPController::runDMP(const Ice::DoubleSeq& goals,
208 double tau,
209 const Ice::Current&)
210 {
211 currentState.clear();
212 targetState.clear();
213 for (size_t i = 0; i < dimNames.size(); i++)
214 {
215 const auto& jointName = dimNames.at(i);
216 DMP::DMPState currentPos;
217 currentPos.pos = (positionSensors.count(jointName) == 1)
218 ? positionSensors[jointName]->position
219 : 0.0f;
220 currentPos.vel = (velocitySensors.count(jointName) == 1)
221 ? velocitySensors[jointName]->velocity
222 : 0.0f;
223 currentState.push_back(currentPos);
224 targetState.push_back(currentPos.pos);
225 }
226 dmpPtr->prepareExecution(goals, currentState, 1, tau);
227 finished = false;
228
229 this->goals = goals;
230 this->tau = tau;
231
233 getWriterControlStruct().tau = tau;
234 getWriterControlStruct().isStart = true;
236 }
237
238 void
240 {
241 }
242
243 void
245 {
246 this->tau = tau;
248 getWriterControlStruct().tau = tau;
249 getWriterControlStruct().isStart = true;
251 }
252
253 void
257
258 void
262
263 void
266 const DebugObserverInterfacePrx& debugObs)
267 {
268 StringVariantBaseMap datafields;
269 auto values = debugOutputData.getUpToDateReadBuffer().latestTargetVelocities;
270 for (auto& pair : values)
271 {
272 datafields[pair.first] = new Variant(pair.second);
273 }
274
275 auto valuesst = debugOutputData.getUpToDateReadBuffer().dmpTargetState;
276 for (auto& pair : valuesst)
277 {
278 datafields[pair.first] = new Variant(pair.second);
279 }
280
281 datafields["canVal"] = new Variant(debugOutputData.getUpToDateReadBuffer().currentCanVal);
282 datafields["mpcFactor"] = new Variant(debugOutputData.getUpToDateReadBuffer().mpcFactor);
283 debugObs->setDebugChannel("latestDMPTargetVelocities", datafields);
284 }
285
286
287} // namespace armarx::control::deprecated_njoint_mp_controller::joint_space
Brief description of class JointControlTargetBase.
const SensorValueBase * useSensorValue(const std::string &sensorDeviceName) const
Get a const ptr to the given SensorDevice's SensorValue.
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 SensorValueBase class.
const T * asA() const
The Variant class is described here: Variants.
Definition Variant.h:224
virtual void onPublish(const SensorAndControl &, const DebugDrawerInterfacePrx &, const DebugObserverInterfacePrx &) 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.
void runDMP(const Ice::DoubleSeq &goals, double tau, const Ice::Current &) override
NJointJointSpaceDMPController(RobotUnitPtr prov, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
void rtPreActivateController() override
This function is called before the controller is activated.
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
NJointControllerRegistration< NJointJointSpaceDMPController > registrationControllerNJointJointSpaceDMPController("NJointJointSpaceDMPController")
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugObserverInterface > DebugObserverInterfacePrx
std::map< std::string, VariantBasePtr > StringVariantBaseMap
IceUtil::Handle< class RobotUnit > RobotUnitPtr
Definition FTSensor.h:34
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface > DebugDrawerInterfacePrx
detail::ControlThreadOutputBufferEntry SensorAndControl