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
26
29#include "Helpers/helpers.h"
30
31// Eigen
32#include <Eigen/Core>
33
34// IVT
35#include <Calibration/StereoCalibration.h>
36#include <Image/ImageProcessor.h>
37#include <Math/Math3d.h>
38
39// Core
41
42// VisionX
45
46
47using namespace armarx;
48
49namespace visionx
50{
51 void
53 {
54 // set desired image provider
55 providerName = getProperty<std::string>("ImageProviderAdapterName").getValue();
56 usingImageProvider(providerName);
57
58 robotStateProxyName = getProperty<std::string>("RobotStateProxyName").getValue();
59 usingProxy(robotStateProxyName);
60
61 handFrameName = getProperty<std::string>("HandFrameName").getValue();
62 cameraFrameName = getProperty<std::string>("CameraFrameName").getValue();
63 }
64
65 void
67 {
68 // connect to image provider
69 ARMARX_INFO << getName() << " connecting to " << providerName << armarx::flush;
70 visionx::ImageProviderInfo imageProviderInfo = getImageProvider(providerName);
71 imageProviderPrx = getProxy<ImageProviderInterfacePrx>(providerName);
72 imageFormat = imageProviderInfo.imageFormat;
73
74 cameraImages = new CByteImage*[2];
75 cameraImages[0] = tools::createByteImage(imageProviderInfo);
76 cameraImages[1] = tools::createByteImage(imageProviderInfo);
77
78 resultImages = new CByteImage*[numResultImages];
79
80 for (int i = 0; i < numResultImages; i++)
81 {
82 resultImages[i] = tools::createByteImage(imageProviderInfo);
83 }
84
85 // retrieve stereo information
86 StereoCalibrationProviderInterfacePrx calibrationProviderPrx =
87 StereoCalibrationProviderInterfacePrx::checkedCast(imageProviderPrx);
88
89 if (!calibrationProviderPrx)
90 {
91 ARMARX_ERROR << "Image provider with name " << providerName
92 << " is not a StereoCalibrationProvider" << std::endl;
93 return;
94 }
95
96 stereoCalibration = visionx::tools::convert(calibrationProviderPrx->getStereoCalibration());
97
98
99 // connect to robot state proxy
100 ARMARX_INFO << getName() << " connecting to " << robotStateProxyName << armarx::flush;
101 robotStateProxy = getProxy<RobotStateComponentInterfacePrx>(robotStateProxyName);
102
103 this->enableResultImages(numResultImages, imageFormat.dimension, imageFormat.type);
104
105 // construct hand localizer
106 handLocalization =
107 new CHandLocalisation(600, 2, 2, stereoCalibration, DSHT_HAND_MODEL_PATH); //6000, 2, 2
108 handModelVisualizer = new CHandModelVisualizer(stereoCalibration);
109 }
110
111 void
113 {
114 if (!waitForImages(8000))
115 {
116 ARMARX_WARNING << "Timeout or error in wait for images" << armarx::flush;
117 }
118 else
119 {
120 // get images
121 int nNumberImages = getImages(cameraImages);
122 ARMARX_VERBOSE << getName() << " got " << nNumberImages << " images";
123
124 // get hand pose from robot state
125 armarx::PosePtr handNodePosePtr =
126 armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()
127 ->getRobotNode(handFrameName)
128 ->getPoseInRootFrame());
129 Eigen::Matrix4f handNodePose = handNodePosePtr->toEigen();
130 armarx::PosePtr cameraNodePosePtr =
131 armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()
132 ->getRobotNode(cameraFrameName)
133 ->getPoseInRootFrame());
134 Eigen::Matrix4f cameraNodePose = cameraNodePosePtr->toEigen();
135 Eigen::Matrix4f handPoseInCameraFrame = cameraNodePose.inverse() * handNodePose;
136 Vec3d handNodePosition = {handPoseInCameraFrame(0, 3),
137 handPoseInCameraFrame(1, 3),
138 handPoseInCameraFrame(2, 3)};
139 Mat3d handNodeOrientation = {handPoseInCameraFrame(0, 0),
140 handPoseInCameraFrame(0, 1),
141 handPoseInCameraFrame(0, 2),
142 handPoseInCameraFrame(1, 0),
143 handPoseInCameraFrame(1, 1),
144 handPoseInCameraFrame(1, 2),
145 handPoseInCameraFrame(2, 0),
146 handPoseInCameraFrame(2, 1),
147 handPoseInCameraFrame(2, 2)};
148
149
150 // TODO: get finger config
151 double* fingerConfig = new double[6];
152 fingerConfig[0] = 90 * M_PI / 180; //100 // palm
153 fingerConfig[1] = 25 * M_PI / 180; // thumb1
154 fingerConfig[2] = 15 * M_PI / 180; // thumb2
155 fingerConfig[3] = 10 * M_PI / 180; // index
156 fingerConfig[4] = 5 * M_PI / 180; // middle
157 fingerConfig[5] = 5 * M_PI / 180; // ring+pinky
158
159
160 // localize hand
161 double* estimatedConfig = new double[12];
162 double confidenceRating;
163 handLocalization->LocaliseHand(cameraImages[0],
164 cameraImages[1],
165 handNodePosition,
166 handNodeOrientation,
167 fingerConfig,
168 estimatedConfig,
169 confidenceRating);
170
171 // draw result images
172 ::ImageProcessor::CopyImage(cameraImages[0], resultImages[0]);
173 ::ImageProcessor::CopyImage(cameraImages[0], resultImages[1]);
174 ::ImageProcessor::CopyImage(cameraImages[0], resultImages[2]);
175 ::ImageProcessor::Zero(resultImages[3]);
176
177 double* localizationResult = handLocalization->GetResultConfig();
178 handModelVisualizer->UpdateHandModel(localizationResult,
179 drawComplexHandModelInResultImage);
180 delete[] localizationResult;
181 handModelVisualizer->DrawHandModelV2(resultImages[1]);
182 handModelVisualizer->DrawHand(resultImages[2]);
183 handModelVisualizer->DrawSegmentedImage(resultImages[3]);
184 provideResultImages(resultImages);
185 }
186 }
187
188 void
190 {
191 delete[] cameraImages;
192 }
193
194 armarx::FramedPoseBasePtr
196 {
197 Eigen::Matrix4f handPose = handLocalization->GetHandPose();
199 handPose, cameraFrameName, robotStateProxy->getSynchronizedRobot()->getName());
200 return ret;
201 }
202
203 visionx::FramedPositionBaseList
205 {
206 visionx::FramedPositionBaseList ret;
207 std::vector<Vec3d> fingertipPositions = handLocalization->GetFingertipPositions();
208
209 for (size_t i = 0; i < fingertipPositions.size(); i++)
210 {
211 Eigen::Vector3f position;
212 position << fingertipPositions.at(i).x, fingertipPositions.at(i).y,
213 fingertipPositions.at(i).z;
215 position, cameraFrameName, robotStateProxy->getSynchronizedRobot()->getName());
216 ret.push_back(pos);
217 }
218
219 return ret;
220 }
221
223
224} // namespace visionx
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
Definition Decoupled.h:29
#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.
RobotHandLocalizationWithFingertips localizes the robot hand using the marker ball and the finger tip...
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.