WPILibC++ 2027.0.0-alpha-2
Loading...
Searching...
No Matches
ChassisSpeeds.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <wpi/SymbolExports.h>
8
12#include "units/velocity.h"
13
14namespace frc {
15/**
16 * Represents the speed of a robot chassis. Although this struct contains
17 * similar members compared to a Twist2d, they do NOT represent the same thing.
18 * Whereas a Twist2d represents a change in pose w.r.t to the robot frame of
19 * reference, a ChassisSpeeds struct represents a robot's velocity.
20 *
21 * A strictly non-holonomic drivetrain, such as a differential drive, should
22 * never have a dy component because it can never move sideways. Holonomic
23 * drivetrains such as swerve and mecanum will often have all three components.
24 */
26 /**
27 * Velocity along the x-axis. (Fwd is +)
28 */
29 units::meters_per_second_t vx = 0_mps;
30
31 /**
32 * Velocity along the y-axis. (Left is +)
33 */
34 units::meters_per_second_t vy = 0_mps;
35
36 /**
37 * Represents the angular velocity of the robot frame. (CCW is +)
38 */
39 units::radians_per_second_t omega = 0_rad_per_s;
40
41 /**
42 * Creates a Twist2d from ChassisSpeeds.
43 *
44 * @param dt The duration of the timestep.
45 *
46 * @return Twist2d.
47 */
48 constexpr Twist2d ToTwist2d(units::second_t dt) const {
49 return Twist2d{vx * dt, vy * dt, omega * dt};
50 }
51
52 /**
53 * Discretizes a continuous-time chassis speed.
54 *
55 * This function converts a continuous-time chassis speed into a discrete-time
56 * one such that when the discrete-time chassis speed is applied for one
57 * timestep, the robot moves as if the velocity components are independent
58 * (i.e., the robot moves v_x * dt along the x-axis, v_y * dt along the
59 * y-axis, and omega * dt around the z-axis).
60 *
61 * This is useful for compensating for translational skew when translating and
62 * rotating a holonomic (swerve or mecanum) drivetrain. However, scaling down
63 * the ChassisSpeeds after discretizing (e.g., when desaturating swerve module
64 * speeds) rotates the direction of net motion in the opposite direction of
65 * rotational velocity, introducing a different translational skew which is
66 * not accounted for by discretization.
67 *
68 * @param dt The duration of the timestep the speeds should be applied for.
69 * @return Discretized ChassisSpeeds.
70 */
71 constexpr ChassisSpeeds Discretize(units::second_t dt) const {
72 // Construct the desired pose after a timestep, relative to the current
73 // pose. The desired pose has decoupled translation and rotation.
74 Pose2d desiredDeltaPose{vx * dt, vy * dt, omega * dt};
75
76 // Find the chassis translation/rotation deltas in the robot frame that move
77 // the robot from its current pose to the desired pose
78 auto twist = Pose2d{}.Log(desiredDeltaPose);
79
80 // Turn the chassis translation/rotation deltas into average velocities
81 return {twist.dx / dt, twist.dy / dt, twist.dtheta / dt};
82 }
83
84 /**
85 * Converts this field-relative set of speeds into a robot-relative
86 * ChassisSpeeds object.
87 *
88 * @param robotAngle The angle of the robot as measured by a gyroscope. The
89 * robot's angle is considered to be zero when it is facing directly away
90 * from your alliance station wall. Remember that this should be CCW
91 * positive.
92 * @return ChassisSpeeds object representing the speeds in the robot's frame
93 * of reference.
94 */
95 constexpr ChassisSpeeds ToRobotRelative(const Rotation2d& robotAngle) const {
96 // CW rotation into chassis frame
97 auto rotated =
98 Translation2d{units::meter_t{vx.value()}, units::meter_t{vy.value()}}
99 .RotateBy(-robotAngle);
100 return {units::meters_per_second_t{rotated.X().value()},
101 units::meters_per_second_t{rotated.Y().value()}, omega};
102 }
103
104 /**
105 * Converts this robot-relative set of speeds into a field-relative
106 * ChassisSpeeds object.
107 *
108 * @param robotAngle The angle of the robot as measured by a gyroscope. The
109 * robot's angle is considered to be zero when it is facing directly away
110 * from your alliance station wall. Remember that this should be CCW
111 * positive.
112 * @return ChassisSpeeds object representing the speeds in the field's frame
113 * of reference.
114 */
115 constexpr ChassisSpeeds ToFieldRelative(const Rotation2d& robotAngle) const {
116 // CCW rotation out of chassis frame
117 auto rotated =
118 Translation2d{units::meter_t{vx.value()}, units::meter_t{vy.value()}}
119 .RotateBy(robotAngle);
120 return {units::meters_per_second_t{rotated.X().value()},
121 units::meters_per_second_t{rotated.Y().value()}, omega};
122 }
123
124 /**
125 * Adds two ChassisSpeeds and returns the sum.
126 *
127 * <p>For example, ChassisSpeeds{1.0, 0.5, 1.5} + ChassisSpeeds{2.0, 1.5, 0.5}
128 * = ChassisSpeeds{3.0, 2.0, 2.0}
129 *
130 * @param other The ChassisSpeeds to add.
131 *
132 * @return The sum of the ChassisSpeeds.
133 */
134 constexpr ChassisSpeeds operator+(const ChassisSpeeds& other) const {
135 return {vx + other.vx, vy + other.vy, omega + other.omega};
136 }
137
138 /**
139 * Subtracts the other ChassisSpeeds from the current ChassisSpeeds and
140 * returns the difference.
141 *
142 * <p>For example, ChassisSpeeds{5.0, 4.0, 2.0} - ChassisSpeeds{1.0, 2.0, 1.0}
143 * = ChassisSpeeds{4.0, 2.0, 1.0}
144 *
145 * @param other The ChassisSpeeds to subtract.
146 *
147 * @return The difference between the two ChassisSpeeds.
148 */
149 constexpr ChassisSpeeds operator-(const ChassisSpeeds& other) const {
150 return *this + -other;
151 }
152
153 /**
154 * Returns the inverse of the current ChassisSpeeds.
155 * This is equivalent to negating all components of the ChassisSpeeds.
156 *
157 * @return The inverse of the current ChassisSpeeds.
158 */
159 constexpr ChassisSpeeds operator-() const { return {-vx, -vy, -omega}; }
160
161 /**
162 * Multiplies the ChassisSpeeds by a scalar and returns the new ChassisSpeeds.
163 *
164 * <p>For example, ChassisSpeeds{2.0, 2.5, 1.0} * 2
165 * = ChassisSpeeds{4.0, 5.0, 1.0}
166 *
167 * @param scalar The scalar to multiply by.
168 *
169 * @return The scaled ChassisSpeeds.
170 */
171 constexpr ChassisSpeeds operator*(double scalar) const {
172 return {scalar * vx, scalar * vy, scalar * omega};
173 }
174
175 /**
176 * Divides the ChassisSpeeds by a scalar and returns the new ChassisSpeeds.
177 *
178 * <p>For example, ChassisSpeeds{2.0, 2.5, 1.0} / 2
179 * = ChassisSpeeds{1.0, 1.25, 0.5}
180 *
181 * @param scalar The scalar to divide by.
182 *
183 * @return The scaled ChassisSpeeds.
184 */
185 constexpr ChassisSpeeds operator/(double scalar) const {
186 return operator*(1.0 / scalar);
187 }
188
189 /**
190 * Compares the ChassisSpeeds with another ChassisSpeed.
191 *
192 * @param other The other ChassisSpeeds.
193 *
194 * @return The result of the comparison. Is true if they are the same.
195 */
196 constexpr bool operator==(const ChassisSpeeds& other) const = default;
197};
198} // namespace frc
199
#define WPILIB_DLLEXPORT
Definition SymbolExports.h:36
Represents a 2D pose containing translational and rotational elements.
Definition Pose2d.h:28
constexpr Twist2d Log(const Pose2d &end) const
Returns a Twist2d that maps this pose to the end pose.
Definition Pose2d.h:354
A rotation in a 2D coordinate frame represented by a point on the unit circle (cosine and sine).
Definition Rotation2d.h:26
Represents a translation in 2D space.
Definition Translation2d.h:29
constexpr Translation2d RotateBy(const Rotation2d &other) const
Applies a rotation to the translation in 2D space.
Definition Translation2d.h:135
Definition SystemServer.h:9
Represents the speed of a robot chassis.
Definition ChassisSpeeds.h:25
constexpr ChassisSpeeds Discretize(units::second_t dt) const
Discretizes a continuous-time chassis speed.
Definition ChassisSpeeds.h:71
constexpr Twist2d ToTwist2d(units::second_t dt) const
Creates a Twist2d from ChassisSpeeds.
Definition ChassisSpeeds.h:48
constexpr ChassisSpeeds ToFieldRelative(const Rotation2d &robotAngle) const
Converts this robot-relative set of speeds into a field-relative ChassisSpeeds object.
Definition ChassisSpeeds.h:115
constexpr ChassisSpeeds operator+(const ChassisSpeeds &other) const
Adds two ChassisSpeeds and returns the sum.
Definition ChassisSpeeds.h:134
constexpr ChassisSpeeds ToRobotRelative(const Rotation2d &robotAngle) const
Converts this field-relative set of speeds into a robot-relative ChassisSpeeds object.
Definition ChassisSpeeds.h:95
constexpr ChassisSpeeds operator-(const ChassisSpeeds &other) const
Subtracts the other ChassisSpeeds from the current ChassisSpeeds and returns the difference.
Definition ChassisSpeeds.h:149
constexpr ChassisSpeeds operator*(double scalar) const
Multiplies the ChassisSpeeds by a scalar and returns the new ChassisSpeeds.
Definition ChassisSpeeds.h:171
constexpr ChassisSpeeds operator/(double scalar) const
Divides the ChassisSpeeds by a scalar and returns the new ChassisSpeeds.
Definition ChassisSpeeds.h:185
constexpr ChassisSpeeds operator-() const
Returns the inverse of the current ChassisSpeeds.
Definition ChassisSpeeds.h:159
constexpr bool operator==(const ChassisSpeeds &other) const =default
Compares the ChassisSpeeds with another ChassisSpeed.
A change in distance along a 2D arc since the last pose update.
Definition Twist2d.h:22
Type representing an arbitrary unit.
Definition base.h:888