Compare commits

...

8 Commits

Author SHA1 Message Date
Prateek Machiraju
278e0f126e [glass] Use .controllable to set widgets' read-only state (#3035)
This modifies the mecanum drive, differential drive, speed controller,
and PID controller widgets to only be writeable when .controllable is
set to true.
2021-01-05 18:33:05 -08:00
Tyler Veness
d8652cfd4f [wpimath] Make Java DCMotor API consistent with C++ and fix motor calcs (#3046)
The stall torque, stall current, and free current are now multiplied by
the number of motors instead of just the stall torque. This produces the
same values for Kt and Kv regardless of the number of motors; the motor
resistance still affects the system response.

For an elevator model, the response should be the same as before since a
factor of "number of motors" shows up in the same place in the
acceleration calculation, but the current calculation will also be
correct now.
2021-01-05 18:28:57 -08:00
Peter Johnson
377b7065aa [build] Add toggleOffOn to Java spotless (#3053)
This allows custom formatting where desired (e.g. of table values).

Also upgrade spotless to 5.5.0.
2021-01-05 17:56:45 -08:00
Prateek Machiraju
1e9c79c587 [sim] Use plant output to retrieve simulated position (#3043)
Using the plant output means that measurement noise can be incorporated.
SingleJointedArmSim (in C++ and Java) and ElevatorSim (in C++) used the
state instead of the measurement.

Closes #3042
2021-01-05 17:55:44 -08:00
Peter Johnson
78147aa342 [sim] GUI: Fix Keyboard Joystick (#3052)
This was broken by #3010.

Also fix a few unknown key cases and a nullptr return that could cause a crash.
2021-01-05 17:55:11 -08:00
Peter Johnson
cd4a2265b9 [ntcore] Fix NetworkTableEntry::GetRaw() (#3051)
It was calling value->GetString() instead of GetRaw(), which would assert.
2021-01-04 22:07:50 -08:00
Austin Shalit
767ac1de10 [build] Use deploy key for doc publish (#3048)
This allows us to limit the scope of personal access tokens
2021-01-04 15:21:47 -08:00
Austin Shalit
d762215d13 [build] Add publish documentation script (#3040) 2021-01-04 13:59:19 -08:00
23 changed files with 238 additions and 106 deletions

58
.github/workflows/documentation.yml vendored Normal file
View File

@@ -0,0 +1,58 @@
name: Documentation
on: [push, workflow_dispatch]
env:
BASE_PATH: allwpilib/docs
jobs:
publish:
name: "Documentation - Publish"
runs-on: ubuntu-latest
if: github.repository_owner == 'wpilibsuite' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v'))
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-java@v1
with:
java-version: 13
- name: Set environment variables (Development)
run: |
echo "TARGET_FOLDER=$BASE_PATH/development" >> $GITHUB_ENV
if: github.ref == 'refs/heads/master'
- name: Set environment variables (Tag)
run: |
echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
echo "TARGET_FOLDER=$BASE_PATH/beta" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v')
- name: Set environment variables (Release)
run: |
echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
echo "TARGET_FOLDER=$BASE_PATH/release" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'alpha') && !contains(github.ref, 'beta')
- name: Build with Gradle
run: ./gradlew docs:generateJavaDocs docs:doxygen -PbuildServer ${{ env.EXTRA_GRADLE_ARGS }}
- name: Install SSH Client 🔑
uses: webfactory/ssh-agent@v0.4.1
with:
ssh-private-key: ${{ secrets.GH_DEPLOY_KEY }}
- name: Deploy Java 🚀
uses: JamesIves/github-pages-deploy-action@3.7.1
with:
SSH: true
REPOSITORY_NAME: wpilibsuite/wpilibsuite.github.io
BRANCH: main
CLEAN: true
FOLDER: docs/build/docs/javadoc
TARGET_FOLDER: ${{ env.TARGET_FOLDER }}/java
- name: Deploy C++ 🚀
uses: JamesIves/github-pages-deploy-action@3.7.1
with:
SSH: true
REPOSITORY_NAME: wpilibsuite/wpilibsuite.github.io
BRANCH: main
CLEAN: true
FOLDER: docs/build/docs/doxygen/html
TARGET_FOLDER: ${{ env.TARGET_FOLDER }}/cpp

View File

@@ -11,7 +11,7 @@ plugins {
id 'visual-studio'
id 'net.ltgt.errorprone' version '1.1.1' apply false
id 'com.github.johnrengelman.shadow' version '5.2.0' apply false
id 'com.diffplug.gradle.spotless' version '4.5.0'
id 'com.diffplug.spotless' version '5.5.0'
}
wpilibVersioning.buildServerMode = project.hasProperty('buildServer')
@@ -135,6 +135,7 @@ spotless {
include '**/*.java'
exclude '**/build/**', '**/build-*/**'
}
toggleOffOn()
googleJavaFormat()
removeUnusedImports()
trimTrailingWhitespace()

View File

@@ -5,6 +5,7 @@
#include "glass/hardware/SpeedController.h"
#include <imgui.h>
#include <imgui_internal.h>
#include "glass/Context.h"
#include "glass/DataSource.h"
@@ -22,6 +23,12 @@ void glass::DisplaySpeedController(SpeedControllerModel* m) {
return;
}
// Set the buttons and sliders to read-only if the model is read-only.
if (m->IsReadOnly()) {
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(210, 210, 210, 255));
}
// Add button to zero output.
if (ImGui::Button("Zero")) {
m->SetPercent(0.0);
@@ -31,7 +38,13 @@ void glass::DisplaySpeedController(SpeedControllerModel* m) {
// Display a slider for the data.
float value = dc->GetValue();
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
if (dc->SliderFloat("% Output", &value, -1.0f, 1.0f)) {
m->SetPercent(value);
}
if (m->IsReadOnly()) {
ImGui::PopStyleColor();
ImGui::PopItemFlag();
}
}

View File

@@ -106,6 +106,12 @@ void glass::DisplayDrive(DriveModel* m) {
drawArrow(arrowPos, a2 + adder);
}
// Set the buttons and sliders to read-only if the model is read-only.
if (m->IsReadOnly()) {
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(210, 210, 210, 255));
}
// Add sliders for the wheel percentages.
ImGui::SetCursorPosY(y2 - pos.y + ImGui::GetFontSize() * 0.5);
for (auto&& wheel : wheels) {
@@ -124,4 +130,9 @@ void glass::DisplayDrive(DriveModel* m) {
}
}
}
if (m->IsReadOnly()) {
ImGui::PopStyleColor();
ImGui::PopItemFlag();
}
}

View File

@@ -20,10 +20,12 @@ void glass::DisplayPIDController(PIDControllerModel* m) {
}
if (m->Exists()) {
auto createTuningParameter = [](const char* name, double* v,
std::function<void(double)> callback) {
auto flag = m->IsReadOnly() ? ImGuiInputTextFlags_ReadOnly
: ImGuiInputTextFlags_None;
auto createTuningParameter = [flag](const char* name, double* v,
std::function<void(double)> callback) {
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 4);
if (ImGui::InputDouble(name, v, 0.0, 0.0, "%.3f")) {
if (ImGui::InputDouble(name, v, 0.0, 0.0, "%.3f", flag)) {
callback(*v);
}
};

View File

@@ -16,12 +16,14 @@ NTDifferentialDriveModel::NTDifferentialDriveModel(NT_Inst instance,
wpi::StringRef path)
: m_nt(instance),
m_name(m_nt.GetEntry(path + "/.name")),
m_controllable(m_nt.GetEntry(path + "/.controllable")),
m_lPercent(m_nt.GetEntry(path + "/Left Motor Speed")),
m_rPercent(m_nt.GetEntry(path + "/Right Motor Speed")),
m_nameValue(path.rsplit('/').second),
m_lPercentData("NTDiffDriveL:" + path),
m_rPercentData("NTDiffDriveR:" + path) {
m_nt.AddListener(m_name);
m_nt.AddListener(m_controllable);
m_nt.AddListener(m_lPercent);
m_nt.AddListener(m_rPercent);
@@ -44,6 +46,9 @@ void NTDifferentialDriveModel::Update() {
} else if (event.entry == m_rPercent && event.value &&
event.value->IsDouble()) {
m_rPercentData.SetValue(event.value->GetDouble());
} else if (event.entry == m_controllable && event.value &&
event.value->IsBoolean()) {
m_controllableValue = event.value->GetBoolean();
}
}

View File

@@ -15,6 +15,7 @@ NTMecanumDriveModel::NTMecanumDriveModel(wpi::StringRef path)
NTMecanumDriveModel::NTMecanumDriveModel(NT_Inst instance, wpi::StringRef path)
: m_nt(instance),
m_name(m_nt.GetEntry(path + "/.name")),
m_controllable(m_nt.GetEntry(path + "/.controllable")),
m_flPercent(m_nt.GetEntry(path + "/Front Left Motor Speed")),
m_frPercent(m_nt.GetEntry(path + "/Front Right Motor Speed")),
m_rlPercent(m_nt.GetEntry(path + "/Rear Left Motor Speed")),
@@ -25,6 +26,7 @@ NTMecanumDriveModel::NTMecanumDriveModel(NT_Inst instance, wpi::StringRef path)
m_rlPercentData("NTMcnmDriveRL:" + path),
m_rrPercentData("NTMcnmDriveRR:" + path) {
m_nt.AddListener(m_name);
m_nt.AddListener(m_controllable);
m_nt.AddListener(m_flPercent);
m_nt.AddListener(m_frPercent);
m_nt.AddListener(m_rlPercent);
@@ -63,6 +65,9 @@ void NTMecanumDriveModel::Update() {
} else if (event.entry == m_rrPercent && event.value &&
event.value->IsDouble()) {
m_rrPercentData.SetValue(event.value->GetDouble());
} else if (event.entry == m_controllable && event.value &&
event.value->IsBoolean()) {
m_controllableValue = event.value->GetBoolean();
}
}

View File

@@ -13,6 +13,7 @@ NTPIDControllerModel::NTPIDControllerModel(NT_Inst instance,
wpi::StringRef path)
: m_nt(instance),
m_name(m_nt.GetEntry(path + "/.name")),
m_controllable(m_nt.GetEntry(path + "/.controllable")),
m_p(m_nt.GetEntry(path + "/p")),
m_i(m_nt.GetEntry(path + "/i")),
m_d(m_nt.GetEntry(path + "/d")),
@@ -23,6 +24,7 @@ NTPIDControllerModel::NTPIDControllerModel(NT_Inst instance,
m_setpointData("NTPIDCtrlStpt:" + path),
m_nameValue(path.rsplit('/').second) {
m_nt.AddListener(m_name);
m_nt.AddListener(m_controllable);
m_nt.AddListener(m_p);
m_nt.AddListener(m_i);
m_nt.AddListener(m_d);
@@ -67,6 +69,10 @@ void NTPIDControllerModel::Update() {
if (event.value && event.value->IsDouble()) {
m_setpointData.SetValue(event.value->GetDouble());
}
} else if (event.entry == m_controllable) {
if (event.value && event.value->IsBoolean()) {
m_controllableValue = event.value->GetBoolean();
}
}
}
}

View File

@@ -14,10 +14,12 @@ NTSpeedControllerModel::NTSpeedControllerModel(NT_Inst instance,
: m_nt(instance),
m_value(m_nt.GetEntry(path + "/Value")),
m_name(m_nt.GetEntry(path + "/.name")),
m_controllable(m_nt.GetEntry(path + "/.controllable")),
m_valueData("NT_SpdCtrl:" + path),
m_nameValue(path.rsplit('/').second) {
m_nt.AddListener(m_value);
m_nt.AddListener(m_name);
m_nt.AddListener(m_controllable);
}
void NTSpeedControllerModel::SetPercent(double value) {
@@ -34,6 +36,10 @@ void NTSpeedControllerModel::Update() {
if (event.value && event.value->IsString()) {
m_nameValue = event.value->GetString();
}
} else if (event.entry == m_controllable) {
if (event.value && event.value->IsBoolean()) {
m_controllableValue = event.value->GetBoolean();
}
}
}
}

View File

@@ -33,15 +33,17 @@ class NTDifferentialDriveModel : public DriveModel {
void Update() override;
bool Exists() override;
bool IsReadOnly() override { return false; }
bool IsReadOnly() override { return !m_controllableValue; }
private:
NetworkTablesHelper m_nt;
NT_Entry m_name;
NT_Entry m_controllable;
NT_Entry m_lPercent;
NT_Entry m_rPercent;
std::string m_nameValue;
bool m_controllableValue = false;
DataSource m_lPercentData;
DataSource m_rPercentData;

View File

@@ -33,17 +33,19 @@ class NTMecanumDriveModel : public DriveModel {
void Update() override;
bool Exists() override;
bool IsReadOnly() override { return false; }
bool IsReadOnly() override { return !m_controllableValue; }
private:
NetworkTablesHelper m_nt;
NT_Entry m_name;
NT_Entry m_controllable;
NT_Entry m_flPercent;
NT_Entry m_frPercent;
NT_Entry m_rlPercent;
NT_Entry m_rrPercent;
std::string m_nameValue;
bool m_controllableValue = false;
DataSource m_flPercentData;
DataSource m_frPercentData;
DataSource m_rlPercentData;

View File

@@ -35,11 +35,12 @@ class NTPIDControllerModel : public PIDControllerModel {
void Update() override;
bool Exists() override;
bool IsReadOnly() override { return false; }
bool IsReadOnly() override { return !m_controllableValue; }
private:
NetworkTablesHelper m_nt;
NT_Entry m_name;
NT_Entry m_controllable;
NT_Entry m_p;
NT_Entry m_i;
NT_Entry m_d;
@@ -51,5 +52,6 @@ class NTPIDControllerModel : public PIDControllerModel {
DataSource m_setpointData;
std::string m_nameValue;
bool m_controllableValue = false;
};
} // namespace glass

View File

@@ -29,14 +29,16 @@ class NTSpeedControllerModel : public SpeedControllerModel {
void Update() override;
bool Exists() override;
bool IsReadOnly() override { return false; }
bool IsReadOnly() override { return !m_controllableValue; }
private:
NetworkTablesHelper m_nt;
NT_Entry m_value;
NT_Entry m_name;
NT_Entry m_controllable;
DataSource m_valueData;
std::string m_nameValue;
bool m_controllableValue = false;
};
} // namespace glass

View File

@@ -79,7 +79,7 @@ inline std::string NetworkTableEntry::GetRaw(StringRef defaultValue) const {
if (!value || value->type() != NT_RAW) {
return defaultValue;
}
return value->GetString();
return value->GetRaw();
}
inline std::vector<int> NetworkTableEntry::GetBooleanArray(

View File

@@ -146,12 +146,7 @@ class GlfwKeyboardJoystick : public KeyboardJoystick {
public:
explicit GlfwKeyboardJoystick(int index, bool noDefaults = false);
const char* GetKeyName(int key) const override {
if (key < 0) {
return "(None)";
}
return glfwGetKeyName(key, 0);
}
const char* GetKeyName(int key) const override;
};
struct RobotJoystick {
@@ -274,7 +269,7 @@ class FMSSimModel : public glass::FMSModel {
// system joysticks
static std::vector<std::unique_ptr<SystemJoystick>> gGlfwJoysticks;
static int gNumGlfwJoysticks = 0;
static std::vector<std::unique_ptr<KeyboardJoystick>> gKeyboardJoysticks;
static std::vector<std::unique_ptr<GlfwKeyboardJoystick>> gKeyboardJoysticks;
// robot joysticks
static RobotJoystick gRobotJoysticks[HAL_kMaxJoysticks];
@@ -427,9 +422,9 @@ static void* KeyboardJoystickReadOpen(ImGuiContext* ctx,
if (num < 0 || num >= static_cast<int>(gKeyboardJoysticks.size())) {
return nullptr;
}
auto& joy = gKeyboardJoysticks[num];
joy = std::make_unique<GlfwKeyboardJoystick>(num, true);
return joy.get();
auto joy = gKeyboardJoysticks[num].get();
*joy = GlfwKeyboardJoystick(num, true);
return joy;
}
static void KeyboardJoystickReadLine(ImGuiContext* ctx,
@@ -1088,6 +1083,40 @@ GlfwKeyboardJoystick::GlfwKeyboardJoystick(int index, bool noDefaults)
}
}
const char* GlfwKeyboardJoystick::GetKeyName(int key) const {
if (key < 0) {
return "(None)";
}
const char* name = glfwGetKeyName(key, 0);
if (name) {
return name;
}
// glfwGetKeyName sometimes doesn't have these keys
switch (key) {
case GLFW_KEY_RIGHT:
return "Right";
case GLFW_KEY_LEFT:
return "Left";
case GLFW_KEY_DOWN:
return "Down";
case GLFW_KEY_UP:
return "Up";
case GLFW_KEY_INSERT:
return "Insert";
case GLFW_KEY_HOME:
return "Home";
case GLFW_KEY_PAGE_UP:
return "PgUp";
case GLFW_KEY_DELETE:
return "Delete";
case GLFW_KEY_END:
return "End";
case GLFW_KEY_PAGE_DOWN:
return "PgDn";
}
return "(Unknown)";
}
void RobotJoystick::Update() {
Clear();
if (sys) {

View File

@@ -48,7 +48,7 @@ bool ElevatorSim::HasHitUpperLimit(const Eigen::Matrix<double, 2, 1>& x) const {
}
units::meter_t ElevatorSim::GetPosition() const {
return units::meter_t{m_x(0)};
return units::meter_t{m_y(0)};
}
units::meters_per_second_t ElevatorSim::GetVelocity() const {

View File

@@ -50,7 +50,7 @@ bool SingleJointedArmSim::HasHitUpperLimit(
}
units::radian_t SingleJointedArmSim::GetAngle() const {
return units::radian_t{m_x(0)};
return units::radian_t{m_y(0)};
}
units::radians_per_second_t SingleJointedArmSim::GetVelocity() const {

View File

@@ -199,7 +199,7 @@ public class SingleJointedArmSim extends LinearSystemSim<N2, N1, N1> {
* @return The current arm angle.
*/
public double getAngleRads() {
return m_x.get(0, 0);
return m_y.get(0, 0);
}
/**

View File

@@ -8,20 +8,29 @@ import edu.wpi.first.wpilibj.util.Units;
/** Holds the constants for a DC motor. */
public class DCMotor {
public final double m_nominalVoltageVolts;
public final double m_stallTorqueNewtonMeters;
public final double m_stallCurrentAmps;
public final double m_freeCurrentAmps;
public final double m_freeSpeedRadPerSec;
@SuppressWarnings("MemberName")
public final double nominalVoltageVolts;
@SuppressWarnings("MemberName")
public final double m_rOhms;
public final double stallTorqueNewtonMeters;
@SuppressWarnings("MemberName")
public final double m_KvRadPerSecPerVolt;
public final double stallCurrentAmps;
@SuppressWarnings("MemberName")
public final double m_KtNMPerAmp;
public final double freeCurrentAmps;
@SuppressWarnings("MemberName")
public final double freeSpeedRadPerSec;
@SuppressWarnings("MemberName")
public final double rOhms;
@SuppressWarnings("MemberName")
public final double KvRadPerSecPerVolt;
@SuppressWarnings("MemberName")
public final double KtNMPerAmp;
/**
* Constructs a DC motor.
@@ -31,23 +40,25 @@ public class DCMotor {
* @param stallCurrentAmps Current draw when stalled.
* @param freeCurrentAmps Current draw under no load.
* @param freeSpeedRadPerSec Angular velocity under no load.
* @param numMotors Number of motors in a gearbox.
*/
public DCMotor(
double nominalVoltageVolts,
double stallTorqueNewtonMeters,
double stallCurrentAmps,
double freeCurrentAmps,
double freeSpeedRadPerSec) {
this.m_nominalVoltageVolts = nominalVoltageVolts;
this.m_stallTorqueNewtonMeters = stallTorqueNewtonMeters;
this.m_stallCurrentAmps = stallCurrentAmps;
this.m_freeCurrentAmps = freeCurrentAmps;
this.m_freeSpeedRadPerSec = freeSpeedRadPerSec;
double freeSpeedRadPerSec,
int numMotors) {
this.nominalVoltageVolts = nominalVoltageVolts;
this.stallTorqueNewtonMeters = stallTorqueNewtonMeters * numMotors;
this.stallCurrentAmps = stallCurrentAmps * numMotors;
this.freeCurrentAmps = freeCurrentAmps * numMotors;
this.freeSpeedRadPerSec = freeSpeedRadPerSec;
this.m_rOhms = nominalVoltageVolts / stallCurrentAmps;
this.m_KvRadPerSecPerVolt =
freeSpeedRadPerSec / (nominalVoltageVolts - m_rOhms * freeCurrentAmps);
this.m_KtNMPerAmp = stallTorqueNewtonMeters / stallCurrentAmps;
this.rOhms = nominalVoltageVolts / this.stallCurrentAmps;
this.KvRadPerSecPerVolt =
freeSpeedRadPerSec / (nominalVoltageVolts - rOhms * this.freeCurrentAmps);
this.KtNMPerAmp = this.stallTorqueNewtonMeters / this.stallCurrentAmps;
}
/**
@@ -57,8 +68,7 @@ public class DCMotor {
* @param voltageInputVolts The input voltage.
*/
public double getCurrent(double speedRadiansPerSec, double voltageInputVolts) {
return -1.0 / m_KvRadPerSecPerVolt / m_rOhms * speedRadiansPerSec
+ 1.0 / m_rOhms * voltageInputVolts;
return -1.0 / KvRadPerSecPerVolt / rOhms * speedRadiansPerSec + 1.0 / rOhms * voltageInputVolts;
}
/**
@@ -68,7 +78,7 @@ public class DCMotor {
*/
public static DCMotor getCIM(int numMotors) {
return new DCMotor(
12, 2.42 * numMotors, 133, 2.7, Units.rotationsPerMinuteToRadiansPerSecond(5310));
12, 2.42, 133, 2.7, Units.rotationsPerMinuteToRadiansPerSecond(5310), numMotors);
}
/**
@@ -77,9 +87,8 @@ public class DCMotor {
* @param numMotors Number of motors in the gearbox.
*/
public static DCMotor getVex775Pro(int numMotors) {
return gearbox(
new DCMotor(12, 0.71, 134, 0.7, Units.rotationsPerMinuteToRadiansPerSecond(18730)),
numMotors);
return new DCMotor(
12, 0.71, 134, 0.7, Units.rotationsPerMinuteToRadiansPerSecond(18730), numMotors);
}
/**
@@ -88,9 +97,8 @@ public class DCMotor {
* @param numMotors Number of motors in the gearbox.
*/
public static DCMotor getNEO(int numMotors) {
return gearbox(
new DCMotor(12, 2.6, 105, 1.8, Units.rotationsPerMinuteToRadiansPerSecond(5676)),
numMotors);
return new DCMotor(
12, 2.6, 105, 1.8, Units.rotationsPerMinuteToRadiansPerSecond(5676), numMotors);
}
/**
@@ -99,8 +107,8 @@ public class DCMotor {
* @param numMotors Number of motors in the gearbox.
*/
public static DCMotor getMiniCIM(int numMotors) {
return gearbox(
new DCMotor(12, 1.41, 89, 3, Units.rotationsPerMinuteToRadiansPerSecond(5840)), numMotors);
return new DCMotor(
12, 1.41, 89, 3, Units.rotationsPerMinuteToRadiansPerSecond(5840), numMotors);
}
/**
@@ -109,9 +117,8 @@ public class DCMotor {
* @param numMotors Number of motors in the gearbox.
*/
public static DCMotor getBag(int numMotors) {
return gearbox(
new DCMotor(12, 0.43, 53, 1.8, Units.rotationsPerMinuteToRadiansPerSecond(13180)),
numMotors);
return new DCMotor(
12, 0.43, 53, 1.8, Units.rotationsPerMinuteToRadiansPerSecond(13180), numMotors);
}
/**
@@ -120,9 +127,8 @@ public class DCMotor {
* @param numMotors Number of motors in the gearbox.
*/
public static DCMotor getAndymarkRs775_125(int numMotors) {
return gearbox(
new DCMotor(12, 0.28, 18, 1.6, Units.rotationsPerMinuteToRadiansPerSecond(5800.0)),
numMotors);
return new DCMotor(
12, 0.28, 18, 1.6, Units.rotationsPerMinuteToRadiansPerSecond(5800.0), numMotors);
}
/**
@@ -131,9 +137,8 @@ public class DCMotor {
* @param numMotors Number of motors in the gearbox.
*/
public static DCMotor getBanebotsRs775(int numMotors) {
return gearbox(
new DCMotor(12, 0.72, 97, 2.7, Units.rotationsPerMinuteToRadiansPerSecond(13050.0)),
numMotors);
return new DCMotor(
12, 0.72, 97, 2.7, Units.rotationsPerMinuteToRadiansPerSecond(13050.0), numMotors);
}
/**
@@ -142,9 +147,8 @@ public class DCMotor {
* @param numMotors Number of motors in the gearbox.
*/
public static DCMotor getAndymark9015(int numMotors) {
return gearbox(
new DCMotor(12, 0.36, 71, 3.7, Units.rotationsPerMinuteToRadiansPerSecond(14270.0)),
numMotors);
return new DCMotor(
12, 0.36, 71, 3.7, Units.rotationsPerMinuteToRadiansPerSecond(14270.0), numMotors);
}
/**
@@ -153,9 +157,8 @@ public class DCMotor {
* @param numMotors Number of motors in the gearbox.
*/
public static DCMotor getBanebotsRs550(int numMotors) {
return gearbox(
new DCMotor(12, 0.38, 84, 0.4, Units.rotationsPerMinuteToRadiansPerSecond(19000.0)),
numMotors);
return new DCMotor(
12, 0.38, 84, 0.4, Units.rotationsPerMinuteToRadiansPerSecond(19000.0), numMotors);
}
/**
@@ -164,9 +167,8 @@ public class DCMotor {
* @param numMotors Number of motors in the gearbox.
*/
public static DCMotor getNeo550(int numMotors) {
return gearbox(
new DCMotor(12, 0.97, 100, 1.4, Units.rotationsPerMinuteToRadiansPerSecond(11000.0)),
numMotors);
return new DCMotor(
12, 0.97, 100, 1.4, Units.rotationsPerMinuteToRadiansPerSecond(11000.0), numMotors);
}
/**
@@ -175,17 +177,7 @@ public class DCMotor {
* @param numMotors Number of motors in the gearbox.
*/
public static DCMotor getFalcon500(int numMotors) {
return gearbox(
new DCMotor(12, 4.69, 257, 1.5, Units.rotationsPerMinuteToRadiansPerSecond(6380.0)),
numMotors);
}
private static DCMotor gearbox(DCMotor motor, double numMotors) {
return new DCMotor(
motor.m_nominalVoltageVolts,
motor.m_stallTorqueNewtonMeters * numMotors,
motor.m_stallCurrentAmps,
motor.m_freeCurrentAmps,
motor.m_freeSpeedRadPerSec);
12, 4.69, 257, 1.5, Units.rotationsPerMinuteToRadiansPerSecond(6380.0), numMotors);
}
}

View File

@@ -35,13 +35,13 @@ public final class LinearSystemId {
1,
0,
-Math.pow(G, 2)
* motor.m_KtNMPerAmp
/ (motor.m_rOhms
* motor.KtNMPerAmp
/ (motor.rOhms
* radiusMeters
* radiusMeters
* massKg
* motor.m_KvRadPerSecPerVolt)),
VecBuilder.fill(0, G * motor.m_KtNMPerAmp / (motor.m_rOhms * radiusMeters * massKg)),
* motor.KvRadPerSecPerVolt)),
VecBuilder.fill(0, G * motor.KtNMPerAmp / (motor.rOhms * radiusMeters * massKg)),
Matrix.mat(Nat.N1(), Nat.N2()).fill(1, 0),
new Matrix<>(Nat.N1(), Nat.N1()));
}
@@ -61,9 +61,9 @@ public final class LinearSystemId {
VecBuilder.fill(
-G
* G
* motor.m_KtNMPerAmp
/ (motor.m_KvRadPerSecPerVolt * motor.m_rOhms * jKgMetersSquared)),
VecBuilder.fill(G * motor.m_KtNMPerAmp / (motor.m_rOhms * jKgMetersSquared)),
* motor.KtNMPerAmp
/ (motor.KvRadPerSecPerVolt * motor.rOhms * jKgMetersSquared)),
VecBuilder.fill(G * motor.KtNMPerAmp / (motor.rOhms * jKgMetersSquared)),
Matrix.eye(Nat.N1()),
new Matrix<>(Nat.N1(), Nat.N1()));
}
@@ -89,10 +89,8 @@ public final class LinearSystemId {
double JKgMetersSquared,
double G) {
var C1 =
-(G * G)
* motor.m_KtNMPerAmp
/ (motor.m_KvRadPerSecPerVolt * motor.m_rOhms * rMeters * rMeters);
var C2 = G * motor.m_KtNMPerAmp / (motor.m_rOhms * rMeters);
-(G * G) * motor.KtNMPerAmp / (motor.KvRadPerSecPerVolt * motor.rOhms * rMeters * rMeters);
var C2 = G * motor.KtNMPerAmp / (motor.rOhms * rMeters);
final double C3 = 1 / massKg + rbMeters * rbMeters / JKgMetersSquared;
final double C4 = 1 / massKg - rbMeters * rbMeters / JKgMetersSquared;
@@ -123,9 +121,9 @@ public final class LinearSystemId {
1,
0,
-Math.pow(G, 2)
* motor.m_KtNMPerAmp
/ (motor.m_KvRadPerSecPerVolt * motor.m_rOhms * jKgSquaredMeters)),
VecBuilder.fill(0, G * motor.m_KtNMPerAmp / (motor.m_rOhms * jKgSquaredMeters)),
* motor.KtNMPerAmp
/ (motor.KvRadPerSecPerVolt * motor.rOhms * jKgSquaredMeters)),
VecBuilder.fill(0, G * motor.KtNMPerAmp / (motor.rOhms * jKgSquaredMeters)),
Matrix.mat(Nat.N1(), Nat.N2()).fill(1, 0),
new Matrix<>(Nat.N1(), Nat.N1()));
}

View File

@@ -55,12 +55,12 @@ class DCMotor {
units::radians_per_second_t freeSpeed, int numMotors = 1)
: nominalVoltage(nominalVoltage),
stallTorque(stallTorque * numMotors),
stallCurrent(stallCurrent),
freeCurrent(freeCurrent),
stallCurrent(stallCurrent * numMotors),
freeCurrent(freeCurrent * numMotors),
freeSpeed(freeSpeed),
R(nominalVoltage / stallCurrent),
Kv(freeSpeed / (nominalVoltage - R * freeCurrent)),
Kt(stallTorque * numMotors / stallCurrent) {}
R(nominalVoltage / this->stallCurrent),
Kv(freeSpeed / (nominalVoltage - R * this->freeCurrent)),
Kt(this->stallTorque / this->stallCurrent) {}
/**
* Returns current drawn by motor with given speed and input voltage.

View File

@@ -39,10 +39,8 @@ public class ExtendedKalmanFilterTest {
final var J = 5.6; // Robot moment of inertia
final var C1 =
-Math.pow(gr, 2)
* motors.m_KtNMPerAmp
/ (motors.m_KvRadPerSecPerVolt * motors.m_rOhms * r * r);
final var C2 = gr * motors.m_KtNMPerAmp / (motors.m_rOhms * r);
-Math.pow(gr, 2) * motors.KtNMPerAmp / (motors.KvRadPerSecPerVolt * motors.rOhms * r * r);
final var C2 = gr * motors.KtNMPerAmp / (motors.rOhms * r);
final var k1 = 1.0 / m + rb * rb / J;
final var k2 = 1.0 / m - rb * rb / J;

View File

@@ -43,9 +43,9 @@ public class UnscentedKalmanFilterTest {
var C1 =
-Math.pow(gHigh, 2)
* motors.m_KtNMPerAmp
/ (motors.m_KvRadPerSecPerVolt * motors.m_rOhms * r * r);
var C2 = gHigh * motors.m_KtNMPerAmp / (motors.m_rOhms * r);
* motors.KtNMPerAmp
/ (motors.KvRadPerSecPerVolt * motors.rOhms * r * r);
var C2 = gHigh * motors.KtNMPerAmp / (motors.rOhms * r);
var c = x.get(2, 0);
var s = x.get(3, 0);