okr.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, 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
19 * @author
20 * @date
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24#include "okr.h"
25
26using namespace armarx;
27
28void
29OKR::calc()
30{
31 std::scoped_lock lock(dataMutex);
32
33 if (!newFlow)
34 {
35 return;
36 }
37
38 // if (velocityBased && !reportedJointVelocitiesBool)
39 // {
40 // return;
41 // }
42 else if (!velocityBased && !reportedJointAnglesBool)
43 {
44 return;
45 }
46
47 newFlow = false;
48
49 // float comp = 0.0;
50 // if (velocityBased)
51 // {
52 // comp = 3;
53 // }
54 // else
55 // {
56 // comp = 1;
57 // }
58
59 /*if (flowX < comp && flowX > -comp)
60 {
61 flowX = 0.0;
62 }
63 if (flowY < comp && flowY > -comp)
64 {
65 flowY = 0.0;
66 }*/
67
68 NameValueMap headJoints;
69 NameControlModeMap jointModes;
70
71 if (velocityBased)
72 {
73 reportedJointVelocitiesBool = false;
74
75 removeSelfInducedOpticalFlow();
76
77 //headJoints[eye_pitch_left] = (flowY) - kp * errorY;
78 //headJoints[eye_yaw_right] = -1.0 * (flowX) + kp * errorX;
79
80 // gain < 1 is to avoid unstability with the head
81 headJoints[eye_pitch_left] = 0.0; //0.8 * (flowY) - kp * errorY;
82 headJoints[eye_yaw_right] = -0.8 * (flowX); // + kp * errorX;
83
84 headJoints[eye_yaw_left] = headJoints[eye_yaw_right];
85
86 // uncomment for baseline
87 //headJoints[eye_pitch_left] = headJoints[eye_yaw_left] = headJoints[eye_yaw_right] = 0.;
88 }
89 else
90 {
91 reportedJointAnglesBool = false;
92
93 headJoints[eye_pitch_left] = (reportedJointAngles[eye_pitch_left] + flowY);
94 jointModes[eye_pitch_left] = ePositionControl;
95
96 if (armar4)
97 {
98 headJoints[eye_pitch_right] = (reportedJointAngles[eye_pitch_left] + flowY);
99 jointModes[eye_pitch_right] = ePositionControl;
100 }
101
102 headJoints[eye_yaw_left] = (reportedJointAngles[eye_yaw_left] - flowX);
103 jointModes[eye_yaw_left] = ePositionControl;
104
105 headJoints[eye_yaw_right] = (reportedJointAngles[eye_yaw_left] - flowX);
106 jointModes[eye_yaw_right] = ePositionControl;
107 }
108
109 // mutexNodeSet.unlock();
110
111 std::scoped_lock lock2(mutex);
112
113 jointAngles.swap(headJoints);
114}
115
116void
117OKR::removeSelfInducedOpticalFlow()
118{
119 NameValueMap velocities;
120
121 if (jointVelocities.size() == 0)
122 {
123 ARMARX_WARNING << deactivateSpam(1) << "No self-induced velocity found (0)";
124 return;
125 }
126
127 // find the velocities closest to the timestamp of the 2nd image
128 for (auto& kv : jointVelocities)
129 {
130 //std::scoped_lock lock(dataMutex);
131 long timestamp = kv.first;
132
133 if (timestamp <= flow_time + flowT)
134 {
135 velocities = kv.second;
136 jointVelocities.erase(
137 kv.first); // erase the values belonging to the previous optical flow
138 }
139 else
140 {
141 velocities = kv.second;
142 break;
143 }
144 }
145
146 if (velocities.find(eye_yaw_right) == velocities.end()) // no velocity found
147 {
148 velocities = jointVelocities.rbegin()->second;
149 ARMARX_WARNING << deactivateSpam(1) << "No self-induced velocity found";
150 }
151
152 flowY = flowY + velocities[eye_pitch_left];
153 flowX = flowX - velocities[eye_yaw_right];
154}
155
156void
157OKR::setJointNames(std::string eye_pitch_left,
158 std::string eye_pitch_right,
159 std::string eye_yaw_left,
160 std::string eye_yaw_right,
161 std::string neck_roll)
162{
163 std::scoped_lock lock(mutex);
164 this->eye_pitch_left = eye_pitch_left;
165 this->eye_pitch_right = eye_pitch_right;
166 this->eye_yaw_left = eye_yaw_left;
167 this->eye_yaw_right = eye_yaw_right;
168 this->neck_roll = neck_roll;
169}
170
171void
172OKR::setPIDValues(float kp, float ki, float kd)
173{
174 std::scoped_lock lock(mutex);
175
176 this->kp = kp;
177 this->ki = ki;
178 this->kd = kd;
179}
180
181void
182OKR::setBools(bool armar4, bool velocityBased)
183{
184 std::scoped_lock lock(mutex);
185
186 this->armar4 = armar4;
187 this->velocityBased = velocityBased;
188}
189
190std::vector<float>
191OKR::pid(std::vector<float> error,
192 std::vector<float> kp,
193 std::vector<float> ki,
194 std::vector<float> kd)
195{
196 if (error.size() != kp.size() || kp.size() != ki.size() || ki.size() != kd.size())
197 {
198 ARMARX_WARNING_S << "Different arraysizes in HeadStabilization::pid";
199 return {0.0, 0.0, 0.0};
200 }
201
202 std::vector<float> y;
203
204 for (size_t i = 0; i < error.size(); i++)
205 {
206 err_sum[i] += error[i];
207
208 y.push_back(kp[i] * error[i] + (ki[i] * err_sum[i]) + (kd[i] * (error[i] - err_old[i])));
209
210 err_old[i] = error[i];
211 }
212
213 return y;
214}
215
216void
217OKR::reportJointAngles(const NameValueMap& values, bool valueChanged, const Ice::Current& c)
218{
219 std::scoped_lock lock(dataMutex);
220
221 reportedJointAnglesBool = true;
222 this->reportedJointAngles = values;
223}
224
225void
226OKR::reportJointVelocities(const NameValueMap& values,
227 bool valueChanged,
228 long timestamp,
229 const Ice::Current& c)
230{
231 std::scoped_lock lock(dataMutex);
232
233 reportedJointVelocitiesBool = true;
234 this->reportedJointVelocities = values;
235
236 NameValueMap test(values);
237 jointVelocities[timestamp] = test;
238}
239
240void
241OKR::reportNewOpticalFlow(float x, float y, float deltaT, long timestamp)
242{
243 std::scoped_lock lock(dataMutex);
244
245 newFlow = true;
246 this->flowX = x;
247 this->flowY = y;
248 this->flowT = deltaT;
249
250 flow_time = timestamp;
251}
252
253void
255 Ice::Float pixelY,
256 Ice::Float angleX,
257 Ice::Float angleY)
258{
259 std::scoped_lock lock(dataMutex);
260
261 this->errorX = angleX;
262 this->errorY = angleY;
263}
264
265void
266OKR::onStop()
267{
268 std::scoped_lock lock(dataMutex);
269
270 newFlow = false;
271 reportedJointVelocitiesBool = false;
272 reportedJointAnglesBool = false;
273}
std::string timestamp()
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
constexpr T c
void reportJointAngles(const NameValueMap &values, bool valueChanged, const Ice::Current &c)
Definition okr.cpp:217
void setJointNames(std::string eye_pitch_left, std::string eye_pitch_right, std::string eye_yaw_left, std::string eye_yaw_right, std::string neck_roll)
Definition okr.cpp:157
void reportNewOpticalFlow(float x, float y, float deltaT, long timestamp)
Definition okr.cpp:241
void reportNewTrackingError(Ice::Float pixelX, Ice::Float pixelY, Ice::Float angleX, Ice::Float angleY)
Definition okr.cpp:254
void setPIDValues(float kp, float ki, float kd)
Definition okr.cpp:172
void setBools(bool armar4, bool velocityBased)
Definition okr.cpp:182
void reportJointVelocities(const NameValueMap &values, bool valueChanged, long timestamp, const Ice::Current &c)
Definition okr.cpp:226
std::mutex mutex
Definition reflex.h:138
std::map< std::string, float > jointAngles
Definition reflex.h:140
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
This file offers overloads of toIce() and fromIce() functions for STL container types.