WPILibC++ 2024.3.2
LTVDifferentialDriveController.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#include <wpi/array.h>
10
11#include "frc/EigenCore.h"
13#include "frc/geometry/Pose2d.h"
16#include "units/length.h"
17#include "units/time.h"
18#include "units/velocity.h"
19#include "units/voltage.h"
20
21namespace frc {
22
23/**
24 * The linear time-varying differential drive controller has a similar form to
25 * the LQR, but the model used to compute the controller gain is the nonlinear
26 * differential drive model linearized around the drivetrain's current state. We
27 * precompute gains for important places in our state-space, then interpolate
28 * between them with a lookup table to save computational resources.
29 *
30 * This controller has a flat hierarchy with pose and wheel velocity references
31 * and voltage outputs. This is different from a Ramsete controller's nested
32 * hierarchy where the top-level controller has a pose reference and chassis
33 * velocity command outputs, and the low-level controller has wheel velocity
34 * references and voltage outputs. Flat hierarchies are easier to tune in one
35 * shot. Furthermore, this controller is more optimal in the "least-squares
36 * error" sense than a controller based on Ramsete.
37 *
38 * See section 8.7 in Controls Engineering in FRC for a derivation of the
39 * control law we used shown in theorem 8.7.4.
40 */
42 public:
43 /**
44 * Constructs a linear time-varying differential drive controller.
45 *
46 * See
47 * https://docs.wpilib.org/en/stable/docs/software/advanced-controls/state-space/state-space-intro.html#lqr-tuning
48 * for how to select the tolerances.
49 *
50 * @param plant The differential drive velocity plant.
51 * @param trackwidth The distance between the differential drive's left and
52 * right wheels.
53 * @param Qelems The maximum desired error tolerance for each state.
54 * @param Relems The maximum desired control effort for each input.
55 * @param dt Discretization timestep.
56 * @throws std::domain_error if max velocity of plant with 12 V input <= 0 m/s
57 * or >= 15 m/s.
58 */
60 units::meter_t trackwidth,
61 const wpi::array<double, 5>& Qelems,
62 const wpi::array<double, 2>& Relems,
63 units::second_t dt);
64
65 /**
66 * Move constructor.
67 */
69
70 /**
71 * Move assignment operator.
72 */
74 default;
75
76 /**
77 * Returns true if the pose error is within tolerance of the reference.
78 */
79 bool AtReference() const;
80
81 /**
82 * Sets the pose error which is considered tolerable for use with
83 * AtReference().
84 *
85 * @param poseTolerance Pose error which is tolerable.
86 * @param leftVelocityTolerance Left velocity error which is tolerable.
87 * @param rightVelocityTolerance Right velocity error which is tolerable.
88 */
89 void SetTolerance(const Pose2d& poseTolerance,
90 units::meters_per_second_t leftVelocityTolerance,
91 units::meters_per_second_t rightVelocityTolerance);
92
93 /**
94 * Returns the left and right output voltages of the LTV controller.
95 *
96 * The reference pose, linear velocity, and angular velocity should come from
97 * a drivetrain trajectory.
98 *
99 * @param currentPose The current pose.
100 * @param leftVelocity The current left velocity.
101 * @param rightVelocity The current right velocity.
102 * @param poseRef The desired pose.
103 * @param leftVelocityRef The desired left velocity.
104 * @param rightVelocityRef The desired right velocity.
105 */
107 const Pose2d& currentPose, units::meters_per_second_t leftVelocity,
108 units::meters_per_second_t rightVelocity, const Pose2d& poseRef,
109 units::meters_per_second_t leftVelocityRef,
110 units::meters_per_second_t rightVelocityRef);
111
112 /**
113 * Returns the left and right output voltages of the LTV controller.
114 *
115 * The reference pose, linear velocity, and angular velocity should come from
116 * a drivetrain trajectory.
117 *
118 * @param currentPose The current pose.
119 * @param leftVelocity The left velocity.
120 * @param rightVelocity The right velocity.
121 * @param desiredState The desired pose, linear velocity, and angular velocity
122 * from a trajectory.
123 */
125 const Pose2d& currentPose, units::meters_per_second_t leftVelocity,
126 units::meters_per_second_t rightVelocity,
127 const Trajectory::State& desiredState);
128
129 private:
130 units::meter_t m_trackwidth;
131
132 // LUT from drivetrain linear velocity to LQR gain
134
135 Vectord<5> m_error;
136 Vectord<5> m_tolerance;
137};
138
139} // namespace frc
#define WPILIB_DLLEXPORT
Definition: SymbolExports.h:36
The linear time-varying differential drive controller has a similar form to the LQR,...
Definition: LTVDifferentialDriveController.h:41
bool AtReference() const
Returns true if the pose error is within tolerance of the reference.
LTVDifferentialDriveController(const frc::LinearSystem< 2, 2, 2 > &plant, units::meter_t trackwidth, const wpi::array< double, 5 > &Qelems, const wpi::array< double, 2 > &Relems, units::second_t dt)
Constructs a linear time-varying differential drive controller.
DifferentialDriveWheelVoltages Calculate(const Pose2d &currentPose, units::meters_per_second_t leftVelocity, units::meters_per_second_t rightVelocity, const Trajectory::State &desiredState)
Returns the left and right output voltages of the LTV controller.
LTVDifferentialDriveController & operator=(LTVDifferentialDriveController &&)=default
Move assignment operator.
DifferentialDriveWheelVoltages Calculate(const Pose2d &currentPose, units::meters_per_second_t leftVelocity, units::meters_per_second_t rightVelocity, const Pose2d &poseRef, units::meters_per_second_t leftVelocityRef, units::meters_per_second_t rightVelocityRef)
Returns the left and right output voltages of the LTV controller.
void SetTolerance(const Pose2d &poseTolerance, units::meters_per_second_t leftVelocityTolerance, units::meters_per_second_t rightVelocityTolerance)
Sets the pose error which is considered tolerable for use with AtReference().
LTVDifferentialDriveController(LTVDifferentialDriveController &&)=default
Move constructor.
Represents a 2D pose containing translational and rotational elements.
Definition: Pose2d.h:23
This class is a wrapper around std::array that does compile time size checking.
Definition: array.h:26
Implements a table of key-value pairs with linear interpolation between values.
Definition: interpolating_map.h:23
Definition: AprilTagPoseEstimator.h:15
Eigen::Vector< double, Size > Vectord
Definition: EigenCore.h:12
Motor voltages for a differential drive.
Definition: DifferentialDriveWheelVoltages.h:14
Represents one point on the trajectory.
Definition: Trajectory.h:30