HandModelV2.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 "HandModelV2.h"
25
26#include <fstream>
27#include <iostream>
28
30
31namespace visionx
32{
33
34 CHandModelV2::CFinger::CFinger(std::vector<float> aJointOffsets,
35 std::vector<Vec3d> aFingerTipCorners)
36 {
37 for (size_t i = 0; i < aJointOffsets.size(); i++)
38 {
39 m_aJointOffsets.push_back(aJointOffsets.at(i));
40 m_aJointAngles.push_back(0);
41 }
42 m_aFingerJointsInFingerBaseCS.resize(aJointOffsets.size() + 1);
43 Math3d::SetVec(m_aFingerJointsInFingerBaseCS.at(0), 0, 0, 0);
44
45 for (size_t i = 0; i < aFingerTipCorners.size(); i++)
46 {
47 m_aFingerTipCornersInLocalCS.push_back(aFingerTipCorners.at(i));
48 }
49 m_aFingerTipCornersInFingerBaseCS.resize(aFingerTipCorners.size());
50
51 // initial calculation, all angles 0
52 UpdateJointAngles(m_aJointAngles);
53 }
54
55 void
56 CHandModelV2::CFinger::UpdateJointAngles(std::vector<float> aNewJointValues)
57 {
58 Mat3d mRotLocal, mRotGlobal = Math3d::unit_mat;
59 Vec3d vTemp = Math3d::zero_vec;
60
61 // joint angles and positions
62 const size_t n = (m_aJointAngles.size() <= aNewJointValues.size()) ? m_aJointAngles.size()
63 : aNewJointValues.size();
64 for (size_t i = 0; i < n; i++)
65 {
66 m_aJointAngles.at(i) = aNewJointValues.at(i);
67 Math3d::SetRotationMatY(mRotLocal, aNewJointValues.at(i));
68 Math3d::MulMatMat(mRotGlobal, mRotLocal, mRotGlobal);
69 vTemp.x = m_aJointOffsets.at(i);
70 Math3d::MulMatVec(mRotGlobal,
71 vTemp,
74 }
75
76 Vec3d vFingerTipPosition = m_aFingerJointsInFingerBaseCS.at(m_aJointAngles.size());
77 for (size_t i = 0; i < m_aFingerTipCornersInLocalCS.size(); i++)
78 {
79 Math3d::MulMatVec(mRotGlobal,
80 m_aFingerTipCornersInLocalCS.at(i),
81 vFingerTipPosition,
83 }
84 }
85
86 CHandModelV2::CHandModelV2(std::string sConfigFileName, CStereoCalibration* pStereoCalibration)
87 {
88 m_pStereoCalibration = pStereoCalibration;
89
90 //****************************************
91 // read hand config file
92 //****************************************
93
94 std::ifstream sFileStream(sConfigFileName.c_str(), std::ifstream::in);
95 if (!sFileStream.good())
96 {
97 ARMARX_WARNING_S << "CHandModelV2 constructor: file " << sConfigFileName
98 << " could not be opened";
99 return;
100 }
101
102 setlocale(LC_NUMERIC, "C");
103
104 std::string sLine;
105 Vec3d vTemp;
106 float fTemp;
107 std::vector<std::vector<float>> aJointOffsets;
108 aJointOffsets.resize(5);
109
110 // offset to thumb base
111 sLine = GetNextNonCommentLine(sFileStream);
112 sscanf(sLine.c_str(), "%f %f %f", &vTemp.x, &vTemp.y, &vTemp.z);
113 m_aOffsetsToFingers.push_back(vTemp);
114
115 // distance from thumb base joint to second joint
116 sLine = GetNextNonCommentLine(sFileStream);
117 sscanf(sLine.c_str(), "%f", &fTemp);
118 aJointOffsets.at(0).push_back(fTemp);
119
120 // distance from second thumb joint to fingertip
121 sLine = GetNextNonCommentLine(sFileStream);
122 sscanf(sLine.c_str(), "%f", &fTemp);
123 aJointOffsets.at(0).push_back(fTemp);
124
125
126 // offset from palm to index base
127 sLine = GetNextNonCommentLine(sFileStream);
128 sscanf(sLine.c_str(), "%f %f %f", &vTemp.x, &vTemp.y, &vTemp.z);
129 m_aOffsetsToFingers.push_back(vTemp);
130
131 // distance from index base joint to second joint
132 sLine = GetNextNonCommentLine(sFileStream);
133 sscanf(sLine.c_str(), "%f", &fTemp);
134 aJointOffsets.at(1).push_back(fTemp);
135
136 // distance from second index joint to fingertip
137 sLine = GetNextNonCommentLine(sFileStream);
138 sscanf(sLine.c_str(), "%f", &fTemp);
139 aJointOffsets.at(1).push_back(fTemp);
140
141
142 // offset from palm to middle base
143 sLine = GetNextNonCommentLine(sFileStream);
144 sscanf(sLine.c_str(), "%f %f %f", &vTemp.x, &vTemp.y, &vTemp.z);
145 m_aOffsetsToFingers.push_back(vTemp);
146
147 // distance from middle base joint to second joint
148 sLine = GetNextNonCommentLine(sFileStream);
149 sscanf(sLine.c_str(), "%f", &fTemp);
150 aJointOffsets.at(2).push_back(fTemp);
151
152 // distance from second middle joint to fingertip
153 sLine = GetNextNonCommentLine(sFileStream);
154 sscanf(sLine.c_str(), "%f", &fTemp);
155 aJointOffsets.at(2).push_back(fTemp);
156
157
158 // offset from palm to ring base
159 sLine = GetNextNonCommentLine(sFileStream);
160 sscanf(sLine.c_str(), "%f %f %f", &vTemp.x, &vTemp.y, &vTemp.z);
161 m_aOffsetsToFingers.push_back(vTemp);
162
163 // distance from ring base joint to second joint
164 sLine = GetNextNonCommentLine(sFileStream);
165 sscanf(sLine.c_str(), "%f", &fTemp);
166 aJointOffsets.at(3).push_back(fTemp);
167
168 // distance from second ring joint to fingertip
169 sLine = GetNextNonCommentLine(sFileStream);
170 sscanf(sLine.c_str(), "%f", &fTemp);
171 aJointOffsets.at(3).push_back(fTemp);
172
173
174 // offset from palm to pinky base
175 sLine = GetNextNonCommentLine(sFileStream);
176 sscanf(sLine.c_str(), "%f %f %f", &vTemp.x, &vTemp.y, &vTemp.z);
177 m_aOffsetsToFingers.push_back(vTemp);
178
179 // distance from pinky base joint to second joint
180 sLine = GetNextNonCommentLine(sFileStream);
181 sscanf(sLine.c_str(), "%f", &fTemp);
182 aJointOffsets.at(4).push_back(fTemp);
183
184 // distance from second pinky joint to fingertip
185 sLine = GetNextNonCommentLine(sFileStream);
186 sscanf(sLine.c_str(), "%f", &fTemp);
187 aJointOffsets.at(4).push_back(fTemp);
188
189
190 // read fingertip points
191
192 int nNumFingertipPoints;
193 sLine = GetNextNonCommentLine(sFileStream);
194 sscanf(sLine.c_str(), "%d", &nNumFingertipPoints);
195
196 float fFingerTipOffsetZ;
197 sLine = GetNextNonCommentLine(sFileStream);
198 sscanf(sLine.c_str(), "%f", &fFingerTipOffsetZ);
199
200
201 std::vector<Vec3d> aFingertipPoints;
202 sLine = GetNextNonCommentLine(sFileStream);
203 for (int i = 0; i < nNumFingertipPoints; i++)
204 {
205 sscanf(sLine.c_str(), "%f %f %f", &vTemp.x, &vTemp.y, &vTemp.z);
206 vTemp.z += fFingerTipOffsetZ;
207 aFingertipPoints.push_back(vTemp);
208 std::getline(sFileStream, sLine);
209 }
210
211
212 // tracking ball
213 sLine = GetNextNonCommentLine(sFileStream);
214 sscanf(sLine.c_str(),
215 "%f %f %f",
219 sLine = GetNextNonCommentLine(sFileStream);
220 sscanf(sLine.c_str(), "%f", &m_fTrackingBallRadius);
221
222
223 //****************************************
224 // construct fingers
225 //****************************************
226
227 // thumb
228 std::vector<Vec3d> aFingertipPointsThumb;
229 aFingertipPointsThumb.resize(nNumFingertipPoints);
230 for (int i = 0; i < nNumFingertipPoints; i++)
231 {
232 Math3d::SetVec(aFingertipPointsThumb.at(i),
233 -aFingertipPoints.at(i).x,
234 aFingertipPoints.at(i).y,
235 aFingertipPoints.at(i).z);
236 }
237 CFinger* pNewFinger = new CFinger(aJointOffsets.at(0), aFingertipPointsThumb);
238 m_aFingers.push_back(pNewFinger);
239
240 // other fingers
241 for (int i = 1; i <= 4; i++)
242 {
243 pNewFinger = new CFinger(aJointOffsets.at(i), aFingertipPoints);
244 m_aFingers.push_back(pNewFinger);
245 }
246
247
248 //****************************************
249 // init variables
250 //****************************************
251
252 m_aFingerJointsInWorldCS.resize(5);
253 for (int i = 0; i < 5; i++)
254 {
255 m_aFingerJointsInWorldCS.at(i).resize(
256 m_aFingers.at(i)->m_aFingerJointsInFingerBaseCS.size());
257 for (size_t j = 0; j < m_aFingerJointsInWorldCS.at(i).size(); j++)
258 {
259 Math3d::SetVec(m_aFingerJointsInWorldCS.at(i).at(j), Math3d::zero_vec);
260 }
261 }
262
264 for (int i = 0; i < 5; i++)
265 {
266 m_aFingerTipCornersInWorldCS.at(i).resize(
267 m_aFingers.at(i)->m_aFingerTipCornersInFingerBaseCS.size());
268 for (size_t j = 0; j < m_aFingerTipCornersInWorldCS.at(i).size(); j++)
269 {
270 Math3d::SetVec(m_aFingerTipCornersInWorldCS.at(i).at(j), Math3d::zero_vec);
271 }
272 }
273
276
278 Math3d::SetVec(m_vHandPosition, Math3d::zero_vec);
279 Math3d::SetMat(m_mHandOrientation, Math3d::unit_mat);
280 }
281
282 std::string
283 CHandModelV2::GetNextNonCommentLine(std::ifstream& sFileStream)
284 {
285 std::string sLine;
286
287 do
288 {
289 std::getline(sFileStream, sLine);
290 } while (sLine.at(0) == '#');
291
292 return sLine;
293 }
294
295 void
296 CHandModelV2::UpdateHand(Vec3d vHandPosition,
297 Mat3d mHandOrientation,
298 float fPalmJointAngle,
299 std::vector<std::vector<float>>& aFingerJointAngles)
300 {
301 Math3d::SetVec(m_vHandPosition, vHandPosition);
302 Math3d::SetMat(m_mHandOrientation, mHandOrientation);
303
304 m_fPalmJointAngle = fPalmJointAngle;
305
306 for (size_t i = 0; i < m_aFingers.size(); i++)
307 {
308 m_aFingers.at(i)->UpdateJointAngles(aFingerJointAngles.at(i));
309 }
310
311 Vec3d vOffsetToFingerBaseRotated, vTemp;
312
313 // thumb
314 Math3d::MulMatVec(
315 m_mHandOrientation, m_aOffsetsToFingers.at(0), vOffsetToFingerBaseRotated);
316 for (size_t i = 0; i < m_aFingers.at(0)->m_aFingerJointsInFingerBaseCS.size(); i++)
317 {
318 Math3d::MulMatVec(m_mHandOrientation,
319 m_aFingers.at(0)->m_aFingerJointsInFingerBaseCS.at(i),
320 vOffsetToFingerBaseRotated,
321 vTemp);
322 Math3d::AddVecVec(vTemp, m_vHandPosition, m_aFingerJointsInWorldCS.at(0).at(i));
323 }
324 for (size_t i = 0; i < m_aFingers.at(0)->m_aFingerTipCornersInFingerBaseCS.size(); i++)
325 {
326 Math3d::MulMatVec(m_mHandOrientation,
327 m_aFingers.at(0)->m_aFingerTipCornersInFingerBaseCS.at(i),
328 vOffsetToFingerBaseRotated,
329 vTemp);
330 Math3d::AddVecVec(vTemp, m_vHandPosition, m_aFingerTipCornersInWorldCS.at(0).at(i));
331 }
332
333 // other fingers
334 Mat3d mPalmJointRotation, mAbsoluteRotationAfterPalmJoint;
335 Math3d::SetRotationMatY(mPalmJointRotation, m_fPalmJointAngle);
336 Math3d::MulMatMat(m_mHandOrientation, mPalmJointRotation, mAbsoluteRotationAfterPalmJoint);
337
338 for (int j = 1; j <= 4; j++)
339 {
340 Math3d::MulMatVec(mAbsoluteRotationAfterPalmJoint,
342 vOffsetToFingerBaseRotated);
343 for (size_t i = 0; i < m_aFingers.at(j)->m_aFingerJointsInFingerBaseCS.size(); i++)
344 {
345 Math3d::MulMatVec(mAbsoluteRotationAfterPalmJoint,
346 m_aFingers.at(j)->m_aFingerJointsInFingerBaseCS.at(i),
347 vOffsetToFingerBaseRotated,
348 vTemp);
349 Math3d::AddVecVec(vTemp, m_vHandPosition, m_aFingerJointsInWorldCS.at(j).at(i));
350 }
351
352 for (size_t i = 0; i < m_aFingers.at(j)->m_aFingerTipCornersInFingerBaseCS.size(); i++)
353 {
354 Math3d::MulMatVec(mAbsoluteRotationAfterPalmJoint,
355 m_aFingers.at(j)->m_aFingerTipCornersInFingerBaseCS.at(i),
356 vOffsetToFingerBaseRotated,
357 vTemp);
358 Math3d::AddVecVec(vTemp, m_vHandPosition, m_aFingerTipCornersInWorldCS.at(j).at(i));
359 }
360 }
361
362
363 // project the fingertips and calculate convex polygons
365
366
367 // tracking ball
368 Vec3d vTrackingBallPositionInWorldCS;
369 Math3d::MulMatVec(m_mHandOrientation,
372 vTrackingBallPositionInWorldCS);
373
374 m_pStereoCalibration->GetLeftCalibration()->WorldToImageCoordinates(
375 vTrackingBallPositionInWorldCS, m_vTrackingBallPosLeftCam, false);
376 float fFocalLengthLeft =
377 0.5f *
378 (m_pStereoCalibration->GetLeftCalibration()->GetCameraParameters().focalLength.x +
379 m_pStereoCalibration->GetLeftCalibration()->GetCameraParameters().focalLength.y);
381 fFocalLengthLeft * m_fTrackingBallRadius / vTrackingBallPositionInWorldCS.z;
382
383 m_pStereoCalibration->GetRightCalibration()->WorldToImageCoordinates(
384 vTrackingBallPositionInWorldCS, m_vTrackingBallPosRightCam, false);
385 float fFocalLengthRight =
386 0.5f *
387 (m_pStereoCalibration->GetRightCalibration()->GetCameraParameters().focalLength.x +
388 m_pStereoCalibration->GetRightCalibration()->GetCameraParameters().focalLength.y);
390 fFocalLengthRight * m_fTrackingBallRadius / vTrackingBallPositionInWorldCS.z;
391 }
392
393 void
395 {
396 Vec3d vHandPosition = {(float)pConfig[0], (float)pConfig[1], (float)pConfig[2]};
397 Mat3d mHandOrientation;
398 Math3d::SetRotationMat(mHandOrientation, pConfig[3], pConfig[4], pConfig[5]);
399
400 float fPalmJointAngle = -pConfig[6];
401
402 std::vector<std::vector<float>> aFingerJointAngles;
403 aFingerJointAngles.resize(5);
404 aFingerJointAngles.at(0).push_back(pConfig[7]);
405 aFingerJointAngles.at(0).push_back(pConfig[8]);
406 aFingerJointAngles.at(1).push_back(-pConfig[9]);
407 aFingerJointAngles.at(1).push_back(-pConfig[9]);
408 aFingerJointAngles.at(2).push_back(-pConfig[10]);
409 aFingerJointAngles.at(2).push_back(-pConfig[10]);
410 aFingerJointAngles.at(3).push_back(-pConfig[11]);
411 aFingerJointAngles.at(3).push_back(-pConfig[11]);
412 aFingerJointAngles.at(4).push_back(-pConfig[11]);
413 aFingerJointAngles.at(4).push_back(-pConfig[11]);
414
415 UpdateHand(vHandPosition, mHandOrientation, fPalmJointAngle, aFingerJointAngles);
416 }
417
418 void
420 {
421 Vec2d vPos2D;
422
423 Vec3d* pBuffer1 = new Vec3d[DSHT_MAX_POLYGON_CORNERS + 1];
424 Vec3d* pBuffer2 = new Vec3d[DSHT_MAX_POLYGON_CORNERS + 1];
425
426 for (int i = 0; i < DSHT_NUM_FINGERS; i++)
427 {
428 Math3d::SetVec(m_aFingerTipPolygonsLeftCam.at(i).center3d, Math3d::zero_vec);
429 Math3d::SetVec(m_aFingerTipPolygonsRightCam.at(i).center3d, Math3d::zero_vec);
430
431 for (size_t j = 0; j < m_aFingerTipCornersInWorldCS.at(i).size(); j++)
432 {
433 Vec3d& vPoint = m_aFingerTipCornersInWorldCS.at(i).at(j);
434 m_pStereoCalibration->GetLeftCalibration()->WorldToImageCoordinates(
435 vPoint, vPos2D, false);
436 m_aFingerTipPolygonsLeftCam.at(i).hull[j].x = vPos2D.x;
437 m_aFingerTipPolygonsLeftCam.at(i).hull[j].y = vPos2D.y;
438 Math3d::AddToVec(vPoint, m_aFingerTipPolygonsLeftCam.at(i).center3d);
439 m_pStereoCalibration->GetRightCalibration()->WorldToImageCoordinates(
440 vPoint, vPos2D, false);
441 m_aFingerTipPolygonsRightCam.at(i).hull[j].x = vPos2D.x;
442 m_aFingerTipPolygonsRightCam.at(i).hull[j].y = vPos2D.y;
443 Math3d::AddToVec(vPoint, m_aFingerTipPolygonsRightCam.at(i).center3d);
444 }
445
446 Math3d::MulVecScalar(m_aFingerTipPolygonsLeftCam.at(i).center3d,
447 1.0f / m_aFingerTipCornersInWorldCS.at(i).size(),
448 m_aFingerTipPolygonsLeftCam.at(i).center3d);
449 Math3d::MulVecScalar(m_aFingerTipPolygonsRightCam.at(i).center3d,
450 1.0f / m_aFingerTipCornersInWorldCS.at(i).size(),
451 m_aFingerTipPolygonsRightCam.at(i).center3d);
452
453 m_aFingerTipPolygonsLeftCam.at(i).nCorners = m_aFingerTipCornersInWorldCS.at(i).size();
455 &m_aFingerTipPolygonsLeftCam.at(i), pBuffer1, pBuffer2);
458 &m_aFingerTipPolygonsRightCam.at(i), pBuffer1, pBuffer2);
459 }
460
461 delete[] pBuffer1;
462 delete[] pBuffer2;
463 }
464} // namespace visionx
#define float
Definition 16_Level.h:22
#define DSHT_MAX_POLYGON_CORNERS
#define DSHT_NUM_FINGERS
std::vector< Vec3d > m_aFingerJointsInFingerBaseCS
Definition HandModelV2.h:49
std::vector< Vec3d > m_aFingerTipCornersInFingerBaseCS
Definition HandModelV2.h:47
CFinger(std::vector< float > aJointOffsets, std::vector< Vec3d > aFingerTipCorners)
void UpdateJointAngles(std::vector< float > aNewJointValues)
std::vector< ConvexPolygonCalculations::Polygon > m_aFingerTipPolygonsRightCam
Definition HandModelV2.h:77
virtual void UpdateHand(double *pConfig)
std::string GetNextNonCommentLine(std::ifstream &sFileStream)
CStereoCalibration * m_pStereoCalibration
Definition HandModelV2.h:91
std::vector< std::vector< Vec3d > > m_aFingerTipCornersInWorldCS
Definition HandModelV2.h:71
std::vector< ConvexPolygonCalculations::Polygon > m_aFingerTipPolygonsLeftCam
Definition HandModelV2.h:76
std::vector< std::vector< Vec3d > > m_aFingerJointsInWorldCS
Definition HandModelV2.h:70
std::vector< CFinger * > m_aFingers
Definition HandModelV2.h:93
float m_fTrackingBallRadiusRightCam
Definition HandModelV2.h:80
std::vector< Vec3d > m_aOffsetsToFingers
Definition HandModelV2.h:95
float m_fTrackingBallRadiusLeftCam
Definition HandModelV2.h:80
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
void CalcConvexHull(Vec3d *in, int num_all_points, Vec3d *hull_left, int *num_hull_points_left, Vec3d *hull_right, int *num_hull_points_right, Vec3d *temp1, Vec3d *temp2)
Definition Polygon.cpp:122
ArmarX headers.