VisualContactDetection.h
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 VisionX::Component
19 * @author David Schiebener (schiebener at kit dot edu)
20 * @date 2011
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25
26#pragma once
27
28#include <map>
29#include <set>
30#include <string>
31
32// VisionX
34#include <VisionX/interface/components/HandLocalization.h>
35#include <VisionX/interface/components/VisualContactDetection.h>
36
37
38// Core
41
43
44// MemoryX
45#include <MemoryX/interface/observers/ObjectMemoryObserverInterface.h>
46
47// IVT
48#include <Image/IplImageAdaptor.h>
49#include <Math/Math2d.h>
50#include <Math/Math3d.h>
51
52// OpenCV
53//#include <highgui.h>
54#include <opencv2/highgui/highgui.hpp>
55//#include <OpenCVLegacy.h>
56
57class CStereoCalibration;
58class CByteImage;
59
60namespace visionx
61{
62 // forward declarations
65
68 {
69 public:
72 {
73 defineOptionalProperty<std::string>("ImageProviderAdapterName",
74 "Armar3ImageProvider",
75 "Ice Adapter name of the image provider");
76 defineOptionalProperty<std::string>("RobotStateProxyName",
77 "RobotStateComponent",
78 "Ice Adapter name of the robot state proxy");
80 "HandFrameName",
81 "TCP R",
82 "Name of the robot state frame of the hand that will be localized");
84 "CameraFrameName",
85 "EyeLeftCamera",
86 "Name of the robot state frame of the primary camera");
88 "NumberOfParticles",
89 1500,
90 "Number of particles for the particle filter for hand localization");
91 defineOptionalProperty<std::string>("ObjectMemoryObserverName",
92 "ObjectMemoryObserver",
93 "Name of the object memory observer proxy");
95 "HandNameInMemoryX", "handright3b", "Name of the hand in the object memory");
96 defineOptionalProperty<int>("MinNumPixelsInClusterForCollisionDetection",
97 3000,
98 "Minimal number of pixels that a motion cluster must "
99 "contain to be considered in collision detection");
101 "UseHandLocalization",
102 true,
103 "Switch on or off whether the hand should be localized with the particle filter. "
104 "If it is switched off, the hand pose from MemoryX is used (if available, "
105 "otherwise just from the kinematic model).");
107 "MinWaitingTimeBetweenTwoFrames",
108 300,
109 "Minimal time to wait between two frames so that enough motion happens (in ms)");
110 }
111 };
112
113 /**
114 * VisualContactDetection determines if the robot hand is colliding with another object, causing it to move.
115 * To this end, it localizes the robot hand using the marker ball and the finger tips, calculates the optical
116 * flow in the image, clusters it, and looks for a cluster that exist solely in front of the hand.
117 *
118 * \componentproperties
119 * \prop VisionX.VisualContactDetection.ImageProviderAdapterName: Name of the
120 * image provider that delivers the camera images.
121 * \prop VisionX.VisualContactDetection.RobotStateProxyName: Name of the robot state
122 * proxy used to obtain the current robot state.
123 * \prop VisionX.VisualContactDetection.HandFrameName: Name of the frame in the robot
124 * model that corresponds to the localized hand.
125 * \prop VisionX.VisualContactDetection.CameraFrameName: Name of the robot state frame of the primary camera
126 */
128 virtual public visionx::ImageProcessor,
129 virtual public visionx::VisualContactDetectionInterface
130 {
131 public:
132 /**
133 * @see Component::getDefaultName()
134 */
135 std::string
136 getDefaultName() const override
137 {
138 return "VisualContactDetection";
139 }
140
141 /**
142 * Returns the hand pose.
143 */
144 armarx::FramedPoseBasePtr getHandPose(const Ice::Current& c = Ice::emptyCurrent) override;
145
146 /**
147 * Returns the positions of the fingertips in this order: thumb, index, middle, ring, pinky.
148 */
149 visionx::FramedPositionBaseList
150 getFingertipPositions(const Ice::Current& c = Ice::emptyCurrent)
151 override; // ordering: thumb, index, middle, ring, pinky
152
153 void activate(const Ice::Current& c = Ice::emptyCurrent) override;
154 void deactivate(const Ice::Current& c = Ice::emptyCurrent) override;
155
156
157 protected:
158 // inherited from VisionComponent
159 void onInitImageProcessor() override;
160 void onConnectImageProcessor() override;
161 void onExitImageProcessor() override;
162
163 void process() override;
164
165 /**
166 * @see PropertyUser::createPropertyDefinitions()
167 */
174
175 private:
176 std::string providerName;
177 ImageProviderInterfacePrx imageProviderPrx;
178 std::string robotStateProxyName;
180 std::string handFrameName, cameraFrameName;
181 memoryx::ObjectMemoryObserverInterfacePrx objectMemoryObserver;
182 std::string handNameInMemoryX;
183 armarx::ChannelRefPtr handMemoryChannel;
184 bool useHandLocalization;
185 bool active;
186 std::mutex activationStateMutex;
187 IceUtil::Time timeOfLastExecution;
188
189 CStereoCalibration* stereoCalibration;
190 CByteImage** cameraImages;
191 CByteImage** resultImages;
192
193 void localizeHand();
194 CHandLocalisation* handLocalization;
195 CHandModelVisualizer *handModelVisualizer, *handModelVisualizer1, *handModelVisualizer2,
196 *handModelVisualizer3;
197 static const bool drawComplexHandModelInResultImage = false;
198
199 void calculateOpticalFlowClusters();
200 IplImage *pCamLeftIpl, *pCamLeftOldIpl;
201 CByteImage *camImgLeftGrey, *camImgLeftGreySmall, *camImgLeftGreyOld,
202 *camImgLeftGreyOldSmall, *tempImageRGB, *pSegmentedImage, *pOpticalFlowClusterImage;
203 bool firstRun;
204 Vec3d oldHandPosSensor;
205 std::vector<std::vector<std::vector<float>>> opticalFlowClusters;
206 float* pVisOptFlowRaw;
207 int* colors;
208 static const int imageResizeFactorForOpticalFlowCalculation = 4;
209 static const int maxNumOptFlowClusters = 5;
210 int minNumPixelsInClusterForCollisionDetection;
211 static const int clusteringSampleStep = 1;
212 static constexpr float pushDetectionBoxForwardOffsetToTCP = 150.0f;
213 float oldCollisionProbability;
214
215 bool detectCollision();
216 Vec2d handPos2D, pushTarget2D, pushTargetBoxLeftUpperCorner, pushTargetBoxRightLowerCorner;
217
218 void drawVisualization(bool collisionDetected);
219 CByteImage *tempImageRGB1, *tempImageRGB2, *tempImageRGB3, *tempImageRGB4;
220
221 static const bool recordImages = true;
222 int visualizationImageNumber;
223 std::vector<CByteImage*> cameraImagesForSaving, localizationResultImages, opticalFlowImages,
224 opticalFlowClusterImages;
225 std::vector<long> timesOfImageCapture;
226
227 static void extractAnglesFromRotationMatrix(const Mat3d& mat, Vec3d& angles);
228 static IplImage* convertToIplImage(CByteImage* pByteImageRGB);
229 static void clusterXMeans(const std::vector<std::vector<float>>& aPoints,
230 const int nMinNumClusters,
231 const int nMaxNumClusters,
232 const float fBICFactor,
233 std::vector<std::vector<std::vector<float>>>& aaPointClusters,
234 std::vector<std::vector<int>>& aaOldIndices);
235
236 void SetNumberInFileName(std::string& sFileName, int nNumber, int nNumDigits = 4);
237
238 VisualContactDetectionListenerPrx listener;
239
240 enum EResultImageIndices
241 {
242 eEverything,
243 //eCameraImage,
244 //ePoseFromKinematik,
245 //ePoseFromLocalization,
246 //ePoseFromLocalizationOI,
247 //eSegmentedImage,
248 //eOpticalFlow,
249 //eOpticalFlowClusters,
250 eNumberOfResultImages
251 };
252 };
253
254} // namespace visionx
constexpr T c
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
PropertyDefinition< PropertyType > & defineOptionalProperty(const std::string &name, PropertyType defaultValue, const std::string &description="", PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
ImageProcessorPropertyDefinitions(std::string prefix)
The ImageProcessor class provides an interface for access to ImageProviders via Ice and shared memory...
VisualContactDetection determines if the robot hand is colliding with another object,...
void deactivate(const Ice::Current &c=Ice::emptyCurrent) override
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,...
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void process() override
Process the vision component.
void onInitImageProcessor() override
Setup the vision component.
void activate(const Ice::Current &c=Ice::emptyCurrent) override
std::string getDefaultName() const override
IceInternal::Handle< ChannelRef > ChannelRefPtr
Definition ChannelRef.h:40
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
::IceInternal::ProxyHandle<::IceProxy::armarx::RobotStateComponentInterface > RobotStateComponentInterfacePrx
ArmarX headers.