2017-09-28 23:30:00 -07:00
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* Copyright (c) 2008-2017 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. */
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
#include "Drive/MecanumDrive.h"
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
|
|
#include <HAL/HAL.h>
|
|
|
|
|
|
|
|
|
|
#include "Drive/Vector2d.h"
|
|
|
|
|
#include "SpeedController.h"
|
|
|
|
|
|
|
|
|
|
using namespace frc;
|
|
|
|
|
|
|
|
|
|
constexpr double kPi = 3.14159265358979323846;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Construct a MecanumDrive.
|
|
|
|
|
*
|
|
|
|
|
* If a motor needs to be inverted, do so before passing it in.
|
|
|
|
|
*/
|
|
|
|
|
MecanumDrive::MecanumDrive(SpeedController& frontLeftMotor,
|
|
|
|
|
SpeedController& rearLeftMotor,
|
|
|
|
|
SpeedController& frontRightMotor,
|
|
|
|
|
SpeedController& rearRightMotor)
|
|
|
|
|
: m_frontLeftMotor(frontLeftMotor),
|
|
|
|
|
m_rearLeftMotor(rearLeftMotor),
|
|
|
|
|
m_frontRightMotor(frontRightMotor),
|
|
|
|
|
m_rearRightMotor(rearRightMotor) {}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Drive method for Mecanum platform.
|
|
|
|
|
*
|
2017-11-26 18:36:51 -08:00
|
|
|
* Angles are measured clockwise from the positive X axis. The robot's speed is
|
|
|
|
|
* independent from its angle or rotation rate.
|
|
|
|
|
*
|
|
|
|
|
* @param ySpeed The robot's speed along the Y axis [-1.0..1.0]. Right is
|
|
|
|
|
* positive.
|
|
|
|
|
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is
|
|
|
|
|
* positive.
|
|
|
|
|
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0].
|
|
|
|
|
* Clockwise is positive.
|
|
|
|
|
* @param gyroAngle The current angle reading from the gyro in degrees around
|
|
|
|
|
* the Z axis. Use this to implement field-oriented controls.
|
2017-09-28 23:30:00 -07:00
|
|
|
*/
|
2017-11-26 18:36:51 -08:00
|
|
|
void MecanumDrive::DriveCartesian(double ySpeed, double xSpeed,
|
|
|
|
|
double zRotation, double gyroAngle) {
|
2017-09-28 23:30:00 -07:00
|
|
|
if (!reported) {
|
|
|
|
|
HAL_Report(HALUsageReporting::kResourceType_RobotDrive, 4,
|
|
|
|
|
HALUsageReporting::kRobotDrive_MecanumCartesian);
|
|
|
|
|
reported = true;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-26 18:36:51 -08:00
|
|
|
ySpeed = Limit(ySpeed);
|
|
|
|
|
ySpeed = ApplyDeadband(ySpeed, m_deadband);
|
2017-09-28 23:30:00 -07:00
|
|
|
|
2017-11-26 18:36:51 -08:00
|
|
|
xSpeed = Limit(xSpeed);
|
|
|
|
|
xSpeed = ApplyDeadband(xSpeed, m_deadband);
|
2017-09-28 23:30:00 -07:00
|
|
|
|
|
|
|
|
// Compensate for gyro angle.
|
2017-11-26 18:36:51 -08:00
|
|
|
Vector2d input{ySpeed, xSpeed};
|
|
|
|
|
input.Rotate(-gyroAngle);
|
2017-09-28 23:30:00 -07:00
|
|
|
|
|
|
|
|
double wheelSpeeds[4];
|
2017-11-26 18:36:51 -08:00
|
|
|
wheelSpeeds[kFrontLeft] = input.x + input.y + zRotation;
|
|
|
|
|
wheelSpeeds[kFrontRight] = input.x - input.y + zRotation;
|
|
|
|
|
wheelSpeeds[kRearLeft] = -input.x + input.y + zRotation;
|
|
|
|
|
wheelSpeeds[kRearRight] = -input.x - input.y + zRotation;
|
2017-09-28 23:30:00 -07:00
|
|
|
|
|
|
|
|
Normalize(wheelSpeeds);
|
|
|
|
|
|
|
|
|
|
m_frontLeftMotor.Set(wheelSpeeds[kFrontLeft] * m_maxOutput);
|
|
|
|
|
m_frontRightMotor.Set(wheelSpeeds[kFrontRight] * m_maxOutput);
|
|
|
|
|
m_rearLeftMotor.Set(wheelSpeeds[kRearLeft] * m_maxOutput);
|
|
|
|
|
m_rearRightMotor.Set(wheelSpeeds[kRearRight] * m_maxOutput);
|
|
|
|
|
|
|
|
|
|
m_safetyHelper.Feed();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Drive method for Mecanum platform.
|
|
|
|
|
*
|
2017-11-26 18:36:51 -08:00
|
|
|
* Angles are measured clockwise from the positive X axis. The robot's speed is
|
|
|
|
|
* independent from its angle or rotation rate.
|
|
|
|
|
*
|
|
|
|
|
* @param magnitude The robot's speed at a given angle [-1.0..1.0]. Forward is
|
|
|
|
|
* positive.
|
|
|
|
|
* @param angle The angle around the Z axis at which the robot drives in
|
|
|
|
|
* degrees [-180..180].
|
|
|
|
|
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0].
|
|
|
|
|
* Clockwise is positive.
|
2017-09-28 23:30:00 -07:00
|
|
|
*/
|
2017-11-26 18:36:51 -08:00
|
|
|
void MecanumDrive::DrivePolar(double magnitude, double angle,
|
|
|
|
|
double zRotation) {
|
2017-09-28 23:30:00 -07:00
|
|
|
if (!reported) {
|
|
|
|
|
HAL_Report(HALUsageReporting::kResourceType_RobotDrive, 4,
|
|
|
|
|
HALUsageReporting::kRobotDrive_MecanumPolar);
|
|
|
|
|
reported = true;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-26 18:36:51 -08:00
|
|
|
DriveCartesian(magnitude * std::sin(angle * (kPi / 180.0)),
|
|
|
|
|
magnitude * std::cos(angle * (kPi / 180.0)), zRotation, 0.0);
|
2017-09-28 23:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MecanumDrive::StopMotor() {
|
|
|
|
|
m_frontLeftMotor.StopMotor();
|
|
|
|
|
m_frontRightMotor.StopMotor();
|
|
|
|
|
m_rearLeftMotor.StopMotor();
|
|
|
|
|
m_rearRightMotor.StopMotor();
|
|
|
|
|
m_safetyHelper.Feed();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MecanumDrive::GetDescription(llvm::raw_ostream& desc) const {
|
|
|
|
|
desc << "MecanumDrive";
|
|
|
|
|
}
|