RobotHandLocalizationWithFingertips.cpp
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* ArmarX is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License version 2 as
6* published by the Free Software Foundation.
7*
8* ArmarX is distributed in the hope that it will be useful, but
9* WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program. If not, see <http://www.gnu.org/licenses/>.
15*
16* @package VisionX::Component
17* @author Kai Welke <kai dot welke at kit dot edu>
18* @copyright 2011 Humanoids Group, HIS, KIT
19* @license http://www.gnu.org/licenses/gpl-2.0.txt
20* GNU General Public License
21*/
22
24
27#include "Helpers/helpers.h"
28
29// Eigen
30#include <Eigen/Core>
31
32// IVT
33#include <Calibration/StereoCalibration.h>
34#include <Image/ImageProcessor.h>
35#include <Math/Math3d.h>
36
37// Core
39
40// VisionX
43
44
45using namespace armarx;
46
47namespace visionx
48{
49 void
51 {
52 // set desired image provider
53 providerName = getProperty<std::string>("ImageProviderAdapterName").getValue();
54 usingImageProvider(providerName);
55
56 robotStateProxyName = getProperty<std::string>("RobotStateProxyName").getValue();
57 usingProxy(robotStateProxyName);
58
59 handFrameName = getProperty<std::string>("HandFrameName").getValue();
60 cameraFrameName = getProperty<std::string>("CameraFrameName").getValue();
61 }
62
63 void
65 {
66 // connect to image provider
67 ARMARX_INFO << getName() << " connecting to " << providerName << armarx::flush;
68 visionx::ImageProviderInfo imageProviderInfo = getImageProvider(providerName);
69 imageProviderPrx = getProxy<ImageProviderInterfacePrx>(providerName);
70 imageFormat = imageProviderInfo.imageFormat;
71
72 cameraImages = new CByteImage*[2];
73 cameraImages[0] = tools::createByteImage(imageProviderInfo);
74 cameraImages[1] = tools::createByteImage(imageProviderInfo);
75
76 resultImages = new CByteImage*[numResultImages];
77
78 for (int i = 0; i < numResultImages; i++)
79 {
80 resultImages[i] = tools::createByteImage(imageProviderInfo);
81 }
82
83 // retrieve stereo information
84 StereoCalibrationProviderInterfacePrx calibrationProviderPrx =
85 StereoCalibrationProviderInterfacePrx::checkedCast(imageProviderPrx);
86
87 if (!calibrationProviderPrx)
88 {
89 ARMARX_ERROR << "Image provider with name " << providerName
90 << " is not a StereoCalibrationProvider" << std::endl;
91 return;
92 }
93
94 stereoCalibration = visionx::tools::convert(calibrationProviderPrx->getStereoCalibration());
95
96
97 // connect to robot state proxy
98 ARMARX_INFO << getName() << " connecting to " << robotStateProxyName << armarx::flush;
99 robotStateProxy = getProxy<RobotStateComponentInterfacePrx>(robotStateProxyName);
100
101 this->enableResultImages(numResultImages, imageFormat.dimension, imageFormat.type);
102
103 // construct hand localizer
104 handLocalization =
105 new CHandLocalisation(600, 2, 2, stereoCalibration, DSHT_HAND_MODEL_PATH); //6000, 2, 2
106 handModelVisualizer = new CHandModelVisualizer(stereoCalibration);
107 }
108
109 void
111 {
112 if (!waitForImages(8000))
113 {
114 ARMARX_WARNING << "Timeout or error in wait for images" << armarx::flush;
115 }
116 else
117 {
118 // get images
119 int nNumberImages = getImages(cameraImages);
120 ARMARX_VERBOSE << getName() << " got " << nNumberImages << " images";
121
122 // get hand pose from robot state
123 armarx::PosePtr handNodePosePtr =
124 armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()
125 ->getRobotNode(handFrameName)
126 ->getPoseInRootFrame());
127 Eigen::Matrix4f handNodePose = handNodePosePtr->toEigen();
128 armarx::PosePtr cameraNodePosePtr =
129 armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()
130 ->getRobotNode(cameraFrameName)
131 ->getPoseInRootFrame());
132 Eigen::Matrix4f cameraNodePose = cameraNodePosePtr->toEigen();
133 Eigen::Matrix4f handPoseInCameraFrame = cameraNodePose.inverse() * handNodePose;
134 Vec3d handNodePosition = {handPoseInCameraFrame(0, 3),
135 handPoseInCameraFrame(1, 3),
136 handPoseInCameraFrame(2, 3)};
137 Mat3d handNodeOrientation = {handPoseInCameraFrame(0, 0),
138 handPoseInCameraFrame(0, 1),
139 handPoseInCameraFrame(0, 2),
140 handPoseInCameraFrame(1, 0),
141 handPoseInCameraFrame(1, 1),
142 handPoseInCameraFrame(1, 2),
143 handPoseInCameraFrame(2, 0),
144 handPoseInCameraFrame(2, 1),
145 handPoseInCameraFrame(2, 2)};
146
147
148 // TODO: get finger config
149 double* fingerConfig = new double[6];
150 fingerConfig[0] = 90 * M_PI / 180; //100 // palm
151 fingerConfig[1] = 25 * M_PI / 180; // thumb1
152 fingerConfig[2] = 15 * M_PI / 180; // thumb2
153 fingerConfig[3] = 10 * M_PI / 180; // index
154 fingerConfig[4] = 5 * M_PI / 180; // middle
155 fingerConfig[5] = 5 * M_PI / 180; // ring+pinky
156
157
158 // localize hand
159 double* estimatedConfig = new double[12];
160 double confidenceRating;
161 handLocalization->LocaliseHand(cameraImages[0],
162 cameraImages[1],
163 handNodePosition,
164 handNodeOrientation,
165 fingerConfig,
166 estimatedConfig,
167 confidenceRating);
168
169 // draw result images
170 ::ImageProcessor::CopyImage(cameraImages[0], resultImages[0]);
171 ::ImageProcessor::CopyImage(cameraImages[0], resultImages[1]);
172 ::ImageProcessor::CopyImage(cameraImages[0], resultImages[2]);
173 ::ImageProcessor::Zero(resultImages[3]);
174
175 double* localizationResult = handLocalization->GetResultConfig();
176 handModelVisualizer->UpdateHandModel(localizationResult,
177 drawComplexHandModelInResultImage);
178 delete[] localizationResult;
179 handModelVisualizer->DrawHandModelV2(resultImages[1]);
180 handModelVisualizer->DrawHand(resultImages[2]);
181 handModelVisualizer->DrawSegmentedImage(resultImages[3]);
182 provideResultImages(resultImages);
183 }
184 }
185
186 void
188 {
189 delete[] cameraImages;
190 }
191
192 armarx::FramedPoseBasePtr
194 {
195 Eigen::Matrix4f handPose = handLocalization->GetHandPose();
197 handPose, cameraFrameName, robotStateProxy->getSynchronizedRobot()->getName());
198 return ret;
199 }
200
201 visionx::FramedPositionBaseList
203 {
204 visionx::FramedPositionBaseList ret;
205 std::vector<Vec3d> fingertipPositions = handLocalization->GetFingertipPositions();
206
207 for (size_t i = 0; i < fingertipPositions.size(); i++)
208 {
209 Eigen::Vector3f position;
210 position << fingertipPositions.at(i).x, fingertipPositions.at(i).y,
211 fingertipPositions.at(i).z;
213 position, cameraFrameName, robotStateProxy->getSynchronizedRobot()->getName());
214 ret.push_back(pos);
215 }
216
217 return ret;
218 }
219
220} // namespace visionx
#define DSHT_HAND_MODEL_PATH
#define M_PI
Definition MathTools.h:17
constexpr T c
Property< PropertyType > getProperty(const std::string &name)
The FramedPose class.
Definition FramedPose.h:281
The FramedPosition class.
Definition FramedPose.h:158
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
std::string getName() const
Retrieve name of object.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
void enableResultImages(int numberImages, ImageDimension imageDimension, ImageType imageType, const std::string &name="")
Enables visualization.
void usingImageProvider(std::string name)
Registers a delayed topic subscription and a delayed provider proxy retrieval which all will be avail...
bool waitForImages(int milliseconds=1000)
Wait for new images.
ImageProviderInfo getImageProvider(std::string name, ImageType destinationImageType=eRgb, bool waitForProxy=false)
Select an ImageProvider.
int getImages(CByteImage **ppImages)
Poll images from provider.
void provideResultImages(CByteImage **images, armarx::MetaInfoSizeBasePtr info=nullptr)
sends result images for visualization
ImageFormatInfo imageFormat
Image format struct that contains all necessary image information.
void onConnectImageProcessor() override
Implement this method in the ImageProcessor in order execute parts when the component is fully initia...
void onExitImageProcessor() override
Exit the ImapeProcessor component.
armarx::FramedPoseBasePtr getHandPose(const Ice::Current &c=Ice::emptyCurrent) override
Returns the hand pose.
visionx::FramedPositionBaseList getFingertipPositions(const Ice::Current &c=Ice::emptyCurrent) override
Returns the positions of the fingertips in this order: thumb, index, middle, ring,...
void onInitImageProcessor() override
Setup the vision component.
#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
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< Pose > PosePtr
Definition Pose.h:306
IceInternal::Handle< FramedPosition > FramedPositionPtr
Definition FramedPose.h:149
const LogSender::manipulator flush
Definition LogSender.h:251
IceInternal::Handle< FramedPose > FramedPosePtr
Definition FramedPose.h:272
CByteImage * createByteImage(const ImageFormatInfo &imageFormat, const ImageType imageType)
Creates a ByteImage for the destination type specified in the given imageProviderInfo.
CByteImage::ImageType convert(const ImageType visionxImageType)
Converts a VisionX image type into an image type of IVT's ByteImage.
ArmarX headers.