TrajoptLib
Library for generating time-optimal trajectories for FRC robots.
Loading...
Searching...
No Matches
point_line_region_constraint.hpp
1// Copyright (c) TrajoptLib contributors
2
3#pragma once
4
5#include <stdint.h>
6
7#include <utility>
8
9#include <sleipnir/autodiff/variable.hpp>
10#include <sleipnir/optimization/problem.hpp>
11
12#include "trajopt/geometry/pose2.hpp"
13#include "trajopt/geometry/translation2.hpp"
14#include "trajopt/util/symbol_exports.hpp"
15
16namespace trajopt {
17
19enum class Side : uint8_t {
21 ABOVE,
23 BELOW,
25 ON,
26};
27
32class TRAJOPT_DLLEXPORT PointLineRegionConstraint {
33 public:
40 explicit PointLineRegionConstraint(Translation2d robot_point,
41 Translation2d field_line_start,
42 Translation2d field_line_end, Side side)
43 : m_robot_point{std::move(robot_point)},
44 m_field_line_start{std::move(field_line_start)},
45 m_field_line_end{std::move(field_line_end)},
46 m_side{side} {}
47
56 void apply(
57 slp::Problem<double>& problem, const Pose2v<double>& pose,
58 [[maybe_unused]] const Translation2v<double>& linear_velocity,
59 [[maybe_unused]] const slp::Variable<double>& angular_velocity,
60 [[maybe_unused]] const Translation2v<double>& linear_acceleration,
61 [[maybe_unused]] const slp::Variable<double>& angular_acceleration) {
62 auto point = pose.translation() + m_robot_point.rotate_by(pose.rotation());
63
64 // Determine which side of the start-end field line a point is on.
65 //
66 // The cross product a x b = |a|₂|b|₂sinθ for a and b vectors with the same
67 // tail. If a x b > 0, b is to the left of a.
68 //
69 // b
70 // ^
71 // |
72 // -----> a
73 //
74 //
75 // If a x b < 0, b is to the right of a.
76 //
77 // -----> a
78 // |
79 // v
80 // b
81 //
82 // Let a be the field line start -> end and let b be the point start ->
83 // point.
84 //
85 // cross > 0 means point is left of line (above)
86 // cross = 0 means point is on line
87 // cross < 0 means point is right of line (below)
88 auto line = m_field_line_end - m_field_line_start;
89 auto start_to_point = point - m_field_line_start;
90 auto cross = line.cross(start_to_point);
91
92 switch (m_side) {
93 case Side::ABOVE:
94 problem.subject_to(cross > 0);
95 break;
96 case Side::BELOW:
97 problem.subject_to(cross < 0);
98 break;
99 case Side::ON:
100 problem.subject_to(cross == 0);
101 break;
102 }
103 }
104
105 private:
106 Translation2d m_robot_point;
107 Translation2d m_field_line_start;
108 Translation2d m_field_line_end;
109 Side m_side;
110};
111
112} // namespace trajopt
PointLineRegionConstraint(Translation2d robot_point, Translation2d field_line_start, Translation2d field_line_end, Side side)
Definition point_line_region_constraint.hpp:40
void apply(slp::Problem< double > &problem, const Pose2v< double > &pose, const Translation2v< double > &linear_velocity, const slp::Variable< double > &angular_velocity, const Translation2v< double > &linear_acceleration, const slp::Variable< double > &angular_acceleration)
Definition point_line_region_constraint.hpp:56
constexpr const Rotation2< T > & rotation() const
Definition pose2.hpp:66
constexpr const Translation2< T > & translation() const
Definition pose2.hpp:51
constexpr auto rotate_by(const Rotation2< U > &rotation) const
Definition translation2.hpp:117