5 #include <opencv2/opencv.hpp>
7 #include <vision_module/Tools/Parameters.hpp>
8 #include <vision_module/Tools/General.hpp>
9 #include <vision_module/Tools/SortFuntions.hpp>
10 #include <vision_module/Tools/LinearBoundaryChecker.hpp>
11 #include <vision_module/Tools/LineSegment.hpp>
12 #include <vision_module/Projections/CameraProjections.hpp>
13 #include <vision_module/Tools/Kalman.hpp>
14 #include <vision_module/SoccerObjects/ObstacleDetector.hpp>
15 #include <gait_msgs/GaitOdom.h>
16 #include <boost/timer/timer.hpp>
18 #include <field_model/field_model.h>
19 #include <tf/transform_broadcaster.h>
22 #include <Eigen/StdVector>
23 #include <g2o/core/sparse_optimizer.h>
24 #include <g2o/core/block_solver.h>
25 #include <g2o/core/hyper_graph.h>
26 #include <g2o/core/solver.h>
27 #include <g2o/core/factory.h>
28 #include <g2o/core/robust_kernel_impl.h>
29 #include <g2o/core/optimization_algorithm_levenberg.h>
30 #include <g2o/solvers/cholmod/linear_solver_cholmod.h>
31 #include <g2o/solvers/dense/linear_solver_dense.h>
32 #include <g2o/types/sba/types_six_dof_expmap.h>
33 #include <g2o/solvers/structure_only/structure_only_solver.h>
34 #include <g2o/solvers/csparse/linear_solver_csparse.h>
35 #include <g2o/types/slam3d/vertex_se3.h>
36 #include <g2o/types/slam2d/edge_se2.h>
37 #include <g2o/types/slam2d/vertex_se2.h>
40 using namespace Eigen;
61 CenterL = 0, RightL, FrontL, LeftL, BackL
64 const std::string LineTypeName[LTRES] =
65 {
"HorUndef",
"HorCenter",
"HorGoal",
"HorGoalNear",
"VerUndef",
"VerLeft",
66 "VerRight",
"VerLeftNear",
"VerRightNear",
"VerLeftT",
"VerRightT" };
70 inline LineContainer(
LineSegment _lineTransformed, LineType _type) :
71 lineTransformed(_lineTransformed), type(_type)
79 class FeatureContainer
82 inline FeatureContainer(Point2f _position,
string _type) :
83 position(_position), type(_type)
98 inline double getUpdateCoef(
double coef, cv::Point2f point)
100 double distance = GetDistance(point);
107 return coef * (1 - (distance / 8));
110 inline double getUpdateCoef(
double coef,
LineSegment line)
112 return getUpdateCoef(coef,
113 line.GetClosestPointOnLineSegment(cv::Point2d(0, 0)))
114 * line.getProbability();
117 ros::NodeHandle nodeHandle;
118 ros::Subscriber setLoc_sub;
119 ros::Subscriber robotTracker_sub;
120 ros::Subscriber robotTracker2_sub;
121 ros::Subscriber odom_sub;
123 Point2d locationKalman;
126 geometry_msgs::Point robotTrackerLoc;
127 float lastOdomX, lastOdomY;
134 tf::TransformBroadcaster tfBroadcaster;
135 tf::StampedTransform tfLocField;
136 vector<ObstacleC> *obstacles;
137 BlockSolverX::LinearSolverType * linearSolver;
138 BlockSolverX* blockSolver;
139 OptimizationAlgorithmLevenberg* optimizationAlgorithm;
141 int PreviousVertexId;
144 bool atLeastOneObservation;
145 ros::Time lastSavedNodeTime;
146 long unsigned int nodeCounter;
148 SparseOptimizer optimizer;
153 delete optimizationAlgorithm;
157 location(-1.42, 0), locationKalman(location), kalmanI(
158 locationKalman), _cameraProjections(
159 NULL), lastOdomX(0), lastOdomY(0), globalPos(0, 0, 0), lastOdom(0,
160 0, 0), lastOdomID(0), ballPos(0, 0), m_field(
161 field_model::FieldModel::getInstance()), obstacles(
162 obstacles), CurrentVertexId(0), PreviousVertexId(0), LandmarkCount(
163 0), odomLastGet(0, 0), atLeastOneObservation(
false), nodeCounter(
167 odom_sub = nodeHandle.subscribe(
"/gait/odometry", 10,
168 &Localization::dead_reckoning_callback,
this);
169 setLoc_sub = nodeHandle.subscribe<geometry_msgs::Point>(
170 "/vision/setLocation", 1, &Localization::setloc_callback,
this);
172 A = m_field->length();
173 B = m_field->width();
174 E = m_field->goalAreaDepth();
175 F = m_field->goalAreaWidth();
176 G = m_field->penaltyMarkerDist();
177 H = m_field->centerCircleDiameter();
178 D = m_field->goalWidth();
179 I = m_field->boundary();
180 params.ball->radius.set(m_field->ballDiameter() / 2.);
194 tfLocField.frame_id_ =
"/ego_floor";
195 tfLocField.child_frame_id_ =
"/loc_field";
196 tfLocField.setIdentity();
198 lastSavedNodeTime = ros::Time::now();
200 linearSolver =
new LinearSolverCSparse<BlockSolverX::PoseMatrixType>();
202 blockSolver =
new BlockSolverX(linearSolver);
204 optimizationAlgorithm =
new OptimizationAlgorithmLevenberg(blockSolver);
207 inline Point2d getOdometryFromLastGet()
209 if (PreviousVertexId > 0)
211 Point2d res = odomLastGet;
212 odomLastGet.x = odomLastGet.y = 0;
216 return Point2d(0, 0);
219 inline void updateVertexIdx()
221 if ((ros::Time::now() - lastSavedNodeTime).toSec() >= 0.03)
224 lastSavedNodeTime = ros::Time::now();
225 PreviousVertexId = CurrentVertexId;
227 if (CurrentVertexId - LandmarkCount >= 100)
229 CurrentVertexId = LandmarkCount;
233 VertexSE2 * r =
new VertexSE2;
234 r->setEstimate(Eigen::Vector3d(location.x, location.y, 0));
236 r->setId(CurrentVertexId);
237 if (optimizer.vertex(CurrentVertexId) != NULL)
239 optimizer.removeVertex(optimizer.vertex(CurrentVertexId));
242 optimizer.addVertex(r);
246 EdgeSE2 * e =
new EdgeSE2;
247 e->vertices()[0] = optimizer.vertex(PreviousVertexId);
248 e->vertices()[1] = optimizer.vertex(CurrentVertexId);
249 Point2d dead_reck = getOdometryFromLastGet();
250 e->setMeasurement(SE2(dead_reck.x, dead_reck.y, 0));
251 Matrix3d information;
252 information.fill(0.);
253 information(0, 0) = 200;
254 information(1, 1) = 200;
255 information(2, 2) = 1;
256 e->setInformation(information);
257 optimizer.addEdge(e);
261 inline bool addObservation(Point2d observation,
double xFasher,
262 double yFasher, LandmarkType type)
266 EdgeSE2 * e =
new EdgeSE2;
268 e->vertices()[0] = optimizer.vertex(type);
269 e->vertices()[1] = optimizer.vertex(CurrentVertexId);
288 e->setMeasurement(SE2(observation.x, observation.y, 0));
289 Matrix3d information;
290 information.fill(0.);
291 information(0, 0) = xFasher;
292 information(1, 1) = yFasher;
293 information(2, 2) = 1;
294 e->setInformation(information);
296 g2o::RobustKernelCauchy* rk =
new g2o::RobustKernelCauchy;
297 e->setRobustKernel(rk);
299 optimizer.addEdge(e);
301 atLeastOneObservation =
true;
305 inline Point2f getBall()
310 inline void setBall(Point2f _in)
315 inline void setloc_callback(
const geometry_msgs::Point::ConstPtr& msg)
317 ROS_INFO(
"Set location received.");
320 locationKalman.x = msg->x;
321 locationKalman.y = msg->y;
324 boundry_n(location.x, -A2 - I, A2 + I);
325 boundry_n(location.y, -B2 - I, B2 + I);
326 boundry_n(locationKalman.x, -A2 - I, A2 + I);
327 boundry_n(locationKalman.y, -B2 - I, B2 + I);
331 inline void setremoteloc_callback(
332 const geometry_msgs::PointStamped::ConstPtr& msg)
334 this->robotTrackerLoc.x = msg->point.x;
335 this->robotTrackerLoc.y = msg->point.y;
336 this->robotTrackerLoc.z = msg->point.z;
339 inline void dead_reckoning_callback(
const gait_msgs::GaitOdomConstPtr & msg)
341 if (_cameraProjections == NULL)
346 curOdom.x = msg->odom2D.x;
347 curOdom.y = msg->odom2D.y;
348 curOdom.z = msg->odom2D.theta;
350 if (lastOdomID == msg->ID)
352 Point3d diffOdom = curOdom - lastOdom;
353 globalPos += diffOdom;
354 Point2d diffOdom2D(diffOdom.x, diffOdom.y);
356 Point2d diffOdom2DCancelOdomRotation = RotateAroundPoint(diffOdom2D,
357 Radian2Degree(curOdom.z));
359 Point2d diffAbsolut = RotateAroundPoint(
360 diffOdom2DCancelOdomRotation,
361 -Radian2Degree(_cameraProjections->getHeading()));
362 location.x += diffAbsolut.x;
363 location.y += diffAbsolut.y;
364 robotTrackerLoc.x += diffAbsolut.x;
365 robotTrackerLoc.y += diffAbsolut.y;
366 odomLastGet.x += diffAbsolut.x;
367 odomLastGet.y += diffAbsolut.y;
369 robotTrackerLoc.z = _cameraProjections->getHeading();
373 lastOdomID = msg->ID;
376 inline Point3d GetLocalization()
381 res.z = _cameraProjections->getHeading();
382 if (params.loc->useKalman())
384 res.x = locationKalman.x;
385 res.y = locationKalman.y;
387 if (params.loc->forwardRobotTrackerXY())
389 res.x = robotTrackerLoc.x;
390 res.y = robotTrackerLoc.y;
392 if (params.loc->forwardRobotTrackerZ())
394 res.z = robotTrackerLoc.z;
399 void SendTransform(ros::Time now);
400 bool Calculate(vector<LineSegment> &,
bool circleDetected,
const Point2f &,
401 const vector<cv::Point2f> &,
const Point2d &,
402 const vector<Point2f> &,
const bool &confiused,
403 vector<LineContainer> &, vector<FeatureContainer> &);
406 bool Init(
string rName);
A class for Kalman filter.
Definition: Kalman.hpp:11
For pixel projections.
Definition: CameraProjections.hpp:50
A class representing line segments.
Definition: LineSegment.hpp:17
Model of the soccer field.
Definition: field_model.h:73
For localization in the soccer field.
Definition: Localization.hpp:95