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