mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-25 01:41:43 +00:00
Add DifferentialDrive voltage constraint (#2075)
This commit is contained in:
@@ -11,11 +11,12 @@ package edu.wpi.first.wpilibj.controller;
|
||||
* A helper class that computes feedforward outputs for a simple arm (modeled as a motor
|
||||
* acting against the force of gravity on a beam suspended at an angle).
|
||||
*/
|
||||
@SuppressWarnings("MemberName")
|
||||
public class ArmFeedforward {
|
||||
private final double m_ks;
|
||||
private final double m_kcos;
|
||||
private final double m_kv;
|
||||
private final double m_ka;
|
||||
public final double ks;
|
||||
public final double kcos;
|
||||
public final double kv;
|
||||
public final double ka;
|
||||
|
||||
/**
|
||||
* Creates a new ArmFeedforward with the specified gains. Units of the gain values
|
||||
@@ -27,10 +28,10 @@ public class ArmFeedforward {
|
||||
* @param ka The acceleration gain.
|
||||
*/
|
||||
public ArmFeedforward(double ks, double kcos, double kv, double ka) {
|
||||
m_ks = ks;
|
||||
m_kcos = kcos;
|
||||
m_kv = kv;
|
||||
m_ka = ka;
|
||||
this.ks = ks;
|
||||
this.kcos = kcos;
|
||||
this.kv = kv;
|
||||
this.ka = ka;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,9 +55,9 @@ public class ArmFeedforward {
|
||||
*/
|
||||
public double calculate(double positionRadians, double velocityRadPerSec,
|
||||
double accelRadPerSecSquared) {
|
||||
return m_ks * Math.signum(velocityRadPerSec) + m_kcos * Math.cos(positionRadians)
|
||||
+ m_kv * velocityRadPerSec
|
||||
+ m_ka * accelRadPerSecSquared;
|
||||
return ks * Math.signum(velocityRadPerSec) + kcos * Math.cos(positionRadians)
|
||||
+ kv * velocityRadPerSec
|
||||
+ ka * accelRadPerSecSquared;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,4 +70,73 @@ public class ArmFeedforward {
|
||||
public double calculate(double positionRadians, double velocity) {
|
||||
return calculate(positionRadians, velocity, 0);
|
||||
}
|
||||
|
||||
// Rearranging the main equation from the calculate() method yields the
|
||||
// formulas for the methods below:
|
||||
|
||||
/**
|
||||
* Calculates the maximum achievable velocity given a maximum voltage supply,
|
||||
* a position, and an acceleration. Useful for ensuring that velocity and
|
||||
* acceleration constraints for a trapezoidal profile are simultaneously
|
||||
* achievable - enter the acceleration constraint, and this will give you
|
||||
* a simultaneously-achievable velocity constraint.
|
||||
*
|
||||
* @param maxVoltage The maximum voltage that can be supplied to the arm.
|
||||
* @param angle The angle of the arm.
|
||||
* @param acceleration The acceleration of the arm.
|
||||
* @return The maximum possible velocity at the given acceleration and angle.
|
||||
*/
|
||||
public double maxAchievableVelocity(double maxVoltage, double angle, double acceleration) {
|
||||
// Assume max velocity is positive
|
||||
return (maxVoltage - ks - Math.cos(angle) * kcos - acceleration * ka) / kv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the minimum achievable velocity given a maximum voltage supply,
|
||||
* a position, and an acceleration. Useful for ensuring that velocity and
|
||||
* acceleration constraints for a trapezoidal profile are simultaneously
|
||||
* achievable - enter the acceleration constraint, and this will give you
|
||||
* a simultaneously-achievable velocity constraint.
|
||||
*
|
||||
* @param maxVoltage The maximum voltage that can be supplied to the arm.
|
||||
* @param angle The angle of the arm.
|
||||
* @param acceleration The acceleration of the arm.
|
||||
* @return The minimum possible velocity at the given acceleration and angle.
|
||||
*/
|
||||
public double minAchievableVelocity(double maxVoltage, double angle, double acceleration) {
|
||||
// Assume min velocity is negative, ks flips sign
|
||||
return (-maxVoltage + ks - Math.cos(angle) * kcos - acceleration * ka) / kv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the maximum achievable acceleration given a maximum voltage
|
||||
* supply, a position, and a velocity. Useful for ensuring that velocity and
|
||||
* acceleration constraints for a trapezoidal profile are simultaneously
|
||||
* achievable - enter the velocity constraint, and this will give you
|
||||
* a simultaneously-achievable acceleration constraint.
|
||||
*
|
||||
* @param maxVoltage The maximum voltage that can be supplied to the arm.
|
||||
* @param angle The angle of the arm.
|
||||
* @param velocity The velocity of the arm.
|
||||
* @return The maximum possible acceleration at the given velocity.
|
||||
*/
|
||||
public double maxAchievableAcceleration(double maxVoltage, double angle, double velocity) {
|
||||
return (maxVoltage - ks * Math.signum(velocity) - Math.cos(angle) * kcos - velocity * kv) / ka;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the minimum achievable acceleration given a maximum voltage
|
||||
* supply, a position, and a velocity. Useful for ensuring that velocity and
|
||||
* acceleration constraints for a trapezoidal profile are simultaneously
|
||||
* achievable - enter the velocity constraint, and this will give you
|
||||
* a simultaneously-achievable acceleration constraint.
|
||||
*
|
||||
* @param maxVoltage The maximum voltage that can be supplied to the arm.
|
||||
* @param angle The angle of the arm.
|
||||
* @param velocity The velocity of the arm.
|
||||
* @return The minimum possible acceleration at the given velocity.
|
||||
*/
|
||||
public double minAchievableAcceleration(double maxVoltage, double angle, double velocity) {
|
||||
return maxAchievableAcceleration(-maxVoltage, angle, velocity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,11 +11,12 @@ package edu.wpi.first.wpilibj.controller;
|
||||
* A helper class that computes feedforward outputs for a simple elevator (modeled as a motor
|
||||
* acting against the force of gravity).
|
||||
*/
|
||||
@SuppressWarnings("MemberName")
|
||||
public class ElevatorFeedforward {
|
||||
private final double m_ks;
|
||||
private final double m_kg;
|
||||
private final double m_kv;
|
||||
private final double m_ka;
|
||||
public final double ks;
|
||||
public final double kg;
|
||||
public final double kv;
|
||||
public final double ka;
|
||||
|
||||
/**
|
||||
* Creates a new ElevatorFeedforward with the specified gains. Units of the gain values
|
||||
@@ -27,10 +28,10 @@ public class ElevatorFeedforward {
|
||||
* @param ka The acceleration gain.
|
||||
*/
|
||||
public ElevatorFeedforward(double ks, double kg, double kv, double ka) {
|
||||
m_ks = ks;
|
||||
m_kg = kg;
|
||||
m_kv = kv;
|
||||
m_ka = ka;
|
||||
this.ks = ks;
|
||||
this.kg = kg;
|
||||
this.kv = kv;
|
||||
this.ka = ka;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,7 +54,7 @@ public class ElevatorFeedforward {
|
||||
* @return The computed feedforward.
|
||||
*/
|
||||
public double calculate(double velocity, double acceleration) {
|
||||
return m_ks * Math.signum(velocity) + m_kg + m_kv * velocity + m_ka * acceleration;
|
||||
return ks * Math.signum(velocity) + kg + kv * velocity + ka * acceleration;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,4 +67,69 @@ public class ElevatorFeedforward {
|
||||
public double calculate(double velocity) {
|
||||
return calculate(velocity, 0);
|
||||
}
|
||||
|
||||
// Rearranging the main equation from the calculate() method yields the
|
||||
// formulas for the methods below:
|
||||
|
||||
/**
|
||||
* Calculates the maximum achievable velocity given a maximum voltage supply
|
||||
* and an acceleration. Useful for ensuring that velocity and
|
||||
* acceleration constraints for a trapezoidal profile are simultaneously
|
||||
* achievable - enter the acceleration constraint, and this will give you
|
||||
* a simultaneously-achievable velocity constraint.
|
||||
*
|
||||
* @param maxVoltage The maximum voltage that can be supplied to the elevator.
|
||||
* @param acceleration The acceleration of the elevator.
|
||||
* @return The maximum possible velocity at the given acceleration.
|
||||
*/
|
||||
public double maxAchievableVelocity(double maxVoltage, double acceleration) {
|
||||
// Assume max velocity is positive
|
||||
return (maxVoltage - ks - kg - acceleration * ka) / kv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the minimum achievable velocity given a maximum voltage supply
|
||||
* and an acceleration. Useful for ensuring that velocity and
|
||||
* acceleration constraints for a trapezoidal profile are simultaneously
|
||||
* achievable - enter the acceleration constraint, and this will give you
|
||||
* a simultaneously-achievable velocity constraint.
|
||||
*
|
||||
* @param maxVoltage The maximum voltage that can be supplied to the elevator.
|
||||
* @param acceleration The acceleration of the elevator.
|
||||
* @return The minimum possible velocity at the given acceleration.
|
||||
*/
|
||||
public double minAchievableVelocity(double maxVoltage, double acceleration) {
|
||||
// Assume min velocity is negative, ks flips sign
|
||||
return (-maxVoltage + ks - kg - acceleration * ka) / kv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the maximum achievable acceleration given a maximum voltage
|
||||
* supply and a velocity. Useful for ensuring that velocity and
|
||||
* acceleration constraints for a trapezoidal profile are simultaneously
|
||||
* achievable - enter the velocity constraint, and this will give you
|
||||
* a simultaneously-achievable acceleration constraint.
|
||||
*
|
||||
* @param maxVoltage The maximum voltage that can be supplied to the elevator.
|
||||
* @param velocity The velocity of the elevator.
|
||||
* @return The maximum possible acceleration at the given velocity.
|
||||
*/
|
||||
public double maxAchievableAcceleration(double maxVoltage, double velocity) {
|
||||
return (maxVoltage - ks * Math.signum(velocity) - kg - velocity * kv) / ka;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the minimum achievable acceleration given a maximum voltage
|
||||
* supply and a velocity. Useful for ensuring that velocity and
|
||||
* acceleration constraints for a trapezoidal profile are simultaneously
|
||||
* achievable - enter the velocity constraint, and this will give you
|
||||
* a simultaneously-achievable acceleration constraint.
|
||||
*
|
||||
* @param maxVoltage The maximum voltage that can be supplied to the elevator.
|
||||
* @param velocity The velocity of the elevator.
|
||||
* @return The minimum possible acceleration at the given velocity.
|
||||
*/
|
||||
public double minAchievableAcceleration(double maxVoltage, double velocity) {
|
||||
return maxAchievableAcceleration(-maxVoltage, velocity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,11 @@ package edu.wpi.first.wpilibj.controller;
|
||||
/**
|
||||
* A helper class that computes feedforward outputs for a simple permanent-magnet DC motor.
|
||||
*/
|
||||
@SuppressWarnings("MemberName")
|
||||
public class SimpleMotorFeedforward {
|
||||
private final double m_ks;
|
||||
private final double m_kv;
|
||||
private final double m_ka;
|
||||
public final double ks;
|
||||
public final double kv;
|
||||
public final double ka;
|
||||
|
||||
/**
|
||||
* Creates a new SimpleMotorFeedforward with the specified gains. Units of the gain values
|
||||
@@ -24,9 +25,9 @@ public class SimpleMotorFeedforward {
|
||||
* @param ka The acceleration gain.
|
||||
*/
|
||||
public SimpleMotorFeedforward(double ks, double kv, double ka) {
|
||||
m_ks = ks;
|
||||
m_kv = kv;
|
||||
m_ka = ka;
|
||||
this.ks = ks;
|
||||
this.kv = kv;
|
||||
this.ka = ka;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,9 +49,12 @@ public class SimpleMotorFeedforward {
|
||||
* @return The computed feedforward.
|
||||
*/
|
||||
public double calculate(double velocity, double acceleration) {
|
||||
return m_ks * Math.signum(velocity) + m_kv * velocity + m_ka * acceleration;
|
||||
return ks * Math.signum(velocity) + kv * velocity + ka * acceleration;
|
||||
}
|
||||
|
||||
// Rearranging the main equation from the calculate() method yields the
|
||||
// formulas for the methods below:
|
||||
|
||||
/**
|
||||
* Calculates the feedforward from the gains and velocity setpoint (acceleration is assumed to
|
||||
* be zero).
|
||||
@@ -61,4 +65,66 @@ public class SimpleMotorFeedforward {
|
||||
public double calculate(double velocity) {
|
||||
return calculate(velocity, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the maximum achievable velocity given a maximum voltage supply
|
||||
* and an acceleration. Useful for ensuring that velocity and
|
||||
* acceleration constraints for a trapezoidal profile are simultaneously
|
||||
* achievable - enter the acceleration constraint, and this will give you
|
||||
* a simultaneously-achievable velocity constraint.
|
||||
*
|
||||
* @param maxVoltage The maximum voltage that can be supplied to the motor.
|
||||
* @param acceleration The acceleration of the motor.
|
||||
* @return The maximum possible velocity at the given acceleration.
|
||||
*/
|
||||
public double maxAchievableVelocity(double maxVoltage, double acceleration) {
|
||||
// Assume max velocity is positive
|
||||
return (maxVoltage - ks - acceleration * ka) / kv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the minimum achievable velocity given a maximum voltage supply
|
||||
* and an acceleration. Useful for ensuring that velocity and
|
||||
* acceleration constraints for a trapezoidal profile are simultaneously
|
||||
* achievable - enter the acceleration constraint, and this will give you
|
||||
* a simultaneously-achievable velocity constraint.
|
||||
*
|
||||
* @param maxVoltage The maximum voltage that can be supplied to the motor.
|
||||
* @param acceleration The acceleration of the motor.
|
||||
* @return The minimum possible velocity at the given acceleration.
|
||||
*/
|
||||
public double minAchievableVelocity(double maxVoltage, double acceleration) {
|
||||
// Assume min velocity is negative, ks flips sign
|
||||
return (-maxVoltage + ks - acceleration * ka) / kv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the maximum achievable acceleration given a maximum voltage
|
||||
* supply and a velocity. Useful for ensuring that velocity and
|
||||
* acceleration constraints for a trapezoidal profile are simultaneously
|
||||
* achievable - enter the velocity constraint, and this will give you
|
||||
* a simultaneously-achievable acceleration constraint.
|
||||
*
|
||||
* @param maxVoltage The maximum voltage that can be supplied to the motor.
|
||||
* @param velocity The velocity of the motor.
|
||||
* @return The maximum possible acceleration at the given velocity.
|
||||
*/
|
||||
public double maxAchievableAcceleration(double maxVoltage, double velocity) {
|
||||
return (maxVoltage - ks * Math.signum(velocity) - velocity * kv) / ka;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the maximum achievable acceleration given a maximum voltage
|
||||
* supply and a velocity. Useful for ensuring that velocity and
|
||||
* acceleration constraints for a trapezoidal profile are simultaneously
|
||||
* achievable - enter the velocity constraint, and this will give you
|
||||
* a simultaneously-achievable acceleration constraint.
|
||||
*
|
||||
* @param maxVoltage The maximum voltage that can be supplied to the motor.
|
||||
* @param velocity The velocity of the motor.
|
||||
* @return The minimum possible acceleration at the given velocity.
|
||||
*/
|
||||
public double minAchievableAcceleration(double maxVoltage, double velocity) {
|
||||
return maxAchievableAcceleration(-maxVoltage, velocity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,9 @@ package edu.wpi.first.wpilibj.kinematics;
|
||||
* velocity components whereas forward kinematics converts left and right
|
||||
* component velocities into a linear and angular chassis speed.
|
||||
*/
|
||||
@SuppressWarnings("MemberName")
|
||||
public class DifferentialDriveKinematics {
|
||||
private final double m_trackWidthMeters;
|
||||
public final double trackWidthMeters;
|
||||
|
||||
/**
|
||||
* Constructs a differential drive kinematics object.
|
||||
@@ -27,7 +28,7 @@ public class DifferentialDriveKinematics {
|
||||
* measured value due to scrubbing effects.
|
||||
*/
|
||||
public DifferentialDriveKinematics(double trackWidthMeters) {
|
||||
m_trackWidthMeters = trackWidthMeters;
|
||||
this.trackWidthMeters = trackWidthMeters;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,7 +42,7 @@ public class DifferentialDriveKinematics {
|
||||
return new ChassisSpeeds(
|
||||
(wheelSpeeds.leftMetersPerSecond + wheelSpeeds.rightMetersPerSecond) / 2, 0,
|
||||
(wheelSpeeds.rightMetersPerSecond - wheelSpeeds.leftMetersPerSecond)
|
||||
/ m_trackWidthMeters
|
||||
/ trackWidthMeters
|
||||
);
|
||||
}
|
||||
|
||||
@@ -55,9 +56,9 @@ public class DifferentialDriveKinematics {
|
||||
*/
|
||||
public DifferentialDriveWheelSpeeds toWheelSpeeds(ChassisSpeeds chassisSpeeds) {
|
||||
return new DifferentialDriveWheelSpeeds(
|
||||
chassisSpeeds.vxMetersPerSecond - m_trackWidthMeters / 2
|
||||
chassisSpeeds.vxMetersPerSecond - trackWidthMeters / 2
|
||||
* chassisSpeeds.omegaRadiansPerSecond,
|
||||
chassisSpeeds.vxMetersPerSecond + m_trackWidthMeters / 2
|
||||
chassisSpeeds.vxMetersPerSecond + trackWidthMeters / 2
|
||||
* chassisSpeeds.omegaRadiansPerSecond
|
||||
);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ public class DifferentialDriveKinematicsConstraint implements TrajectoryConstrai
|
||||
/**
|
||||
* Constructs a differential drive dynamics constraint.
|
||||
*
|
||||
* @param kinematics A kinematics component describing the drive geometry.
|
||||
* @param maxSpeedMetersPerSecond The max speed that a side of the robot can travel at.
|
||||
*/
|
||||
public DifferentialDriveKinematicsConstraint(final DifferentialDriveKinematics kinematics,
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2019 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
package edu.wpi.first.wpilibj.trajectory.constraint;
|
||||
|
||||
import edu.wpi.first.wpilibj.controller.SimpleMotorFeedforward;
|
||||
import edu.wpi.first.wpilibj.geometry.Pose2d;
|
||||
import edu.wpi.first.wpilibj.kinematics.ChassisSpeeds;
|
||||
import edu.wpi.first.wpilibj.kinematics.DifferentialDriveKinematics;
|
||||
|
||||
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
|
||||
|
||||
/**
|
||||
* A class that enforces constraints on differential drive voltage expenditure based on the motor
|
||||
* dynamics and the drive kinematics. Ensures that the acceleration of any wheel of the robot
|
||||
* while following the trajectory is never higher than what can be achieved with the given
|
||||
* maximum voltage.
|
||||
*/
|
||||
public class DifferentialDriveVoltageConstraint implements TrajectoryConstraint {
|
||||
private final SimpleMotorFeedforward m_feedforward;
|
||||
private final DifferentialDriveKinematics m_kinematics;
|
||||
private final double m_maxVoltage;
|
||||
|
||||
/**
|
||||
* Creates a new DifferentialDriveVoltageConstraint.
|
||||
*
|
||||
* @param feedforward A feedforward component describing the behavior of the drive.
|
||||
* @param kinematics A kinematics component describing the drive geometry.
|
||||
* @param maxVoltage The maximum voltage available to the motors while following the path.
|
||||
* Should be somewhat less than the nominal battery voltage (12V) to account
|
||||
* for "voltage sag" due to current draw.
|
||||
*/
|
||||
public DifferentialDriveVoltageConstraint(SimpleMotorFeedforward feedforward,
|
||||
DifferentialDriveKinematics kinematics,
|
||||
double maxVoltage) {
|
||||
m_feedforward = requireNonNullParam(feedforward, "feedforward",
|
||||
"DifferentialDriveVoltageConstraint");
|
||||
m_kinematics = requireNonNullParam(kinematics, "kinematics",
|
||||
"DifferentialDriveVoltageConstraint");
|
||||
m_maxVoltage = maxVoltage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMaxVelocityMetersPerSecond(Pose2d poseMeters, double curvatureRadPerMeter,
|
||||
double velocityMetersPerSecond) {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinMax getMinMaxAccelerationMetersPerSecondSq(Pose2d poseMeters,
|
||||
double curvatureRadPerMeter,
|
||||
double velocityMetersPerSecond) {
|
||||
|
||||
var wheelSpeeds = m_kinematics.toWheelSpeeds(new ChassisSpeeds(velocityMetersPerSecond, 0,
|
||||
velocityMetersPerSecond
|
||||
* curvatureRadPerMeter));
|
||||
|
||||
double maxWheelSpeed = Math.max(wheelSpeeds.leftMetersPerSecond,
|
||||
wheelSpeeds.rightMetersPerSecond);
|
||||
double minWheelSpeed = Math.min(wheelSpeeds.leftMetersPerSecond,
|
||||
wheelSpeeds.rightMetersPerSecond);
|
||||
|
||||
// Calculate maximum/minimum possible accelerations from motor dynamics
|
||||
// and max/min wheel speeds
|
||||
double maxWheelAcceleration =
|
||||
m_feedforward.maxAchievableAcceleration(m_maxVoltage, maxWheelSpeed);
|
||||
double minWheelAcceleration =
|
||||
m_feedforward.minAchievableAcceleration(m_maxVoltage, minWheelSpeed);
|
||||
|
||||
// Robot chassis turning on radius = 1/|curvature|. Outer wheel has radius
|
||||
// increased by half of the trackwidth T. Inner wheel has radius decreased
|
||||
// by half of the trackwidth. Achassis / radius = Aouter / (radius + T/2), so
|
||||
// Achassis = Aouter * radius / (radius + T/2) = Aouter / (1 + |curvature|T/2).
|
||||
// Inner wheel is similar.
|
||||
|
||||
// sgn(speed) term added to correctly account for which wheel is on
|
||||
// outside of turn:
|
||||
// If moving forward, max acceleration constraint corresponds to wheel on outside of turn
|
||||
// If moving backward, max acceleration constraint corresponds to wheel on inside of turn
|
||||
|
||||
double maxChassisAcceleration =
|
||||
maxWheelAcceleration
|
||||
/ (1 + m_kinematics.trackWidthMeters * Math.abs(curvatureRadPerMeter)
|
||||
* Math.signum(velocityMetersPerSecond) / 2);
|
||||
double minChassisAcceleration =
|
||||
minWheelAcceleration
|
||||
/ (1 - m_kinematics.trackWidthMeters * Math.abs(curvatureRadPerMeter)
|
||||
* Math.signum(velocityMetersPerSecond) / 2);
|
||||
|
||||
// Negate acceleration of wheel on inside of turn if center of turn is inside of wheelbase
|
||||
if ((m_kinematics.trackWidthMeters / 2) > (1 / Math.abs(curvatureRadPerMeter))) {
|
||||
if (velocityMetersPerSecond > 0) {
|
||||
minChassisAcceleration = -minChassisAcceleration;
|
||||
} else {
|
||||
maxChassisAcceleration = -maxChassisAcceleration;
|
||||
}
|
||||
}
|
||||
|
||||
return new MinMax(minChassisAcceleration, maxChassisAcceleration);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user