feedforward.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 "feedforward.h"
25
26using namespace armarx;
27
28void
30{
31
32 if (!update_input_fromArmarX(stabilizer->input))
33 {
34 return;
35 }
36
37 reportedJointVelocitiesBool = false;
38 reportedJointAnglesBool = false;
39
40 stabilizer->control_loop();
41
42 optFlow_pred = stabilizer->getOptFlowPred();
43 mean_optFl_pred = stabilizer->getMeanOptFlPred();
44 gyroscopeRotation_pred = stabilizer->getIMUPred();
45
46 update_output_toArmarX(stabilizer->output);
47}
48
49void
50FeedforwardReflex::setRobot(std::string nodeSetName,
51 std::string headIKName,
52 RobotStateComponentInterfacePrx robotStateComponent)
53{
54 std::scoped_lock lock(mutex);
55
56 this->robotStateComponent = robotStateComponent;
57
58 globalPos = new FramedPosition();
59
60 GazeStabOptions* gs_options;
61
62 if (armar4)
63 {
64 gs_options = new GazeStabOptions(1);
65 }
66 else // armar3
67 {
68 gs_options = new GazeStabOptions(2);
69 }
70
71 stabilizer = new GazeStabilization(gs_options);
72 stabilizer->init();
73
74 forward_predictor = new ForwardPredictor();
75
76 startTime = armarx::TimeUtil::GetTime();
77
78 if (armar4)
79 {
80 headJointNames = {"Neck_1_joint",
81 "Neck_2_joint",
82 "Neck_3_joint",
83 "Head_1_joint",
84 "Head_2_joint",
85 "EyeR_1_joint",
86 "EyeR_2_joint"};
87 }
88 else // armar3
89 {
90 headJointNames = {"Neck_1_Pitch", "Neck_2_Roll", "Neck_3_Yaw", "Cameras", "Eye_Right"};
91 }
92}
93
94bool
96{
97
98 std::scoped_lock lock(dataMutex);
99
100 //Check if all sensor values have at least been reported once to avoid segfaults
101 if (!(reportedJointAnglesBool && reportedJointVelocitiesBool)) // TODO:: && globalPos))
102 {
103 ARMARX_WARNING_S << "Try to access gaze stab input that haven't been reported";
104 return false;
105 }
106
107 // globalPos->changeFrame("Neck_1_joint");
108
109 if (armar4)
110 {
111 PoseBasePtr globalPose = robotStateComponent->getSynchronizedRobot()
112 ->getRobotNode("Torso_Yaw_joint")
113 ->getGlobalPose();
114
115 Eigen::Quaternionf quaternion =
116 QuaternionPtr::dynamicCast(globalPose->orientation)->toEigenQuaternion();
117 Eigen::Vector3f rpy = quaternionToRPY(quaternion);
118
119
120 gs_input->q_LB[0] =
121 globalPose->position->x; // should be probably converted from mm to m (TBC)
122 gs_input->q_LB[1] = globalPose->position->y;
123 gs_input->q_LB[2] = globalPose->position->z;
124
125 gs_input->q_LB[3] = rpy(0);
126 gs_input->q_LB[4] = rpy(1);
127 gs_input->q_LB[5] = rpy(2);
128
129 gs_input->q_LB[6] = this->reportedJointAngles["Torso_Yaw_joint"];
130 gs_input->q_LB[7] = -1 * this->reportedJointAngles["Torso_Pitch_joint"];
131
132
133 // in this test we assume we don´t know the floaring base velocity
134 gs_input->qd_LB_des[0] = 0.;
135 gs_input->qd_LB_des[1] = 0.;
136 gs_input->qd_LB_des[2] = 0.;
137 gs_input->qd_LB_des[3] = 0.;
138 gs_input->qd_LB_des[4] = 0.;
139 gs_input->qd_LB_des[5] = 0.;
140
141 gs_input->qd_LB_des[6] = -1 * this->reportedJointVelocities["Torso_Yaw_joint"];
142 gs_input->qd_LB_des[7] = this->reportedJointVelocities["Torso_Pitch_joint"];
143 }
144 else // armar3
145 {
146 PoseBasePtr globalPose = robotStateComponent->getSynchronizedRobot()->getGlobalPose();
147
148 Eigen::Quaternionf quaternion =
149 QuaternionPtr::dynamicCast(globalPose->orientation)->toEigenQuaternion();
150 Eigen::Vector3f rpy = quaternionToRPY(quaternion);
151
152 gs_input->q_LB[0] = globalPose->position->x / 1000.;
153 gs_input->q_LB[1] = globalPose->position->y / 1000.;
154 gs_input->q_LB[2] = globalPose->position->z / 1000.;
155
156 gs_input->q_LB[3] = rpy(0);
157 gs_input->q_LB[4] = rpy(1);
158 gs_input->q_LB[5] = rpy(2);
159
160 gs_input->q_LB[6] = 0.; // yaw platform (unused here...)
161 gs_input->q_LB[7] = this->reportedJointAngles["Hip Pitch"];
162 gs_input->q_LB[8] = this->reportedJointAngles["Hip Roll"];
163 gs_input->q_LB[9] = this->reportedJointAngles["Hip Yaw"];
164
165 // in this test we assume we don´t know the floating base velocity
166 //gs_inputt->qd_LB_des[0] = 0.; //x
167 //gs_input->qd_LB_des[1] = 0.; //y
168 gs_input->qd_LB_des[2] = 0.;
169 gs_input->qd_LB_des[3] = 0.;
170 gs_input->qd_LB_des[4] = 0.;
171 //gs_input->qd_LB_des[5] = 0.; // theta
172
173 gs_input->qd_LB_des[6] = 0.; // yaw platform (unused here...)
174 gs_input->qd_LB_des[7] = -1 * this->reportedJointVelocities["Hip Pitch"];
175 gs_input->qd_LB_des[8] = -1 * this->reportedJointVelocities["Hip Roll"];
176 gs_input->qd_LB_des[9] = this->reportedJointVelocities["Hip Yaw"];
177
178 // for now we don't make any diff between desired and measured velocity (to be corrected).
179 for (int i = 0; i < 10; i++)
180 {
181 gs_input->qd_LB[i] = gs_input->qd_LB_des[i];
182 }
183 }
184
185 for (size_t i = 0; i < headJointNames.size(); i++)
186 {
187 gs_input->q_UB[i] = this->reportedJointAngles[headJointNames[i]];
188 gs_input->qd_UB[i] = this->reportedJointVelocities[headJointNames[i]];
189 }
190
191 if (armar4)
192 {
193 gs_input->q_UB[2] += M_PI; // shift between models
194 gs_input->q_UB[0] *= -1; // sense of rotation between models
195 gs_input->q_UB[1] *= -1;
196 gs_input->q_UB[6] *= -1;
197 }
198 else
199 {
200 // gs_input->q_UB[4] *= -1;
201 }
202
203 gs_input->tsim = (armarx::TimeUtil::GetTime() - startTime).toSecondsDouble();
204
205 return true;
206}
207
208void
210{
211
212 std::map<std::string, float> targetJointAngles;
213
214 for (size_t i = 0; i < headJointNames.size(); i++)
215 {
216 targetJointAngles[headJointNames[i]] = gs_output->qd_UB_des[i];
217 }
218 if (armar4)
219 {
220 targetJointAngles[headJointNames[0]] *= -1; // sense of rotation between models
221 targetJointAngles[headJointNames[1]] *= -1;
222 targetJointAngles[headJointNames[6]] *= -1;
223 }
224 else // armar 3
225 {
226 targetJointAngles["Eye_Left"] = targetJointAngles["Eye_Right"];
227 }
228
229 std::scoped_lock lock(mutex);
230
231 jointAngles.swap(targetJointAngles);
232}
233
234void
235FeedforwardReflex::setBools(bool armar4, bool velocityBased)
236{
237 std::scoped_lock lock(mutex);
238
239 this->armar4 = armar4;
240 this->velocityBased = velocityBased;
241}
242
243void
244FeedforwardReflex::reportJointAngles(const NameValueMap& values,
245 bool valueChanged,
246 const Ice::Current& c)
247{
248 std::scoped_lock lock(dataMutex);
249
250 reportedJointAnglesBool = true;
251 this->reportedJointAngles = values;
252}
253
254void
256 bool valueChanged,
257 const Ice::Current& c)
258{
259 std::scoped_lock lock(dataMutex);
260
261 reportedJointVelocitiesBool = true;
262 this->reportedJointVelocities = values;
263}
264
265void
267{
268 stabilizer->input->qd_LB_des[0] = x / 1000.;
269 stabilizer->input->qd_LB_des[1] = y / 1000.;
270 stabilizer->input->qd_LB_des[5] = a;
271}
272
273void
274FeedforwardReflex::reportHeadTargetChanged(const NameValueMap& targetJointAngles,
275 const FramedPositionBasePtr& targetPosition)
276{
277 std::scoped_lock lock(dataMutex);
278
279 globalPos = FramedPositionPtr::dynamicCast(targetPosition);
280
281 Eigen::Vector3f x = globalPos->toEigen() / 1000.0f;
282
283 stabilizer->input->pos_target = x.cast<double>();
284}
285
286void
288{
289 std::scoped_lock lock(dataMutex);
290
291 // globalPos = {};
292 reportedJointVelocitiesBool = false;
293 reportedJointAnglesBool = false;
294}
#define M_PI
Definition MathTools.h:17
constexpr T c
std::vector< double > q_UB
std::vector< double > qd_UB
std::vector< double > qd_LB
Eigen::VectorXd qd_LB_des
std::vector< double > q_LB
std::vector< double > qd_UB_des
void reportJointAngles(const NameValueMap &values, bool valueChanged, const Ice::Current &c)
void reportHeadTargetChanged(const NameValueMap &targetJointAngles, const FramedPositionBasePtr &targetPosition)
std::vector< float > optFlow_pred
Definition feedforward.h:98
bool update_input_fromArmarX(GazeStabInput *gs_input)
std::vector< float > gyroscopeRotation_pred
void update_output_toArmarX(GazeStabOutput *gs_output)
void reportPlatformVelocity(float x, float y, float a)
void reportJointVelocities(const NameValueMap &values, bool valueChanged, const Ice::Current &c)
void setBools(bool armar4, bool velocityBased)
void setRobot(std::string nodeSetName, std::string headIKName, RobotStateComponentInterfacePrx robotStateComponent)
The FramedPosition class.
Definition FramedPose.h:158
std::mutex mutex
Definition reflex.h:138
Eigen::Vector3f quaternionToRPY(Eigen::Quaternionf q)
Definition reflex.h:121
std::map< std::string, float > jointAngles
Definition reflex.h:140
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Definition TimeUtil.cpp:42
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
Quaternion< float, 0 > Quaternionf
This file offers overloads of toIce() and fromIce() functions for STL container types.
::IceInternal::ProxyHandle<::IceProxy::armarx::RobotStateComponentInterface > RobotStateComponentInterfacePrx