mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-21 01:01:43 +00:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45590eea22 | ||
|
|
834a64920b | ||
|
|
2c2ccb3618 | ||
|
|
fb5c8c39ae | ||
|
|
f7d39193a4 | ||
|
|
aec796b212 | ||
|
|
fb13bb2393 | ||
|
|
c517ec6779 | ||
|
|
e8cbf2a717 | ||
|
|
e9c86df468 | ||
|
|
6ba8c289c5 | ||
|
|
3f1672e89f | ||
|
|
15be5cbf1f | ||
|
|
4cf0e5e6db | ||
|
|
6b1898f12e | ||
|
|
b3426e9c0d | ||
|
|
38c1a1f3e0 |
@@ -1,6 +1,8 @@
|
||||
# WPILib Project
|
||||
|
||||

|
||||
[](https://first.wpi.edu/wpilib/allwpilib/docs/development/cpp/)
|
||||
[](https://first.wpi.edu/wpilib/allwpilib/docs/development/java/)
|
||||
|
||||
Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WPILibC projects. These are the core libraries for creating robot programs for the roboRIO.
|
||||
|
||||
|
||||
@@ -4,9 +4,65 @@ def baseArtifactId = 'Glass'
|
||||
def artifactGroupId = 'edu.wpi.first.tools'
|
||||
def zipBaseName = '_GROUP_edu_wpi_first_tools_ID_Glass_CLS'
|
||||
|
||||
def libBaseArtifactId = 'libglass'
|
||||
def libArtifactGroupId = 'edu.wpi.first.glass'
|
||||
def libZipBaseName = '_GROUP_edu_wpi_first_glass_ID_libglass_CLS'
|
||||
|
||||
def libntBaseArtifactId = 'libglassnt'
|
||||
def libntArtifactGroupId = 'edu.wpi.first.glass'
|
||||
def libntZipBaseName = '_GROUP_edu_wpi_first_glass_ID_libglassnt_CLS'
|
||||
|
||||
def outputsFolder = file("$project.buildDir/outputs")
|
||||
|
||||
task libCppSourcesZip(type: Zip) {
|
||||
destinationDirectory = outputsFolder
|
||||
archiveBaseName = libZipBaseName
|
||||
classifier = "sources"
|
||||
|
||||
from(licenseFile) { into '/' }
|
||||
from('src/lib/native/cpp') { into '/' }
|
||||
}
|
||||
|
||||
task libCppHeadersZip(type: Zip) {
|
||||
destinationDirectory = outputsFolder
|
||||
archiveBaseName = libZipBaseName
|
||||
classifier = "headers"
|
||||
|
||||
from(licenseFile) { into '/' }
|
||||
from('src/lib/native/include') { into '/' }
|
||||
}
|
||||
|
||||
task libntCppSourcesZip(type: Zip) {
|
||||
destinationDirectory = outputsFolder
|
||||
archiveBaseName = libntZipBaseName
|
||||
classifier = "sources"
|
||||
|
||||
from(licenseFile) { into '/' }
|
||||
from('src/libnt/native/cpp') { into '/' }
|
||||
}
|
||||
|
||||
task libntCppHeadersZip(type: Zip) {
|
||||
destinationDirectory = outputsFolder
|
||||
archiveBaseName = libntZipBaseName
|
||||
classifier = "headers"
|
||||
|
||||
from(licenseFile) { into '/' }
|
||||
from('src/libnt/native/include') { into '/' }
|
||||
}
|
||||
|
||||
build.dependsOn libCppHeadersZip
|
||||
build.dependsOn libCppSourcesZip
|
||||
build.dependsOn libntCppHeadersZip
|
||||
build.dependsOn libntCppSourcesZip
|
||||
|
||||
addTaskToCopyAllOutputs(libCppHeadersZip)
|
||||
addTaskToCopyAllOutputs(libCppSourcesZip)
|
||||
addTaskToCopyAllOutputs(libntCppHeadersZip)
|
||||
addTaskToCopyAllOutputs(libntCppSourcesZip)
|
||||
|
||||
model {
|
||||
publishing {
|
||||
def tasks = []
|
||||
def glassAppTaskList = []
|
||||
$.components.each { component ->
|
||||
component.binaries.each { binary ->
|
||||
if (binary in NativeExecutableBinarySpec && binary.component.name.contains("glassApp")) {
|
||||
@@ -50,7 +106,6 @@ model {
|
||||
}
|
||||
|
||||
// Create the ZIP.
|
||||
def outputsFolder = file("$project.buildDir/outputs")
|
||||
def task = project.tasks.create("copyGlassExecutable", Zip) {
|
||||
description("Copies the Glass executable to the outputs directory.")
|
||||
destinationDirectory = outputsFolder
|
||||
@@ -73,7 +128,7 @@ model {
|
||||
}
|
||||
|
||||
task.dependsOn binary.tasks.link
|
||||
tasks.add(task)
|
||||
glassAppTaskList.add(task)
|
||||
project.build.dependsOn task
|
||||
project.artifacts { task }
|
||||
addTaskToCopyAllOutputs(task)
|
||||
@@ -82,13 +137,37 @@ model {
|
||||
}
|
||||
}
|
||||
|
||||
def libGlassTaskList = createComponentZipTasks($.components, ['glass'], libZipBaseName, Zip, project, includeStandardZipFormat)
|
||||
def libGlassntTaskList = createComponentZipTasks($.components, ['glassnt'], libntZipBaseName, Zip, project, includeStandardZipFormat)
|
||||
|
||||
publications {
|
||||
cpp(MavenPublication) {
|
||||
tasks.each { artifact it }
|
||||
glassApp(MavenPublication) {
|
||||
glassAppTaskList.each { artifact it }
|
||||
|
||||
artifactId = baseArtifactId
|
||||
groupId = artifactGroupId
|
||||
version wpilibVersioning.version.get()
|
||||
}
|
||||
libglass(MavenPublication) {
|
||||
libGlassTaskList.each { artifact it }
|
||||
|
||||
artifact libCppHeadersZip
|
||||
artifact libCppSourcesZip
|
||||
|
||||
artifactId = libBaseArtifactId
|
||||
groupId = libArtifactGroupId
|
||||
version wpilibVersioning.version.get()
|
||||
}
|
||||
libglassnt(MavenPublication) {
|
||||
libGlassntTaskList.each { artifact it }
|
||||
|
||||
artifact libntCppHeadersZip
|
||||
artifact libntCppSourcesZip
|
||||
|
||||
artifactId = libntBaseArtifactId
|
||||
groupId = libntArtifactGroupId
|
||||
version wpilibVersioning.version.get()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,42 @@ public class SimDevice implements AutoCloseable {
|
||||
return new SimValue(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an int value on the simulated device.
|
||||
*
|
||||
* <p>Returns null if not in simulation.
|
||||
*
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param initialValue initial value
|
||||
* @return simulated double value object
|
||||
*/
|
||||
public SimInt createInt(String name, Direction direction, int initialValue) {
|
||||
int handle = SimDeviceJNI.createSimValueInt(m_handle, name, direction.m_value, initialValue);
|
||||
if (handle <= 0) {
|
||||
return null;
|
||||
}
|
||||
return new SimInt(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a long value on the simulated device.
|
||||
*
|
||||
* <p>Returns null if not in simulation.
|
||||
*
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param initialValue initial value
|
||||
* @return simulated double value object
|
||||
*/
|
||||
public SimLong createLong(String name, Direction direction, long initialValue) {
|
||||
int handle = SimDeviceJNI.createSimValueLong(m_handle, name, direction.m_value, initialValue);
|
||||
if (handle <= 0) {
|
||||
return null;
|
||||
}
|
||||
return new SimLong(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a double value on the simulated device.
|
||||
*
|
||||
|
||||
@@ -32,8 +32,8 @@ int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime,
|
||||
return sch.sched_priority;
|
||||
} else {
|
||||
*isRealTime = false;
|
||||
// 0 is the only suppored priority for non-realtime, so scale to 1
|
||||
return 1;
|
||||
// 0 is the only supported priority for non-real-time
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,46 @@ inline HAL_SimValueHandle HAL_CreateSimValue(HAL_SimDeviceHandle device,
|
||||
} // extern "C++"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Creates an int value on a simulated device.
|
||||
*
|
||||
* Returns 0 if not in simulation; this can be used to avoid calls
|
||||
* to Set/Get functions.
|
||||
*
|
||||
* @param device simulated device handle
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param initialValue initial value
|
||||
* @return simulated value handle
|
||||
*/
|
||||
inline HAL_SimValueHandle HAL_CreateSimValueInt(HAL_SimDeviceHandle device,
|
||||
const char* name,
|
||||
int32_t direction,
|
||||
int32_t initialValue) {
|
||||
struct HAL_Value v = HAL_MakeInt(initialValue);
|
||||
return HAL_CreateSimValue(device, name, direction, &v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a long value on a simulated device.
|
||||
*
|
||||
* Returns 0 if not in simulation; this can be used to avoid calls
|
||||
* to Set/Get functions.
|
||||
*
|
||||
* @param device simulated device handle
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param initialValue initial value
|
||||
* @return simulated value handle
|
||||
*/
|
||||
inline HAL_SimValueHandle HAL_CreateSimValueLong(HAL_SimDeviceHandle device,
|
||||
const char* name,
|
||||
int32_t direction,
|
||||
int64_t initialValue) {
|
||||
struct HAL_Value v = HAL_MakeLong(initialValue);
|
||||
return HAL_CreateSimValue(device, name, direction, &v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a double value on a simulated device.
|
||||
*
|
||||
@@ -708,6 +748,37 @@ class SimDevice {
|
||||
return HAL_CreateSimValue(m_handle, name, direction, &initialValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an int value on the simulated device.
|
||||
*
|
||||
* If not in simulation, results in an "empty" object that evaluates to false
|
||||
* in a boolean context.
|
||||
*
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param initialValue initial value
|
||||
* @return simulated double value object
|
||||
*/
|
||||
SimInt CreateInt(const char* name, int32_t direction, int32_t initialValue) {
|
||||
return HAL_CreateSimValueInt(m_handle, name, direction, initialValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a long value on the simulated device.
|
||||
*
|
||||
* If not in simulation, results in an "empty" object that evaluates to false
|
||||
* in a boolean context.
|
||||
*
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param initialValue initial value
|
||||
* @return simulated double value object
|
||||
*/
|
||||
SimLong CreateLong(const char* name, int32_t direction,
|
||||
int64_t initialValue) {
|
||||
return HAL_CreateSimValueLong(m_handle, name, direction, initialValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a double value on the simulated device.
|
||||
*
|
||||
|
||||
@@ -21,11 +21,13 @@ extern "C" {
|
||||
/**
|
||||
* Gets the thread priority for the specified thread.
|
||||
*
|
||||
* @param handle Native handle pointer to the thread to get the priority for
|
||||
* @param isRealTime Set to true if thread is realtime, otherwise false
|
||||
* @param status Error status variable. 0 on success
|
||||
* @return The current thread priority. Scaled 1-99, with 1 being
|
||||
* highest.
|
||||
* @param handle Native handle pointer to the thread to get the priority
|
||||
* for.
|
||||
* @param isRealTime Set to true if thread is real-time, otherwise false.
|
||||
* @param status Error status variable. 0 on success.
|
||||
* @return The current thread priority. For real-time, this is 1-99
|
||||
* with 99 being highest. For non-real-time, this is 0. See
|
||||
* "man 7 sched" for details.
|
||||
*/
|
||||
int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime,
|
||||
int32_t* status);
|
||||
@@ -34,23 +36,25 @@ int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime,
|
||||
* Gets the thread priority for the current thread.
|
||||
*
|
||||
* @param handle Native handle pointer to the thread to get the priority for
|
||||
* @param isRealTime Set to true if thread is realtime, otherwise false
|
||||
* @param status Error status variable. 0 on success
|
||||
* @return The current thread priority. Scaled 1-99, with 1 being
|
||||
* highest.
|
||||
* @param isRealTime Set to true if thread is real-time, otherwise false.
|
||||
* @param status Error status variable. 0 on success.
|
||||
* @return The current thread priority. For real-time, this is 1-99
|
||||
* with 99 being highest. For non-real-time, this is 0. See
|
||||
* "man 7 sched" for details.
|
||||
*/
|
||||
int32_t HAL_GetCurrentThreadPriority(HAL_Bool* isRealTime, int32_t* status);
|
||||
|
||||
/**
|
||||
* Sets the thread priority for the specified thread.
|
||||
*
|
||||
* @param thread Reference to the thread to set the priority of
|
||||
* @param realTime Set to true to set a realtime priority, false for standard
|
||||
* priority
|
||||
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being
|
||||
* highest
|
||||
* @param status Error status variable. 0 on success
|
||||
* @return The success state of setting the priority
|
||||
* @param thread Reference to the thread to set the priority of.
|
||||
* @param realTime Set to true to set a real-time priority, false for standard
|
||||
* priority.
|
||||
* @param priority Priority to set the thread to. For real-time, this is 1-99
|
||||
* with 99 being highest. For non-real-time, this is forced to
|
||||
* 0. See "man 7 sched" for more details.
|
||||
* @param status Error status variable. 0 on success.
|
||||
* @return True on success.
|
||||
*/
|
||||
HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime,
|
||||
int32_t priority, int32_t* status);
|
||||
@@ -58,13 +62,14 @@ HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime,
|
||||
/**
|
||||
* Sets the thread priority for the current thread.
|
||||
*
|
||||
* @param thread Reference to the thread to set the priority of
|
||||
* @param realTime Set to true to set a realtime priority, false for standard
|
||||
* priority
|
||||
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being
|
||||
* highest
|
||||
* @param status Error status variable. 0 on success
|
||||
* @return The success state of setting the priority
|
||||
* @param thread Reference to the thread to set the priority of.
|
||||
* @param realTime Set to true to set a real-time priority, false for standard
|
||||
* priority.
|
||||
* @param priority Priority to set the thread to. For real-time, this is 1-99
|
||||
* with 99 being highest. For non-real-time, this is forced to
|
||||
* 0. See "man 7 sched" for more details.
|
||||
* @param status Error status variable. 0 on success.
|
||||
* @return True on success.
|
||||
*/
|
||||
HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority,
|
||||
int32_t* status);
|
||||
|
||||
@@ -112,7 +112,7 @@ class DispatcherBase : public IDispatcher {
|
||||
// Condition variable for forced dispatch wakeup (flush)
|
||||
wpi::mutex m_flush_mutex;
|
||||
wpi::condition_variable m_flush_cv;
|
||||
uint64_t m_last_flush;
|
||||
uint64_t m_last_flush = 0;
|
||||
bool m_do_flush = false;
|
||||
|
||||
// Condition variable for client reconnect (uses user mutex)
|
||||
|
||||
@@ -11,7 +11,7 @@ nativeUtils {
|
||||
niLibVersion = "2020.10.1"
|
||||
opencvVersion = "3.4.7-5"
|
||||
googleTestVersion = "1.9.0-5-437e100-1"
|
||||
imguiVersion = "1.79-1"
|
||||
imguiVersion = "1.79-2"
|
||||
wpimathVersion = "-1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1348,7 +1348,19 @@ static void DisplaySystemJoysticks() {
|
||||
DisplaySystemJoystick(*gGlfwJoysticks[i], i);
|
||||
}
|
||||
for (size_t i = 0; i < gKeyboardJoysticks.size(); ++i) {
|
||||
DisplaySystemJoystick(*gKeyboardJoysticks[i], i + GLFW_JOYSTICK_LAST + 1);
|
||||
auto joy = gKeyboardJoysticks[i].get();
|
||||
DisplaySystemJoystick(*joy, i + GLFW_JOYSTICK_LAST + 1);
|
||||
if (ImGui::BeginPopupContextItem()) {
|
||||
char buf[64];
|
||||
std::snprintf(buf, sizeof(buf), "%s Settings", joy->GetName());
|
||||
if (ImGui::MenuItem(buf)) {
|
||||
if (auto win = DriverStationGui::dsManager.GetWindow(buf)) {
|
||||
win->SetVisible(true);
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2020 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. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
//
|
||||
// Portable File Dialogs
|
||||
|
||||
@@ -193,9 +193,11 @@ bool gui::Initialize(const char* title, int width, int height) {
|
||||
}
|
||||
|
||||
if (!gContext->loadedWidthHeight) {
|
||||
#ifndef __APPLE__
|
||||
if (windowScale == 1.0) {
|
||||
glfwGetWindowContentScale(gContext->window, &windowScale, nullptr);
|
||||
}
|
||||
#endif
|
||||
// force user scale if window scale is smaller
|
||||
if (windowScale <= 0.5) {
|
||||
gContext->userScale = 0;
|
||||
@@ -284,7 +286,9 @@ void gui::CommonRenderFrame() {
|
||||
|
||||
// Scale based on OS window content scaling
|
||||
float windowScale = 1.0;
|
||||
#ifndef __APPLE__
|
||||
glfwGetWindowContentScale(gContext->window, &windowScale, nullptr);
|
||||
#endif
|
||||
// map to closest font size: 0 = 0.5x, 1 = 0.75x, 2 = 1.0x, 3 = 1.25x,
|
||||
// 4 = 1.5x, 5 = 1.75x, 6 = 2x
|
||||
gContext->fontScale = std::clamp(
|
||||
@@ -394,12 +398,14 @@ void gui::ConfigurePlatformSaveFile(const std::string& name) {
|
||||
gContext->iniPath = name;
|
||||
#if defined(_MSC_VER)
|
||||
const char* env = std::getenv("APPDATA");
|
||||
if (env)
|
||||
if (env) {
|
||||
gContext->iniPath = env + std::string("/" + name);
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
const char* env = std::getenv("HOME");
|
||||
if (env)
|
||||
if (env) {
|
||||
gContext->iniPath = env + std::string("/Library/Preferences/" + name);
|
||||
}
|
||||
#else
|
||||
const char* xdg = std::getenv("XDG_CONFIG_HOME");
|
||||
const char* env = std::getenv("HOME");
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2019-2020 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. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#define GLFW_EXPOSE_NATIVE_COCOA
|
||||
|
||||
@@ -46,8 +46,9 @@ class Notifier : public ErrorBase {
|
||||
* This is useful for reducing scheduling jitter on processes which are
|
||||
* sensitive to timing variance, like model-based control.
|
||||
*
|
||||
* @param priority The FIFO real-time scheduler priority ([0..100] where a
|
||||
* lower number represents higher priority).
|
||||
* @param priority The FIFO real-time scheduler priority ([1..99] where a
|
||||
* higher number represents higher priority). See "man 7
|
||||
* sched" for more details.
|
||||
* @param handler The handler is called at the notification time which is set
|
||||
* using StartSingle or StartPeriodic.
|
||||
*/
|
||||
|
||||
@@ -12,16 +12,20 @@ namespace frc {
|
||||
* Get the thread priority for the specified thread.
|
||||
*
|
||||
* @param thread Reference to the thread to get the priority for.
|
||||
* @param isRealTime Set to true if thread is realtime, otherwise false.
|
||||
* @return The current thread priority. Scaled 1-99, with 1 being highest.
|
||||
* @param isRealTime Set to true if thread is real-time, otherwise false.
|
||||
* @return The current thread priority. For real-time, this is 1-99
|
||||
* with 99 being highest. For non-real-time, this is 0. See
|
||||
* "man 7 sched" for details.
|
||||
*/
|
||||
int GetThreadPriority(std::thread& thread, bool* isRealTime);
|
||||
|
||||
/**
|
||||
* Get the thread priority for the current thread
|
||||
*
|
||||
* @param isRealTime Set to true if thread is realtime, otherwise false.
|
||||
* @return The current thread priority. Scaled 1-99.
|
||||
* @param isRealTime Set to true if thread is real-time, otherwise false.
|
||||
* @return The current thread priority. For real-time, this is 1-99
|
||||
* with 99 being highest. For non-real-time, this is 0. See
|
||||
* "man 7 sched" for details.
|
||||
*/
|
||||
int GetCurrentThreadPriority(bool* isRealTime);
|
||||
|
||||
@@ -29,26 +33,24 @@ int GetCurrentThreadPriority(bool* isRealTime);
|
||||
* Sets the thread priority for the specified thread
|
||||
*
|
||||
* @param thread Reference to the thread to set the priority of.
|
||||
* @param realTime Set to true to set a realtime priority, false for standard
|
||||
* @param realTime Set to true to set a real-time priority, false for standard
|
||||
* priority.
|
||||
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being
|
||||
* highest. On RoboRIO, priority is ignored for non realtime
|
||||
* setting.
|
||||
*
|
||||
* @return The success state of setting the priority
|
||||
* @param priority Priority to set the thread to. For real-time, this is 1-99
|
||||
* with 99 being highest. For non-real-time, this is forced to
|
||||
* 0. See "man 7 sched" for more details.
|
||||
* @return True on success.
|
||||
*/
|
||||
bool SetThreadPriority(std::thread& thread, bool realTime, int priority);
|
||||
|
||||
/**
|
||||
* Sets the thread priority for the current thread
|
||||
*
|
||||
* @param realTime Set to true to set a realtime priority, false for standard
|
||||
* @param realTime Set to true to set a real-time priority, false for standard
|
||||
* priority.
|
||||
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being
|
||||
* highest. On RoboRIO, priority is ignored for non realtime
|
||||
* setting.
|
||||
*
|
||||
* @return The success state of setting the priority
|
||||
* @param priority Priority to set the thread to. For real-time, this is 1-99
|
||||
* with 99 being highest. For non-real-time, this is forced to
|
||||
* 0. See "man 7 sched" for more details.
|
||||
* @return True on success.
|
||||
*/
|
||||
bool SetCurrentThreadPriority(bool realTime, int priority);
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
DriveStraight::DriveStraight(double distance, DriveTrain* drivetrain)
|
||||
: frc2::CommandHelper<frc2::PIDCommand, DriveStraight>(
|
||||
frc2::PIDController(4, 0, 0),
|
||||
[this]() { return m_drivetrain->GetDistance(); }, distance,
|
||||
[this](double output) { m_drivetrain->Drive(output, output); },
|
||||
[drivetrain] { return drivetrain->GetDistance(); }, distance,
|
||||
[drivetrain](double output) { drivetrain->Drive(output, output); },
|
||||
{drivetrain}),
|
||||
m_drivetrain(drivetrain) {
|
||||
m_controller.SetTolerance(0.01);
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
SetDistanceToBox::SetDistanceToBox(double distance, DriveTrain* drivetrain)
|
||||
: frc2::CommandHelper<frc2::PIDCommand, SetDistanceToBox>(
|
||||
frc2::PIDController(-2, 0, 0),
|
||||
[this]() { return m_drivetrain->GetDistanceToObstacle(); }, distance,
|
||||
[this](double output) { m_drivetrain->Drive(output, output); },
|
||||
[drivetrain] { return drivetrain->GetDistanceToObstacle(); },
|
||||
distance,
|
||||
[drivetrain](double output) { drivetrain->Drive(output, output); },
|
||||
{drivetrain}),
|
||||
m_drivetrain(drivetrain) {
|
||||
m_controller.SetTolerance(0.01);
|
||||
|
||||
@@ -25,7 +25,7 @@ class Robot : public frc::TimedRobot {
|
||||
// Drive for 2 seconds
|
||||
if (m_timer.Get() < 2.0) {
|
||||
// Drive forwards half speed
|
||||
m_robotDrive.ArcadeDrive(-0.5, 0.0);
|
||||
m_robotDrive.ArcadeDrive(0.5, 0.0);
|
||||
} else {
|
||||
// Stop robot
|
||||
m_robotDrive.ArcadeDrive(0.0, 0.0);
|
||||
|
||||
@@ -48,8 +48,8 @@ void DriveSubsystem::Periodic() {
|
||||
}
|
||||
|
||||
void DriveSubsystem::Drive(double xSpeed, double ySpeed, double rot,
|
||||
bool feildRelative) {
|
||||
if (feildRelative) {
|
||||
bool fieldRelative) {
|
||||
if (fieldRelative) {
|
||||
m_drive.DriveCartesian(ySpeed, xSpeed, rot, -m_gyro.GetAngle());
|
||||
} else {
|
||||
m_drive.DriveCartesian(ySpeed, xSpeed, rot);
|
||||
|
||||
@@ -39,7 +39,7 @@ class DriveSubsystem : public frc2::SubsystemBase {
|
||||
* @param fieldRelative Whether the provided x and y speeds are relative to
|
||||
* the field.
|
||||
*/
|
||||
void Drive(double xSpeed, double ySpeed, double rot, bool feildRelative);
|
||||
void Drive(double xSpeed, double ySpeed, double rot, bool fieldRelative);
|
||||
|
||||
/**
|
||||
* Resets the drive encoders to currently read a position of 0.
|
||||
|
||||
@@ -43,7 +43,7 @@ class DriveSubsystem : public frc2::SubsystemBase {
|
||||
*/
|
||||
void Drive(units::meters_per_second_t xSpeed,
|
||||
units::meters_per_second_t ySpeed, units::radians_per_second_t rot,
|
||||
bool feildRelative);
|
||||
bool fieldRelative);
|
||||
|
||||
/**
|
||||
* Resets the drive encoders to currently read a position of 0.
|
||||
|
||||
@@ -10,16 +10,17 @@ public final class Threads {
|
||||
/**
|
||||
* Get the thread priority for the current thread.
|
||||
*
|
||||
* @return The current thread priority. Scaled 1-99.
|
||||
* @return The current thread priority. For real-time, this is 1-99 with 99 being highest. For
|
||||
* non-real-time, this is 0. See "man 7 sched" for details.
|
||||
*/
|
||||
public static int getCurrentThreadPriority() {
|
||||
return ThreadsJNI.getCurrentThreadPriority();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the current thread is realtime.
|
||||
* Get if the current thread is real-time.
|
||||
*
|
||||
* @return If the current thread is realtime
|
||||
* @return If the current thread is real-time.
|
||||
*/
|
||||
public static boolean getCurrentThreadIsRealTime() {
|
||||
return ThreadsJNI.getCurrentThreadIsRealTime();
|
||||
@@ -28,10 +29,10 @@ public final class Threads {
|
||||
/**
|
||||
* Sets the thread priority for the current thread.
|
||||
*
|
||||
* @param realTime Set to true to set a realtime priority, false for standard priority
|
||||
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being highest. On RoboRIO,
|
||||
* priority is ignored for non realtime setting
|
||||
* @return The success state of setting the priority
|
||||
* @param realTime Set to true to set a real-time priority, false for standard priority.
|
||||
* @param priority Priority to set the thread to. For real-time, this is 1-99 with 99 being
|
||||
* highest. For non-real-time, this is forced to 0. See "man 7 sched" for details.
|
||||
* @return True on success.
|
||||
*/
|
||||
public static boolean setCurrentThreadPriority(boolean realTime, int priority) {
|
||||
return ThreadsJNI.setCurrentThreadPriority(realTime, priority);
|
||||
|
||||
@@ -183,7 +183,8 @@ public class Rotation2d {
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Rotation2d) {
|
||||
return Math.abs(((Rotation2d) obj).m_value - m_value) < 1E-9;
|
||||
var other = (Rotation2d) obj;
|
||||
return Math.hypot(m_cos - other.m_cos, m_sin - other.m_sin) < 1E-9;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ Rotation2d Rotation2d::operator*(double scalar) const {
|
||||
}
|
||||
|
||||
bool Rotation2d::operator==(const Rotation2d& other) const {
|
||||
return units::math::abs(m_value - other.m_value) < 1E-9_rad;
|
||||
return std::hypot(m_cos - other.m_cos, m_sin - other.m_sin) < 1E-9;
|
||||
}
|
||||
|
||||
bool Rotation2d::operator!=(const Rotation2d& other) const {
|
||||
|
||||
@@ -101,8 +101,8 @@ class DifferentialDrivePoseEstimator {
|
||||
* gyroscope angle does not need to be reset here on the user's robot code.
|
||||
* The library automatically takes care of offsetting the gyro angle.
|
||||
*
|
||||
*@param pose The estimated pose of the robot on the field.
|
||||
*@param gyroAngle The current gyro angle.
|
||||
* @param pose The estimated pose of the robot on the field.
|
||||
* @param gyroAngle The current gyro angle.
|
||||
*/
|
||||
void ResetPosition(const Pose2d& pose, const Rotation2d& gyroAngle);
|
||||
|
||||
|
||||
@@ -41,9 +41,8 @@ namespace frc {
|
||||
*
|
||||
* <strong> u = [[vx, vy, omega]]^T </strong> in the field-coordinate system.
|
||||
*
|
||||
* <strong> y = [[x, y, std::theta]]^T </strong> in field
|
||||
* coords from vision, or <strong> y = [[theta]]^T
|
||||
* </strong> from the gyro.
|
||||
* <strong> y = [[x, y, theta]]^T </strong> in field coords from vision,
|
||||
* or <strong> y = [[theta]]^T </strong> from the gyro.
|
||||
*/
|
||||
template <size_t NumModules>
|
||||
class SwerveDrivePoseEstimator {
|
||||
|
||||
@@ -15,22 +15,22 @@ class Rotation2dTest {
|
||||
|
||||
@Test
|
||||
void testRadiansToDegrees() {
|
||||
var one = new Rotation2d(Math.PI / 3);
|
||||
var two = new Rotation2d(Math.PI / 4);
|
||||
var rot1 = new Rotation2d(Math.PI / 3);
|
||||
var rot2 = new Rotation2d(Math.PI / 4);
|
||||
|
||||
assertAll(
|
||||
() -> assertEquals(one.getDegrees(), 60.0, kEpsilon),
|
||||
() -> assertEquals(two.getDegrees(), 45.0, kEpsilon));
|
||||
() -> assertEquals(rot1.getDegrees(), 60.0, kEpsilon),
|
||||
() -> assertEquals(rot2.getDegrees(), 45.0, kEpsilon));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRadiansAndDegrees() {
|
||||
var one = Rotation2d.fromDegrees(45.0);
|
||||
var two = Rotation2d.fromDegrees(30.0);
|
||||
var rot1 = Rotation2d.fromDegrees(45.0);
|
||||
var rot2 = Rotation2d.fromDegrees(30.0);
|
||||
|
||||
assertAll(
|
||||
() -> assertEquals(one.getRadians(), Math.PI / 4, kEpsilon),
|
||||
() -> assertEquals(two.getRadians(), Math.PI / 6, kEpsilon));
|
||||
() -> assertEquals(rot1.getRadians(), Math.PI / 4, kEpsilon),
|
||||
() -> assertEquals(rot2.getRadians(), Math.PI / 6, kEpsilon));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -53,23 +53,27 @@ class Rotation2dTest {
|
||||
|
||||
@Test
|
||||
void testMinus() {
|
||||
var one = Rotation2d.fromDegrees(70.0);
|
||||
var two = Rotation2d.fromDegrees(30.0);
|
||||
var rot1 = Rotation2d.fromDegrees(70.0);
|
||||
var rot2 = Rotation2d.fromDegrees(30.0);
|
||||
|
||||
assertEquals(one.minus(two).getDegrees(), 40.0, kEpsilon);
|
||||
assertEquals(rot1.minus(rot2).getDegrees(), 40.0, kEpsilon);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquality() {
|
||||
var one = Rotation2d.fromDegrees(43.0);
|
||||
var two = Rotation2d.fromDegrees(43.0);
|
||||
assertEquals(one, two);
|
||||
var rot1 = Rotation2d.fromDegrees(43.0);
|
||||
var rot2 = Rotation2d.fromDegrees(43.0);
|
||||
assertEquals(rot1, rot2);
|
||||
|
||||
var rot3 = Rotation2d.fromDegrees(-180.0);
|
||||
var rot4 = Rotation2d.fromDegrees(180.0);
|
||||
assertEquals(rot3, rot4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInequality() {
|
||||
var one = Rotation2d.fromDegrees(43.0);
|
||||
var two = Rotation2d.fromDegrees(43.5);
|
||||
assertNotEquals(one, two);
|
||||
var rot1 = Rotation2d.fromDegrees(43.0);
|
||||
var rot2 = Rotation2d.fromDegrees(43.5);
|
||||
assertNotEquals(rot1, rot2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.wpilibj.kinematics;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import edu.wpi.first.wpilibj.geometry.Rotation2d;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class SwerveModuleStateTest {
|
||||
private static final double kEpsilon = 1E-9;
|
||||
|
||||
@Test
|
||||
void testOptimize() {
|
||||
var angleA = Rotation2d.fromDegrees(45);
|
||||
var refA = new SwerveModuleState(-2.0, Rotation2d.fromDegrees(180));
|
||||
var optimizedA = SwerveModuleState.optimize(refA, angleA);
|
||||
|
||||
assertAll(
|
||||
() -> assertEquals(2.0, optimizedA.speedMetersPerSecond, kEpsilon),
|
||||
() -> assertEquals(0.0, optimizedA.angle.getDegrees(), kEpsilon));
|
||||
|
||||
var angleB = Rotation2d.fromDegrees(-50);
|
||||
var refB = new SwerveModuleState(4.7, Rotation2d.fromDegrees(41));
|
||||
var optimizedB = SwerveModuleState.optimize(refB, angleB);
|
||||
|
||||
assertAll(
|
||||
() -> assertEquals(-4.7, optimizedB.speedMetersPerSecond, kEpsilon),
|
||||
() -> assertEquals(-139.0, optimizedB.angle.getDegrees(), kEpsilon));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoOptimize() {
|
||||
var angleA = Rotation2d.fromDegrees(0);
|
||||
var refA = new SwerveModuleState(2.0, Rotation2d.fromDegrees(89));
|
||||
var optimizedA = SwerveModuleState.optimize(refA, angleA);
|
||||
|
||||
assertAll(
|
||||
() -> assertEquals(2.0, optimizedA.speedMetersPerSecond, kEpsilon),
|
||||
() -> assertEquals(89.0, optimizedA.angle.getDegrees(), kEpsilon));
|
||||
|
||||
var angleB = Rotation2d.fromDegrees(0);
|
||||
var refB = new SwerveModuleState(-2.0, Rotation2d.fromDegrees(-2));
|
||||
var optimizedB = SwerveModuleState.optimize(refB, angleB);
|
||||
|
||||
assertAll(
|
||||
() -> assertEquals(-2.0, optimizedB.speedMetersPerSecond, kEpsilon),
|
||||
() -> assertEquals(-2.0, optimizedB.angle.getDegrees(), kEpsilon));
|
||||
}
|
||||
}
|
||||
@@ -14,19 +14,19 @@ using namespace frc;
|
||||
static constexpr double kEpsilon = 1E-9;
|
||||
|
||||
TEST(Rotation2dTest, RadiansToDegrees) {
|
||||
const Rotation2d one{units::radian_t(wpi::math::pi / 3)};
|
||||
const Rotation2d two{units::radian_t(wpi::math::pi / 4)};
|
||||
const Rotation2d rot1{units::radian_t(wpi::math::pi / 3)};
|
||||
const Rotation2d rot2{units::radian_t(wpi::math::pi / 4)};
|
||||
|
||||
EXPECT_NEAR(one.Degrees().to<double>(), 60.0, kEpsilon);
|
||||
EXPECT_NEAR(two.Degrees().to<double>(), 45.0, kEpsilon);
|
||||
EXPECT_NEAR(rot1.Degrees().to<double>(), 60.0, kEpsilon);
|
||||
EXPECT_NEAR(rot2.Degrees().to<double>(), 45.0, kEpsilon);
|
||||
}
|
||||
|
||||
TEST(Rotation2dTest, DegreesToRadians) {
|
||||
const auto one = Rotation2d(45.0_deg);
|
||||
const auto two = Rotation2d(30.0_deg);
|
||||
const auto rot1 = Rotation2d(45.0_deg);
|
||||
const auto rot2 = Rotation2d(30.0_deg);
|
||||
|
||||
EXPECT_NEAR(one.Radians().to<double>(), wpi::math::pi / 4.0, kEpsilon);
|
||||
EXPECT_NEAR(two.Radians().to<double>(), wpi::math::pi / 6.0, kEpsilon);
|
||||
EXPECT_NEAR(rot1.Radians().to<double>(), wpi::math::pi / 4.0, kEpsilon);
|
||||
EXPECT_NEAR(rot2.Radians().to<double>(), wpi::math::pi / 6.0, kEpsilon);
|
||||
}
|
||||
|
||||
TEST(Rotation2dTest, RotateByFromZero) {
|
||||
@@ -45,20 +45,24 @@ TEST(Rotation2dTest, RotateByNonZero) {
|
||||
}
|
||||
|
||||
TEST(Rotation2dTest, Minus) {
|
||||
const auto one = Rotation2d(70.0_deg);
|
||||
const auto two = Rotation2d(30.0_deg);
|
||||
const auto rot1 = Rotation2d(70.0_deg);
|
||||
const auto rot2 = Rotation2d(30.0_deg);
|
||||
|
||||
EXPECT_NEAR((one - two).Degrees().to<double>(), 40.0, kEpsilon);
|
||||
EXPECT_NEAR((rot1 - rot2).Degrees().to<double>(), 40.0, kEpsilon);
|
||||
}
|
||||
|
||||
TEST(Rotation2dTest, Equality) {
|
||||
const auto one = Rotation2d(43_deg);
|
||||
const auto two = Rotation2d(43_deg);
|
||||
EXPECT_TRUE(one == two);
|
||||
const auto rot1 = Rotation2d(43_deg);
|
||||
const auto rot2 = Rotation2d(43_deg);
|
||||
EXPECT_EQ(rot1, rot2);
|
||||
|
||||
const auto rot3 = Rotation2d(-180_deg);
|
||||
const auto rot4 = Rotation2d(180_deg);
|
||||
EXPECT_EQ(rot3, rot4);
|
||||
}
|
||||
|
||||
TEST(Rotation2dTest, Inequality) {
|
||||
const auto one = Rotation2d(43_deg);
|
||||
const auto two = Rotation2d(43.5_deg);
|
||||
EXPECT_TRUE(one != two);
|
||||
const auto rot1 = Rotation2d(43_deg);
|
||||
const auto rot2 = Rotation2d(43.5_deg);
|
||||
EXPECT_NE(rot1, rot2);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "frc/geometry/Rotation2d.h"
|
||||
#include "frc/kinematics/SwerveModuleState.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
static constexpr double kEpsilon = 1E-9;
|
||||
|
||||
TEST(SwerveModuleState, Optimize) {
|
||||
frc::Rotation2d angleA{45_deg};
|
||||
frc::SwerveModuleState refA{-2_mps, 180_deg};
|
||||
auto optimizedA = frc::SwerveModuleState::Optimize(refA, angleA);
|
||||
|
||||
EXPECT_NEAR(optimizedA.speed.to<double>(), 2.0, kEpsilon);
|
||||
EXPECT_NEAR(optimizedA.angle.Degrees().to<double>(), 0.0, kEpsilon);
|
||||
|
||||
frc::Rotation2d angleB{-50_deg};
|
||||
frc::SwerveModuleState refB{4.7_mps, 41_deg};
|
||||
auto optimizedB = frc::SwerveModuleState::Optimize(refB, angleB);
|
||||
|
||||
EXPECT_NEAR(optimizedB.speed.to<double>(), -4.7, kEpsilon);
|
||||
EXPECT_NEAR(optimizedB.angle.Degrees().to<double>(), -139.0, kEpsilon);
|
||||
}
|
||||
|
||||
TEST(SwerveModuleState, NoOptimize) {
|
||||
frc::Rotation2d angleA{0_deg};
|
||||
frc::SwerveModuleState refA{2_mps, 89_deg};
|
||||
auto optimizedA = frc::SwerveModuleState::Optimize(refA, angleA);
|
||||
|
||||
EXPECT_NEAR(optimizedA.speed.to<double>(), 2.0, kEpsilon);
|
||||
EXPECT_NEAR(optimizedA.angle.Degrees().to<double>(), 89.0, kEpsilon);
|
||||
|
||||
frc::Rotation2d angleB{0_deg};
|
||||
frc::SwerveModuleState refB{-2_mps, -2_deg};
|
||||
auto optimizedB = frc::SwerveModuleState::Optimize(refB, angleB);
|
||||
|
||||
EXPECT_NEAR(optimizedB.speed.to<double>(), -2.0, kEpsilon);
|
||||
EXPECT_NEAR(optimizedB.angle.Degrees().to<double>(), -2.0, kEpsilon);
|
||||
}
|
||||
@@ -55,7 +55,7 @@ void SetProcessorAffinity(int32_t core_id) {
|
||||
|
||||
void SetThreadRealtimePriorityOrDie(int32_t priority) {
|
||||
struct sched_param param;
|
||||
// Set realtime priority for this thread
|
||||
// Set real-time priority for this thread
|
||||
param.sched_priority = priority + sched_get_priority_min(SCHED_RR);
|
||||
ASSERT_EQ(pthread_setschedparam(pthread_self(), SCHED_RR, ¶m), 0)
|
||||
<< ": Failed to set scheduler priority.";
|
||||
|
||||
Reference in New Issue
Block a user