38 logger->logError(
"Track file is incomplete, very limited competition logic functionality!");
44 double as = ((b.y() - c.y()) * (point.x() - c.x()) + (c.x() - b.x()) * (point.y() - c.y()))
45 / ((b.y() - c.y()) * (a.x() - c.x()) + (c.x() - b.x()) * (a.y() - c.y()));
46 double bs = ((c.y() - a.y()) * (point.x() - c.x()) + (a.x() - c.x()) * (point.y() - c.y()))
47 / ((b.y() - c.y()) * (a.x() - c.x()) + (c.x() - b.x()) * (a.y() - c.y()));
48 double cs = 1 - as - bs;
50 return ((as >= 0) && (as <= 1) && (bs >= 0) && (bs <= 1) && (cs >= 0) && (cs <= 1));
55 std::vector<size_t> leftToRight;
56 leftToRight.reserve(track.
left_lane.size());
57 std::vector<size_t> rightToLeft;
59 Eigen::Vector2d referencePoint = points.at(0);
61 size_t currentLeftIndex = 0;
62 for (
size_t i = 0; i < track.
left_lane.size(); ++i)
66 size_t argmin_local = 0;
67 double min_dist_local = std::numeric_limits<double>::max();
68 for (
size_t j = 0; j < 5; ++j)
71 double dist = (left_cone.position - right_cone.position).norm();
72 if (dist < min_dist_local)
75 min_dist_local = dist;
78 currentLeftIndex += argmin_local;
79 leftToRight.push_back(currentLeftIndex);
82 size_t currentRightIndex = 0;
83 for (
size_t i = 0; i < track.
right_lane.size(); ++i)
87 size_t argmin_local = 0;
88 double min_dist_local = std::numeric_limits<double>::max();
89 for (
size_t j = 0; j < 5; ++j)
92 double dist = (left_cone.position - right_cone.position).norm();
93 if (dist < min_dist_local)
96 min_dist_local = dist;
99 currentRightIndex += argmin_local;
100 rightToLeft.push_back(currentRightIndex);
104 double bestDist = std::numeric_limits<double>::max();
107 for (
size_t i = 0; i < track.
left_lane.size(); ++i)
109 double dist = (track.
left_lane[i].position.head(2) - referencePoint).norm();
113 indexRight = leftToRight.at(i);
117 for (
size_t i = 0; i < track.
right_lane.size(); ++i)
119 double dist = (track.
right_lane[i].position.head(2) - referencePoint).norm();
122 indexLeft = rightToLeft.at(i);
128 std::vector<std::vector<Eigen::Vector2d>> triPoints;
129 for (
int i = -7; i < 7; ++i)
131 Eigen::Vector2d left1
134 Eigen::Vector2d left2
136 Eigen::Vector2d right1
138 .at((leftToRight.at((indexLeft + i - 1 + track.
left_lane.size()) % track.
left_lane.size())
142 Eigen::Vector2d right2
144 .at((leftToRight.at((indexLeft + i + track.
left_lane.size()) % track.
left_lane.size())
148 std::vector<Eigen::Vector2d> tmpVector { left1, left2, right1 };
149 std::vector<Eigen::Vector2d> tmpVector2 { left1, left2, right2 };
150 triPoints.push_back(tmpVector);
151 triPoints.push_back(tmpVector2);
154 for (
int i = -7; i < 7; ++i)
156 Eigen::Vector2d right1
159 Eigen::Vector2d right2
161 Eigen::Vector2d left1
167 Eigen::Vector2d left2
173 std::vector<Eigen::Vector2d> tmpVector { right1, right2, left1 };
174 std::vector<Eigen::Vector2d> tmpVector2 { right1, right2, left2 };
175 triPoints.push_back(tmpVector);
176 triPoints.push_back(tmpVector2);
179 std::vector<bool> ret;
180 for (Eigen::Vector2d& point : points)
182 bool inTrack =
false;
183 for (
int i = 0; i < triPoints.size(); ++i)
186 ||
pointInTriangle(triPoints.at(i).at(0), triPoints.at(i).at(1), triPoints.at(i).at(2), point);
188 ret.push_back(inTrack);
196 Eigen::Vector2d a, Eigen::Vector2d b, Eigen::Vector2d rayOrigin, Eigen::Vector2d rayDirection)
200 Eigen::Vector2d segDirection = b - a;
201 double RayDxSegD =
cross2d(rayDirection, segDirection);
202 double aRayOxRayD =
cross2d(a - rayOrigin, rayDirection);
204 if (RayDxSegD == 0 && aRayOxRayD == 0)
206 return std::make_pair(
false,
true);
209 else if (RayDxSegD == 0 && aRayOxRayD != 0)
211 return std::make_pair(
false,
false);
214 else if (RayDxSegD != 0)
216 double u = aRayOxRayD / RayDxSegD;
217 double t =
cross2d(a - rayOrigin, segDirection) / RayDxSegD;
218 if (t > 0 && (u >= 0) && (u <= 1))
220 return std::make_pair(
true,
false);
224 return std::make_pair(
false,
false);
231 return std::make_pair(
false,
false);
240 int intersectCount = 0;
241 double rayAngle = 0.01;
252 Eigen::Vector2d rayDirection(std::cos(rayAngle), std::sin(rayAngle));
253 for (
int i = 1; i < polyPoints.size(); ++i)
255 std::pair<bool, bool> intersectRes
258 if (intersectRes.second)
264 if (intersectRes.first)
271 ret = (intersectCount % 2) == 1;
277 std::vector<Eigen::Vector2d> polyPoints;
280 polyPoints.push_back(lm.position.head(2));
282 for (
int i = (track.
right_lane.size() - 1); i >= 0; --i)
284 polyPoints.push_back(track.
right_lane[i].position.head(2));
286 polyPoints.push_back(track.
left_lane[0].position.head(2));
288 Eigen::Vector2d point(0, 0);
289 std::vector<bool> ret;
290 for (
auto& point : points)
298 Track& track,
double time, Eigen::Vector3d& position, Eigen::Vector3d& orientation)
302 double halfwidth = 0.6;
303 Eigen::Vector2d flLocal(lf, halfwidth);
304 Eigen::Vector2d frLocal(lf, -halfwidth);
305 Eigen::Vector2d rlLocal(-lr, halfwidth);
306 Eigen::Vector2d rrLocal(-lr, -halfwidth);
307 Eigen::Matrix2d rotM;
308 rotM << std::cos(orientation.z()), -std::sin(orientation.z()), std::sin(orientation.z()), std::cos(orientation.z());
309 Eigen::Vector2d fl = position.head(2) + rotM * flLocal;
310 Eigen::Vector2d fr = position.head(2) + rotM * frLocal;
311 Eigen::Vector2d rl = position.head(2) + rotM * rlLocal;
312 Eigen::Vector2d rr = position.head(2) + rotM * rrLocal;
313 std::vector<Eigen::Vector2d> pointsToBeChecked { fl, fr, rl, rr };
314 std::vector<bool> inTrack;
323 bool flOk = inTrack.at(0);
324 bool frOk = inTrack.at(1);
325 bool rlOk = inTrack.at(2);
326 bool rrOk = inTrack.at(3);
328 bool inLane = flOk || frOk || rlOk || rrOk;
352 for (
int i = 0; i < (conePoly.size() - 1); ++i)
356 for (
int i = 0; i < (carPoly.size() - 1); ++i)
364 Track& track,
double time, Eigen::Vector3d& position, Eigen::Vector3d& orientation)
366 double lf = 0.75 + 0.9;
367 double lr = 0.75 + 0.3;
368 double halfwidth = 0.6;
369 Eigen::Vector2d flLocal(lf, halfwidth);
370 Eigen::Vector2d frLocal(lf, -halfwidth);
371 Eigen::Vector2d rlLocal(-lr, halfwidth);
372 Eigen::Vector2d rrLocal(-lr, -halfwidth);
373 Eigen::Matrix2d rotM;
374 rotM << std::cos(orientation.z()), -std::sin(orientation.z()), std::sin(orientation.z()), std::cos(orientation.z());
375 Eigen::Vector2d fl = position.head(2) + rotM * flLocal;
376 Eigen::Vector2d fr = position.head(2) + rotM * frLocal;
377 Eigen::Vector2d rl = position.head(2) + rotM * rlLocal;
378 Eigen::Vector2d rr = position.head(2) + rotM * rrLocal;
379 std::vector<Eigen::Vector2d> pointsToBeChecked { fl, fr, rr, rl, fl };
381 double coneCheckDist = 5.0;
382 double coneWidth = 0.228;
383 std::vector<Landmark*> closeCones;
384 double closeThresh = 5.0;
385 for (
int i = 0; i < track.
left_lane.size(); ++i)
387 if ((position.head(2) - track.
left_lane.at(i).position.head(2)).norm() <= closeThresh)
389 closeCones.push_back(&track.
left_lane.at(i));
392 for (
int i = 0; i < track.
right_lane.size(); ++i)
394 if ((position.head(2) - track.
right_lane.at(i).position.head(2)).norm() <= closeThresh)
396 closeCones.push_back(&track.
right_lane.at(i));
399 for (
int i = 0; i < track.
unknown.size(); ++i)
401 if ((position.head(2) - track.
unknown.at(i).position.head(2)).norm() <= closeThresh)
403 closeCones.push_back(&track.
unknown.at(i));
407 for (
int i = 0; i < closeCones.size(); ++i)
409 Eigen::Vector2d conePos = closeCones.at(i)->position.head(2);
410 Eigen::Vector2d p1 = conePos + Eigen::Vector2d(coneWidth * 0.5, coneWidth * 0.5);
411 Eigen::Vector2d p2 = conePos + Eigen::Vector2d(coneWidth * 0.5, -coneWidth * 0.5);
412 Eigen::Vector2d p3 = conePos + Eigen::Vector2d(-coneWidth * 0.5, -coneWidth * 0.5);
413 Eigen::Vector2d p4 = conePos + Eigen::Vector2d(-coneWidth * 0.5, coneWidth * 0.5);
414 std::vector<Eigen::Vector2d> conePoints { p1, p2, p3, p4, p1 };
416 if (!closeCones.at(i)->beenHit && hitStatus)
429 closeCones.at(i)->beenHit = closeCones.at(i)->beenHit || hitStatus;
437 double ret = (b.x() - a.x()) * (c.y() - a.y()) - (c.x() - a.x()) * (b.y() - a.y());
443 Eigen::Vector2d slope = b - a;
444 Eigen::Vector2d slopeOrtho = Eigen::Vector2d(-slope.y(), slope.x()).normalized();
445 Eigen::Vector2d orthoBack1 = a - slopeOrtho;
446 Eigen::Vector2d orthoBack2 = a + slopeOrtho;
447 Eigen::Vector2d orthoFront1 = b - slopeOrtho;
448 Eigen::Vector2d orthoFront2 = b + slopeOrtho;
451 bool ret = backOk && frontOk;
456 Eigen::Vector3d lm1, Eigen::Vector3d lm2, Eigen::Vector3d& position, Eigen::Vector3d& orientation)
458 Eigen::Vector2d transponderPosition = position.head(2);
460 if (
inLineSegement(lm1.head(2), lm2.head(2), transponderPosition))
463 ret = 1 +
static_cast<int>(valLine <= 0);
509 Track& track, Eigen::Vector3d& position, Eigen::Vector3d& orientation,
double time)
553 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"pacsim_logger"),
"Finish conditions met at!");
567 double x = point.x();
568 double y = point.y();
574 double dot = A * C + B * D;
575 double len_sq = C * C + D * D;
578 param = dot / len_sq;
600 double ret = std::sqrt(dx * dx + dy * dy);
638 if (
checkUSS(track, time, position))
651 if (goneWrongLeft || goneWrongRight)
670 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"pacsim_logger"),
"checkDNF returned DNF = true");
675 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"pacsim_logger"),
"checkDNF returned DNF = true");
735 Track& track,
double time, Eigen::Vector3d& position, Eigen::Vector3d& orientation)
745 ret = ret ||
checkDNF(track, time, position);
761 std::string ret =
"unknown";
772 ret =
"acceleration";
783 std::string ret =
"unknown";
848 for (
int i = 0; i <
lapTimes.size(); ++i)
852 std::vector<double> sectors;
860 for (
int i = 0; i <
penalties.size(); ++i)
double timeout_trackdrive_total
bool checkUSS(Track track, double time, Eigen::Vector3d position)
std::vector< std::vector< double > > sectorTimes
double cross2d(Eigen::Vector2d a, Eigen::Vector2d b)
std::vector< double > currentSectorTimes
bool evaluateOffCourse(Track &track, double time, Eigen::Vector3d &position, Eigen::Vector3d &orientation)
bool pointInTriangle(Eigen::Vector2d a, Eigen::Vector2d b, Eigen::Vector2d c, Eigen::Vector2d point)
std::vector< bool > pointsInTrackConnected(Track &track, std::vector< Eigen::Vector2d > points)
bool checkDNF(Track track, double time, Eigen::Vector3d position)
std::vector< int > timeKeepingStatuses
std::vector< Penalty > penalties
double timeout_trackdrive_first
bool carConePolyIntersect(std::vector< Eigen::Vector2d > carPoly, std::vector< Eigen::Vector2d > conePoly)
bool inLineSegement(Eigen::Vector2d a, Eigen::Vector2d b, Eigen::Vector2d position)
int timeKeepingStatus(Eigen::Vector3d lm1, Eigen::Vector3d lm2, Eigen::Vector3d &position, Eigen::Vector3d &orientation)
std::vector< bool > pointsInTrackNotConnected(Track &track, std::vector< Eigen::Vector2d > points)
bool pointInPolygon(std::vector< Eigen::Vector2d > polyPoints, Eigen::Vector2d point)
std::string discipline2str(Discipline d)
std::vector< double > lapTimes
std::vector< int > timeKeepingFirstTriggerStatuses
std::vector< std::vector< double > > triggerTimes
void evaluateTimeKeepings(Track &track, Eigen::Vector3d &position, Eigen::Vector3d &orientation, double time)
bool checkFinishConditionsMet(double time)
bool performAllChecks(Track &track, double time, Eigen::Vector3d &position, Eigen::Vector3d &orientation)
CompetitionLogic(std::shared_ptr< Logger > logger, Track &track, MainConfig config)
std::pair< bool, bool > rayIntersectLineSegment(Eigen::Vector2d a, Eigen::Vector2d b, Eigen::Vector2d rayOrigin, Eigen::Vector2d rayDirection)
void evaluateTimeKeepingGateTrigger(Track track, double time, int index)
void fillReport(Report &report, double time)
double finishConditionsMetFirstTime
std::string penalty2str(PENALTY_TYPE p)
bool checkTimeout(double time)
double timeout_acceleration
void evaluateConeHit(Track &track, double time, Eigen::Vector3d &position, Eigen::Vector3d &orientation)
double determinantLinePoint(Eigen::Vector2d a, Eigen::Vector2d b, Eigen::Vector2d c)
double distanceToLineSegment(Eigen::Vector2d a, Eigen::Vector2d b, Eigen::Vector2d point)
std::shared_ptr< Logger > logger
double timeout_acceleration
double timeout_trackdrive_first
double timeout_trackdrive_total
std::vector< double > sector_times
std::vector< Penalty > penalties
std::vector< LapTime > lap_times
std::vector< std::pair< Landmark, Landmark > > time_keeping_gates
std::vector< Landmark > left_lane
bool lanesFirstWithLastConnected
std::vector< Landmark > unknown
std::vector< Landmark > right_lane