WPILibC++ 2025.2.1
Loading...
Searching...
No Matches
DifferentialDriveVoltageConstraint.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 <algorithm>
8#include <limits>
9#include <utility>
10
11#include <wpi/MathExtras.h>
12#include <wpi/SymbolExports.h>
13
17#include "units/length.h"
18#include "units/math.h"
19#include "units/voltage.h"
20
21namespace frc {
22/**
23 * A class that enforces constraints on differential drive voltage expenditure
24 * based on the motor dynamics and the drive kinematics. Ensures that the
25 * acceleration of any wheel of the robot while following the trajectory is
26 * never higher than what can be achieved with the given maximum voltage.
27 */
29 : public TrajectoryConstraint {
30 public:
31 /**
32 * Creates a new DifferentialDriveVoltageConstraint.
33 *
34 * @param feedforward A feedforward component describing the behavior of the
35 * drive.
36 * @param kinematics A kinematics component describing the drive geometry.
37 * @param maxVoltage The maximum voltage available to the motors while
38 * following the path. Should be somewhat less than the nominal battery
39 * voltage (12V) to account for "voltage sag" due to current draw.
40 */
42 const SimpleMotorFeedforward<units::meter>& feedforward,
43 DifferentialDriveKinematics kinematics, units::volt_t maxVoltage)
44 : m_feedforward(feedforward),
45 m_kinematics(std::move(kinematics)),
46 m_maxVoltage(maxVoltage) {}
47
48 constexpr units::meters_per_second_t MaxVelocity(
49 const Pose2d& pose, units::curvature_t curvature,
50 units::meters_per_second_t velocity) const override {
51 return units::meters_per_second_t{std::numeric_limits<double>::max()};
52 }
53
55 const Pose2d& pose, units::curvature_t curvature,
56 units::meters_per_second_t speed) const override {
57 auto wheelSpeeds =
58 m_kinematics.ToWheelSpeeds({speed, 0_mps, speed * curvature});
59
60 auto maxWheelSpeed = (std::max)(wheelSpeeds.left, wheelSpeeds.right);
61 auto minWheelSpeed = (std::min)(wheelSpeeds.left, wheelSpeeds.right);
62
63 // Calculate maximum/minimum possible accelerations from motor dynamics
64 // and max/min wheel speeds
65 auto maxWheelAcceleration =
66 m_feedforward.MaxAchievableAcceleration(m_maxVoltage, maxWheelSpeed);
67 auto minWheelAcceleration =
68 m_feedforward.MinAchievableAcceleration(m_maxVoltage, minWheelSpeed);
69
70 // Robot chassis turning on radius = 1/|curvature|. Outer wheel has radius
71 // increased by half of the trackwidth T. Inner wheel has radius decreased
72 // by half of the trackwidth. Achassis / radius = Aouter / (radius + T/2),
73 // so Achassis = Aouter * radius / (radius + T/2) = Aouter / (1 +
74 // |curvature|T/2). Inner wheel is similar.
75
76 // sgn(speed) term added to correctly account for which wheel is on
77 // outside of turn:
78 // If moving forward, max acceleration constraint corresponds to wheel on
79 // outside of turn If moving backward, max acceleration constraint
80 // corresponds to wheel on inside of turn
81
82 // When velocity is zero, then wheel velocities are uniformly zero (robot
83 // cannot be turning on its center) - we have to treat this as a special
84 // case, as it breaks the signum function. Both max and min acceleration
85 // are *reduced in magnitude* in this case.
86
87 units::meters_per_second_squared_t maxChassisAcceleration;
88 units::meters_per_second_squared_t minChassisAcceleration;
89
90 if (speed == 0_mps) {
91 maxChassisAcceleration =
92 maxWheelAcceleration /
93 (1 + m_kinematics.trackWidth * units::math::abs(curvature) / (2_rad));
94 minChassisAcceleration =
95 minWheelAcceleration /
96 (1 + m_kinematics.trackWidth * units::math::abs(curvature) / (2_rad));
97 } else {
98 maxChassisAcceleration =
99 maxWheelAcceleration /
100 (1 + m_kinematics.trackWidth * units::math::abs(curvature) *
101 wpi::sgn(speed) / (2_rad));
102 minChassisAcceleration =
103 minWheelAcceleration /
104 (1 - m_kinematics.trackWidth * units::math::abs(curvature) *
105 wpi::sgn(speed) / (2_rad));
106 }
107
108 // When turning about a point inside of the wheelbase (i.e. radius less than
109 // half the trackwidth), the inner wheel's direction changes, but the
110 // magnitude remains the same. The formula above changes sign for the inner
111 // wheel when this happens. We can accurately account for this by simply
112 // negating the inner wheel.
113
114 if ((m_kinematics.trackWidth / 2) > 1_rad / units::math::abs(curvature)) {
115 if (speed > 0_mps) {
116 minChassisAcceleration = -minChassisAcceleration;
117 } else if (speed < 0_mps) {
118 maxChassisAcceleration = -maxChassisAcceleration;
119 }
120 }
121
122 return {minChassisAcceleration, maxChassisAcceleration};
123 }
124
125 private:
127 DifferentialDriveKinematics m_kinematics;
128 units::volt_t m_maxVoltage;
129};
130} // namespace frc
#define WPILIB_DLLEXPORT
Definition SymbolExports.h:36
Helper class that converts a chassis velocity (dx and dtheta components) to left and right wheel velo...
Definition DifferentialDriveKinematics.h:31
A class that enforces constraints on differential drive voltage expenditure based on the motor dynami...
Definition DifferentialDriveVoltageConstraint.h:29
constexpr DifferentialDriveVoltageConstraint(const SimpleMotorFeedforward< units::meter > &feedforward, DifferentialDriveKinematics kinematics, units::volt_t maxVoltage)
Creates a new DifferentialDriveVoltageConstraint.
Definition DifferentialDriveVoltageConstraint.h:41
constexpr units::meters_per_second_t MaxVelocity(const Pose2d &pose, units::curvature_t curvature, units::meters_per_second_t velocity) const override
Returns the max velocity given the current pose and curvature.
Definition DifferentialDriveVoltageConstraint.h:48
constexpr MinMax MinMaxAcceleration(const Pose2d &pose, units::curvature_t curvature, units::meters_per_second_t speed) const override
Returns the minimum and maximum allowable acceleration for the trajectory given pose,...
Definition DifferentialDriveVoltageConstraint.h:54
Represents a 2D pose containing translational and rotational elements.
Definition Pose2d.h:28
A helper class that computes feedforward voltages for a simple permanent-magnet DC motor.
Definition SimpleMotorFeedforward.h:24
An interface for defining user-defined velocity and acceleration constraints while generating traject...
Definition TrajectoryConstraint.h:21
constexpr UnitType abs(const UnitType x) noexcept
Compute absolute value.
Definition math.h:726
Definition CAN.h:11
Implement std::hash so that hash_code can be used in STL containers.
Definition PointerIntPair.h:280
constexpr int sgn(T val)
Definition MathExtras.h:758
Represents a minimum and maximum acceleration.
Definition TrajectoryConstraint.h:37