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 
26 using namespace armarx;
27 
28 void
29 OKR::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 
116 void
117 OKR::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 
156 void
157 OKR::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 
171 void
172 OKR::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 
181 void
182 OKR::setBools(bool armar4, bool velocityBased)
183 {
184  std::scoped_lock lock(mutex);
185 
186  this->armar4 = armar4;
187  this->velocityBased = velocityBased;
188 }
189 
190 std::vector<float>
191 OKR::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 
216 void
217 OKR::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 
225 void
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 
240 void
241 OKR::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 
253 void
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 
265 void
266 OKR::onStop()
267 {
268  std::scoped_lock lock(dataMutex);
269 
270  newFlow = false;
271  reportedJointVelocitiesBool = false;
272  reportedJointAnglesBool = false;
273 }
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:919
armarx::OKR::setJointNames
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
okr.h
armarx::OKR::reportNewTrackingError
void reportNewTrackingError(Ice::Float pixelX, Ice::Float pixelY, Ice::Float angleX, Ice::Float angleY)
Definition: okr.cpp:254
armarx::OKR::setPIDValues
void setPIDValues(float kp, float ki, float kd)
Definition: okr.cpp:172
ProsthesisInterface.values
values
Definition: ProsthesisInterface.py:190
armarx::OKR::reportJointVelocities
void reportJointVelocities(const NameValueMap &values, bool valueChanged, long timestamp, const Ice::Current &c)
Definition: okr.cpp:226
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
armarx::Reflex::jointAngles
std::map< std::string, float > jointAngles
Definition: reflex.h:140
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:75
armarx::OKR::reportNewOpticalFlow
void reportNewOpticalFlow(float x, float y, float deltaT, long timestamp)
Definition: okr.cpp:241
armarx::Reflex::mutex
std::mutex mutex
Definition: reflex.h:138
timestamp
std::string timestamp()
Definition: CartographerAdapter.cpp:85
armarx::channels::KinematicUnitObserver::jointVelocities
const KinematicUnitDatafieldCreator jointVelocities("jointVelocities")
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:213
armarx::control::njoint_controller::platform::platform_follower_controller::NameValueMap
std::map< std::string, float > NameValueMap
Definition: PlatformFollowerController.h:88
armarx::OKR::setBools
void setBools(bool armar4, bool velocityBased)
Definition: okr.cpp:182
armarx::OKR::reportJointAngles
void reportJointAngles(const NameValueMap &values, bool valueChanged, const Ice::Current &c)
Definition: okr.cpp:217
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27