Compare commits
110 Commits
v2022.1.1-
...
v2022.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f4265facc | ||
|
|
63d1fb3bed | ||
|
|
36af6d25a5 | ||
|
|
8f387f7255 | ||
|
|
792e735e08 | ||
|
|
3b76de83eb | ||
|
|
ad9f738cfa | ||
|
|
49455199e5 | ||
|
|
64426502ea | ||
|
|
8cc112d196 | ||
|
|
e78cd49861 | ||
|
|
cfb4f756d6 | ||
|
|
ba0908216c | ||
|
|
a3a0334fad | ||
|
|
cf7460c3a8 | ||
|
|
db0fbb6448 | ||
|
|
8ac45f20bb | ||
|
|
b3707cca0b | ||
|
|
a69ee3ece9 | ||
|
|
750d9a30c9 | ||
|
|
41c5b2b5ac | ||
|
|
6cf3f9b28e | ||
|
|
269cf03472 | ||
|
|
5ccfc4adbd | ||
|
|
b6f44f98be | ||
|
|
0dca57e9ec | ||
|
|
22c4da152e | ||
|
|
05d66f862d | ||
|
|
b09f5b2cf2 | ||
|
|
a2510aaa0e | ||
|
|
947f589916 | ||
|
|
bbd8980a20 | ||
|
|
831052f118 | ||
|
|
c137569f91 | ||
|
|
dae61226fa | ||
|
|
3ad4594a88 | ||
|
|
112acb9a62 | ||
|
|
ecee224e81 | ||
|
|
a3645dea34 | ||
|
|
7c09f44898 | ||
|
|
f401ea9aae | ||
|
|
bf8517f1e6 | ||
|
|
528087e308 | ||
|
|
1f59ff72f9 | ||
|
|
315be873c4 | ||
|
|
b8d019cdb4 | ||
|
|
102f23bbdb | ||
|
|
b85c24a79c | ||
|
|
eee29daaf9 | ||
|
|
aa9dfabde2 | ||
|
|
5999a26fba | ||
|
|
1e82595ffb | ||
|
|
e373fa476b | ||
|
|
dceb5364f4 | ||
|
|
baacbc8e24 | ||
|
|
84b15f0883 | ||
|
|
c0da9d2d35 | ||
|
|
0fe0be2733 | ||
|
|
eafa947338 | ||
|
|
9d13ae8d01 | ||
|
|
2a64e4bae5 | ||
|
|
c3fd20db59 | ||
|
|
6f91f37cd0 | ||
|
|
5158730b81 | ||
|
|
2ad2d2ca96 | ||
|
|
b5fd29774f | ||
|
|
9f8f330e96 | ||
|
|
1ad3b1b333 | ||
|
|
dfc24425c3 | ||
|
|
c02577bb51 | ||
|
|
c9e6a96a61 | ||
|
|
9778626f34 | ||
|
|
34b2d0dae1 | ||
|
|
59a7528fd6 | ||
|
|
11d9859ef1 | ||
|
|
e44ed752ad | ||
|
|
52b2dd5b89 | ||
|
|
c46636f218 | ||
|
|
dc531462e1 | ||
|
|
92ba98621c | ||
|
|
d41d051f1b | ||
|
|
c5ae0effac | ||
|
|
b3974c6ed3 | ||
|
|
589a00e379 | ||
|
|
8d9836ca02 | ||
|
|
8b5bf8632e | ||
|
|
1846114491 | ||
|
|
2c461c794e | ||
|
|
109363daa4 | ||
|
|
41d26bee8d | ||
|
|
7269a170fb | ||
|
|
441f2ed9b0 | ||
|
|
15275433d4 | ||
|
|
1ac02d2f58 | ||
|
|
8ee6257e92 | ||
|
|
d81ef2bc5c | ||
|
|
acb64dff97 | ||
|
|
3f6cf76a8c | ||
|
|
3ef2dab465 | ||
|
|
a5a56dd067 | ||
|
|
04957a6d30 | ||
|
|
5da54888f8 | ||
|
|
6c93365b0f | ||
|
|
1c4a8bfb66 | ||
|
|
d51a1d3b3d | ||
|
|
aced2e7da6 | ||
|
|
fa1ceca83a | ||
|
|
0ea05d34e6 | ||
|
|
09db4f672b | ||
|
|
4ba80a3a8c |
4
.github/workflows/cmake.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
name: Linux
|
||||
container: wpilib/roborio-cross-ubuntu:2022-20.04
|
||||
flags: ""
|
||||
- os: macos-latest
|
||||
- os: macOS-11
|
||||
name: macOS
|
||||
container: ""
|
||||
flags: "-DWITH_JAVA=OFF"
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
|
||||
build-vcpkg:
|
||||
name: "Build - Windows"
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Prepare vcpkg
|
||||
|
||||
6
.github/workflows/gradle.yml
vendored
@@ -44,13 +44,13 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: windows-latest
|
||||
- os: windows-2019
|
||||
artifact-name: Win64
|
||||
architecture: x64
|
||||
- os: windows-latest
|
||||
- os: windows-2019
|
||||
artifact-name: Win32
|
||||
architecture: x86
|
||||
- os: macos-latest
|
||||
- os: macOS-11
|
||||
artifact-name: macOS
|
||||
architecture: x64
|
||||
name: "Build - ${{ matrix.artifact-name }}"
|
||||
|
||||
@@ -11,6 +11,7 @@ cppSrcFileInclude {
|
||||
|
||||
modifiableFileExclude {
|
||||
\.patch$
|
||||
gradlew
|
||||
}
|
||||
|
||||
generatedFileExclude {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"enableCppIntellisense": true,
|
||||
"currentLanguage": "cpp",
|
||||
"projectYear": "2021",
|
||||
"projectYear": "intellisense",
|
||||
"teamNumber": 0
|
||||
}
|
||||
|
||||
@@ -145,6 +145,8 @@ if (USE_VCPKG_EIGEN)
|
||||
set (EIGEN_VCPKG_REPLACE "find_package(Eigen3 CONFIG)")
|
||||
endif()
|
||||
|
||||
find_package(LIBSSH 0.7.1)
|
||||
|
||||
if (WITH_FLAT_INSTALL)
|
||||
set(WPIUTIL_DEP_REPLACE "include($\{SELF_DIR\}/wpiutil-config.cmake)")
|
||||
set(NTCORE_DEP_REPLACE "include($\{SELF_DIR\}/ntcore-config.cmake)")
|
||||
@@ -245,7 +247,6 @@ if (WITH_TESTS)
|
||||
include(GoogleTest)
|
||||
endif()
|
||||
|
||||
add_subdirectory(fieldImages)
|
||||
add_subdirectory(wpiutil)
|
||||
add_subdirectory(ntcore)
|
||||
|
||||
@@ -254,10 +255,14 @@ if (WITH_WPIMATH)
|
||||
endif()
|
||||
|
||||
if (WITH_GUI)
|
||||
add_subdirectory(fieldImages)
|
||||
add_subdirectory(imgui)
|
||||
add_subdirectory(wpigui)
|
||||
add_subdirectory(glass)
|
||||
add_subdirectory(outlineviewer)
|
||||
if (LIBSSH_FOUND)
|
||||
add_subdirectory(roborioteamnumbersetter)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (WITH_WPILIB OR WITH_SIMULATION_MODULES)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2009-2021 FIRST and other WPILib contributors
|
||||
Copyright (c) 2009-2022 FIRST and other WPILib contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -69,15 +69,36 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
|
||||
|
||||
* wpiutil
|
||||
|
||||
* wpigui
|
||||
* imgui
|
||||
|
||||
* ntcore
|
||||
* wpiutil
|
||||
|
||||
* wpimath
|
||||
* wpiutil
|
||||
|
||||
* glass/libglass
|
||||
* wpiutil
|
||||
* wpimath
|
||||
* wpigui
|
||||
|
||||
* glass/libglassnt
|
||||
* wpiutil
|
||||
* ntcore
|
||||
* wpimath
|
||||
* wpigui
|
||||
|
||||
* hal
|
||||
* wpiutil
|
||||
|
||||
* halsim
|
||||
* imgui
|
||||
* wpiutil
|
||||
|
||||
* ntcore
|
||||
* wpiutil
|
||||
* ntcore
|
||||
* wpimath
|
||||
* wpigui
|
||||
* libglass
|
||||
* libglassnt
|
||||
|
||||
* cscore
|
||||
* opencv
|
||||
@@ -101,6 +122,7 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
|
||||
* cameraserver
|
||||
* ntcore
|
||||
* cscore
|
||||
* wpimath
|
||||
* wpiutil
|
||||
|
||||
* wpilibNewCommands
|
||||
@@ -109,9 +131,10 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
|
||||
* cameraserver
|
||||
* ntcore
|
||||
* cscore
|
||||
* wpimath
|
||||
* wpiutil
|
||||
|
||||
* wpilibNewCommands
|
||||
* wpilibOldCommands
|
||||
* wpilibc
|
||||
* hal
|
||||
* cameraserver
|
||||
@@ -119,6 +142,7 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
|
||||
* cscore
|
||||
* wpiutil
|
||||
|
||||
|
||||
### Third Party Artifacts
|
||||
|
||||
This repository provides the builds of the following third party software.
|
||||
@@ -128,3 +152,4 @@ All artifacts are based at `edu.wpi.first.thirdparty.frcYEAR` in the repository.
|
||||
* googletest
|
||||
* imgui
|
||||
* opencv
|
||||
* libssh
|
||||
|
||||
@@ -11,6 +11,7 @@ Development builds are the per-commit build hosted everytime a commit is pushed
|
||||
In order to build a project using a development build, find the build.gradle file and open it. Then, add the following code below the plugin section and replace YEAR with the year of the development version.
|
||||
|
||||
```groovy
|
||||
wpi.maven.useLocal = false
|
||||
wpi.maven.useDevelopment = true
|
||||
wpi.versions.wpilibVersion = 'YEAR.+'
|
||||
wpi.versions.wpimathVersion = 'YEAR.+
|
||||
|
||||
@@ -39,7 +39,7 @@ Using Gradle makes building WPILib very straightforward. It only has a few depen
|
||||
- On macOS, install the JDK 11 .pkg from the link above
|
||||
- C++ compiler
|
||||
- On Linux, install GCC 8 or greater
|
||||
- On Windows, install [Visual Studio Community 2019](https://visualstudio.microsoft.com/vs/community/) and select the C++ programming language during installation (Gradle can't use the build tools for Visual Studio 2019)
|
||||
- On Windows, install [Visual Studio Community 2022 or 2019](https://visualstudio.microsoft.com/vs/community/) and select the C++ programming language during installation (Gradle can't use the build tools for Visual Studio)
|
||||
- On macOS, install the Xcode command-line build tools via `xcode-select --install`
|
||||
- ARM compiler toolchain
|
||||
- Run `./gradlew installRoboRioToolchain` after cloning this repository
|
||||
@@ -71,6 +71,8 @@ The gradlew wrapper only exists in the root of the main project, so be sure to r
|
||||
|
||||
There are a few tasks other than `build` available. To see them, run the meta-task `tasks`. This will print a list of all available tasks, with a description of each task.
|
||||
|
||||
If opening from a fresh clone, generated java dependencies will not exist. Most IDEs will not run the generation tasks, which will cause lots of IDE errors. Manually run `./gradlew compileJava` from a terminal to run all the compile tasks, and then refresh your IDE's configuration (In VS Code open settings.gradle and save).
|
||||
|
||||
### Faster builds
|
||||
|
||||
`./gradlew build` builds _everything_, which includes debug and release builds for desktop and all installed cross compilers. Many developers don't need or want to build all of this. Therefore, common tasks have shortcuts to only build necessary components for common development and testing tasks.
|
||||
|
||||
14
build.gradle
@@ -5,7 +5,7 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.hubspot.jinjava:jinjava:2.5.8'
|
||||
classpath 'com.hubspot.jinjava:jinjava:2.6.0'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,13 @@ plugins {
|
||||
id 'edu.wpi.first.wpilib.repositories.WPILibRepositoriesPlugin' version '2020.2'
|
||||
id 'edu.wpi.first.NativeUtils' apply false
|
||||
id 'edu.wpi.first.GradleJni' version '1.0.0'
|
||||
id 'edu.wpi.first.GradleVsCode' version '1.0.0'
|
||||
id 'edu.wpi.first.GradleVsCode'
|
||||
id 'idea'
|
||||
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.spotless' version '5.5.0' apply false
|
||||
id 'com.github.spotbugs' version '5.0.0-beta.1' apply false
|
||||
id 'net.ltgt.errorprone' version '2.0.2' apply false
|
||||
id 'com.github.johnrengelman.shadow' version '7.1.2' apply false
|
||||
id 'com.diffplug.spotless' version '6.1.2' apply false
|
||||
id 'com.github.spotbugs' version '5.0.4' apply false
|
||||
}
|
||||
|
||||
wpilibVersioning.buildServerMode = project.hasProperty('buildServer')
|
||||
@@ -147,5 +147,5 @@ ext.getCurrentArch = {
|
||||
}
|
||||
|
||||
wrapper {
|
||||
gradleVersion = '7.1.1'
|
||||
gradleVersion = '7.3.3'
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ repositories {
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
implementation "edu.wpi.first:native-utils:2022.3.1"
|
||||
implementation "edu.wpi.first:native-utils:2022.7.1"
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.code.gson:gson:2.8.5'
|
||||
implementation 'com.google.code.gson:gson:2.8.9'
|
||||
|
||||
implementation project(':wpiutil')
|
||||
implementation project(':ntcore')
|
||||
|
||||
@@ -56,9 +56,9 @@ public final class Main {
|
||||
public JsonObject config;
|
||||
}
|
||||
|
||||
static int team;
|
||||
static boolean server;
|
||||
static List<CameraConfig> cameras = new ArrayList<>();
|
||||
private static int team;
|
||||
private static boolean server;
|
||||
private static List<CameraConfig> cameras = new ArrayList<>();
|
||||
|
||||
private Main() {}
|
||||
|
||||
|
||||
116
cmake/modules/FindLIBSSH.cmake
Normal file
@@ -0,0 +1,116 @@
|
||||
# - Try to find LibSSH
|
||||
# Once done this will define
|
||||
#
|
||||
# LIBSSH_FOUND - system has LibSSH
|
||||
# LIBSSH_INCLUDE_DIRS - the LibSSH include directory
|
||||
# LIBSSH_LIBRARIES - link these to use LibSSH
|
||||
# LIBSSH_VERSION -
|
||||
#
|
||||
# Author Michal Vasko <mvasko@cesnet.cz>
|
||||
# Copyright (c) 2020 CESNET, z.s.p.o.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
if(LIBSSH_LIBRARIES AND LIBSSH_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(LIBSSH_FOUND TRUE)
|
||||
else()
|
||||
find_path(LIBSSH_INCLUDE_DIR
|
||||
NAMES
|
||||
libssh/libssh.h
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
${CMAKE_INCLUDE_PATH}
|
||||
${CMAKE_INSTALL_PREFIX}/include
|
||||
)
|
||||
|
||||
find_library(LIBSSH_LIBRARY
|
||||
NAMES
|
||||
ssh.so
|
||||
libssh.so
|
||||
libssh.dylib
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
${CMAKE_LIBRARY_PATH}
|
||||
${CMAKE_INSTALL_PREFIX}/lib
|
||||
)
|
||||
|
||||
if(LIBSSH_INCLUDE_DIR AND LIBSSH_LIBRARY)
|
||||
# learn libssh version
|
||||
if(EXISTS ${LIBSSH_INCLUDE_DIR}/libssh/libssh_version.h)
|
||||
set(LIBSSH_HEADER_PATH ${LIBSSH_INCLUDE_DIR}/libssh/libssh_version.h)
|
||||
else()
|
||||
set(LIBSSH_HEADER_PATH ${LIBSSH_INCLUDE_DIR}/libssh/libssh.h)
|
||||
endif()
|
||||
file(STRINGS ${LIBSSH_HEADER_PATH} LIBSSH_VERSION_MAJOR
|
||||
REGEX "#define[ ]+LIBSSH_VERSION_MAJOR[ ]+[0-9]+")
|
||||
if(NOT LIBSSH_VERSION_MAJOR)
|
||||
message(STATUS "LIBSSH_VERSION_MAJOR not found, assuming libssh is too old and cannot be used!")
|
||||
set(LIBSSH_INCLUDE_DIR "LIBSSH_INCLUDE_DIR-NOTFOUND")
|
||||
set(LIBSSH_LIBRARY "LIBSSH_LIBRARY-NOTFOUND")
|
||||
else()
|
||||
string(REGEX MATCH "[0-9]+" LIBSSH_VERSION_MAJOR ${LIBSSH_VERSION_MAJOR})
|
||||
file(STRINGS ${LIBSSH_HEADER_PATH} LIBSSH_VERSION_MINOR
|
||||
REGEX "#define[ ]+LIBSSH_VERSION_MINOR[ ]+[0-9]+")
|
||||
string(REGEX MATCH "[0-9]+" LIBSSH_VERSION_MINOR ${LIBSSH_VERSION_MINOR})
|
||||
file(STRINGS ${LIBSSH_HEADER_PATH} LIBSSH_VERSION_PATCH
|
||||
REGEX "#define[ ]+LIBSSH_VERSION_MICRO[ ]+[0-9]+")
|
||||
string(REGEX MATCH "[0-9]+" LIBSSH_VERSION_PATCH ${LIBSSH_VERSION_PATCH})
|
||||
|
||||
set(LIBSSH_VERSION ${LIBSSH_VERSION_MAJOR}.${LIBSSH_VERSION_MINOR}.${LIBSSH_VERSION_PATCH})
|
||||
|
||||
if(LIBSSH_VERSION VERSION_LESS 0.8.0)
|
||||
# libssh_threads also needs to be linked for these versions
|
||||
string(REPLACE "libssh.so" "libssh_threads.so"
|
||||
LIBSSH_THREADS_LIBRARY
|
||||
${LIBSSH_LIBRARY}
|
||||
)
|
||||
string(REPLACE "libssh.dylib" "libssh_threads.dylib"
|
||||
LIBSSH_THREADS_LIBRARY
|
||||
${LIBSSH_THREADS_LIBRARY}
|
||||
)
|
||||
string(REPLACE "ssh.so" "ssh_threads.so"
|
||||
LIBSSH_THREADS_LIBRARY
|
||||
${LIBSSH_THREADS_LIBRARY}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(LIBSSH_INCLUDE_DIRS ${LIBSSH_INCLUDE_DIR})
|
||||
set(LIBSSH_LIBRARIES ${LIBSSH_LIBRARY} ${LIBSSH_THREADS_LIBRARY})
|
||||
mark_as_advanced(LIBSSH_INCLUDE_DIRS LIBSSH_LIBRARIES)
|
||||
|
||||
find_package_handle_standard_args(LibSSH FOUND_VAR LIBSSH_FOUND
|
||||
REQUIRED_VARS LIBSSH_INCLUDE_DIRS LIBSSH_LIBRARIES
|
||||
VERSION_VAR LIBSSH_VERSION)
|
||||
endif()
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <windowsx.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <codecvt>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -25,7 +24,9 @@
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
#include <wpi/ConvertUTF.h>
|
||||
#include <wpi/MemAlloc.h>
|
||||
#include <wpi/SmallString.h>
|
||||
#include <wpi/StringExtras.h>
|
||||
#include <wpi/timestamp.h>
|
||||
|
||||
@@ -72,8 +73,9 @@ UsbCameraImpl::UsbCameraImpl(std::string_view name, wpi::Logger& logger,
|
||||
Notifier& notifier, Telemetry& telemetry,
|
||||
std::string_view path)
|
||||
: SourceImpl{name, logger, notifier, telemetry}, m_path{path} {
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
||||
m_widePath = utf8_conv.from_bytes(m_path.c_str());
|
||||
wpi::SmallVector<wchar_t, 128> wideStorage;
|
||||
wpi::sys::windows::UTF8ToUTF16(m_path, wideStorage);
|
||||
m_widePath = std::wstring{wideStorage.data(), wideStorage.size()};
|
||||
m_deviceId = -1;
|
||||
StartMessagePump();
|
||||
}
|
||||
@@ -227,7 +229,7 @@ void UsbCameraImpl::PostRequestNewFrame() {
|
||||
|
||||
bool UsbCameraImpl::CheckDeviceChange(WPARAM wParam, DEV_BROADCAST_HDR* pHdr,
|
||||
bool* connected) {
|
||||
DEV_BROADCAST_DEVICEINTERFACE* pDi = NULL;
|
||||
DEV_BROADCAST_DEVICEINTERFACE_A* pDi = NULL;
|
||||
|
||||
*connected = false;
|
||||
|
||||
@@ -240,9 +242,9 @@ bool UsbCameraImpl::CheckDeviceChange(WPARAM wParam, DEV_BROADCAST_HDR* pHdr,
|
||||
|
||||
// Compare the device name with the symbolic link.
|
||||
|
||||
pDi = reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(pHdr);
|
||||
pDi = reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE_A*>(pHdr);
|
||||
|
||||
if (_stricmp(m_path.c_str(), pDi->dbcc_name) == 0) {
|
||||
if (wpi::equals_lower(m_path, pDi->dbcc_name)) {
|
||||
if (wParam == DBT_DEVICEARRIVAL) {
|
||||
*connected = true;
|
||||
return true;
|
||||
@@ -411,11 +413,12 @@ LRESULT UsbCameraImpl::PumpMain(HWND hwnd, UINT uiMsg, WPARAM wParam,
|
||||
// If has device ID, use the device ID from the event
|
||||
// because of windows bug
|
||||
auto&& device = devices[m_deviceId];
|
||||
DEV_BROADCAST_DEVICEINTERFACE* pDi =
|
||||
reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(parameter);
|
||||
DEV_BROADCAST_DEVICEINTERFACE_A* pDi =
|
||||
reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE_A*>(parameter);
|
||||
m_path = pDi->dbcc_name;
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
||||
m_widePath = utf8_conv.from_bytes(m_path.c_str());
|
||||
wpi::SmallVector<wchar_t, 128> wideStorage;
|
||||
wpi::sys::windows::UTF8ToUTF16(m_path, wideStorage);
|
||||
m_widePath = std::wstring{wideStorage.data(), wideStorage.size()};
|
||||
} else {
|
||||
// This device not found
|
||||
break;
|
||||
@@ -482,9 +485,16 @@ bool UsbCameraImpl::DeviceConnect() {
|
||||
const wchar_t* path = m_widePath.c_str();
|
||||
m_mediaSource = CreateVideoCaptureDevice(path);
|
||||
|
||||
if (!m_mediaSource)
|
||||
if (!m_mediaSource) {
|
||||
return false;
|
||||
m_imageCallback = CreateSourceReaderCB(shared_from_this(), m_mode);
|
||||
}
|
||||
auto weakThis = weak_from_this();
|
||||
auto sharedThis = weakThis.lock();
|
||||
if (sharedThis) {
|
||||
m_imageCallback = CreateSourceReaderCB(sharedThis, m_mode);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_sourceReader =
|
||||
CreateSourceReader(m_mediaSource.Get(), m_imageCallback.Get());
|
||||
@@ -747,8 +757,9 @@ CS_StatusValue UsbCameraImpl::DeviceProcessCommand(
|
||||
{
|
||||
std::scoped_lock lock(m_mutex);
|
||||
m_path = msg->dataStr;
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
||||
m_widePath = utf8_conv.from_bytes(m_path.c_str());
|
||||
wpi::SmallVector<wchar_t, 128> wideStorage;
|
||||
wpi::sys::windows::UTF8ToUTF16(m_path, wideStorage);
|
||||
m_widePath = std::wstring{wideStorage.data(), wideStorage.size()};
|
||||
}
|
||||
DeviceDisconnect();
|
||||
DeviceConnect();
|
||||
@@ -1048,7 +1059,8 @@ std::vector<UsbCameraInfo> EnumerateUsbCameras(CS_Status* status) {
|
||||
// Ensure we are initialized by grabbing the message pump
|
||||
// GetMessagePump();
|
||||
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
||||
wpi::SmallString<128> storage;
|
||||
WCHAR buf[512];
|
||||
ComPtr<IMFAttributes> pAttributes;
|
||||
IMFActivate** ppDevices = nullptr;
|
||||
UINT32 count = 0;
|
||||
@@ -1080,14 +1092,19 @@ std::vector<UsbCameraInfo> EnumerateUsbCameras(CS_Status* status) {
|
||||
for (UINT32 i = 0; i < count; i++) {
|
||||
UsbCameraInfo info;
|
||||
info.dev = i;
|
||||
WCHAR buf[512];
|
||||
|
||||
UINT32 characters = 0;
|
||||
ppDevices[i]->GetString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, buf,
|
||||
sizeof(buf) / sizeof(WCHAR), NULL);
|
||||
info.name = utf8_conv.to_bytes(buf);
|
||||
sizeof(buf) / sizeof(WCHAR), &characters);
|
||||
storage.clear();
|
||||
wpi::sys::windows::UTF16ToUTF8(buf, characters, storage);
|
||||
info.name = storage.string();
|
||||
ppDevices[i]->GetString(
|
||||
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, buf,
|
||||
sizeof(buf) / sizeof(WCHAR), NULL);
|
||||
info.path = utf8_conv.to_bytes(buf);
|
||||
sizeof(buf) / sizeof(WCHAR), &characters);
|
||||
storage.clear();
|
||||
wpi::sys::windows::UTF16ToUTF8(buf, characters, storage);
|
||||
info.path = storage.string();
|
||||
|
||||
// Try to parse path from symbolic link
|
||||
ParseVidAndPid(info.path, &info.productId, &info.vendorId);
|
||||
|
||||
@@ -89,7 +89,7 @@ static std::shared_ptr<ClassHolder> GetClassHolder() {
|
||||
WindowsMessagePump::WindowsMessagePump(
|
||||
std::function<LRESULT(HWND, UINT, WPARAM, LPARAM)> callback) {
|
||||
m_callback = callback;
|
||||
auto handle = CreateEvent(NULL, true, false, NULL);
|
||||
auto handle = CreateEventA(NULL, true, false, NULL);
|
||||
m_mainThread = std::thread([=] { ThreadMain(handle); });
|
||||
auto waitResult = WaitForSingleObject(handle, 1000);
|
||||
if (waitResult == WAIT_OBJECT_0) {
|
||||
@@ -98,7 +98,7 @@ WindowsMessagePump::WindowsMessagePump(
|
||||
}
|
||||
|
||||
WindowsMessagePump::~WindowsMessagePump() {
|
||||
auto res = SendMessage(hwnd, WM_CLOSE, NULL, NULL);
|
||||
auto res = SendMessageA(hwnd, WM_CLOSE, NULL, NULL);
|
||||
if (m_mainThread.joinable())
|
||||
m_mainThread.join();
|
||||
}
|
||||
@@ -110,28 +110,28 @@ void WindowsMessagePump::ThreadMain(HANDLE eventHandle) {
|
||||
MFStartup(MF_VERSION);
|
||||
|
||||
auto classHolder = GetClassHolder();
|
||||
hwnd = CreateWindowEx(0, classHolder->class_name, "dummy_name", 0, 0, 0, 0, 0,
|
||||
HWND_MESSAGE, NULL, NULL, this);
|
||||
hwnd = CreateWindowExA(0, classHolder->class_name, "dummy_name", 0, 0, 0, 0,
|
||||
0, HWND_MESSAGE, NULL, NULL, this);
|
||||
|
||||
// Register for device notifications
|
||||
HDEVNOTIFY g_hdevnotify = NULL;
|
||||
HDEVNOTIFY g_hdevnotify2 = NULL;
|
||||
|
||||
DEV_BROADCAST_DEVICEINTERFACE di = {0};
|
||||
DEV_BROADCAST_DEVICEINTERFACE_A di = {0};
|
||||
di.dbcc_size = sizeof(di);
|
||||
di.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||
di.dbcc_classguid = KSCATEGORY_CAPTURE;
|
||||
|
||||
g_hdevnotify =
|
||||
RegisterDeviceNotification(hwnd, &di, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
RegisterDeviceNotificationA(hwnd, &di, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
|
||||
DEV_BROADCAST_DEVICEINTERFACE di2 = {0};
|
||||
DEV_BROADCAST_DEVICEINTERFACE_A di2 = {0};
|
||||
di2.dbcc_size = sizeof(di2);
|
||||
di2.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||
di2.dbcc_classguid = KSCATEGORY_VIDEO_CAMERA;
|
||||
|
||||
g_hdevnotify2 =
|
||||
RegisterDeviceNotification(hwnd, &di2, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
RegisterDeviceNotificationA(hwnd, &di2, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
|
||||
SetEvent(eventHandle);
|
||||
|
||||
|
||||
@@ -15,10 +15,14 @@ if (!project.hasProperty('onlylinuxathena') && !project.hasProperty('onlylinuxra
|
||||
|
||||
ext {
|
||||
nativeName = 'fieldImages'
|
||||
baseId = nativeName
|
||||
groupId = 'edu.wpi.first.fieldImages'
|
||||
devMain = "edu.wpi.first.fieldImages.DevMain"
|
||||
}
|
||||
|
||||
apply from: "${rootDir}/shared/resources.gradle"
|
||||
apply from: "${rootDir}/shared/config.gradle"
|
||||
apply from: "${rootDir}/shared/java/javacommon.gradle"
|
||||
|
||||
def generateTask = createGenerateResourcesTask('main', 'FIELDS', 'fields', project)
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
def baseArtifactId = 'fieldImages'
|
||||
def artifactGroupId = 'edu.wpi.first.fieldImages'
|
||||
def zipBaseName = '_GROUP_edu_wpi_first_field_images_ID_CLS'
|
||||
def baseArtifactId = project.nativeName
|
||||
def artifactGroupId = project.groupId
|
||||
def cppZipBaseName = "_GROUP_edu_wpi_first_fieldIimages_ID_${baseArtifactId}-cpp_CLS"
|
||||
|
||||
def outputsFolder = file("$project.buildDir/outputs")
|
||||
|
||||
task cppSourcesZip(type: Zip) {
|
||||
destinationDirectory = outputsFolder
|
||||
archiveBaseName = zipBaseName
|
||||
archiveBaseName = cppZipBaseName
|
||||
classifier = "sources"
|
||||
|
||||
from(licenseFile) {
|
||||
@@ -25,7 +25,7 @@ task cppSourcesZip(type: Zip) {
|
||||
|
||||
task cppHeadersZip(type: Zip) {
|
||||
destinationDirectory = outputsFolder
|
||||
archiveBaseName = zipBaseName
|
||||
archiveBaseName = cppZipBaseName
|
||||
classifier = "headers"
|
||||
|
||||
from(licenseFile) {
|
||||
@@ -51,7 +51,7 @@ addTaskToCopyAllOutputs(cppSourcesZip)
|
||||
|
||||
model {
|
||||
publishing {
|
||||
def wpilibCTaskList = createComponentZipTasks($.components, ['fieldImages'], zipBaseName, Zip, project, includeStandardZipFormat)
|
||||
def wpilibCTaskList = createComponentZipTasks($.components, ['fieldImages'], cppZipBaseName, Zip, project, includeStandardZipFormat)
|
||||
|
||||
publications {
|
||||
cpp(MavenPublication) {
|
||||
@@ -62,7 +62,7 @@ model {
|
||||
artifact cppHeadersZip
|
||||
artifact cppSourcesZip
|
||||
|
||||
artifactId = baseArtifactId
|
||||
artifactId = "${baseArtifactId}-cpp"
|
||||
groupId artifactGroupId
|
||||
version wpilibVersioning.version.get()
|
||||
}
|
||||
|
||||
@@ -20,4 +20,6 @@ public class FieldImages {
|
||||
public static final String k2021GalacticSearchBFieldConfig =
|
||||
"/edu/wpi/first/fields/2021-galacticsearchb.json";
|
||||
public static final String k2021SlalomFieldConfig = "/edu/wpi/first/fields/2021-slalompath.json";
|
||||
public static final String k2022RapidReactFieldConfig =
|
||||
"/edu/wpi/first/fields/2022-rapidreact.json";
|
||||
}
|
||||
|
||||
12
fieldImages/src/main/native/include/fields/2022-rapidreact.h
Normal file
@@ -0,0 +1,12 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace fields {
|
||||
std::string_view GetResource_2022_rapidreact_json();
|
||||
std::string_view GetResource_2022_field_png();
|
||||
} // namespace fields
|
||||
|
After Width: | Height: | Size: 1.8 MiB |
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"game": "Rapid React",
|
||||
"field-image": "2022-field.png",
|
||||
"field-corners": {
|
||||
"top-left": [74, 50],
|
||||
"bottom-right": [1774, 900]
|
||||
},
|
||||
"field-size": [54, 27],
|
||||
"field-unit": "foot"
|
||||
}
|
||||
@@ -185,15 +185,18 @@ if (!project.hasProperty('onlylinuxathena') && !project.hasProperty('onlylinuxra
|
||||
it.buildable = false
|
||||
return
|
||||
}
|
||||
lib project: ':cscore', library: 'cscore', linkage: 'static'
|
||||
lib library: 'glassnt', linkage: 'static'
|
||||
lib library: nativeName, linkage: 'static'
|
||||
lib project: ':ntcore', library: 'ntcore', linkage: 'static'
|
||||
lib project: ':wpiutil', library: 'wpiutil', linkage: 'static'
|
||||
lib project: ':wpimath', library: 'wpimath', linkage: 'static'
|
||||
lib project: ':wpigui', library: 'wpigui', linkage: 'static'
|
||||
nativeUtils.useRequiredLibrary(it, 'opencv_static')
|
||||
nativeUtils.useRequiredLibrary(it, 'imgui_static')
|
||||
if (it.targetPlatform.operatingSystem.isWindows()) {
|
||||
it.linker.args << 'Gdi32.lib' << 'Shell32.lib' << 'd3d11.lib' << 'd3dcompiler.lib'
|
||||
it.linker.args << '/DELAYLOAD:MF.dll' << '/DELAYLOAD:MFReadWrite.dll' << '/DELAYLOAD:MFPlat.dll' << '/delay:nobind'
|
||||
} else if (it.targetPlatform.operatingSystem.isMacOsX()) {
|
||||
it.linker.args << '-framework' << 'Metal' << '-framework' << 'MetalKit' << '-framework' << 'Cocoa' << '-framework' << 'IOKit' << '-framework' << 'CoreFoundation' << '-framework' << 'CoreVideo' << '-framework' << 'QuartzCore'
|
||||
} else {
|
||||
|
||||
52
glass/src/app/native/cpp/camerasupport.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
// 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 "camerasupport.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Windows.h"
|
||||
#include "delayimp.h"
|
||||
#pragma comment(lib, "delayimp.lib")
|
||||
static int CheckDelayException(int exception_value) {
|
||||
if (exception_value ==
|
||||
VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND) ||
|
||||
exception_value ==
|
||||
VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND)) {
|
||||
// This example just executes the handler.
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
// Don't attempt to handle other errors
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
static bool TryDelayLoadAllImports(LPCSTR szDll) {
|
||||
__try {
|
||||
HRESULT hr = __HrLoadAllImportsForDll(szDll);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
} __except (CheckDelayException(GetExceptionCode())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
namespace glass {
|
||||
bool HasCameraSupport() {
|
||||
bool hasCameraSupport = false;
|
||||
hasCameraSupport = TryDelayLoadAllImports("MF.dll");
|
||||
if (hasCameraSupport) {
|
||||
hasCameraSupport = TryDelayLoadAllImports("MFPlat.dll");
|
||||
}
|
||||
if (hasCameraSupport) {
|
||||
hasCameraSupport = TryDelayLoadAllImports("MFReadWrite.dll");
|
||||
}
|
||||
return hasCameraSupport;
|
||||
}
|
||||
} // namespace glass
|
||||
#else
|
||||
namespace glass {
|
||||
bool HasCameraSupport() {
|
||||
return true;
|
||||
}
|
||||
} // namespace glass
|
||||
#endif
|
||||
9
glass/src/app/native/cpp/camerasupport.h
Normal file
@@ -0,0 +1,9 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace glass {
|
||||
bool HasCameraSupport();
|
||||
} // namespace glass
|
||||
@@ -70,17 +70,17 @@ void glass::DisplayEncoder(EncoderModel* model) {
|
||||
std::string& name = GetStorage().GetString("name");
|
||||
char label[128];
|
||||
if (!name.empty()) {
|
||||
std::snprintf(label, sizeof(label), "%s [%d,%d]###name", name.c_str(), chA,
|
||||
chB);
|
||||
std::snprintf(label, sizeof(label), "%s [%d,%d]###header", name.c_str(),
|
||||
chA, chB);
|
||||
} else {
|
||||
std::snprintf(label, sizeof(label), "Encoder[%d,%d]###name", chA, chB);
|
||||
std::snprintf(label, sizeof(label), "Encoder[%d,%d]###header", chA, chB);
|
||||
}
|
||||
|
||||
// header
|
||||
bool open = CollapsingHeader(label);
|
||||
|
||||
// context menu to change name
|
||||
if (PopupEditName("name", &name)) {
|
||||
if (PopupEditName("header", &name)) {
|
||||
model->SetName(name);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,15 +46,16 @@ bool glass::DisplayPCMSolenoids(PCMModel* model, int index,
|
||||
std::string& name = GetStorage().GetString("name");
|
||||
char label[128];
|
||||
if (!name.empty()) {
|
||||
std::snprintf(label, sizeof(label), "%s [%d]###name", name.c_str(), index);
|
||||
std::snprintf(label, sizeof(label), "%s [%d]###header", name.c_str(),
|
||||
index);
|
||||
} else {
|
||||
std::snprintf(label, sizeof(label), "PCM[%d]###name", index);
|
||||
std::snprintf(label, sizeof(label), "PCM[%d]###header", index);
|
||||
}
|
||||
|
||||
// header
|
||||
bool open = CollapsingHeader(label);
|
||||
|
||||
PopupEditName("name", &name);
|
||||
PopupEditName("header", &name);
|
||||
|
||||
ImGui::SetItemAllowOverlap();
|
||||
ImGui::SameLine();
|
||||
|
||||
@@ -53,11 +53,11 @@ bool glass::BeginDevice(const char* id, ImGuiTreeNodeFlags flags) {
|
||||
// build label
|
||||
std::string& name = GetStorage().GetString("name");
|
||||
char label[128];
|
||||
std::snprintf(label, sizeof(label), "%s###name",
|
||||
std::snprintf(label, sizeof(label), "%s###header",
|
||||
name.empty() ? id : name.c_str());
|
||||
|
||||
bool open = CollapsingHeader(label, flags);
|
||||
PopupEditName("name", &name);
|
||||
PopupEditName("header", &name);
|
||||
|
||||
if (!open) {
|
||||
PopID();
|
||||
|
||||
@@ -17,10 +17,15 @@
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||
#endif
|
||||
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include <imgui.h>
|
||||
#include <imgui_stdlib.h>
|
||||
#include <implot.h>
|
||||
#include <implot_internal.h>
|
||||
#include <wpi/Signal.h>
|
||||
#include <wpi/SmallString.h>
|
||||
#include <wpi/SmallVector.h>
|
||||
@@ -36,6 +41,8 @@
|
||||
|
||||
using namespace glass;
|
||||
|
||||
static constexpr int kAxisCount = 3;
|
||||
|
||||
namespace {
|
||||
class PlotView;
|
||||
|
||||
@@ -129,6 +136,7 @@ class Plot {
|
||||
|
||||
private:
|
||||
void EmitSettingsLimits(int axis);
|
||||
void DragDropAccept(PlotView& view, size_t i, int yAxis);
|
||||
|
||||
bool m_paused = false;
|
||||
|
||||
@@ -137,13 +145,19 @@ class Plot {
|
||||
bool& m_showPause;
|
||||
bool& m_lockPrevX;
|
||||
bool& m_legend;
|
||||
bool& m_legendOutside;
|
||||
bool& m_legendHorizontal;
|
||||
int& m_legendLocation;
|
||||
bool& m_crosshairs;
|
||||
bool& m_antialiased;
|
||||
bool& m_mousePosition;
|
||||
bool& m_yAxis2;
|
||||
bool& m_yAxis3;
|
||||
float& m_viewTime;
|
||||
bool& m_autoHeight;
|
||||
int& m_height;
|
||||
struct PlotRange {
|
||||
explicit PlotRange(Storage& storage);
|
||||
struct PlotAxis {
|
||||
PlotAxis(Storage& storage, int num);
|
||||
|
||||
std::string& label;
|
||||
double& min;
|
||||
@@ -151,8 +165,15 @@ class Plot {
|
||||
bool& lockMin;
|
||||
bool& lockMax;
|
||||
bool apply = false;
|
||||
bool& autoFit;
|
||||
bool& logScale;
|
||||
bool& invert;
|
||||
bool& opposite;
|
||||
bool& gridLines;
|
||||
bool& tickMarks;
|
||||
bool& tickLabels;
|
||||
};
|
||||
std::vector<PlotRange> m_axis;
|
||||
std::vector<PlotAxis> m_axis;
|
||||
ImPlotRange m_xaxisRange; // read from plot, used for lockPrevX
|
||||
};
|
||||
|
||||
@@ -178,7 +199,7 @@ class PlotView : public View {
|
||||
PlotSeries::PlotSeries(Storage& storage, int yAxis)
|
||||
: m_id{storage.GetString("id")},
|
||||
m_name{storage.GetString("name")},
|
||||
m_yAxis{storage.GetInt("yAxis", yAxis)},
|
||||
m_yAxis{storage.GetInt("yAxis", 0)},
|
||||
m_color{storage.GetFloatArray("color", kDefaultColor)},
|
||||
m_marker{storage.GetString("marker"),
|
||||
0,
|
||||
@@ -188,7 +209,9 @@ PlotSeries::PlotSeries(Storage& storage, int yAxis)
|
||||
m_digital{
|
||||
storage.GetString("digital"), kAuto, {"Auto", "Digital", "Analog"}},
|
||||
m_digitalBitHeight{storage.GetInt("digitalBitHeight", 8)},
|
||||
m_digitalBitGap{storage.GetInt("digitalBitGap", 4)} {}
|
||||
m_digitalBitGap{storage.GetInt("digitalBitGap", 4)} {
|
||||
m_yAxis = yAxis;
|
||||
}
|
||||
|
||||
PlotSeries::PlotSeries(Storage& storage, std::string_view id)
|
||||
: PlotSeries{storage, 0} {
|
||||
@@ -288,7 +311,8 @@ PlotSeries::Action PlotSeries::EmitPlot(PlotView& view, double now, size_t i,
|
||||
CheckSource();
|
||||
|
||||
char label[128];
|
||||
std::snprintf(label, sizeof(label), "%s###name", GetName());
|
||||
std::snprintf(label, sizeof(label), "%s###name%d_%d", GetName(),
|
||||
static_cast<int>(i), static_cast<int>(plotIndex));
|
||||
|
||||
int size = m_size;
|
||||
int offset = m_offset;
|
||||
@@ -330,7 +354,11 @@ PlotSeries::Action PlotSeries::EmitPlot(PlotView& view, double now, size_t i,
|
||||
ImPlot::PopStyleVar();
|
||||
ImPlot::PopStyleVar();
|
||||
} else {
|
||||
ImPlot::SetPlotYAxis(m_yAxis);
|
||||
if (ImPlot::GetCurrentPlot()->YAxis(m_yAxis).Enabled) {
|
||||
ImPlot::SetAxis(ImAxis_Y1 + m_yAxis);
|
||||
} else {
|
||||
ImPlot::SetAxis(ImAxis_Y1);
|
||||
}
|
||||
ImPlot::SetNextMarkerStyle(m_marker.GetValue() - 1);
|
||||
ImPlot::PlotLineG(label, getter, &getterData, size + 1);
|
||||
}
|
||||
@@ -433,12 +461,19 @@ void PlotSeries::EmitSettings(size_t i) {
|
||||
}
|
||||
}
|
||||
|
||||
Plot::PlotRange::PlotRange(Storage& storage)
|
||||
Plot::PlotAxis::PlotAxis(Storage& storage, int num)
|
||||
: label{storage.GetString("label")},
|
||||
min{storage.GetDouble("min", 0)},
|
||||
max{storage.GetDouble("max", 1)},
|
||||
lockMin{storage.GetBool("lockMin", false)},
|
||||
lockMax{storage.GetBool("lockMax", false)} {}
|
||||
lockMax{storage.GetBool("lockMax", false)},
|
||||
autoFit{storage.GetBool("autoFit", false)},
|
||||
logScale{storage.GetBool("logScale", false)},
|
||||
invert{storage.GetBool("invert", false)},
|
||||
opposite{storage.GetBool("opposite", num != 0)},
|
||||
gridLines{storage.GetBool("gridLines", num == 0)},
|
||||
tickMarks{storage.GetBool("tickMarks", true)},
|
||||
tickLabels{storage.GetBool("tickLabels", true)} {}
|
||||
|
||||
Plot::Plot(Storage& storage)
|
||||
: m_seriesStorage{storage.GetChildArray("series")},
|
||||
@@ -447,18 +482,25 @@ Plot::Plot(Storage& storage)
|
||||
m_showPause{storage.GetBool("showPause", true)},
|
||||
m_lockPrevX{storage.GetBool("lockPrevX", false)},
|
||||
m_legend{storage.GetBool("legend", true)},
|
||||
m_legendOutside{storage.GetBool("legendOutside", false)},
|
||||
m_legendHorizontal{storage.GetBool("legendHorizontal", false)},
|
||||
m_legendLocation{
|
||||
storage.GetInt("legendLocation", ImPlotLocation_NorthWest)},
|
||||
m_crosshairs{storage.GetBool("crosshairs", false)},
|
||||
m_antialiased{storage.GetBool("antialiased", false)},
|
||||
m_mousePosition{storage.GetBool("mousePosition", true)},
|
||||
m_yAxis2{storage.GetBool("yaxis2", false)},
|
||||
m_yAxis3{storage.GetBool("yaxis3", false)},
|
||||
m_viewTime{storage.GetFloat("viewTime", 10)},
|
||||
m_autoHeight{storage.GetBool("autoHeight", true)},
|
||||
m_height{storage.GetInt("height", 300)} {
|
||||
auto& axesStorage = storage.GetChildArray("axis");
|
||||
axesStorage.resize(3);
|
||||
for (auto&& axisStorage : axesStorage) {
|
||||
if (!axisStorage) {
|
||||
axisStorage = std::make_unique<Storage>();
|
||||
axesStorage.resize(kAxisCount);
|
||||
for (int i = 0; i < kAxisCount; ++i) {
|
||||
if (!axesStorage[i]) {
|
||||
axesStorage[i] = std::make_unique<Storage>();
|
||||
}
|
||||
m_axis.emplace_back(*axisStorage);
|
||||
m_axis.emplace_back(*axesStorage[i], i);
|
||||
}
|
||||
|
||||
// loop over series
|
||||
@@ -468,20 +510,7 @@ Plot::Plot(Storage& storage)
|
||||
}
|
||||
}
|
||||
|
||||
void Plot::DragDropTarget(PlotView& view, size_t i, bool inPlot) {
|
||||
if (!ImGui::BeginDragDropTarget()) {
|
||||
return;
|
||||
}
|
||||
// handle dragging onto a specific Y axis
|
||||
int yAxis = -1;
|
||||
if (inPlot) {
|
||||
for (int y = 0; y < 3; ++y) {
|
||||
if (ImPlot::IsPlotYAxisHovered(y)) {
|
||||
yAxis = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Plot::DragDropAccept(PlotView& view, size_t i, int yAxis) {
|
||||
if (const ImGuiPayload* payload =
|
||||
ImGui::AcceptDragDropPayload("DataSource")) {
|
||||
auto source = *static_cast<DataSource**>(payload->Data);
|
||||
@@ -508,6 +537,26 @@ void Plot::DragDropTarget(PlotView& view, size_t i, bool inPlot) {
|
||||
}
|
||||
}
|
||||
|
||||
void Plot::DragDropTarget(PlotView& view, size_t i, bool inPlot) {
|
||||
if (inPlot) {
|
||||
if (ImPlot::BeginDragDropTargetPlot() ||
|
||||
ImPlot::BeginDragDropTargetLegend()) {
|
||||
DragDropAccept(view, i, -1);
|
||||
ImPlot::EndDragDropTarget();
|
||||
}
|
||||
for (int y = 0; y < kAxisCount; ++y) {
|
||||
if (ImPlot::GetCurrentPlot()->YAxis(y).Enabled &&
|
||||
ImPlot::BeginDragDropTargetAxis(ImAxis_Y1 + y)) {
|
||||
DragDropAccept(view, i, y);
|
||||
ImPlot::EndDragDropTarget();
|
||||
}
|
||||
}
|
||||
} else if (ImGui::BeginDragDropTarget()) {
|
||||
DragDropAccept(view, i, -1);
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
}
|
||||
|
||||
void Plot::EmitPlot(PlotView& view, double now, bool paused, size_t i) {
|
||||
if (!m_visible) {
|
||||
return;
|
||||
@@ -520,49 +569,63 @@ void Plot::EmitPlot(PlotView& view, double now, bool paused, size_t i) {
|
||||
}
|
||||
|
||||
char label[128];
|
||||
std::snprintf(label, sizeof(label), "%s##plot", m_name.c_str());
|
||||
|
||||
if (lockX) {
|
||||
ImPlot::SetNextPlotLimitsX(view.m_plots[i - 1]->m_xaxisRange.Min,
|
||||
view.m_plots[i - 1]->m_xaxisRange.Max,
|
||||
ImGuiCond_Always);
|
||||
} else {
|
||||
// also force-pause plots if overall timing is paused
|
||||
double zeroTime = GetZeroTime() * 1.0e-6;
|
||||
ImPlot::SetNextPlotLimitsX(
|
||||
now - zeroTime - m_viewTime, now - zeroTime,
|
||||
(paused || m_paused) ? ImGuiCond_Once : ImGuiCond_Always);
|
||||
}
|
||||
|
||||
ImPlotAxisFlags yFlags[3] = {ImPlotAxisFlags_None,
|
||||
ImPlotAxisFlags_NoGridLines,
|
||||
ImPlotAxisFlags_NoGridLines};
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
ImPlot::SetNextPlotLimitsY(
|
||||
m_axis[i].min, m_axis[i].max,
|
||||
m_axis[i].apply ? ImGuiCond_Always : ImGuiCond_Once, i);
|
||||
m_axis[i].apply = false;
|
||||
if (m_axis[i].lockMin) {
|
||||
yFlags[i] |= ImPlotAxisFlags_LockMin;
|
||||
}
|
||||
if (m_axis[i].lockMax) {
|
||||
yFlags[i] |= ImPlotAxisFlags_LockMax;
|
||||
}
|
||||
}
|
||||
|
||||
std::snprintf(label, sizeof(label), "%s###plot%d", m_name.c_str(),
|
||||
static_cast<int>(i));
|
||||
ImPlotFlags plotFlags = (m_legend ? 0 : ImPlotFlags_NoLegend) |
|
||||
(m_yAxis2 ? ImPlotFlags_YAxis2 : 0) |
|
||||
(m_yAxis3 ? ImPlotFlags_YAxis3 : 0);
|
||||
(m_crosshairs ? ImPlotFlags_Crosshairs : 0) |
|
||||
(m_antialiased ? ImPlotFlags_AntiAliased : 0) |
|
||||
(m_mousePosition ? 0 : ImPlotFlags_NoMouseText);
|
||||
|
||||
if (ImPlot::BeginPlot(label, ImVec2(-1, m_height), plotFlags)) {
|
||||
// setup legend
|
||||
if (m_legend) {
|
||||
ImPlotLegendFlags legendFlags =
|
||||
(m_legendOutside ? ImPlotLegendFlags_Outside : 0) |
|
||||
(m_legendHorizontal ? ImPlotLegendFlags_Horizontal : 0);
|
||||
ImPlot::SetupLegend(m_legendLocation, legendFlags);
|
||||
}
|
||||
|
||||
// setup x axis
|
||||
ImPlot::SetupAxis(ImAxis_X1, nullptr, ImPlotAxisFlags_NoMenus);
|
||||
if (lockX) {
|
||||
ImPlot::SetupAxisLimits(ImAxis_X1, view.m_plots[i - 1]->m_xaxisRange.Min,
|
||||
view.m_plots[i - 1]->m_xaxisRange.Max,
|
||||
ImGuiCond_Always);
|
||||
} else {
|
||||
// also force-pause plots if overall timing is paused
|
||||
double zeroTime = GetZeroTime() * 1.0e-6;
|
||||
ImPlot::SetupAxisLimits(
|
||||
ImAxis_X1, now - zeroTime - m_viewTime, now - zeroTime,
|
||||
(paused || m_paused) ? ImGuiCond_Once : ImGuiCond_Always);
|
||||
}
|
||||
|
||||
// setup y axes
|
||||
for (int i = 0; i < kAxisCount; ++i) {
|
||||
if ((i == 1 && !m_yAxis2) || (i == 2 && !m_yAxis3)) {
|
||||
continue;
|
||||
}
|
||||
ImPlotAxisFlags flags =
|
||||
(m_axis[i].lockMin ? ImPlotAxisFlags_LockMin : 0) |
|
||||
(m_axis[i].lockMax ? ImPlotAxisFlags_LockMax : 0) |
|
||||
(m_axis[i].autoFit ? ImPlotAxisFlags_AutoFit : 0) |
|
||||
(m_axis[i].logScale ? ImPlotAxisFlags_AutoFit : 0) |
|
||||
(m_axis[i].invert ? ImPlotAxisFlags_Invert : 0) |
|
||||
(m_axis[i].opposite ? ImPlotAxisFlags_Opposite : 0) |
|
||||
(m_axis[i].gridLines ? 0 : ImPlotAxisFlags_NoGridLines) |
|
||||
(m_axis[i].tickMarks ? 0 : ImPlotAxisFlags_NoTickMarks) |
|
||||
(m_axis[i].tickLabels ? 0 : ImPlotAxisFlags_NoTickLabels);
|
||||
ImPlot::SetupAxis(
|
||||
ImAxis_Y1 + i,
|
||||
m_axis[i].label.empty() ? nullptr : m_axis[i].label.c_str(), flags);
|
||||
ImPlot::SetupAxisLimits(
|
||||
ImAxis_Y1 + i, m_axis[i].min, m_axis[i].max,
|
||||
m_axis[i].apply ? ImGuiCond_Always : ImGuiCond_Once);
|
||||
m_axis[i].apply = false;
|
||||
}
|
||||
|
||||
ImPlot::SetupFinish();
|
||||
|
||||
if (ImPlot::BeginPlot(
|
||||
label, nullptr,
|
||||
m_axis[0].label.empty() ? nullptr : m_axis[0].label.c_str(),
|
||||
ImVec2(-1, m_height), plotFlags, ImPlotAxisFlags_None, yFlags[0],
|
||||
yFlags[1], yFlags[2],
|
||||
m_axis[1].label.empty() ? nullptr : m_axis[1].label.c_str(),
|
||||
m_axis[2].label.empty() ? nullptr : m_axis[2].label.c_str())) {
|
||||
for (size_t j = 0; j < m_series.size(); ++j) {
|
||||
ImGui::PushID(j);
|
||||
switch (m_series[j]->EmitPlot(view, now, j, i)) {
|
||||
case PlotSeries::kMoveUp:
|
||||
if (j > 0) {
|
||||
@@ -583,11 +646,38 @@ void Plot::EmitPlot(PlotView& view, double now, bool paused, size_t i) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
DragDropTarget(view, i, true);
|
||||
m_xaxisRange = ImPlot::GetPlotLimits().X;
|
||||
|
||||
ImPlotPlot* plot = ImPlot::GetCurrentPlot();
|
||||
ImPlot::EndPlot();
|
||||
|
||||
// copy plot settings back to storage
|
||||
m_legend = (plot->Flags & ImPlotFlags_NoLegend) == 0;
|
||||
m_crosshairs = (plot->Flags & ImPlotFlags_Crosshairs) != 0;
|
||||
m_antialiased = (plot->Flags & ImPlotFlags_AntiAliased) != 0;
|
||||
m_legendOutside =
|
||||
(plot->Items.Legend.Flags & ImPlotLegendFlags_Outside) != 0;
|
||||
m_legendHorizontal =
|
||||
(plot->Items.Legend.Flags & ImPlotLegendFlags_Horizontal) != 0;
|
||||
m_legendLocation = plot->Items.Legend.Location;
|
||||
|
||||
for (int i = 0; i < kAxisCount; ++i) {
|
||||
if ((i == 1 && !m_yAxis2) || (i == 2 && !m_yAxis3)) {
|
||||
continue;
|
||||
}
|
||||
auto flags = plot->Axes[ImAxis_Y1 + i].Flags;
|
||||
m_axis[i].lockMin = (flags & ImPlotAxisFlags_LockMin) != 0;
|
||||
m_axis[i].lockMax = (flags & ImPlotAxisFlags_LockMax) != 0;
|
||||
m_axis[i].autoFit = (flags & ImPlotAxisFlags_AutoFit) != 0;
|
||||
m_axis[i].logScale = (flags & ImPlotAxisFlags_LogScale) != 0;
|
||||
m_axis[i].invert = (flags & ImPlotAxisFlags_Invert) != 0;
|
||||
m_axis[i].opposite = (flags & ImPlotAxisFlags_Opposite) != 0;
|
||||
m_axis[i].gridLines = (flags & ImPlotAxisFlags_NoGridLines) == 0;
|
||||
m_axis[i].tickMarks = (flags & ImPlotAxisFlags_NoTickMarks) == 0;
|
||||
m_axis[i].tickLabels = (flags & ImPlotAxisFlags_NoTickLabels) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -622,7 +712,6 @@ void Plot::EmitSettings(size_t i) {
|
||||
ImGui::InputText("##editname", &m_name);
|
||||
ImGui::Checkbox("Visible", &m_visible);
|
||||
ImGui::Checkbox("Show Pause Button", &m_showPause);
|
||||
ImGui::Checkbox("Show Legend", &m_legend);
|
||||
if (i != 0) {
|
||||
ImGui::Checkbox("Lock X-axis to previous plot", &m_lockPrevX);
|
||||
}
|
||||
|
||||
@@ -160,17 +160,17 @@ bool DeleteButton(ImGuiID id, const ImVec2& pos) {
|
||||
bool HeaderDeleteButton(const char* label) {
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiLastItemDataBackup last_item_backup;
|
||||
ImGuiLastItemData last_item_backup = g.LastItemData;
|
||||
ImGuiID id = window->GetID(label);
|
||||
float button_size = g.FontSize;
|
||||
float button_x = ImMax(window->DC.LastItemRect.Min.x,
|
||||
window->DC.LastItemRect.Max.x -
|
||||
g.Style.FramePadding.x * 2.0f - button_size);
|
||||
float button_y = window->DC.LastItemRect.Min.y;
|
||||
float button_x = ImMax(
|
||||
g.LastItemData.Rect.Min.x,
|
||||
g.LastItemData.Rect.Max.x - g.Style.FramePadding.x * 2.0f - button_size);
|
||||
float button_y = g.LastItemData.Rect.Min.y;
|
||||
bool rv = DeleteButton(
|
||||
window->GetID(reinterpret_cast<void*>(static_cast<intptr_t>(id) + 1)),
|
||||
ImVec2(button_x, button_y));
|
||||
last_item_backup.Restore();
|
||||
g.LastItemData = last_item_backup;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1,8 @@
|
||||
org.gradle.jvmargs=-Xmx1g
|
||||
# The --add-exports flags work around a bug with spotless and JDK 17
|
||||
# https://github.com/diffplug/spotless/issues/834
|
||||
org.gradle.jvmargs=-Xmx1g \
|
||||
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
|
||||
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
|
||||
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
|
||||
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
|
||||
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
269
gradlew
vendored
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env sh
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -17,67 +17,101 @@
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MSYS* | MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
@@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
@@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
@@ -106,80 +140,95 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
@@ -28,6 +28,20 @@ public class ControlWord {
|
||||
m_dsAttached = dsAttached;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates from an existing word.
|
||||
*
|
||||
* @param word word to update from
|
||||
*/
|
||||
public void update(ControlWord word) {
|
||||
m_enabled = word.m_enabled;
|
||||
m_autonomous = word.m_autonomous;
|
||||
m_test = word.m_test;
|
||||
m_emergencyStop = word.m_emergencyStop;
|
||||
m_fmsAttached = word.m_fmsAttached;
|
||||
m_dsAttached = word.m_dsAttached;
|
||||
}
|
||||
|
||||
public boolean getEnabled() {
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
@@ -196,8 +196,8 @@ public final class HAL extends JNIWrapper {
|
||||
@SuppressWarnings("MissingJavadocMethod")
|
||||
public static native boolean waitForDSDataTimeout(double timeout);
|
||||
|
||||
public static int kMaxJoystickAxes = 12;
|
||||
public static int kMaxJoystickPOVs = 12;
|
||||
public static final int kMaxJoystickAxes = 12;
|
||||
public static final int kMaxJoystickPOVs = 12;
|
||||
|
||||
public static native short getJoystickAxes(byte joystickNum, float[] axesArray);
|
||||
|
||||
|
||||
123
hal/src/main/java/edu/wpi/first/hal/PowerDistributionFaults.java
Normal file
@@ -0,0 +1,123 @@
|
||||
// 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.hal;
|
||||
|
||||
public class PowerDistributionFaults {
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel0BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel1BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel2BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel3BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel4BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel5BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel6BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel7BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel8BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel9BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel10BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel11BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel12BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel13BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel14BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel15BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel16BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel17BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel18BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel19BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel20BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel21BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel22BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel23BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Brownout;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean CanWarning;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean HardwareFault;
|
||||
|
||||
/**
|
||||
* Constructs from a bitfield.
|
||||
*
|
||||
* @param faults faults
|
||||
*/
|
||||
public PowerDistributionFaults(int faults) {
|
||||
Channel0BreakerFault = (faults & 0x1) != 0;
|
||||
Channel1BreakerFault = (faults & 0x2) != 0;
|
||||
Channel2BreakerFault = (faults & 0x4) != 0;
|
||||
Channel3BreakerFault = (faults & 0x8) != 0;
|
||||
Channel4BreakerFault = (faults & 0x10) != 0;
|
||||
Channel5BreakerFault = (faults & 0x20) != 0;
|
||||
Channel6BreakerFault = (faults & 0x40) != 0;
|
||||
Channel7BreakerFault = (faults & 0x80) != 0;
|
||||
Channel8BreakerFault = (faults & 0x100) != 0;
|
||||
Channel9BreakerFault = (faults & 0x200) != 0;
|
||||
Channel10BreakerFault = (faults & 0x400) != 0;
|
||||
Channel11BreakerFault = (faults & 0x800) != 0;
|
||||
Channel12BreakerFault = (faults & 0x1000) != 0;
|
||||
Channel13BreakerFault = (faults & 0x2000) != 0;
|
||||
Channel14BreakerFault = (faults & 0x4000) != 0;
|
||||
Channel15BreakerFault = (faults & 0x8000) != 0;
|
||||
Channel16BreakerFault = (faults & 0x10000) != 0;
|
||||
Channel17BreakerFault = (faults & 0x20000) != 0;
|
||||
Channel18BreakerFault = (faults & 0x40000) != 0;
|
||||
Channel19BreakerFault = (faults & 0x80000) != 0;
|
||||
Channel20BreakerFault = (faults & 0x100000) != 0;
|
||||
Channel21BreakerFault = (faults & 0x200000) != 0;
|
||||
Channel22BreakerFault = (faults & 0x400000) != 0;
|
||||
Channel23BreakerFault = (faults & 0x800000) != 0;
|
||||
Brownout = (faults & 0x1000000) != 0;
|
||||
CanWarning = (faults & 0x2000000) != 0;
|
||||
HardwareFault = (faults & 0x4000000) != 0;
|
||||
}
|
||||
}
|
||||
@@ -56,4 +56,18 @@ public class PowerDistributionJNI extends JNIWrapper {
|
||||
public static native boolean getSwitchableChannelNoError(int handle);
|
||||
|
||||
public static native void setSwitchableChannelNoError(int handle, boolean enabled);
|
||||
|
||||
public static native int getFaultsNative(int handle);
|
||||
|
||||
public static PowerDistributionFaults getFaults(int handle) {
|
||||
return new PowerDistributionFaults(getFaultsNative(handle));
|
||||
}
|
||||
|
||||
public static native int getStickyFaultsNative(int handle);
|
||||
|
||||
public static PowerDistributionStickyFaults getStickyFaults(int handle) {
|
||||
return new PowerDistributionStickyFaults(getStickyFaultsNative(handle));
|
||||
}
|
||||
|
||||
public static native PowerDistributionVersion getVersion(int handle);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
// 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.hal;
|
||||
|
||||
public class PowerDistributionStickyFaults {
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel0BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel1BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel2BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel3BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel4BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel5BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel6BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel7BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel8BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel9BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel10BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel11BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel12BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel13BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel14BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel15BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel16BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel17BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel18BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel19BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel20BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel21BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel22BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel23BreakerFault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Brownout;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean CanWarning;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean CanBusOff;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean HasReset;
|
||||
|
||||
/**
|
||||
* Constructs from a bitfield.
|
||||
*
|
||||
* @param faults faults
|
||||
*/
|
||||
public PowerDistributionStickyFaults(int faults) {
|
||||
Channel0BreakerFault = (faults & 0x1) != 0;
|
||||
Channel1BreakerFault = (faults & 0x2) != 0;
|
||||
Channel2BreakerFault = (faults & 0x4) != 0;
|
||||
Channel3BreakerFault = (faults & 0x8) != 0;
|
||||
Channel4BreakerFault = (faults & 0x10) != 0;
|
||||
Channel5BreakerFault = (faults & 0x20) != 0;
|
||||
Channel6BreakerFault = (faults & 0x40) != 0;
|
||||
Channel7BreakerFault = (faults & 0x80) != 0;
|
||||
Channel8BreakerFault = (faults & 0x100) != 0;
|
||||
Channel9BreakerFault = (faults & 0x200) != 0;
|
||||
Channel10BreakerFault = (faults & 0x400) != 0;
|
||||
Channel11BreakerFault = (faults & 0x800) != 0;
|
||||
Channel12BreakerFault = (faults & 0x1000) != 0;
|
||||
Channel13BreakerFault = (faults & 0x2000) != 0;
|
||||
Channel14BreakerFault = (faults & 0x4000) != 0;
|
||||
Channel15BreakerFault = (faults & 0x8000) != 0;
|
||||
Channel16BreakerFault = (faults & 0x10000) != 0;
|
||||
Channel17BreakerFault = (faults & 0x20000) != 0;
|
||||
Channel18BreakerFault = (faults & 0x40000) != 0;
|
||||
Channel19BreakerFault = (faults & 0x80000) != 0;
|
||||
Channel20BreakerFault = (faults & 0x100000) != 0;
|
||||
Channel21BreakerFault = (faults & 0x200000) != 0;
|
||||
Channel22BreakerFault = (faults & 0x400000) != 0;
|
||||
Channel23BreakerFault = (faults & 0x800000) != 0;
|
||||
Brownout = (faults & 0x1000000) != 0;
|
||||
CanWarning = (faults & 0x2000000) != 0;
|
||||
CanBusOff = (faults & 0x4000000) != 0;
|
||||
HasReset = (faults & 0x8000000) != 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// 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.hal;
|
||||
|
||||
public class PowerDistributionVersion {
|
||||
@SuppressWarnings("MemberName")
|
||||
public final int firmwareMajor;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final int firmwareMinor;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final int firmwareFix;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final int hardwareMinor;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final int hardwareMajor;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final int uniqueId;
|
||||
|
||||
/**
|
||||
* Constructs a power distribution version (Called from the HAL).
|
||||
*
|
||||
* @param firmwareMajor firmware major
|
||||
* @param firmwareMinor firmware minor
|
||||
* @param firmwareFix firmware fix
|
||||
* @param hardwareMinor hardware minor
|
||||
* @param hardwareMajor hardware major
|
||||
* @param uniqueId unique id
|
||||
*/
|
||||
public PowerDistributionVersion(
|
||||
int firmwareMajor,
|
||||
int firmwareMinor,
|
||||
int firmwareFix,
|
||||
int hardwareMinor,
|
||||
int hardwareMajor,
|
||||
int uniqueId) {
|
||||
this.firmwareMajor = firmwareMajor;
|
||||
this.firmwareMinor = firmwareMinor;
|
||||
this.firmwareFix = firmwareFix;
|
||||
this.hardwareMinor = hardwareMinor;
|
||||
this.hardwareMajor = hardwareMajor;
|
||||
this.uniqueId = uniqueId;
|
||||
}
|
||||
}
|
||||
104
hal/src/main/java/edu/wpi/first/hal/REVPHFaults.java
Normal file
@@ -0,0 +1,104 @@
|
||||
// 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.hal;
|
||||
|
||||
@SuppressWarnings("AbbreviationAsWordInName")
|
||||
public class REVPHFaults {
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel0Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel1Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel2Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel3Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel4Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel5Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel6Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel7Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel8Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel9Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel10Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel11Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel12Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel13Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel14Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Channel15Fault;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean CompressorOverCurrent;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean CompressorOpen;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean SolenoidOverCurrent;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Brownout;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean CanWarning;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean HardwareFault;
|
||||
|
||||
/**
|
||||
* Called from HAL to construct.
|
||||
*
|
||||
* @param faults the fault bitfields
|
||||
*/
|
||||
public REVPHFaults(int faults) {
|
||||
Channel0Fault = (faults & 0x1) != 0;
|
||||
Channel1Fault = (faults & 0x2) != 0;
|
||||
Channel2Fault = (faults & 0x4) != 0;
|
||||
Channel3Fault = (faults & 0x8) != 0;
|
||||
Channel4Fault = (faults & 0x10) != 0;
|
||||
Channel5Fault = (faults & 0x20) != 0;
|
||||
Channel6Fault = (faults & 0x40) != 0;
|
||||
Channel7Fault = (faults & 0x80) != 0;
|
||||
Channel8Fault = (faults & 0x100) != 0;
|
||||
Channel9Fault = (faults & 0x200) != 0;
|
||||
Channel10Fault = (faults & 0x400) != 0;
|
||||
Channel11Fault = (faults & 0x800) != 0;
|
||||
Channel12Fault = (faults & 0x1000) != 0;
|
||||
Channel13Fault = (faults & 0x2000) != 0;
|
||||
Channel14Fault = (faults & 0x4000) != 0;
|
||||
Channel15Fault = (faults & 0x8000) != 0;
|
||||
CompressorOverCurrent = (faults & 0x8000) != 0;
|
||||
CompressorOpen = (faults & 0x10000) != 0;
|
||||
SolenoidOverCurrent = (faults & 0x20000) != 0;
|
||||
Brownout = (faults & 0x40000) != 0;
|
||||
CanWarning = (faults & 0x80000) != 0;
|
||||
HardwareFault = (faults & 0x100000) != 0;
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ public class REVPHJNI extends JNIWrapper {
|
||||
|
||||
public static native boolean getPressureSwitch(int handle);
|
||||
|
||||
public static native double getAnalogPressure(int handle, int channel);
|
||||
public static native double getAnalogVoltage(int handle, int channel);
|
||||
|
||||
public static native double getCompressorCurrent(int handle);
|
||||
|
||||
@@ -49,4 +49,28 @@ public class REVPHJNI extends JNIWrapper {
|
||||
public static native void setSolenoids(int handle, int mask, int values);
|
||||
|
||||
public static native void fireOneShot(int handle, int index, int durMs);
|
||||
|
||||
public static native void clearStickyFaults(int handle);
|
||||
|
||||
public static native double getInputVoltage(int handle);
|
||||
|
||||
public static native double get5VVoltage(int handle);
|
||||
|
||||
public static native double getSolenoidCurrent(int handle);
|
||||
|
||||
public static native double getSolenoidVoltage(int handle);
|
||||
|
||||
public static native int getStickyFaultsNative(int handle);
|
||||
|
||||
public static REVPHStickyFaults getStickyFaults(int handle) {
|
||||
return new REVPHStickyFaults(getStickyFaultsNative(handle));
|
||||
}
|
||||
|
||||
public static native int getFaultsNative(int handle);
|
||||
|
||||
public static REVPHFaults getFaults(int handle) {
|
||||
return new REVPHFaults(getFaultsNative(handle));
|
||||
}
|
||||
|
||||
public static native REVPHVersion getVersion(int handle);
|
||||
}
|
||||
|
||||
44
hal/src/main/java/edu/wpi/first/hal/REVPHStickyFaults.java
Normal file
@@ -0,0 +1,44 @@
|
||||
// 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.hal;
|
||||
|
||||
@SuppressWarnings("AbbreviationAsWordInName")
|
||||
public class REVPHStickyFaults {
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean CompressorOverCurrent;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean CompressorOpen;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean SolenoidOverCurrent;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean Brownout;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean CanWarning;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean CanBusOff;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final boolean HasReset;
|
||||
|
||||
/**
|
||||
* Called from HAL.
|
||||
*
|
||||
* @param faults sticky fault bit mask
|
||||
*/
|
||||
public REVPHStickyFaults(int faults) {
|
||||
CompressorOverCurrent = (faults & 0x1) != 0;
|
||||
CompressorOpen = (faults & 0x2) != 0;
|
||||
SolenoidOverCurrent = (faults & 0x4) != 0;
|
||||
Brownout = (faults & 0x8) != 0;
|
||||
CanWarning = (faults & 0x10) != 0;
|
||||
CanBusOff = (faults & 0x20) != 0;
|
||||
HasReset = (faults & 0x40) != 0;
|
||||
}
|
||||
}
|
||||
51
hal/src/main/java/edu/wpi/first/hal/REVPHVersion.java
Normal file
@@ -0,0 +1,51 @@
|
||||
// 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.hal;
|
||||
|
||||
@SuppressWarnings("AbbreviationAsWordInName")
|
||||
public class REVPHVersion {
|
||||
@SuppressWarnings("MemberName")
|
||||
public final int firmwareMajor;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final int firmwareMinor;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final int firmwareFix;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final int hardwareMinor;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final int hardwareMajor;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public final int uniqueId;
|
||||
|
||||
/**
|
||||
* Constructs a revph version (Called from the HAL).
|
||||
*
|
||||
* @param firmwareMajor firmware major
|
||||
* @param firmwareMinor firmware minor
|
||||
* @param firmwareFix firmware fix
|
||||
* @param hardwareMinor hardware minor
|
||||
* @param hardwareMajor hardware major
|
||||
* @param uniqueId unique id
|
||||
*/
|
||||
public REVPHVersion(
|
||||
int firmwareMajor,
|
||||
int firmwareMinor,
|
||||
int firmwareFix,
|
||||
int hardwareMinor,
|
||||
int hardwareMajor,
|
||||
int uniqueId) {
|
||||
this.firmwareMajor = firmwareMajor;
|
||||
this.firmwareMinor = firmwareMinor;
|
||||
this.firmwareFix = firmwareFix;
|
||||
this.hardwareMinor = hardwareMinor;
|
||||
this.hardwareMajor = hardwareMajor;
|
||||
this.uniqueId = uniqueId;
|
||||
}
|
||||
}
|
||||
@@ -14,10 +14,17 @@ public final class CANExceptionFactory {
|
||||
static final int ERR_CANSessionMux_NotAllowed = -44088;
|
||||
static final int ERR_CANSessionMux_NotInitialized = -44089;
|
||||
|
||||
@SuppressWarnings("MissingJavadocMethod")
|
||||
public static void checkStatus(int status, int messageID)
|
||||
throws CANInvalidBufferException, CANMessageNotAllowedException, CANNotInitializedException,
|
||||
UncleanStatusException {
|
||||
/**
|
||||
* Checks the status of a CAN message with the given message ID.
|
||||
*
|
||||
* @param status The CAN status.
|
||||
* @param messageID The CAN message ID.
|
||||
* @throws CANInvalidBufferException if the buffer is invalid.
|
||||
* @throws CANMessageNotAllowedException if the message isn't allowed.
|
||||
* @throws CANNotInitializedException if the CAN bus isn't initialized.
|
||||
* @throws UncleanStatusException if the status code passed in reports an error.
|
||||
*/
|
||||
public static void checkStatus(int status, int messageID) {
|
||||
switch (status) {
|
||||
case NIRioStatus.kRioStatusSuccess:
|
||||
// Everything is ok... don't throw.
|
||||
|
||||
@@ -54,6 +54,10 @@ void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) {
|
||||
}
|
||||
|
||||
if (port == HAL_I2C_kOnboard) {
|
||||
HAL_SendError(0, 0, 0,
|
||||
"Onboard I2C port is subject to system lockups. See Known "
|
||||
"Issues page for details",
|
||||
"", "", true);
|
||||
std::scoped_lock lock(digitalI2COnBoardMutex);
|
||||
i2COnboardObjCount++;
|
||||
if (i2COnboardObjCount > 1) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "hal/PowerDistribution.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
|
||||
#include "CTREPDP.h"
|
||||
@@ -55,7 +56,7 @@ HAL_PowerDistributionHandle HAL_InitializePowerDistribution(
|
||||
HAL_CleanPDP(pdpHandle);
|
||||
}
|
||||
*status = 0;
|
||||
auto pdhHandle = HAL_REV_InitializePDH(1, allocationLocation, status);
|
||||
auto pdhHandle = HAL_InitializeREVPDH(1, allocationLocation, status);
|
||||
return static_cast<HAL_PowerDistributionHandle>(pdhHandle);
|
||||
}
|
||||
|
||||
@@ -70,7 +71,7 @@ HAL_PowerDistributionHandle HAL_InitializePowerDistribution(
|
||||
moduleNumber = 1;
|
||||
}
|
||||
return static_cast<HAL_PowerDistributionHandle>(
|
||||
HAL_REV_InitializePDH(moduleNumber, allocationLocation, status));
|
||||
HAL_InitializeREVPDH(moduleNumber, allocationLocation, status));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +81,7 @@ void HAL_CleanPowerDistribution(HAL_PowerDistributionHandle handle) {
|
||||
if (IsCtre(handle)) {
|
||||
HAL_CleanPDP(handle);
|
||||
} else {
|
||||
HAL_REV_FreePDH(handle);
|
||||
HAL_FreeREVPDH(handle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +90,7 @@ int32_t HAL_GetPowerDistributionModuleNumber(HAL_PowerDistributionHandle handle,
|
||||
if (IsCtre(handle)) {
|
||||
return HAL_GetPDPModuleNumber(handle, status);
|
||||
} else {
|
||||
return HAL_REV_GetPDHModuleNumber(handle, status);
|
||||
return HAL_GetREVPDHModuleNumber(handle, status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +99,7 @@ HAL_Bool HAL_CheckPowerDistributionChannel(HAL_PowerDistributionHandle handle,
|
||||
if (IsCtre(handle)) {
|
||||
return HAL_CheckPDPChannel(channel);
|
||||
} else {
|
||||
return HAL_REV_CheckPDHChannelNumber(channel);
|
||||
return HAL_CheckREVPDHChannelNumber(channel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +108,7 @@ HAL_Bool HAL_CheckPowerDistributionModule(int32_t module,
|
||||
if (type == HAL_PowerDistributionType::HAL_PowerDistributionType_kCTRE) {
|
||||
return HAL_CheckPDPModule(module);
|
||||
} else {
|
||||
return HAL_REV_CheckPDHModuleNumber(module);
|
||||
return HAL_CheckREVPDHModuleNumber(module);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +143,7 @@ double HAL_GetPowerDistributionVoltage(HAL_PowerDistributionHandle handle,
|
||||
if (IsCtre(handle)) {
|
||||
return HAL_GetPDPVoltage(handle, status);
|
||||
} else {
|
||||
return HAL_REV_GetPDHSupplyVoltage(handle, status);
|
||||
return HAL_GetREVPDHVoltage(handle, status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +152,7 @@ double HAL_GetPowerDistributionChannelCurrent(
|
||||
if (IsCtre(handle)) {
|
||||
return HAL_GetPDPChannelCurrent(handle, channel, status);
|
||||
} else {
|
||||
return HAL_REV_GetPDHChannelCurrent(handle, channel, status);
|
||||
return HAL_GetREVPDHChannelCurrent(handle, channel, status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +172,7 @@ void HAL_GetPowerDistributionAllChannelCurrents(
|
||||
SetLastError(status, "Output array not large enough");
|
||||
return;
|
||||
}
|
||||
return HAL_REV_GetPDHAllChannelCurrents(handle, currents, status);
|
||||
return HAL_GetREVPDHAllChannelCurrents(handle, currents, status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +181,7 @@ double HAL_GetPowerDistributionTotalCurrent(HAL_PowerDistributionHandle handle,
|
||||
if (IsCtre(handle)) {
|
||||
return HAL_GetPDPTotalCurrent(handle, status);
|
||||
} else {
|
||||
return HAL_REV_GetPDHTotalCurrent(handle, status);
|
||||
return HAL_GetREVPDHTotalCurrent(handle, status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +219,7 @@ void HAL_ClearPowerDistributionStickyFaults(HAL_PowerDistributionHandle handle,
|
||||
if (IsCtre(handle)) {
|
||||
HAL_ClearPDPStickyFaults(handle, status);
|
||||
} else {
|
||||
HAL_REV_ClearPDHFaults(handle, status);
|
||||
HAL_ClearREVPDHStickyFaults(handle, status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +229,7 @@ void HAL_SetPowerDistributionSwitchableChannel(
|
||||
// No-op on CTRE
|
||||
return;
|
||||
} else {
|
||||
HAL_REV_SetPDHSwitchableChannel(handle, enabled, status);
|
||||
HAL_SetREVPDHSwitchableChannel(handle, enabled, status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,7 +239,37 @@ HAL_Bool HAL_GetPowerDistributionSwitchableChannel(
|
||||
// No-op on CTRE
|
||||
return false;
|
||||
} else {
|
||||
return HAL_REV_GetPDHSwitchableChannelState(handle, status);
|
||||
return HAL_GetREVPDHSwitchableChannelState(handle, status);
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_GetPowerDistributionVersion(HAL_PowerDistributionHandle handle,
|
||||
HAL_PowerDistributionVersion* version,
|
||||
int32_t* status) {
|
||||
if (IsCtre(handle)) {
|
||||
std::memset(version, 0, sizeof(*version));
|
||||
} else {
|
||||
HAL_GetREVPDHVersion(handle, version, status);
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_GetPowerDistributionFaults(HAL_PowerDistributionHandle handle,
|
||||
HAL_PowerDistributionFaults* faults,
|
||||
int32_t* status) {
|
||||
if (IsCtre(handle)) {
|
||||
std::memset(faults, 0, sizeof(*faults));
|
||||
} else {
|
||||
HAL_GetREVPDHFaults(handle, faults, status);
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_GetPowerDistributionStickyFaults(
|
||||
HAL_PowerDistributionHandle handle,
|
||||
HAL_PowerDistributionStickyFaults* stickyFaults, int32_t* status) {
|
||||
if (IsCtre(handle)) {
|
||||
std::memset(stickyFaults, 0, sizeof(*stickyFaults));
|
||||
} else {
|
||||
HAL_GetREVPDHStickyFaults(handle, stickyFaults, status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <hal/handles/IndexedHandleResource.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
@@ -35,6 +36,7 @@ struct REV_PDHObj {
|
||||
int32_t controlPeriod;
|
||||
HAL_CANHandle hcan;
|
||||
std::string previousAllocation;
|
||||
HAL_PowerDistributionVersion versionInfo;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -43,32 +45,26 @@ static constexpr uint32_t APIFromExtId(uint32_t extId) {
|
||||
return (extId >> 6) & 0x3FF;
|
||||
}
|
||||
|
||||
static constexpr uint32_t PDH_SWITCH_CHANNEL_SET_FRAME_API =
|
||||
APIFromExtId(PDH_SWITCH_CHANNEL_SET_FRAME_ID);
|
||||
static constexpr uint32_t PDH_SET_SWITCH_CHANNEL_FRAME_API =
|
||||
APIFromExtId(PDH_SET_SWITCH_CHANNEL_FRAME_ID);
|
||||
|
||||
static constexpr uint32_t PDH_STATUS0_FRAME_API =
|
||||
APIFromExtId(PDH_STATUS0_FRAME_ID);
|
||||
static constexpr uint32_t PDH_STATUS1_FRAME_API =
|
||||
APIFromExtId(PDH_STATUS1_FRAME_ID);
|
||||
static constexpr uint32_t PDH_STATUS2_FRAME_API =
|
||||
APIFromExtId(PDH_STATUS2_FRAME_ID);
|
||||
static constexpr uint32_t PDH_STATUS3_FRAME_API =
|
||||
APIFromExtId(PDH_STATUS3_FRAME_ID);
|
||||
static constexpr uint32_t PDH_STATUS4_FRAME_API =
|
||||
APIFromExtId(PDH_STATUS4_FRAME_ID);
|
||||
static constexpr uint32_t PDH_STATUS_0_FRAME_API =
|
||||
APIFromExtId(PDH_STATUS_0_FRAME_ID);
|
||||
static constexpr uint32_t PDH_STATUS_1_FRAME_API =
|
||||
APIFromExtId(PDH_STATUS_1_FRAME_ID);
|
||||
static constexpr uint32_t PDH_STATUS_2_FRAME_API =
|
||||
APIFromExtId(PDH_STATUS_2_FRAME_ID);
|
||||
static constexpr uint32_t PDH_STATUS_3_FRAME_API =
|
||||
APIFromExtId(PDH_STATUS_3_FRAME_ID);
|
||||
static constexpr uint32_t PDH_STATUS_4_FRAME_API =
|
||||
APIFromExtId(PDH_STATUS_4_FRAME_ID);
|
||||
|
||||
static constexpr uint32_t PDH_CLEAR_FAULTS_FRAME_API =
|
||||
APIFromExtId(PDH_CLEAR_FAULTS_FRAME_ID);
|
||||
|
||||
static constexpr uint32_t PDH_IDENTIFY_FRAME_API =
|
||||
APIFromExtId(PDH_IDENTIFY_FRAME_ID);
|
||||
|
||||
static constexpr uint32_t PDH_VERSION_FRAME_API =
|
||||
APIFromExtId(PDH_VERSION_FRAME_ID);
|
||||
|
||||
static constexpr uint32_t PDH_CONFIGURE_HR_CHANNEL_FRAME_API =
|
||||
APIFromExtId(PDH_CONFIGURE_HR_CHANNEL_FRAME_ID);
|
||||
|
||||
static constexpr int32_t kPDHFrameStatus0Timeout = 20;
|
||||
static constexpr int32_t kPDHFrameStatus1Timeout = 20;
|
||||
static constexpr int32_t kPDHFrameStatus2Timeout = 20;
|
||||
@@ -89,97 +85,97 @@ void InitializeREVPDH() {
|
||||
|
||||
extern "C" {
|
||||
|
||||
static PDH_status0_t HAL_REV_ReadPDHStatus0(HAL_CANHandle hcan,
|
||||
static PDH_status_0_t HAL_ReadREVPDHStatus0(HAL_CANHandle hcan,
|
||||
int32_t* status) {
|
||||
uint8_t packedData[8] = {0};
|
||||
int32_t length = 0;
|
||||
uint64_t timestamp = 0;
|
||||
PDH_status0_t result = {};
|
||||
PDH_status_0_t result = {};
|
||||
|
||||
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS0_FRAME_API, packedData, &length,
|
||||
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS_0_FRAME_API, packedData, &length,
|
||||
×tamp, kPDHFrameStatus0Timeout * 2, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
PDH_status0_unpack(&result, packedData, PDH_STATUS0_LENGTH);
|
||||
PDH_status_0_unpack(&result, packedData, PDH_STATUS_0_LENGTH);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static PDH_status1_t HAL_REV_ReadPDHStatus1(HAL_CANHandle hcan,
|
||||
static PDH_status_1_t HAL_ReadREVPDHStatus1(HAL_CANHandle hcan,
|
||||
int32_t* status) {
|
||||
uint8_t packedData[8] = {0};
|
||||
int32_t length = 0;
|
||||
uint64_t timestamp = 0;
|
||||
PDH_status1_t result = {};
|
||||
PDH_status_1_t result = {};
|
||||
|
||||
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS1_FRAME_API, packedData, &length,
|
||||
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS_1_FRAME_API, packedData, &length,
|
||||
×tamp, kPDHFrameStatus1Timeout * 2, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
PDH_status1_unpack(&result, packedData, PDH_STATUS1_LENGTH);
|
||||
PDH_status_1_unpack(&result, packedData, PDH_STATUS_1_LENGTH);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static PDH_status2_t HAL_REV_ReadPDHStatus2(HAL_CANHandle hcan,
|
||||
static PDH_status_2_t HAL_ReadREVPDHStatus2(HAL_CANHandle hcan,
|
||||
int32_t* status) {
|
||||
uint8_t packedData[8] = {0};
|
||||
int32_t length = 0;
|
||||
uint64_t timestamp = 0;
|
||||
PDH_status2_t result = {};
|
||||
PDH_status_2_t result = {};
|
||||
|
||||
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS2_FRAME_API, packedData, &length,
|
||||
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS_2_FRAME_API, packedData, &length,
|
||||
×tamp, kPDHFrameStatus2Timeout * 2, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
PDH_status2_unpack(&result, packedData, PDH_STATUS2_LENGTH);
|
||||
PDH_status_2_unpack(&result, packedData, PDH_STATUS_2_LENGTH);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static PDH_status3_t HAL_REV_ReadPDHStatus3(HAL_CANHandle hcan,
|
||||
static PDH_status_3_t HAL_ReadREVPDHStatus3(HAL_CANHandle hcan,
|
||||
int32_t* status) {
|
||||
uint8_t packedData[8] = {0};
|
||||
int32_t length = 0;
|
||||
uint64_t timestamp = 0;
|
||||
PDH_status3_t result = {};
|
||||
PDH_status_3_t result = {};
|
||||
|
||||
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS3_FRAME_API, packedData, &length,
|
||||
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS_3_FRAME_API, packedData, &length,
|
||||
×tamp, kPDHFrameStatus3Timeout * 2, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
PDH_status3_unpack(&result, packedData, PDH_STATUS3_LENGTH);
|
||||
PDH_status_3_unpack(&result, packedData, PDH_STATUS_3_LENGTH);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static PDH_status4_t HAL_REV_ReadPDHStatus4(HAL_CANHandle hcan,
|
||||
static PDH_status_4_t HAL_ReadREVPDHStatus4(HAL_CANHandle hcan,
|
||||
int32_t* status) {
|
||||
uint8_t packedData[8] = {0};
|
||||
int32_t length = 0;
|
||||
uint64_t timestamp = 0;
|
||||
PDH_status4_t result = {};
|
||||
PDH_status_4_t result = {};
|
||||
|
||||
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS4_FRAME_API, packedData, &length,
|
||||
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS_4_FRAME_API, packedData, &length,
|
||||
×tamp, kPDHFrameStatus4Timeout * 2, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
PDH_status4_unpack(&result, packedData, PDH_STATUS4_LENGTH);
|
||||
PDH_status_4_unpack(&result, packedData, PDH_STATUS_4_LENGTH);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -187,23 +183,23 @@ static PDH_status4_t HAL_REV_ReadPDHStatus4(HAL_CANHandle hcan,
|
||||
/**
|
||||
* Helper function for the individual getter functions for status 4
|
||||
*/
|
||||
PDH_status4_t HAL_REV_GetPDHStatus4(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
PDH_status4_t statusFrame = {};
|
||||
PDH_status_4_t HAL_GetREVPDHStatus4(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
PDH_status_4_t statusFrame = {};
|
||||
auto hpdh = REVPDHHandles->Get(handle);
|
||||
if (hpdh == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return statusFrame;
|
||||
}
|
||||
|
||||
statusFrame = HAL_REV_ReadPDHStatus4(hpdh->hcan, status);
|
||||
statusFrame = HAL_ReadREVPDHStatus4(hpdh->hcan, status);
|
||||
return statusFrame;
|
||||
}
|
||||
|
||||
HAL_REVPDHHandle HAL_REV_InitializePDH(int32_t module,
|
||||
const char* allocationLocation,
|
||||
int32_t* status) {
|
||||
HAL_REVPDHHandle HAL_InitializeREVPDH(int32_t module,
|
||||
const char* allocationLocation,
|
||||
int32_t* status) {
|
||||
hal::init::CheckInit();
|
||||
if (!HAL_REV_CheckPDHModuleNumber(module)) {
|
||||
if (!HAL_CheckREVPDHModuleNumber(module)) {
|
||||
*status = RESOURCE_OUT_OF_RANGE;
|
||||
return HAL_kInvalidHandle;
|
||||
}
|
||||
@@ -232,11 +228,12 @@ HAL_REVPDHHandle HAL_REV_InitializePDH(int32_t module,
|
||||
hpdh->previousAllocation = allocationLocation ? allocationLocation : "";
|
||||
hpdh->hcan = hcan;
|
||||
hpdh->controlPeriod = kDefaultControlPeriod;
|
||||
std::memset(&hpdh->versionInfo, 0, sizeof(hpdh->versionInfo));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void HAL_REV_FreePDH(HAL_REVPDHHandle handle) {
|
||||
void HAL_FreeREVPDH(HAL_REVPDHHandle handle) {
|
||||
auto hpdh = REVPDHHandles->Get(handle);
|
||||
if (hpdh == nullptr) {
|
||||
return;
|
||||
@@ -247,27 +244,27 @@ void HAL_REV_FreePDH(HAL_REVPDHHandle handle) {
|
||||
REVPDHHandles->Free(handle);
|
||||
}
|
||||
|
||||
int32_t HAL_REV_GetPDHModuleNumber(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
int32_t HAL_GetREVPDHModuleNumber(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
return hal::getHandleIndex(handle);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_CheckPDHModuleNumber(int32_t module) {
|
||||
HAL_Bool HAL_CheckREVPDHModuleNumber(int32_t module) {
|
||||
return ((module >= 1) && (module < kNumREVPDHModules)) ? 1 : 0;
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_CheckPDHChannelNumber(int32_t channel) {
|
||||
HAL_Bool HAL_CheckREVPDHChannelNumber(int32_t channel) {
|
||||
return ((channel >= 0) && (channel < kNumREVPDHChannels)) ? 1 : 0;
|
||||
}
|
||||
|
||||
double HAL_REV_GetPDHChannelCurrent(HAL_REVPDHHandle handle, int32_t channel,
|
||||
int32_t* status) {
|
||||
double HAL_GetREVPDHChannelCurrent(HAL_REVPDHHandle handle, int32_t channel,
|
||||
int32_t* status) {
|
||||
auto hpdh = REVPDHHandles->Get(handle);
|
||||
if (hpdh == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!HAL_REV_CheckPDHChannelNumber(channel)) {
|
||||
if (!HAL_CheckREVPDHChannelNumber(channel)) {
|
||||
*status = RESOURCE_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
@@ -275,174 +272,101 @@ double HAL_REV_GetPDHChannelCurrent(HAL_REVPDHHandle handle, int32_t channel,
|
||||
// Determine what periodic status the channel is in
|
||||
if (channel < 6) {
|
||||
// Periodic status 0
|
||||
PDH_status0_t statusFrame = HAL_REV_ReadPDHStatus0(hpdh->hcan, status);
|
||||
PDH_status_0_t statusFrame = HAL_ReadREVPDHStatus0(hpdh->hcan, status);
|
||||
switch (channel) {
|
||||
case 0:
|
||||
return PDH_status0_channel_0_current_decode(
|
||||
return PDH_status_0_channel_0_current_decode(
|
||||
statusFrame.channel_0_current);
|
||||
case 1:
|
||||
return PDH_status0_channel_1_current_decode(
|
||||
return PDH_status_0_channel_1_current_decode(
|
||||
statusFrame.channel_1_current);
|
||||
case 2:
|
||||
return PDH_status0_channel_2_current_decode(
|
||||
return PDH_status_0_channel_2_current_decode(
|
||||
statusFrame.channel_2_current);
|
||||
case 3:
|
||||
return PDH_status0_channel_3_current_decode(
|
||||
return PDH_status_0_channel_3_current_decode(
|
||||
statusFrame.channel_3_current);
|
||||
case 4:
|
||||
return PDH_status0_channel_4_current_decode(
|
||||
return PDH_status_0_channel_4_current_decode(
|
||||
statusFrame.channel_4_current);
|
||||
case 5:
|
||||
return PDH_status0_channel_5_current_decode(
|
||||
return PDH_status_0_channel_5_current_decode(
|
||||
statusFrame.channel_5_current);
|
||||
}
|
||||
} else if (channel < 12) {
|
||||
// Periodic status 1
|
||||
PDH_status1_t statusFrame = HAL_REV_ReadPDHStatus1(hpdh->hcan, status);
|
||||
PDH_status_1_t statusFrame = HAL_ReadREVPDHStatus1(hpdh->hcan, status);
|
||||
switch (channel) {
|
||||
case 6:
|
||||
return PDH_status1_channel_6_current_decode(
|
||||
return PDH_status_1_channel_6_current_decode(
|
||||
statusFrame.channel_6_current);
|
||||
case 7:
|
||||
return PDH_status1_channel_7_current_decode(
|
||||
return PDH_status_1_channel_7_current_decode(
|
||||
statusFrame.channel_7_current);
|
||||
case 8:
|
||||
return PDH_status1_channel_8_current_decode(
|
||||
return PDH_status_1_channel_8_current_decode(
|
||||
statusFrame.channel_8_current);
|
||||
case 9:
|
||||
return PDH_status1_channel_9_current_decode(
|
||||
return PDH_status_1_channel_9_current_decode(
|
||||
statusFrame.channel_9_current);
|
||||
case 10:
|
||||
return PDH_status1_channel_10_current_decode(
|
||||
return PDH_status_1_channel_10_current_decode(
|
||||
statusFrame.channel_10_current);
|
||||
case 11:
|
||||
return PDH_status1_channel_11_current_decode(
|
||||
return PDH_status_1_channel_11_current_decode(
|
||||
statusFrame.channel_11_current);
|
||||
}
|
||||
} else if (channel < 18) {
|
||||
// Periodic status 2
|
||||
PDH_status2_t statusFrame = HAL_REV_ReadPDHStatus2(hpdh->hcan, status);
|
||||
PDH_status_2_t statusFrame = HAL_ReadREVPDHStatus2(hpdh->hcan, status);
|
||||
switch (channel) {
|
||||
case 12:
|
||||
return PDH_status2_channel_12_current_decode(
|
||||
return PDH_status_2_channel_12_current_decode(
|
||||
statusFrame.channel_12_current);
|
||||
case 13:
|
||||
return PDH_status2_channel_13_current_decode(
|
||||
return PDH_status_2_channel_13_current_decode(
|
||||
statusFrame.channel_13_current);
|
||||
case 14:
|
||||
return PDH_status2_channel_14_current_decode(
|
||||
return PDH_status_2_channel_14_current_decode(
|
||||
statusFrame.channel_14_current);
|
||||
case 15:
|
||||
return PDH_status2_channel_15_current_decode(
|
||||
return PDH_status_2_channel_15_current_decode(
|
||||
statusFrame.channel_15_current);
|
||||
case 16:
|
||||
return PDH_status2_channel_16_current_decode(
|
||||
return PDH_status_2_channel_16_current_decode(
|
||||
statusFrame.channel_16_current);
|
||||
case 17:
|
||||
return PDH_status2_channel_17_current_decode(
|
||||
return PDH_status_2_channel_17_current_decode(
|
||||
statusFrame.channel_17_current);
|
||||
}
|
||||
} else if (channel < 24) {
|
||||
// Periodic status 3
|
||||
PDH_status3_t statusFrame = HAL_REV_ReadPDHStatus3(hpdh->hcan, status);
|
||||
PDH_status_3_t statusFrame = HAL_ReadREVPDHStatus3(hpdh->hcan, status);
|
||||
switch (channel) {
|
||||
case 18:
|
||||
return PDH_status3_channel_18_current_decode(
|
||||
return PDH_status_3_channel_18_current_decode(
|
||||
statusFrame.channel_18_current);
|
||||
case 19:
|
||||
return PDH_status3_channel_19_current_decode(
|
||||
return PDH_status_3_channel_19_current_decode(
|
||||
statusFrame.channel_19_current);
|
||||
case 20:
|
||||
return PDH_status3_channel_20_current_decode(
|
||||
return PDH_status_3_channel_20_current_decode(
|
||||
statusFrame.channel_20_current);
|
||||
case 21:
|
||||
return PDH_status3_channel_21_current_decode(
|
||||
return PDH_status_3_channel_21_current_decode(
|
||||
statusFrame.channel_21_current);
|
||||
case 22:
|
||||
return PDH_status3_channel_22_current_decode(
|
||||
return PDH_status_3_channel_22_current_decode(
|
||||
statusFrame.channel_22_current);
|
||||
case 23:
|
||||
return PDH_status3_channel_23_current_decode(
|
||||
return PDH_status_3_channel_23_current_decode(
|
||||
statusFrame.channel_23_current);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HAL_REV_GetPDHAllChannelCurrents(HAL_REVPDHHandle handle, double* currents,
|
||||
int32_t* status) {
|
||||
auto hpdh = REVPDHHandles->Get(handle);
|
||||
if (hpdh == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
PDH_status0_t statusFrame0 = HAL_REV_ReadPDHStatus0(hpdh->hcan, status);
|
||||
PDH_status1_t statusFrame1 = HAL_REV_ReadPDHStatus1(hpdh->hcan, status);
|
||||
PDH_status2_t statusFrame2 = HAL_REV_ReadPDHStatus2(hpdh->hcan, status);
|
||||
PDH_status3_t statusFrame3 = HAL_REV_ReadPDHStatus3(hpdh->hcan, status);
|
||||
|
||||
currents[0] =
|
||||
PDH_status0_channel_0_current_decode(statusFrame0.channel_0_current);
|
||||
currents[1] =
|
||||
PDH_status0_channel_1_current_decode(statusFrame0.channel_1_current);
|
||||
currents[2] =
|
||||
PDH_status0_channel_2_current_decode(statusFrame0.channel_2_current);
|
||||
currents[3] =
|
||||
PDH_status0_channel_3_current_decode(statusFrame0.channel_3_current);
|
||||
currents[4] =
|
||||
PDH_status0_channel_4_current_decode(statusFrame0.channel_4_current);
|
||||
currents[5] =
|
||||
PDH_status0_channel_5_current_decode(statusFrame0.channel_5_current);
|
||||
currents[6] =
|
||||
PDH_status1_channel_6_current_decode(statusFrame1.channel_6_current);
|
||||
currents[7] =
|
||||
PDH_status1_channel_7_current_decode(statusFrame1.channel_7_current);
|
||||
currents[8] =
|
||||
PDH_status1_channel_8_current_decode(statusFrame1.channel_8_current);
|
||||
currents[9] =
|
||||
PDH_status1_channel_9_current_decode(statusFrame1.channel_9_current);
|
||||
currents[10] =
|
||||
PDH_status1_channel_10_current_decode(statusFrame1.channel_10_current);
|
||||
currents[11] =
|
||||
PDH_status1_channel_11_current_decode(statusFrame1.channel_11_current);
|
||||
currents[12] =
|
||||
PDH_status2_channel_12_current_decode(statusFrame2.channel_12_current);
|
||||
currents[13] =
|
||||
PDH_status2_channel_13_current_decode(statusFrame2.channel_13_current);
|
||||
currents[14] =
|
||||
PDH_status2_channel_14_current_decode(statusFrame2.channel_14_current);
|
||||
currents[15] =
|
||||
PDH_status2_channel_15_current_decode(statusFrame2.channel_15_current);
|
||||
currents[16] =
|
||||
PDH_status2_channel_16_current_decode(statusFrame2.channel_16_current);
|
||||
currents[17] =
|
||||
PDH_status2_channel_17_current_decode(statusFrame2.channel_17_current);
|
||||
currents[18] =
|
||||
PDH_status3_channel_18_current_decode(statusFrame3.channel_18_current);
|
||||
currents[19] =
|
||||
PDH_status3_channel_19_current_decode(statusFrame3.channel_19_current);
|
||||
currents[20] =
|
||||
PDH_status3_channel_20_current_decode(statusFrame3.channel_20_current);
|
||||
currents[21] =
|
||||
PDH_status3_channel_21_current_decode(statusFrame3.channel_21_current);
|
||||
currents[22] =
|
||||
PDH_status3_channel_22_current_decode(statusFrame3.channel_22_current);
|
||||
currents[23] =
|
||||
PDH_status3_channel_23_current_decode(statusFrame3.channel_23_current);
|
||||
}
|
||||
|
||||
uint16_t HAL_REV_GetPDHTotalCurrent(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PDH_status4_total_current_decode(statusFrame.total_current);
|
||||
}
|
||||
|
||||
void HAL_REV_SetPDHSwitchableChannel(HAL_REVPDHHandle handle, HAL_Bool enabled,
|
||||
void HAL_GetREVPDHAllChannelCurrents(HAL_REVPDHHandle handle, double* currents,
|
||||
int32_t* status) {
|
||||
auto hpdh = REVPDHHandles->Get(handle);
|
||||
if (hpdh == nullptr) {
|
||||
@@ -450,291 +374,115 @@ void HAL_REV_SetPDHSwitchableChannel(HAL_REVPDHHandle handle, HAL_Bool enabled,
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t packedData[8] = {0};
|
||||
PDH_switch_channel_set_t frame;
|
||||
frame.output_set_value = enabled;
|
||||
frame.use_system_enable = false;
|
||||
PDH_switch_channel_set_pack(packedData, &frame, 1);
|
||||
PDH_status_0_t statusFrame0 = HAL_ReadREVPDHStatus0(hpdh->hcan, status);
|
||||
PDH_status_1_t statusFrame1 = HAL_ReadREVPDHStatus1(hpdh->hcan, status);
|
||||
PDH_status_2_t statusFrame2 = HAL_ReadREVPDHStatus2(hpdh->hcan, status);
|
||||
PDH_status_3_t statusFrame3 = HAL_ReadREVPDHStatus3(hpdh->hcan, status);
|
||||
|
||||
HAL_WriteCANPacket(hpdh->hcan, packedData, PDH_SWITCH_CHANNEL_SET_LENGTH,
|
||||
PDH_SWITCH_CHANNEL_SET_FRAME_API, status);
|
||||
currents[0] =
|
||||
PDH_status_0_channel_0_current_decode(statusFrame0.channel_0_current);
|
||||
currents[1] =
|
||||
PDH_status_0_channel_1_current_decode(statusFrame0.channel_1_current);
|
||||
currents[2] =
|
||||
PDH_status_0_channel_2_current_decode(statusFrame0.channel_2_current);
|
||||
currents[3] =
|
||||
PDH_status_0_channel_3_current_decode(statusFrame0.channel_3_current);
|
||||
currents[4] =
|
||||
PDH_status_0_channel_4_current_decode(statusFrame0.channel_4_current);
|
||||
currents[5] =
|
||||
PDH_status_0_channel_5_current_decode(statusFrame0.channel_5_current);
|
||||
currents[6] =
|
||||
PDH_status_1_channel_6_current_decode(statusFrame1.channel_6_current);
|
||||
currents[7] =
|
||||
PDH_status_1_channel_7_current_decode(statusFrame1.channel_7_current);
|
||||
currents[8] =
|
||||
PDH_status_1_channel_8_current_decode(statusFrame1.channel_8_current);
|
||||
currents[9] =
|
||||
PDH_status_1_channel_9_current_decode(statusFrame1.channel_9_current);
|
||||
currents[10] =
|
||||
PDH_status_1_channel_10_current_decode(statusFrame1.channel_10_current);
|
||||
currents[11] =
|
||||
PDH_status_1_channel_11_current_decode(statusFrame1.channel_11_current);
|
||||
currents[12] =
|
||||
PDH_status_2_channel_12_current_decode(statusFrame2.channel_12_current);
|
||||
currents[13] =
|
||||
PDH_status_2_channel_13_current_decode(statusFrame2.channel_13_current);
|
||||
currents[14] =
|
||||
PDH_status_2_channel_14_current_decode(statusFrame2.channel_14_current);
|
||||
currents[15] =
|
||||
PDH_status_2_channel_15_current_decode(statusFrame2.channel_15_current);
|
||||
currents[16] =
|
||||
PDH_status_2_channel_16_current_decode(statusFrame2.channel_16_current);
|
||||
currents[17] =
|
||||
PDH_status_2_channel_17_current_decode(statusFrame2.channel_17_current);
|
||||
currents[18] =
|
||||
PDH_status_3_channel_18_current_decode(statusFrame3.channel_18_current);
|
||||
currents[19] =
|
||||
PDH_status_3_channel_19_current_decode(statusFrame3.channel_19_current);
|
||||
currents[20] =
|
||||
PDH_status_3_channel_20_current_decode(statusFrame3.channel_20_current);
|
||||
currents[21] =
|
||||
PDH_status_3_channel_21_current_decode(statusFrame3.channel_21_current);
|
||||
currents[22] =
|
||||
PDH_status_3_channel_22_current_decode(statusFrame3.channel_22_current);
|
||||
currents[23] =
|
||||
PDH_status_3_channel_23_current_decode(statusFrame3.channel_23_current);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_GetPDHSwitchableChannelState(HAL_REVPDHHandle handle,
|
||||
int32_t* status) {
|
||||
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
|
||||
uint16_t HAL_GetREVPDHTotalCurrent(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
PDH_status_4_t statusFrame = HAL_GetREVPDHStatus4(handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0.0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PDH_status4_sw_state_decode(statusFrame.sw_state);
|
||||
return PDH_status_4_total_current_decode(statusFrame.total_current);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_CheckPDHChannelBrownout(HAL_REVPDHHandle handle,
|
||||
int32_t channel, int32_t* status) {
|
||||
void HAL_SetREVPDHSwitchableChannel(HAL_REVPDHHandle handle, HAL_Bool enabled,
|
||||
int32_t* status) {
|
||||
auto hpdh = REVPDHHandles->Get(handle);
|
||||
if (hpdh == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HAL_REV_CheckPDHChannelNumber(channel)) {
|
||||
*status = RESOURCE_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
uint8_t packedData[8] = {0};
|
||||
PDH_set_switch_channel_t frame;
|
||||
frame.output_set_value = enabled;
|
||||
PDH_set_switch_channel_pack(packedData, &frame,
|
||||
PDH_SET_SWITCH_CHANNEL_LENGTH);
|
||||
|
||||
// Determine what periodic status the channel is in
|
||||
if (channel < 4) {
|
||||
// Periodic status 0
|
||||
PDH_status0_t statusFrame = HAL_REV_ReadPDHStatus0(hpdh->hcan, status);
|
||||
switch (channel) {
|
||||
case 0:
|
||||
return PDH_status0_channel_0_brownout_decode(
|
||||
statusFrame.channel_0_brownout);
|
||||
case 1:
|
||||
return PDH_status0_channel_1_brownout_decode(
|
||||
statusFrame.channel_1_brownout);
|
||||
case 2:
|
||||
return PDH_status0_channel_2_brownout_decode(
|
||||
statusFrame.channel_2_brownout);
|
||||
case 3:
|
||||
return PDH_status0_channel_3_brownout_decode(
|
||||
statusFrame.channel_3_brownout);
|
||||
}
|
||||
} else if (channel < 8) {
|
||||
// Periodic status 1
|
||||
PDH_status1_t statusFrame = HAL_REV_ReadPDHStatus1(hpdh->hcan, status);
|
||||
switch (channel) {
|
||||
case 4:
|
||||
return PDH_status1_channel_4_brownout_decode(
|
||||
statusFrame.channel_4_brownout);
|
||||
case 5:
|
||||
return PDH_status1_channel_5_brownout_decode(
|
||||
statusFrame.channel_5_brownout);
|
||||
case 6:
|
||||
return PDH_status1_channel_6_brownout_decode(
|
||||
statusFrame.channel_6_brownout);
|
||||
case 7:
|
||||
return PDH_status1_channel_7_brownout_decode(
|
||||
statusFrame.channel_7_brownout);
|
||||
}
|
||||
} else if (channel < 12) {
|
||||
// Periodic status 2
|
||||
PDH_status2_t statusFrame = HAL_REV_ReadPDHStatus2(hpdh->hcan, status);
|
||||
switch (channel) {
|
||||
case 8:
|
||||
return PDH_status2_channel_8_brownout_decode(
|
||||
statusFrame.channel_8_brownout);
|
||||
case 9:
|
||||
return PDH_status2_channel_9_brownout_decode(
|
||||
statusFrame.channel_9_brownout);
|
||||
case 10:
|
||||
return PDH_status2_channel_10_brownout_decode(
|
||||
statusFrame.channel_10_brownout);
|
||||
case 11:
|
||||
return PDH_status2_channel_11_brownout_decode(
|
||||
statusFrame.channel_11_brownout);
|
||||
}
|
||||
} else if (channel < 24) {
|
||||
// Periodic status 3
|
||||
PDH_status3_t statusFrame = HAL_REV_ReadPDHStatus3(hpdh->hcan, status);
|
||||
switch (channel) {
|
||||
case 12:
|
||||
return PDH_status3_channel_12_brownout_decode(
|
||||
statusFrame.channel_12_brownout);
|
||||
case 13:
|
||||
return PDH_status3_channel_13_brownout_decode(
|
||||
statusFrame.channel_13_brownout);
|
||||
case 14:
|
||||
return PDH_status3_channel_14_brownout_decode(
|
||||
statusFrame.channel_14_brownout);
|
||||
case 15:
|
||||
return PDH_status3_channel_15_brownout_decode(
|
||||
statusFrame.channel_15_brownout);
|
||||
case 16:
|
||||
return PDH_status3_channel_16_brownout_decode(
|
||||
statusFrame.channel_16_brownout);
|
||||
case 17:
|
||||
return PDH_status3_channel_17_brownout_decode(
|
||||
statusFrame.channel_17_brownout);
|
||||
case 18:
|
||||
return PDH_status3_channel_18_brownout_decode(
|
||||
statusFrame.channel_18_brownout);
|
||||
case 19:
|
||||
return PDH_status3_channel_19_brownout_decode(
|
||||
statusFrame.channel_19_brownout);
|
||||
case 20:
|
||||
return PDH_status3_channel_20_brownout_decode(
|
||||
statusFrame.channel_20_brownout);
|
||||
case 21:
|
||||
return PDH_status3_channel_21_brownout_decode(
|
||||
statusFrame.channel_21_brownout);
|
||||
case 22:
|
||||
return PDH_status3_channel_22_brownout_decode(
|
||||
statusFrame.channel_22_brownout);
|
||||
case 23:
|
||||
return PDH_status3_channel_23_brownout_decode(
|
||||
statusFrame.channel_23_brownout);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
HAL_WriteCANPacket(hpdh->hcan, packedData, PDH_SET_SWITCH_CHANNEL_LENGTH,
|
||||
PDH_SET_SWITCH_CHANNEL_FRAME_API, status);
|
||||
}
|
||||
|
||||
double HAL_REV_GetPDHSupplyVoltage(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return PDH_status4_v_bus_decode(statusFrame.v_bus);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_IsPDHEnabled(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return PDH_status4_system_enable_decode(statusFrame.system_enable);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_CheckPDHBrownout(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return PDH_status4_brownout_decode(statusFrame.brownout);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_CheckPDHCANWarning(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return PDH_status4_can_warning_decode(statusFrame.can_warning);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_CheckPDHHardwareFault(HAL_REVPDHHandle handle,
|
||||
int32_t* status) {
|
||||
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return PDH_status4_hardware_fault_decode(statusFrame.hardware_fault);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_CheckPDHStickyBrownout(HAL_REVPDHHandle handle,
|
||||
int32_t* status) {
|
||||
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return PDH_status4_sticky_brownout_decode(statusFrame.sticky_brownout);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_CheckPDHStickyCANWarning(HAL_REVPDHHandle handle,
|
||||
int32_t* status) {
|
||||
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return PDH_status4_sticky_can_warning_decode(statusFrame.sticky_can_warning);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_CheckPDHStickyCANBusOff(HAL_REVPDHHandle handle,
|
||||
int32_t* status) {
|
||||
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return PDH_status4_sticky_can_bus_off_decode(statusFrame.sticky_can_bus_off);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_CheckPDHStickyHardwareFault(HAL_REVPDHHandle handle,
|
||||
HAL_Bool HAL_GetREVPDHSwitchableChannelState(HAL_REVPDHHandle handle,
|
||||
int32_t* status) {
|
||||
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
|
||||
PDH_status_4_t statusFrame = HAL_GetREVPDHStatus4(handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return PDH_status4_sticky_hardware_fault_decode(
|
||||
statusFrame.sticky_hardware_fault);
|
||||
return PDH_status_4_switch_channel_state_decode(
|
||||
statusFrame.switch_channel_state);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_CheckPDHStickyFirmwareFault(HAL_REVPDHHandle handle,
|
||||
int32_t* status) {
|
||||
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
|
||||
double HAL_GetREVPDHVoltage(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
PDH_status_4_t statusFrame = HAL_GetREVPDHStatus4(handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return PDH_status4_sticky_firmware_fault_decode(
|
||||
statusFrame.sticky_firmware_fault);
|
||||
return PDH_status_4_v_bus_decode(statusFrame.v_bus);
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_CheckPDHStickyChannelBrownout(HAL_REVPDHHandle handle,
|
||||
int32_t channel,
|
||||
int32_t* status) {
|
||||
if (channel < 20 || channel > 23) {
|
||||
*status = RESOURCE_OUT_OF_RANGE;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
switch (channel) {
|
||||
case 20:
|
||||
return PDH_status4_sticky_ch20_brownout_decode(
|
||||
statusFrame.sticky_ch20_brownout);
|
||||
case 21:
|
||||
return PDH_status4_sticky_ch21_brownout_decode(
|
||||
statusFrame.sticky_ch21_brownout);
|
||||
case 22:
|
||||
return PDH_status4_sticky_ch22_brownout_decode(
|
||||
statusFrame.sticky_ch22_brownout);
|
||||
case 23:
|
||||
return PDH_status4_sticky_ch23_brownout_decode(
|
||||
statusFrame.sticky_ch23_brownout);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
HAL_Bool HAL_REV_CheckPDHStickyHasReset(HAL_REVPDHHandle handle,
|
||||
int32_t* status) {
|
||||
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return PDH_status4_sticky_has_reset_decode(statusFrame.sticky_has_reset);
|
||||
}
|
||||
|
||||
REV_PDH_Version HAL_REV_GetPDHVersion(HAL_REVPDHHandle handle,
|
||||
int32_t* status) {
|
||||
REV_PDH_Version version;
|
||||
std::memset(&version, 0, sizeof(version));
|
||||
void HAL_GetREVPDHVersion(HAL_REVPDHHandle handle,
|
||||
HAL_PowerDistributionVersion* version,
|
||||
int32_t* status) {
|
||||
std::memset(version, 0, sizeof(*version));
|
||||
uint8_t packedData[8] = {0};
|
||||
int32_t length = 0;
|
||||
uint64_t timestamp = 0;
|
||||
@@ -742,36 +490,141 @@ REV_PDH_Version HAL_REV_GetPDHVersion(HAL_REVPDHHandle handle,
|
||||
auto hpdh = REVPDHHandles->Get(handle);
|
||||
if (hpdh == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return version;
|
||||
return;
|
||||
}
|
||||
|
||||
if (hpdh->versionInfo.firmwareMajor > 0) {
|
||||
version->firmwareMajor = hpdh->versionInfo.firmwareMajor;
|
||||
version->firmwareMinor = hpdh->versionInfo.firmwareMinor;
|
||||
version->firmwareFix = hpdh->versionInfo.firmwareFix;
|
||||
version->hardwareMajor = hpdh->versionInfo.hardwareMajor;
|
||||
version->hardwareMinor = hpdh->versionInfo.hardwareMinor;
|
||||
version->uniqueId = hpdh->versionInfo.uniqueId;
|
||||
|
||||
*status = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
HAL_WriteCANRTRFrame(hpdh->hcan, PDH_VERSION_LENGTH, PDH_VERSION_FRAME_API,
|
||||
status);
|
||||
|
||||
if (*status != 0) {
|
||||
return version;
|
||||
return;
|
||||
}
|
||||
|
||||
HAL_ReadCANPacketTimeout(hpdh->hcan, PDH_VERSION_FRAME_API, packedData,
|
||||
&length, ×tamp, kDefaultControlPeriod * 2,
|
||||
status);
|
||||
uint32_t timeoutMs = 100;
|
||||
for (uint32_t i = 0; i <= timeoutMs; i++) {
|
||||
HAL_ReadCANPacketNew(hpdh->hcan, PDH_VERSION_FRAME_API, packedData, &length,
|
||||
×tamp, status);
|
||||
if (*status == 0) {
|
||||
break;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
if (*status != 0) {
|
||||
return version;
|
||||
return;
|
||||
}
|
||||
|
||||
PDH_version_unpack(&result, packedData, PDH_VERSION_LENGTH);
|
||||
|
||||
version.firmwareMajor = result.firmware_year;
|
||||
version.firmwareMinor = result.firmware_minor;
|
||||
version.firmwareFix = result.firmware_fix;
|
||||
version.hardwareRev = result.hardware_code;
|
||||
version.uniqueId = result.unique_id;
|
||||
version->firmwareMajor = result.firmware_year;
|
||||
version->firmwareMinor = result.firmware_minor;
|
||||
version->firmwareFix = result.firmware_fix;
|
||||
version->hardwareMinor = result.hardware_minor;
|
||||
version->hardwareMajor = result.hardware_major;
|
||||
version->uniqueId = result.unique_id;
|
||||
|
||||
return version;
|
||||
hpdh->versionInfo = *version;
|
||||
}
|
||||
|
||||
void HAL_REV_ClearPDHFaults(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
void HAL_GetREVPDHFaults(HAL_REVPDHHandle handle,
|
||||
HAL_PowerDistributionFaults* faults, int32_t* status) {
|
||||
std::memset(faults, 0, sizeof(*faults));
|
||||
auto hpdh = REVPDHHandles->Get(handle);
|
||||
if (hpdh == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
PDH_status_0_t status0 = HAL_ReadREVPDHStatus0(hpdh->hcan, status);
|
||||
PDH_status_1_t status1 = HAL_ReadREVPDHStatus1(hpdh->hcan, status);
|
||||
PDH_status_2_t status2 = HAL_ReadREVPDHStatus2(hpdh->hcan, status);
|
||||
PDH_status_3_t status3 = HAL_ReadREVPDHStatus3(hpdh->hcan, status);
|
||||
PDH_status_4_t status4 = HAL_ReadREVPDHStatus4(hpdh->hcan, status);
|
||||
|
||||
faults->channel0BreakerFault = status0.channel_0_breaker_fault;
|
||||
faults->channel1BreakerFault = status0.channel_1_breaker_fault;
|
||||
faults->channel2BreakerFault = status0.channel_2_breaker_fault;
|
||||
faults->channel3BreakerFault = status0.channel_3_breaker_fault;
|
||||
faults->channel4BreakerFault = status1.channel_4_breaker_fault;
|
||||
faults->channel5BreakerFault = status1.channel_5_breaker_fault;
|
||||
faults->channel6BreakerFault = status1.channel_6_breaker_fault;
|
||||
faults->channel7BreakerFault = status1.channel_7_breaker_fault;
|
||||
faults->channel8BreakerFault = status2.channel_8_breaker_fault;
|
||||
faults->channel9BreakerFault = status2.channel_9_breaker_fault;
|
||||
faults->channel10BreakerFault = status2.channel_10_breaker_fault;
|
||||
faults->channel11BreakerFault = status2.channel_11_breaker_fault;
|
||||
faults->channel12BreakerFault = status3.channel_12_breaker_fault;
|
||||
faults->channel13BreakerFault = status3.channel_13_breaker_fault;
|
||||
faults->channel14BreakerFault = status3.channel_14_breaker_fault;
|
||||
faults->channel15BreakerFault = status3.channel_15_breaker_fault;
|
||||
faults->channel16BreakerFault = status3.channel_16_breaker_fault;
|
||||
faults->channel17BreakerFault = status3.channel_17_breaker_fault;
|
||||
faults->channel18BreakerFault = status3.channel_18_breaker_fault;
|
||||
faults->channel19BreakerFault = status3.channel_19_breaker_fault;
|
||||
faults->channel20BreakerFault = status3.channel_20_breaker_fault;
|
||||
faults->channel21BreakerFault = status3.channel_21_breaker_fault;
|
||||
faults->channel22BreakerFault = status3.channel_22_breaker_fault;
|
||||
faults->channel23BreakerFault = status3.channel_23_breaker_fault;
|
||||
faults->brownout = status4.brownout_fault;
|
||||
faults->canWarning = status4.can_warning_fault;
|
||||
faults->hardwareFault = status4.hardware_fault;
|
||||
}
|
||||
|
||||
void HAL_GetREVPDHStickyFaults(HAL_REVPDHHandle handle,
|
||||
HAL_PowerDistributionStickyFaults* stickyFaults,
|
||||
int32_t* status) {
|
||||
std::memset(stickyFaults, 0, sizeof(*stickyFaults));
|
||||
auto hpdh = REVPDHHandles->Get(handle);
|
||||
if (hpdh == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
PDH_status_4_t status4 = HAL_ReadREVPDHStatus4(hpdh->hcan, status);
|
||||
|
||||
stickyFaults->channel0BreakerFault = status4.sticky_ch0_breaker_fault;
|
||||
stickyFaults->channel1BreakerFault = status4.sticky_ch1_breaker_fault;
|
||||
stickyFaults->channel2BreakerFault = status4.sticky_ch2_breaker_fault;
|
||||
stickyFaults->channel3BreakerFault = status4.sticky_ch3_breaker_fault;
|
||||
stickyFaults->channel4BreakerFault = status4.sticky_ch4_breaker_fault;
|
||||
stickyFaults->channel5BreakerFault = status4.sticky_ch5_breaker_fault;
|
||||
stickyFaults->channel6BreakerFault = status4.sticky_ch6_breaker_fault;
|
||||
stickyFaults->channel7BreakerFault = status4.sticky_ch7_breaker_fault;
|
||||
stickyFaults->channel8BreakerFault = status4.sticky_ch8_breaker_fault;
|
||||
stickyFaults->channel9BreakerFault = status4.sticky_ch9_breaker_fault;
|
||||
stickyFaults->channel10BreakerFault = status4.sticky_ch10_breaker_fault;
|
||||
stickyFaults->channel11BreakerFault = status4.sticky_ch11_breaker_fault;
|
||||
stickyFaults->channel12BreakerFault = status4.sticky_ch12_breaker_fault;
|
||||
stickyFaults->channel13BreakerFault = status4.sticky_ch13_breaker_fault;
|
||||
stickyFaults->channel14BreakerFault = status4.sticky_ch14_breaker_fault;
|
||||
stickyFaults->channel15BreakerFault = status4.sticky_ch15_breaker_fault;
|
||||
stickyFaults->channel16BreakerFault = status4.sticky_ch16_breaker_fault;
|
||||
stickyFaults->channel17BreakerFault = status4.sticky_ch17_breaker_fault;
|
||||
stickyFaults->channel18BreakerFault = status4.sticky_ch18_breaker_fault;
|
||||
stickyFaults->channel19BreakerFault = status4.sticky_ch19_breaker_fault;
|
||||
stickyFaults->channel20BreakerFault = status4.sticky_ch20_breaker_fault;
|
||||
stickyFaults->channel21BreakerFault = status4.sticky_ch21_breaker_fault;
|
||||
stickyFaults->channel22BreakerFault = status4.sticky_ch22_breaker_fault;
|
||||
stickyFaults->channel23BreakerFault = status4.sticky_ch23_breaker_fault;
|
||||
stickyFaults->brownout = status4.sticky_brownout_fault;
|
||||
stickyFaults->canWarning = status4.sticky_can_warning_fault;
|
||||
stickyFaults->canBusOff = status4.sticky_can_bus_off_fault;
|
||||
stickyFaults->hasReset = status4.sticky_has_reset_fault;
|
||||
}
|
||||
|
||||
void HAL_ClearREVPDHStickyFaults(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
auto hpdh = REVPDHHandles->Get(handle);
|
||||
if (hpdh == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
@@ -783,16 +636,4 @@ void HAL_REV_ClearPDHFaults(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
PDH_CLEAR_FAULTS_FRAME_API, status);
|
||||
}
|
||||
|
||||
void HAL_REV_IdentifyPDH(HAL_REVPDHHandle handle, int32_t* status) {
|
||||
auto hpdh = REVPDHHandles->Get(handle);
|
||||
if (hpdh == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t packedData[8] = {0};
|
||||
HAL_WriteCANPacket(hpdh->hcan, packedData, PDH_IDENTIFY_LENGTH,
|
||||
PDH_IDENTIFY_FRAME_API, status);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hal/PowerDistribution.h"
|
||||
#include "hal/Types.h"
|
||||
|
||||
/**
|
||||
@@ -14,14 +15,6 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
struct REV_PDH_Version {
|
||||
uint32_t firmwareMajor;
|
||||
uint32_t firmwareMinor;
|
||||
uint32_t firmwareFix;
|
||||
uint32_t hardwareRev;
|
||||
uint32_t uniqueId;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -32,21 +25,21 @@ extern "C" {
|
||||
* @param module the device CAN ID (1 .. 63)
|
||||
* @return the created PDH handle
|
||||
*/
|
||||
HAL_REVPDHHandle HAL_REV_InitializePDH(int32_t module,
|
||||
const char* allocationLocation,
|
||||
int32_t* status);
|
||||
HAL_REVPDHHandle HAL_InitializeREVPDH(int32_t module,
|
||||
const char* allocationLocation,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Frees a PDH device handle.
|
||||
*
|
||||
* @param handle the previously created PDH handle
|
||||
*/
|
||||
void HAL_REV_FreePDH(HAL_REVPDHHandle handle);
|
||||
void HAL_FreeREVPDH(HAL_REVPDHHandle handle);
|
||||
|
||||
/**
|
||||
* Gets the module number for a pdh.
|
||||
*/
|
||||
int32_t HAL_REV_GetPDHModuleNumber(HAL_REVPDHHandle handle, int32_t* status);
|
||||
int32_t HAL_GetREVPDHModuleNumber(HAL_REVPDHHandle handle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Checks if a PDH module number is valid.
|
||||
@@ -56,34 +49,34 @@ int32_t HAL_REV_GetPDHModuleNumber(HAL_REVPDHHandle handle, int32_t* status);
|
||||
* @param module module number (1 .. 63)
|
||||
* @return 1 if the module number is valid; 0 otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_CheckPDHModuleNumber(int32_t module);
|
||||
HAL_Bool HAL_CheckREVPDHModuleNumber(int32_t module);
|
||||
|
||||
/**
|
||||
* Checks if a PDH channel number is valid.
|
||||
*
|
||||
* @param module channel number (0 .. HAL_REV_PDH_NUM_CHANNELS)
|
||||
* @param module channel number (0 .. kNumREVPDHChannels)
|
||||
* @return 1 if the channel number is valid; 0 otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_CheckPDHChannelNumber(int32_t channel);
|
||||
HAL_Bool HAL_CheckREVPDHChannelNumber(int32_t channel);
|
||||
|
||||
/**
|
||||
* Gets the current of a PDH channel in Amps.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
* @param channel the channel to retrieve the current of (0 ..
|
||||
* HAL_REV_PDH_NUM_CHANNELS)
|
||||
* kNumREVPDHChannels)
|
||||
*
|
||||
* @return the current of the PDH channel in Amps
|
||||
*/
|
||||
double HAL_REV_GetPDHChannelCurrent(HAL_REVPDHHandle handle, int32_t channel,
|
||||
int32_t* status);
|
||||
double HAL_GetREVPDHChannelCurrent(HAL_REVPDHHandle handle, int32_t channel,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* @param handle PDH handle
|
||||
* @param currents array of currents
|
||||
*/
|
||||
void HAL_REV_GetPDHAllChannelCurrents(HAL_REVPDHHandle handle, double* currents,
|
||||
int32_t* status);
|
||||
void HAL_GetREVPDHAllChannelCurrents(HAL_REVPDHHandle handle, double* currents,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Gets the total current of the PDH in Amps, measured to the nearest even
|
||||
@@ -93,7 +86,7 @@ void HAL_REV_GetPDHAllChannelCurrents(HAL_REVPDHHandle handle, double* currents,
|
||||
*
|
||||
* @return the total current of the PDH in Amps
|
||||
*/
|
||||
uint16_t HAL_REV_GetPDHTotalCurrent(HAL_REVPDHHandle handle, int32_t* status);
|
||||
uint16_t HAL_GetREVPDHTotalCurrent(HAL_REVPDHHandle handle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Sets the state of the switchable channel on a PDH device.
|
||||
@@ -102,8 +95,8 @@ uint16_t HAL_REV_GetPDHTotalCurrent(HAL_REVPDHHandle handle, int32_t* status);
|
||||
* @param enabled 1 if the switchable channel should be enabled; 0
|
||||
* otherwise
|
||||
*/
|
||||
void HAL_REV_SetPDHSwitchableChannel(HAL_REVPDHHandle handle, HAL_Bool enabled,
|
||||
int32_t* status);
|
||||
void HAL_SetREVPDHSwitchableChannel(HAL_REVPDHHandle handle, HAL_Bool enabled,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Gets the current state of the switchable channel on a PDH device.
|
||||
@@ -114,174 +107,9 @@ void HAL_REV_SetPDHSwitchableChannel(HAL_REVPDHHandle handle, HAL_Bool enabled,
|
||||
* @param handle PDH handle
|
||||
* @return 1 if the switchable channel is enabled; 0 otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_GetPDHSwitchableChannelState(HAL_REVPDHHandle handle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Checks if a PDH channel is currently experiencing a brownout condition.
|
||||
*
|
||||
* NOTE: Not implemented in firmware as of 2021-04-23.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
* @param channel the channel to retrieve the brownout status of
|
||||
*
|
||||
* @return 1 if the channel is experiencing a brownout; 0 otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_CheckPDHChannelBrownout(HAL_REVPDHHandle handle,
|
||||
int32_t channel, int32_t* status);
|
||||
|
||||
/**
|
||||
* Gets the voltage being supplied to a PDH device.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*
|
||||
* @return the voltage at the input of the PDH in Volts
|
||||
*/
|
||||
double HAL_REV_GetPDHSupplyVoltage(HAL_REVPDHHandle handle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Checks if a PDH device is currently enabled.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*
|
||||
* @return 1 if the PDH is enabled; 0 otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_IsPDHEnabled(HAL_REVPDHHandle handle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Checks if the input voltage on a PDH device is currently below the minimum
|
||||
* voltage.
|
||||
*
|
||||
* NOTE: Not implemented in firmware as of 2021-04-23.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*
|
||||
* @return 1 if the PDH is experiencing a brownout; 0 otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_CheckPDHBrownout(HAL_REVPDHHandle handle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Checks if the CAN RX or TX error levels on a PDH device have exceeded the
|
||||
* warning threshold.
|
||||
*
|
||||
* NOTE: Not implemented in firmware as of 2021-04-23.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*
|
||||
* @return 1 if the device has exceeded the warning threshold; 0
|
||||
* otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_CheckPDHCANWarning(HAL_REVPDHHandle handle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Checks if a PDH device is currently malfunctioning.
|
||||
*
|
||||
* NOTE: Not implemented in firmware as of 2021-04-23.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*
|
||||
* @return 1 if the device is in a hardware fault state; 0
|
||||
* otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_CheckPDHHardwareFault(HAL_REVPDHHandle handle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Checks if the input voltage on a PDH device has gone below the specified
|
||||
* minimum voltage.
|
||||
*
|
||||
* NOTE: Not implemented in firmware as of 2021-04-23.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*
|
||||
* @return 1 if the device has had a brownout; 0 otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_CheckPDHStickyBrownout(HAL_REVPDHHandle handle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Checks if the CAN RX or TX error levels on a PDH device have exceeded the
|
||||
* warning threshold.
|
||||
*
|
||||
* NOTE: Not implemented in firmware as of 2021-04-23.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*
|
||||
* @return 1 if the device has exceeded the CAN warning threshold;
|
||||
* 0 otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_CheckPDHStickyCANWarning(HAL_REVPDHHandle handle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Checks if the CAN bus on a PDH device has previously experienced a 'Bus Off'
|
||||
* event.
|
||||
*
|
||||
* NOTE: Not implemented in firmware as of 2021-04-23.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*
|
||||
* @return 1 if the device has experienced a 'Bus Off' event; 0
|
||||
* otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_CheckPDHStickyCANBusOff(HAL_REVPDHHandle handle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Checks if a PDH device has malfunctioned.
|
||||
*
|
||||
* NOTE: Not implemented in firmware as of 2021-04-23.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*
|
||||
* @return 1 if the device has had a malfunction; 0 otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_CheckPDHStickyHardwareFault(HAL_REVPDHHandle handle,
|
||||
HAL_Bool HAL_GetREVPDHSwitchableChannelState(HAL_REVPDHHandle handle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Checks if the firmware on a PDH device has malfunctioned and reset during
|
||||
* operation.
|
||||
*
|
||||
* NOTE: Not implemented in firmware as of 2021-04-23.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*
|
||||
* @return 1 if the device has had a malfunction and reset; 0
|
||||
* otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_CheckPDHStickyFirmwareFault(HAL_REVPDHHandle handle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Checks if a brownout has happened on channels 20-23 of a PDH device while it
|
||||
* was enabled.
|
||||
*
|
||||
* NOTE: Not implemented in firmware as of 2021-04-23.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
* @param channel PDH channel to retrieve sticky brownout status (20 ..
|
||||
* 23)
|
||||
*
|
||||
*
|
||||
* @return 1 if the channel has had a brownout; 0 otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_CheckPDHStickyChannelBrownout(HAL_REVPDHHandle handle,
|
||||
int32_t channel,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Checks if a PDH device has reset.
|
||||
*
|
||||
* NOTE: Not implemented in firmware as of 2021-04-23.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*
|
||||
* @return 1 if the device has reset; 0 otherwise
|
||||
*/
|
||||
HAL_Bool HAL_REV_CheckPDHStickyHasReset(HAL_REVPDHHandle handle,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Gets the firmware and hardware versions of a PDH device.
|
||||
*
|
||||
@@ -289,25 +117,46 @@ HAL_Bool HAL_REV_CheckPDHStickyHasReset(HAL_REVPDHHandle handle,
|
||||
*
|
||||
* @return version information
|
||||
*/
|
||||
REV_PDH_Version HAL_REV_GetPDHVersion(HAL_REVPDHHandle handle, int32_t* status);
|
||||
void HAL_GetREVPDHVersion(HAL_REVPDHHandle handle,
|
||||
HAL_PowerDistributionVersion* version,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Gets the voltage being supplied to a PDH device.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*
|
||||
* @return the voltage at the input of the PDH in Volts
|
||||
*/
|
||||
double HAL_GetREVPDHVoltage(HAL_REVPDHHandle handle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Gets the faults of a PDH device.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*
|
||||
* @return the faults of the PDH
|
||||
*/
|
||||
void HAL_GetREVPDHFaults(HAL_REVPDHHandle handle,
|
||||
HAL_PowerDistributionFaults* faults, int32_t* status);
|
||||
|
||||
/**
|
||||
* Gets the sticky faults of a PDH device.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*
|
||||
* @return the sticky faults of the PDH
|
||||
*/
|
||||
void HAL_GetREVPDHStickyFaults(HAL_REVPDHHandle handle,
|
||||
HAL_PowerDistributionStickyFaults* stickyFaults,
|
||||
int32_t* status);
|
||||
|
||||
/**
|
||||
* Clears the sticky faults on a PDH device.
|
||||
*
|
||||
* NOTE: Not implemented in firmware as of 2021-04-23.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*/
|
||||
void HAL_REV_ClearPDHFaults(HAL_REVPDHHandle handle, int32_t* status);
|
||||
|
||||
/**
|
||||
* Identifies a PDH device by blinking its LED.
|
||||
*
|
||||
* NOTE: Not implemented in firmware as of 2021-04-23.
|
||||
*
|
||||
* @param handle PDH handle
|
||||
*/
|
||||
void HAL_REV_IdentifyPDH(HAL_REVPDHHandle handle, int32_t* status);
|
||||
void HAL_ClearREVPDHStickyFaults(HAL_REVPDHHandle handle, int32_t* status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "hal/REVPH.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "HALInitializer.h"
|
||||
@@ -23,30 +25,34 @@ static constexpr HAL_CANDeviceType deviceType =
|
||||
HAL_CANDeviceType::HAL_CAN_Dev_kPneumatics;
|
||||
|
||||
static constexpr int32_t kDefaultControlPeriod = 20;
|
||||
// static constexpr uint8_t kDefaultSensorMask = (1 <<
|
||||
// HAL_REV_PHSENSOR_DIGITAL);
|
||||
static constexpr uint8_t kDefaultCompressorDuty = 255;
|
||||
static constexpr uint8_t kDefaultPressureTarget = 120;
|
||||
static constexpr uint8_t kDefaultPressureHysteresis = 60;
|
||||
|
||||
#define HAL_REV_MAX_PULSE_TIME 65534
|
||||
#define HAL_REV_MAX_PRESSURE_TARGET 120
|
||||
#define HAL_REV_MAX_PRESSURE_HYSTERESIS HAL_REV_MAX_PRESSURE_TARGET
|
||||
#define HAL_REVPH_MAX_PULSE_TIME 65534
|
||||
|
||||
static constexpr uint32_t APIFromExtId(uint32_t extId) {
|
||||
return (extId >> 6) & 0x3FF;
|
||||
}
|
||||
|
||||
static constexpr uint32_t PH_STATUS_0_FRAME_API =
|
||||
APIFromExtId(PH_STATUS_0_FRAME_ID);
|
||||
static constexpr uint32_t PH_STATUS_1_FRAME_API =
|
||||
APIFromExtId(PH_STATUS_1_FRAME_ID);
|
||||
|
||||
static constexpr uint32_t PH_SET_ALL_FRAME_API =
|
||||
APIFromExtId(PH_SET_ALL_FRAME_ID);
|
||||
static constexpr uint32_t PH_PULSE_ONCE_FRAME_API =
|
||||
APIFromExtId(PH_PULSE_ONCE_FRAME_ID);
|
||||
|
||||
static constexpr uint32_t PH_COMPRESSOR_CONFIG_API =
|
||||
APIFromExtId(PH_COMPRESSOR_CONFIG_FRAME_ID);
|
||||
static constexpr uint32_t PH_STATUS0_FRAME_API =
|
||||
APIFromExtId(PH_STATUS0_FRAME_ID);
|
||||
static constexpr uint32_t PH_STATUS1_FRAME_API =
|
||||
APIFromExtId(PH_STATUS1_FRAME_ID);
|
||||
|
||||
static constexpr uint32_t PH_CLEAR_FAULTS_FRAME_API =
|
||||
APIFromExtId(PH_CLEAR_FAULTS_FRAME_ID);
|
||||
|
||||
static constexpr uint32_t PH_VERSION_FRAME_API =
|
||||
APIFromExtId(PH_VERSION_FRAME_ID);
|
||||
|
||||
static constexpr int32_t kPHFrameStatus0Timeout = 50;
|
||||
static constexpr int32_t kPHFrameStatus1Timeout = 50;
|
||||
@@ -59,6 +65,7 @@ struct REV_PHObj {
|
||||
wpi::mutex solenoidLock;
|
||||
HAL_CANHandle hcan;
|
||||
std::string previousAllocation;
|
||||
HAL_REVPHVersion versionInfo;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -75,38 +82,38 @@ void InitializeREVPH() {
|
||||
}
|
||||
} // namespace hal::init
|
||||
|
||||
static PH_status0_t HAL_REV_ReadPHStatus0(HAL_CANHandle hcan, int32_t* status) {
|
||||
static PH_status_0_t HAL_ReadREVPHStatus0(HAL_CANHandle hcan, int32_t* status) {
|
||||
uint8_t packedData[8] = {0};
|
||||
int32_t length = 0;
|
||||
uint64_t timestamp = 0;
|
||||
PH_status0_t result = {};
|
||||
PH_status_0_t result = {};
|
||||
|
||||
HAL_ReadCANPacketTimeout(hcan, PH_STATUS0_FRAME_API, packedData, &length,
|
||||
HAL_ReadCANPacketTimeout(hcan, PH_STATUS_0_FRAME_API, packedData, &length,
|
||||
×tamp, kPHFrameStatus0Timeout * 2, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
PH_status0_unpack(&result, packedData, PH_STATUS0_LENGTH);
|
||||
PH_status_0_unpack(&result, packedData, PH_STATUS_0_LENGTH);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static PH_status1_t HAL_REV_ReadPHStatus1(HAL_CANHandle hcan, int32_t* status) {
|
||||
static PH_status_1_t HAL_ReadREVPHStatus1(HAL_CANHandle hcan, int32_t* status) {
|
||||
uint8_t packedData[8] = {0};
|
||||
int32_t length = 0;
|
||||
uint64_t timestamp = 0;
|
||||
PH_status1_t result = {};
|
||||
PH_status_1_t result = {};
|
||||
|
||||
HAL_ReadCANPacketTimeout(hcan, PH_STATUS1_FRAME_API, packedData, &length,
|
||||
HAL_ReadCANPacketTimeout(hcan, PH_STATUS_1_FRAME_API, packedData, &length,
|
||||
×tamp, kPHFrameStatus1Timeout * 2, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
PH_status1_unpack(&result, packedData, PH_STATUS1_LENGTH);
|
||||
PH_status_1_unpack(&result, packedData, PH_STATUS_1_LENGTH);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -117,9 +124,9 @@ enum REV_SolenoidState {
|
||||
kSolenoidControlledViaPulse
|
||||
};
|
||||
|
||||
static void HAL_REV_UpdateDesiredPHSolenoidState(REV_PHObj* hph,
|
||||
int32_t solenoid,
|
||||
REV_SolenoidState state) {
|
||||
static void HAL_UpdateDesiredREVPHSolenoidState(REV_PHObj* hph,
|
||||
int32_t solenoid,
|
||||
REV_SolenoidState state) {
|
||||
switch (solenoid) {
|
||||
case 0:
|
||||
hph->desiredSolenoidsState.channel_0 = state;
|
||||
@@ -172,15 +179,15 @@ static void HAL_REV_UpdateDesiredPHSolenoidState(REV_PHObj* hph,
|
||||
}
|
||||
}
|
||||
|
||||
static void HAL_REV_SendSolenoidsState(REV_PHObj* hph, int32_t* status) {
|
||||
static void HAL_SendREVPHSolenoidsState(REV_PHObj* hph, int32_t* status) {
|
||||
uint8_t packedData[PH_SET_ALL_LENGTH] = {0};
|
||||
PH_set_all_pack(packedData, &(hph->desiredSolenoidsState), PH_SET_ALL_LENGTH);
|
||||
HAL_WriteCANPacketRepeating(hph->hcan, packedData, PH_SET_ALL_LENGTH,
|
||||
PH_SET_ALL_FRAME_API, hph->controlPeriod, status);
|
||||
}
|
||||
|
||||
static HAL_Bool HAL_REV_CheckPHPulseTime(int32_t time) {
|
||||
return ((time > 0) && (time <= HAL_REV_MAX_PULSE_TIME)) ? 1 : 0;
|
||||
static HAL_Bool HAL_CheckREVPHPulseTime(int32_t time) {
|
||||
return ((time > 0) && (time <= HAL_REVPH_MAX_PULSE_TIME)) ? 1 : 0;
|
||||
}
|
||||
|
||||
HAL_REVPHHandle HAL_InitializeREVPH(int32_t module,
|
||||
@@ -217,9 +224,12 @@ HAL_REVPHHandle HAL_InitializeREVPH(int32_t module,
|
||||
hph->previousAllocation = allocationLocation ? allocationLocation : "";
|
||||
hph->hcan = hcan;
|
||||
hph->controlPeriod = kDefaultControlPeriod;
|
||||
std::memset(&hph->desiredSolenoidsState, 0,
|
||||
sizeof(hph->desiredSolenoidsState));
|
||||
std::memset(&hph->versionInfo, 0, sizeof(hph->versionInfo));
|
||||
|
||||
// Start closed-loop compressor control by starting solenoid state updates
|
||||
HAL_REV_SendSolenoidsState(hph.get(), status);
|
||||
HAL_SendREVPHSolenoidsState(hph.get(), status);
|
||||
|
||||
return handle;
|
||||
}
|
||||
@@ -249,7 +259,7 @@ HAL_Bool HAL_GetREVPHCompressor(HAL_REVPHHandle handle, int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PH_status0_t status0 = HAL_REV_ReadPHStatus0(ph->hcan, status);
|
||||
PH_status_0_t status0 = HAL_ReadREVPHStatus0(ph->hcan, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return false;
|
||||
@@ -331,7 +341,7 @@ HAL_REVPHCompressorConfigType HAL_GetREVPHCompressorConfig(
|
||||
return HAL_REVPHCompressorConfigType_kDisabled;
|
||||
}
|
||||
|
||||
PH_status0_t status0 = HAL_REV_ReadPHStatus0(ph->hcan, status);
|
||||
PH_status_0_t status0 = HAL_ReadREVPHStatus0(ph->hcan, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return HAL_REVPHCompressorConfigType_kDisabled;
|
||||
@@ -347,7 +357,7 @@ HAL_Bool HAL_GetREVPHPressureSwitch(HAL_REVPHHandle handle, int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PH_status0_t status0 = HAL_REV_ReadPHStatus0(ph->hcan, status);
|
||||
PH_status_0_t status0 = HAL_ReadREVPHStatus0(ph->hcan, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return false;
|
||||
@@ -363,17 +373,17 @@ double HAL_GetREVPHCompressorCurrent(HAL_REVPHHandle handle, int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PH_status1_t status1 = HAL_REV_ReadPHStatus1(ph->hcan, status);
|
||||
PH_status_1_t status1 = HAL_ReadREVPHStatus1(ph->hcan, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PH_status1_compressor_current_decode(status1.compressor_current);
|
||||
return PH_status_1_compressor_current_decode(status1.compressor_current);
|
||||
}
|
||||
|
||||
double HAL_GetREVPHAnalogPressure(HAL_REVPHHandle handle, int32_t channel,
|
||||
int32_t* status) {
|
||||
double HAL_GetREVPHAnalogVoltage(HAL_REVPHHandle handle, int32_t channel,
|
||||
int32_t* status) {
|
||||
auto ph = REVPHHandles->Get(handle);
|
||||
if (ph == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
@@ -387,16 +397,138 @@ double HAL_GetREVPHAnalogPressure(HAL_REVPHHandle handle, int32_t channel,
|
||||
return 0;
|
||||
}
|
||||
|
||||
PH_status0_t status0 = HAL_REV_ReadPHStatus0(ph->hcan, status);
|
||||
PH_status_0_t status0 = HAL_ReadREVPHStatus0(ph->hcan, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (channel == 0) {
|
||||
return PH_status0_analog_0_decode(status0.analog_0);
|
||||
return PH_status_0_analog_0_decode(status0.analog_0);
|
||||
}
|
||||
return PH_status0_analog_1_decode(status0.analog_1);
|
||||
return PH_status_0_analog_1_decode(status0.analog_1);
|
||||
}
|
||||
|
||||
double HAL_GetREVPHVoltage(HAL_REVPHHandle handle, int32_t* status) {
|
||||
auto ph = REVPHHandles->Get(handle);
|
||||
if (ph == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PH_status_1_t status1 = HAL_ReadREVPHStatus1(ph->hcan, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PH_status_1_v_bus_decode(status1.v_bus);
|
||||
}
|
||||
|
||||
double HAL_GetREVPH5VVoltage(HAL_REVPHHandle handle, int32_t* status) {
|
||||
auto ph = REVPHHandles->Get(handle);
|
||||
if (ph == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PH_status_1_t status1 = HAL_ReadREVPHStatus1(ph->hcan, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PH_status_1_supply_voltage_5_v_decode(status1.supply_voltage_5_v);
|
||||
}
|
||||
|
||||
double HAL_GetREVPHSolenoidCurrent(HAL_REVPHHandle handle, int32_t* status) {
|
||||
auto ph = REVPHHandles->Get(handle);
|
||||
if (ph == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PH_status_1_t status1 = HAL_ReadREVPHStatus1(ph->hcan, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PH_status_1_solenoid_current_decode(status1.solenoid_current);
|
||||
}
|
||||
|
||||
double HAL_GetREVPHSolenoidVoltage(HAL_REVPHHandle handle, int32_t* status) {
|
||||
auto ph = REVPHHandles->Get(handle);
|
||||
if (ph == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PH_status_1_t status1 = HAL_ReadREVPHStatus1(ph->hcan, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PH_status_1_solenoid_voltage_decode(status1.solenoid_voltage);
|
||||
}
|
||||
|
||||
void HAL_GetREVPHVersion(HAL_REVPHHandle handle, HAL_REVPHVersion* version,
|
||||
int32_t* status) {
|
||||
std::memset(version, 0, sizeof(*version));
|
||||
uint8_t packedData[8] = {0};
|
||||
int32_t length = 0;
|
||||
uint64_t timestamp = 0;
|
||||
PH_version_t result = {};
|
||||
auto ph = REVPHHandles->Get(handle);
|
||||
if (ph == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ph->versionInfo.firmwareMajor > 0) {
|
||||
version->firmwareMajor = ph->versionInfo.firmwareMajor;
|
||||
version->firmwareMinor = ph->versionInfo.firmwareMinor;
|
||||
version->firmwareFix = ph->versionInfo.firmwareFix;
|
||||
version->hardwareMajor = ph->versionInfo.hardwareMajor;
|
||||
version->hardwareMinor = ph->versionInfo.hardwareMinor;
|
||||
version->uniqueId = ph->versionInfo.uniqueId;
|
||||
|
||||
*status = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
HAL_WriteCANRTRFrame(ph->hcan, PH_VERSION_LENGTH, PH_VERSION_FRAME_API,
|
||||
status);
|
||||
|
||||
if (*status != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t timeoutMs = 100;
|
||||
for (uint32_t i = 0; i <= timeoutMs; i++) {
|
||||
HAL_ReadCANPacketNew(ph->hcan, PH_VERSION_FRAME_API, packedData, &length,
|
||||
×tamp, status);
|
||||
if (*status == 0) {
|
||||
break;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
if (*status != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
PH_version_unpack(&result, packedData, PH_VERSION_LENGTH);
|
||||
|
||||
version->firmwareMajor = result.firmware_year;
|
||||
version->firmwareMinor = result.firmware_minor;
|
||||
version->firmwareFix = result.firmware_fix;
|
||||
version->hardwareMinor = result.hardware_minor;
|
||||
version->hardwareMajor = result.hardware_major;
|
||||
version->uniqueId = result.unique_id;
|
||||
|
||||
ph->versionInfo = *version;
|
||||
}
|
||||
|
||||
int32_t HAL_GetREVPHSolenoids(HAL_REVPHHandle handle, int32_t* status) {
|
||||
@@ -406,7 +538,7 @@ int32_t HAL_GetREVPHSolenoids(HAL_REVPHHandle handle, int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PH_status0_t status0 = HAL_REV_ReadPHStatus0(ph->hcan, status);
|
||||
PH_status_0_t status0 = HAL_ReadREVPHStatus0(ph->hcan, status);
|
||||
|
||||
if (*status != 0) {
|
||||
return 0;
|
||||
@@ -446,11 +578,11 @@ void HAL_SetREVPHSolenoids(HAL_REVPHHandle handle, int32_t mask, int32_t values,
|
||||
// The mask bit for the solenoid is set, so we update the solenoid state
|
||||
REV_SolenoidState desiredSolenoidState =
|
||||
values & (1 << solenoid) ? kSolenoidEnabled : kSolenoidDisabled;
|
||||
HAL_REV_UpdateDesiredPHSolenoidState(ph.get(), solenoid,
|
||||
desiredSolenoidState);
|
||||
HAL_UpdateDesiredREVPHSolenoidState(ph.get(), solenoid,
|
||||
desiredSolenoidState);
|
||||
}
|
||||
}
|
||||
HAL_REV_SendSolenoidsState(ph.get(), status);
|
||||
HAL_SendREVPHSolenoidsState(ph.get(), status);
|
||||
}
|
||||
|
||||
void HAL_FireREVPHOneShot(HAL_REVPHHandle handle, int32_t index, int32_t durMs,
|
||||
@@ -469,7 +601,7 @@ void HAL_FireREVPHOneShot(HAL_REVPHHandle handle, int32_t index, int32_t durMs,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HAL_REV_CheckPHPulseTime(durMs)) {
|
||||
if (!HAL_CheckREVPHPulseTime(durMs)) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
hal::SetLastError(
|
||||
status,
|
||||
@@ -480,9 +612,9 @@ void HAL_FireREVPHOneShot(HAL_REVPHHandle handle, int32_t index, int32_t durMs,
|
||||
|
||||
{
|
||||
std::scoped_lock lock{ph->solenoidLock};
|
||||
HAL_REV_UpdateDesiredPHSolenoidState(ph.get(), index,
|
||||
kSolenoidControlledViaPulse);
|
||||
HAL_REV_SendSolenoidsState(ph.get(), status);
|
||||
HAL_UpdateDesiredREVPHSolenoidState(ph.get(), index,
|
||||
kSolenoidControlledViaPulse);
|
||||
HAL_SendREVPHSolenoidsState(ph.get(), status);
|
||||
}
|
||||
|
||||
if (*status != 0) {
|
||||
@@ -553,58 +685,68 @@ void HAL_FireREVPHOneShot(HAL_REVPHHandle handle, int32_t index, int32_t durMs,
|
||||
PH_PULSE_ONCE_FRAME_API, status);
|
||||
}
|
||||
|
||||
HAL_REVPHFaults HAL_GetREVPHFaults(HAL_REVPHHandle handle, int32_t* status) {
|
||||
HAL_REVPHFaults faults = {};
|
||||
void HAL_GetREVPHFaults(HAL_REVPHHandle handle, HAL_REVPHFaults* faults,
|
||||
int32_t* status) {
|
||||
std::memset(faults, 0, sizeof(*faults));
|
||||
auto ph = REVPHHandles->Get(handle);
|
||||
if (ph == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return faults;
|
||||
return;
|
||||
}
|
||||
|
||||
PH_status0_t status0 = HAL_REV_ReadPHStatus0(ph->hcan, status);
|
||||
faults.channel0Fault = status0.channel_0_fault;
|
||||
faults.channel1Fault = status0.channel_1_fault;
|
||||
faults.channel2Fault = status0.channel_2_fault;
|
||||
faults.channel3Fault = status0.channel_3_fault;
|
||||
faults.channel4Fault = status0.channel_4_fault;
|
||||
faults.channel5Fault = status0.channel_5_fault;
|
||||
faults.channel6Fault = status0.channel_6_fault;
|
||||
faults.channel7Fault = status0.channel_7_fault;
|
||||
faults.channel8Fault = status0.channel_8_fault;
|
||||
faults.channel9Fault = status0.channel_9_fault;
|
||||
faults.channel10Fault = status0.channel_10_fault;
|
||||
faults.channel11Fault = status0.channel_11_fault;
|
||||
faults.channel12Fault = status0.channel_12_fault;
|
||||
faults.channel13Fault = status0.channel_13_fault;
|
||||
faults.channel14Fault = status0.channel_14_fault;
|
||||
faults.channel15Fault = status0.channel_15_fault;
|
||||
faults.compressorOverCurrent = status0.compressor_oc;
|
||||
faults.compressorOpen = status0.compressor_open;
|
||||
faults.solenoidOverCurrent = status0.solenoid_oc;
|
||||
faults.brownout = status0.brownout;
|
||||
faults.canWarning = status0.can_warning;
|
||||
faults.hardwareFault = status0.hardware_fault;
|
||||
|
||||
return faults;
|
||||
PH_status_0_t status0 = HAL_ReadREVPHStatus0(ph->hcan, status);
|
||||
faults->channel0Fault = status0.channel_0_fault;
|
||||
faults->channel1Fault = status0.channel_1_fault;
|
||||
faults->channel2Fault = status0.channel_2_fault;
|
||||
faults->channel3Fault = status0.channel_3_fault;
|
||||
faults->channel4Fault = status0.channel_4_fault;
|
||||
faults->channel5Fault = status0.channel_5_fault;
|
||||
faults->channel6Fault = status0.channel_6_fault;
|
||||
faults->channel7Fault = status0.channel_7_fault;
|
||||
faults->channel8Fault = status0.channel_8_fault;
|
||||
faults->channel9Fault = status0.channel_9_fault;
|
||||
faults->channel10Fault = status0.channel_10_fault;
|
||||
faults->channel11Fault = status0.channel_11_fault;
|
||||
faults->channel12Fault = status0.channel_12_fault;
|
||||
faults->channel13Fault = status0.channel_13_fault;
|
||||
faults->channel14Fault = status0.channel_14_fault;
|
||||
faults->channel15Fault = status0.channel_15_fault;
|
||||
faults->compressorOverCurrent = status0.compressor_oc_fault;
|
||||
faults->compressorOpen = status0.compressor_open_fault;
|
||||
faults->solenoidOverCurrent = status0.solenoid_oc_fault;
|
||||
faults->brownout = status0.brownout_fault;
|
||||
faults->canWarning = status0.can_warning_fault;
|
||||
faults->hardwareFault = status0.hardware_fault;
|
||||
}
|
||||
|
||||
HAL_REVPHStickyFaults HAL_GetREVPHStickyFaults(HAL_REVPHHandle handle,
|
||||
int32_t* status) {
|
||||
HAL_REVPHStickyFaults stickyFaults = {};
|
||||
void HAL_GetREVPHStickyFaults(HAL_REVPHHandle handle,
|
||||
HAL_REVPHStickyFaults* stickyFaults,
|
||||
int32_t* status) {
|
||||
std::memset(stickyFaults, 0, sizeof(*stickyFaults));
|
||||
auto ph = REVPHHandles->Get(handle);
|
||||
if (ph == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return stickyFaults;
|
||||
return;
|
||||
}
|
||||
|
||||
PH_status1_t status1 = HAL_REV_ReadPHStatus1(ph->hcan, status);
|
||||
stickyFaults.compressorOverCurrent = status1.sticky_compressor_over_current;
|
||||
stickyFaults.compressorOpen = status1.sticky_compressor_not_present;
|
||||
stickyFaults.solenoidOverCurrent = status1.sticky_solenoid_over_current;
|
||||
stickyFaults.brownout = status1.sticky_brownout;
|
||||
stickyFaults.canWarning = status1.sticky_can_warning;
|
||||
stickyFaults.canBusOff = status1.sticky_can_bus_off;
|
||||
stickyFaults.hasReset = status1.sticky_has_reset;
|
||||
|
||||
return stickyFaults;
|
||||
PH_status_1_t status1 = HAL_ReadREVPHStatus1(ph->hcan, status);
|
||||
stickyFaults->compressorOverCurrent = status1.sticky_compressor_oc_fault;
|
||||
stickyFaults->compressorOpen = status1.sticky_compressor_open_fault;
|
||||
stickyFaults->solenoidOverCurrent = status1.sticky_solenoid_oc_fault;
|
||||
stickyFaults->brownout = status1.sticky_brownout_fault;
|
||||
stickyFaults->canWarning = status1.sticky_can_warning_fault;
|
||||
stickyFaults->canBusOff = status1.sticky_can_bus_off_fault;
|
||||
stickyFaults->hasReset = status1.sticky_has_reset_fault;
|
||||
}
|
||||
|
||||
void HAL_ClearREVPHStickyFaults(HAL_REVPHHandle handle, int32_t* status) {
|
||||
auto ph = REVPHHandles->Get(handle);
|
||||
if (ph == nullptr) {
|
||||
*status = HAL_HANDLE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t packedData[8] = {0};
|
||||
HAL_WriteCANPacket(ph->hcan, packedData, PH_CLEAR_FAULTS_LENGTH,
|
||||
PH_CLEAR_FAULTS_FRAME_API, status);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ static JException canMessageNotFoundExCls;
|
||||
static JException canMessageNotAllowedExCls;
|
||||
static JException canNotInitializedExCls;
|
||||
static JException uncleanStatusExCls;
|
||||
static JClass powerDistributionVersionCls;
|
||||
static JClass pwmConfigDataResultCls;
|
||||
static JClass canStatusCls;
|
||||
static JClass matchInfoDataCls;
|
||||
@@ -53,15 +54,19 @@ static JClass accumulatorResultCls;
|
||||
static JClass canDataCls;
|
||||
static JClass halValueCls;
|
||||
static JClass baseStoreCls;
|
||||
static JClass revPHVersionCls;
|
||||
|
||||
static const JClassInit classes[] = {
|
||||
{"edu/wpi/first/hal/PowerDistributionVersion",
|
||||
&powerDistributionVersionCls},
|
||||
{"edu/wpi/first/hal/PWMConfigDataResult", &pwmConfigDataResultCls},
|
||||
{"edu/wpi/first/hal/can/CANStatus", &canStatusCls},
|
||||
{"edu/wpi/first/hal/MatchInfoData", &matchInfoDataCls},
|
||||
{"edu/wpi/first/hal/AccumulatorResult", &accumulatorResultCls},
|
||||
{"edu/wpi/first/hal/CANData", &canDataCls},
|
||||
{"edu/wpi/first/hal/HALValue", &halValueCls},
|
||||
{"edu/wpi/first/hal/DMAJNISample$BaseStore", &baseStoreCls}};
|
||||
{"edu/wpi/first/hal/DMAJNISample$BaseStore", &baseStoreCls},
|
||||
{"edu/wpi/first/hal/REVPHVersion", &revPHVersionCls}};
|
||||
|
||||
static const JExceptionInit exceptions[] = {
|
||||
{"java/lang/IllegalArgumentException", &illegalArgExCls},
|
||||
@@ -238,6 +243,19 @@ jobject CreatePWMConfigDataResult(JNIEnv* env, int32_t maxPwm,
|
||||
static_cast<jint>(deadbandMinPwm), static_cast<jint>(minPwm));
|
||||
}
|
||||
|
||||
jobject CreateREVPHVersion(JNIEnv* env, uint32_t firmwareMajor,
|
||||
uint32_t firmwareMinor, uint32_t firmwareFix,
|
||||
uint32_t hardwareMinor, uint32_t hardwareMajor,
|
||||
uint32_t uniqueId) {
|
||||
static jmethodID constructor =
|
||||
env->GetMethodID(revPHVersionCls, "<init>", "(IIIIII)V");
|
||||
return env->NewObject(
|
||||
revPHVersionCls, constructor, static_cast<jint>(firmwareMajor),
|
||||
static_cast<jint>(firmwareMinor), static_cast<jint>(firmwareFix),
|
||||
static_cast<jint>(hardwareMinor), static_cast<jint>(hardwareMajor),
|
||||
static_cast<jint>(uniqueId));
|
||||
}
|
||||
|
||||
void SetCanStatusObject(JNIEnv* env, jobject canStatus,
|
||||
float percentBusUtilization, uint32_t busOffCount,
|
||||
uint32_t txFullCount, uint32_t receiveErrorCount,
|
||||
@@ -318,6 +336,21 @@ jobject CreateDMABaseStore(JNIEnv* env, jint valueType, jint index) {
|
||||
return env->NewObject(baseStoreCls, ctor, valueType, index);
|
||||
}
|
||||
|
||||
jobject CreatePowerDistributionVersion(JNIEnv* env, uint32_t firmwareMajor,
|
||||
uint32_t firmwareMinor,
|
||||
uint32_t firmwareFix,
|
||||
uint32_t hardwareMinor,
|
||||
uint32_t hardwareMajor,
|
||||
uint32_t uniqueId) {
|
||||
static jmethodID constructor =
|
||||
env->GetMethodID(powerDistributionVersionCls, "<init>", "(IIIIII)V");
|
||||
return env->NewObject(
|
||||
powerDistributionVersionCls, constructor,
|
||||
static_cast<jint>(firmwareMajor), static_cast<jint>(firmwareMinor),
|
||||
static_cast<jint>(firmwareFix), static_cast<jint>(hardwareMinor),
|
||||
static_cast<jint>(hardwareMajor), static_cast<jint>(uniqueId));
|
||||
}
|
||||
|
||||
JavaVM* GetJVM() {
|
||||
return jvm;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,11 @@ jobject CreatePWMConfigDataResult(JNIEnv* env, int32_t maxPwm,
|
||||
int32_t deadbandMaxPwm, int32_t centerPwm,
|
||||
int32_t deadbandMinPwm, int32_t minPwm);
|
||||
|
||||
jobject CreateREVPHVersion(JNIEnv* env, uint32_t firmwareMajor,
|
||||
uint32_t firmwareMinor, uint32_t firmwareFix,
|
||||
uint32_t hardwareMinor, uint32_t hardwareMajor,
|
||||
uint32_t uniqueId);
|
||||
|
||||
void SetCanStatusObject(JNIEnv* env, jobject canStatus,
|
||||
float percentBusUtilization, uint32_t busOffCount,
|
||||
uint32_t txFullCount, uint32_t receiveErrorCount,
|
||||
@@ -77,6 +82,13 @@ jobject CreateHALValue(JNIEnv* env, const HAL_Value& value);
|
||||
|
||||
jobject CreateDMABaseStore(JNIEnv* env, jint valueType, jint index);
|
||||
|
||||
jobject CreatePowerDistributionVersion(JNIEnv* env, uint32_t firmwareMajor,
|
||||
uint32_t firmwareMinor,
|
||||
uint32_t firmwareFix,
|
||||
uint32_t hardwareMinor,
|
||||
uint32_t hardwareMajor,
|
||||
uint32_t uniqueId);
|
||||
|
||||
JavaVM* GetJVM();
|
||||
|
||||
} // namespace hal
|
||||
|
||||
@@ -362,4 +362,63 @@ Java_edu_wpi_first_hal_PowerDistributionJNI_getSwitchableChannelNoError
|
||||
return state;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_PowerDistributionJNI
|
||||
* Method: getStickyFaultsNative
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_PowerDistributionJNI_getStickyFaultsNative
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_PowerDistributionStickyFaults halFaults;
|
||||
std::memset(&halFaults, 0, sizeof(halFaults));
|
||||
HAL_GetPowerDistributionStickyFaults(handle, &halFaults, &status);
|
||||
CheckStatus(env, status, false);
|
||||
jint faults;
|
||||
static_assert(sizeof(faults) == sizeof(halFaults));
|
||||
std::memcpy(&faults, &halFaults, sizeof(faults));
|
||||
return faults;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_PowerDistributionJNI
|
||||
* Method: getFaultsNative
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_PowerDistributionJNI_getFaultsNative
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_PowerDistributionFaults halFaults;
|
||||
std::memset(&halFaults, 0, sizeof(halFaults));
|
||||
HAL_GetPowerDistributionFaults(handle, &halFaults, &status);
|
||||
CheckStatus(env, status, false);
|
||||
jint faults;
|
||||
static_assert(sizeof(faults) == sizeof(halFaults));
|
||||
std::memcpy(&faults, &halFaults, sizeof(faults));
|
||||
return faults;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_PowerDistributionJNI
|
||||
* Method: getVersion
|
||||
* Signature: (I)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_edu_wpi_first_hal_PowerDistributionJNI_getVersion
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_PowerDistributionVersion version;
|
||||
std::memset(&version, 0, sizeof(version));
|
||||
HAL_GetPowerDistributionVersion(handle, &version, &status);
|
||||
CheckStatus(env, status, false);
|
||||
return CreatePowerDistributionVersion(
|
||||
env, version.firmwareMajor, version.firmwareMinor, version.firmwareFix,
|
||||
version.hardwareMinor, version.hardwareMajor, version.uniqueId);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -196,15 +196,15 @@ Java_edu_wpi_first_hal_REVPHJNI_getPressureSwitch
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_REVPHJNI
|
||||
* Method: getAnalogPressure
|
||||
* Method: getAnalogVoltage
|
||||
* Signature: (II)D
|
||||
*/
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_edu_wpi_first_hal_REVPHJNI_getAnalogPressure
|
||||
Java_edu_wpi_first_hal_REVPHJNI_getAnalogVoltage
|
||||
(JNIEnv* env, jclass, jint handle, jint channel)
|
||||
{
|
||||
int32_t status = 0;
|
||||
auto result = HAL_GetREVPHAnalogPressure(handle, channel, &status);
|
||||
auto result = HAL_GetREVPHAnalogVoltage(handle, channel, &status);
|
||||
CheckStatus(env, status, false);
|
||||
return result;
|
||||
}
|
||||
@@ -267,4 +267,137 @@ Java_edu_wpi_first_hal_REVPHJNI_fireOneShot
|
||||
CheckStatus(env, status, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_REVPHJNI
|
||||
* Method: clearStickyFaults
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_REVPHJNI_clearStickyFaults
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_ClearREVPHStickyFaults(handle, &status);
|
||||
CheckStatus(env, status, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_REVPHJNI
|
||||
* Method: getInputVoltage
|
||||
* Signature: (I)D
|
||||
*/
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_edu_wpi_first_hal_REVPHJNI_getInputVoltage
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
auto voltage = HAL_GetREVPHVoltage(handle, &status);
|
||||
CheckStatus(env, status, false);
|
||||
return voltage;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_REVPHJNI
|
||||
* Method: get5VVoltage
|
||||
* Signature: (I)D
|
||||
*/
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_edu_wpi_first_hal_REVPHJNI_get5VVoltage
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
auto voltage = HAL_GetREVPH5VVoltage(handle, &status);
|
||||
CheckStatus(env, status, false);
|
||||
return voltage;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_REVPHJNI
|
||||
* Method: getSolenoidCurrent
|
||||
* Signature: (I)D
|
||||
*/
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_edu_wpi_first_hal_REVPHJNI_getSolenoidCurrent
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
auto voltage = HAL_GetREVPHSolenoidCurrent(handle, &status);
|
||||
CheckStatus(env, status, false);
|
||||
return voltage;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_REVPHJNI
|
||||
* Method: getSolenoidVoltage
|
||||
* Signature: (I)D
|
||||
*/
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_edu_wpi_first_hal_REVPHJNI_getSolenoidVoltage
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
auto voltage = HAL_GetREVPHSolenoidVoltage(handle, &status);
|
||||
CheckStatus(env, status, false);
|
||||
return voltage;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_REVPHJNI
|
||||
* Method: getStickyFaultsNative
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_REVPHJNI_getStickyFaultsNative
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_REVPHStickyFaults halFaults;
|
||||
std::memset(&halFaults, 0, sizeof(halFaults));
|
||||
HAL_GetREVPHStickyFaults(handle, &halFaults, &status);
|
||||
CheckStatus(env, status, false);
|
||||
jint faults;
|
||||
static_assert(sizeof(faults) == sizeof(halFaults));
|
||||
std::memcpy(&faults, &halFaults, sizeof(faults));
|
||||
return faults;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_REVPHJNI
|
||||
* Method: getFaultsNative
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_REVPHJNI_getFaultsNative
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_REVPHFaults halFaults;
|
||||
std::memset(&halFaults, 0, sizeof(halFaults));
|
||||
HAL_GetREVPHFaults(handle, &halFaults, &status);
|
||||
CheckStatus(env, status, false);
|
||||
jint faults;
|
||||
static_assert(sizeof(faults) == sizeof(halFaults));
|
||||
std::memcpy(&faults, &halFaults, sizeof(faults));
|
||||
return faults;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_REVPHJNI
|
||||
* Method: getVersion
|
||||
* Signature: (I)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_edu_wpi_first_hal_REVPHJNI_getVersion
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
int32_t status = 0;
|
||||
HAL_REVPHVersion version;
|
||||
std::memset(&version, 0, sizeof(version));
|
||||
HAL_GetREVPHVersion(handle, &version, &status);
|
||||
CheckStatus(env, status, false);
|
||||
return CreateREVPHVersion(env, version.firmwareMajor, version.firmwareMinor,
|
||||
version.firmwareFix, version.hardwareMinor,
|
||||
version.hardwareMajor, version.uniqueId);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -218,6 +218,89 @@ void HAL_SetPowerDistributionSwitchableChannel(
|
||||
HAL_Bool HAL_GetPowerDistributionSwitchableChannel(
|
||||
HAL_PowerDistributionHandle handle, int32_t* status);
|
||||
|
||||
struct HAL_PowerDistributionVersion {
|
||||
uint32_t firmwareMajor;
|
||||
uint32_t firmwareMinor;
|
||||
uint32_t firmwareFix;
|
||||
uint32_t hardwareMinor;
|
||||
uint32_t hardwareMajor;
|
||||
uint32_t uniqueId;
|
||||
};
|
||||
|
||||
struct HAL_PowerDistributionFaults {
|
||||
uint32_t channel0BreakerFault : 1;
|
||||
uint32_t channel1BreakerFault : 1;
|
||||
uint32_t channel2BreakerFault : 1;
|
||||
uint32_t channel3BreakerFault : 1;
|
||||
uint32_t channel4BreakerFault : 1;
|
||||
uint32_t channel5BreakerFault : 1;
|
||||
uint32_t channel6BreakerFault : 1;
|
||||
uint32_t channel7BreakerFault : 1;
|
||||
uint32_t channel8BreakerFault : 1;
|
||||
uint32_t channel9BreakerFault : 1;
|
||||
uint32_t channel10BreakerFault : 1;
|
||||
uint32_t channel11BreakerFault : 1;
|
||||
uint32_t channel12BreakerFault : 1;
|
||||
uint32_t channel13BreakerFault : 1;
|
||||
uint32_t channel14BreakerFault : 1;
|
||||
uint32_t channel15BreakerFault : 1;
|
||||
uint32_t channel16BreakerFault : 1;
|
||||
uint32_t channel17BreakerFault : 1;
|
||||
uint32_t channel18BreakerFault : 1;
|
||||
uint32_t channel19BreakerFault : 1;
|
||||
uint32_t channel20BreakerFault : 1;
|
||||
uint32_t channel21BreakerFault : 1;
|
||||
uint32_t channel22BreakerFault : 1;
|
||||
uint32_t channel23BreakerFault : 1;
|
||||
uint32_t brownout : 1;
|
||||
uint32_t canWarning : 1;
|
||||
uint32_t hardwareFault : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Storage for REV PDH Sticky Faults
|
||||
*/
|
||||
struct HAL_PowerDistributionStickyFaults {
|
||||
uint32_t channel0BreakerFault : 1;
|
||||
uint32_t channel1BreakerFault : 1;
|
||||
uint32_t channel2BreakerFault : 1;
|
||||
uint32_t channel3BreakerFault : 1;
|
||||
uint32_t channel4BreakerFault : 1;
|
||||
uint32_t channel5BreakerFault : 1;
|
||||
uint32_t channel6BreakerFault : 1;
|
||||
uint32_t channel7BreakerFault : 1;
|
||||
uint32_t channel8BreakerFault : 1;
|
||||
uint32_t channel9BreakerFault : 1;
|
||||
uint32_t channel10BreakerFault : 1;
|
||||
uint32_t channel11BreakerFault : 1;
|
||||
uint32_t channel12BreakerFault : 1;
|
||||
uint32_t channel13BreakerFault : 1;
|
||||
uint32_t channel14BreakerFault : 1;
|
||||
uint32_t channel15BreakerFault : 1;
|
||||
uint32_t channel16BreakerFault : 1;
|
||||
uint32_t channel17BreakerFault : 1;
|
||||
uint32_t channel18BreakerFault : 1;
|
||||
uint32_t channel19BreakerFault : 1;
|
||||
uint32_t channel20BreakerFault : 1;
|
||||
uint32_t channel21BreakerFault : 1;
|
||||
uint32_t channel22BreakerFault : 1;
|
||||
uint32_t channel23BreakerFault : 1;
|
||||
uint32_t brownout : 1;
|
||||
uint32_t canWarning : 1;
|
||||
uint32_t canBusOff : 1;
|
||||
uint32_t hasReset : 1;
|
||||
};
|
||||
|
||||
void HAL_GetPowerDistributionVersion(HAL_PowerDistributionHandle handle,
|
||||
HAL_PowerDistributionVersion* version,
|
||||
int32_t* status);
|
||||
void HAL_GetPowerDistributionFaults(HAL_PowerDistributionHandle handle,
|
||||
HAL_PowerDistributionFaults* faults,
|
||||
int32_t* status);
|
||||
void HAL_GetPowerDistributionStickyFaults(
|
||||
HAL_PowerDistributionHandle handle,
|
||||
HAL_PowerDistributionStickyFaults* stickyFaults, int32_t* status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,18 @@ HAL_ENUM(HAL_REVPHCompressorConfigType){
|
||||
HAL_REVPHCompressorConfigType_kHybrid = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* Storage for REV PH Version
|
||||
*/
|
||||
struct HAL_REVPHVersion {
|
||||
uint32_t firmwareMajor;
|
||||
uint32_t firmwareMinor;
|
||||
uint32_t firmwareFix;
|
||||
uint32_t hardwareMinor;
|
||||
uint32_t hardwareMajor;
|
||||
uint32_t uniqueId;
|
||||
};
|
||||
|
||||
/**
|
||||
* Storage for compressor config
|
||||
*/
|
||||
@@ -108,8 +120,14 @@ HAL_REVPHCompressorConfigType HAL_GetREVPHCompressorConfig(
|
||||
HAL_REVPHHandle handle, int32_t* status);
|
||||
HAL_Bool HAL_GetREVPHPressureSwitch(HAL_REVPHHandle handle, int32_t* status);
|
||||
double HAL_GetREVPHCompressorCurrent(HAL_REVPHHandle handle, int32_t* status);
|
||||
double HAL_GetREVPHAnalogPressure(HAL_REVPHHandle handle, int32_t channel,
|
||||
int32_t* status);
|
||||
double HAL_GetREVPHAnalogVoltage(HAL_REVPHHandle handle, int32_t channel,
|
||||
int32_t* status);
|
||||
double HAL_GetREVPHVoltage(HAL_REVPHHandle handle, int32_t* status);
|
||||
double HAL_GetREVPH5VVoltage(HAL_REVPHHandle handle, int32_t* status);
|
||||
double HAL_GetREVPHSolenoidCurrent(HAL_REVPHHandle handle, int32_t* status);
|
||||
double HAL_GetREVPHSolenoidVoltage(HAL_REVPHHandle handle, int32_t* status);
|
||||
void HAL_GetREVPHVersion(HAL_REVPHHandle handle, HAL_REVPHVersion* version,
|
||||
int32_t* status);
|
||||
|
||||
int32_t HAL_GetREVPHSolenoids(HAL_REVPHHandle handle, int32_t* status);
|
||||
void HAL_SetREVPHSolenoids(HAL_REVPHHandle handle, int32_t mask, int32_t values,
|
||||
@@ -118,10 +136,14 @@ void HAL_SetREVPHSolenoids(HAL_REVPHHandle handle, int32_t mask, int32_t values,
|
||||
void HAL_FireREVPHOneShot(HAL_REVPHHandle handle, int32_t index, int32_t durMs,
|
||||
int32_t* status);
|
||||
|
||||
HAL_REVPHFaults HAL_GetREVPHFaults(HAL_REVPHHandle handle, int32_t* status);
|
||||
void HAL_GetREVPHFaults(HAL_REVPHHandle handle, HAL_REVPHFaults* faults,
|
||||
int32_t* status);
|
||||
|
||||
HAL_REVPHStickyFaults HAL_GetREVPHStickyFaults(HAL_REVPHHandle handle,
|
||||
int32_t* status);
|
||||
void HAL_GetREVPHStickyFaults(HAL_REVPHHandle handle,
|
||||
HAL_REVPHStickyFaults* stickyFaults,
|
||||
int32_t* status);
|
||||
|
||||
void HAL_ClearREVPHStickyFaults(HAL_REVPHHandle handle, int32_t* status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
||||
@@ -74,6 +74,11 @@ typedef int32_t HAL_Bool;
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define HAL_ENUM(name) enum name : int32_t
|
||||
#elif defined(__clang__)
|
||||
#define HAL_ENUM(name) \
|
||||
enum name : int32_t; \
|
||||
typedef enum name name; \
|
||||
enum name : int32_t
|
||||
#else
|
||||
#define HAL_ENUM(name) \
|
||||
typedef int32_t name; \
|
||||
|
||||
@@ -320,7 +320,7 @@ int32_t HALSIM_GetNotifierInfo(struct HALSIM_NotifierInfo* arr, int32_t size) {
|
||||
static_cast<int>(getHandleIndex(handle)));
|
||||
} else {
|
||||
std::strncpy(arr[num].name, notifier->name.c_str(),
|
||||
sizeof(arr[num].name));
|
||||
sizeof(arr[num].name) - 1);
|
||||
arr[num].name[sizeof(arr[num].name) - 1] = '\0';
|
||||
}
|
||||
arr[num].timeout = notifier->waitTime;
|
||||
|
||||
@@ -168,4 +168,16 @@ HAL_Bool HAL_GetPowerDistributionSwitchableChannel(
|
||||
HAL_PowerDistributionHandle handle, int32_t* status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void HAL_GetPowerDistributionVersion(HAL_PowerDistributionHandle handle,
|
||||
HAL_PowerDistributionVersion* version,
|
||||
int32_t* status) {}
|
||||
|
||||
void HAL_GetPowerDistributionFaults(HAL_PowerDistributionHandle handle,
|
||||
HAL_PowerDistributionFaults* faults,
|
||||
int32_t* status) {}
|
||||
|
||||
void HAL_GetPowerDistributionStickyFaults(
|
||||
HAL_PowerDistributionHandle handle,
|
||||
HAL_PowerDistributionStickyFaults* stickyFaults, int32_t* status) {}
|
||||
} // extern "C"
|
||||
|
||||
@@ -177,8 +177,8 @@ HAL_Bool HAL_GetREVPHPressureSwitch(HAL_REVPHHandle handle, int32_t* status) {
|
||||
return SimREVPHData[pcm->module].pressureSwitch;
|
||||
}
|
||||
|
||||
double HAL_GetREVPHAnalogPressure(HAL_REVPHHandle handle, int32_t channel,
|
||||
int32_t* status) {
|
||||
double HAL_GetREVPHAnalogVoltage(HAL_REVPHHandle handle, int32_t channel,
|
||||
int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -227,3 +227,31 @@ void HAL_SetREVPHSolenoids(HAL_REVPHHandle handle, int32_t mask, int32_t values,
|
||||
|
||||
void HAL_FireREVPHOneShot(HAL_REVPHHandle handle, int32_t index, int32_t durMs,
|
||||
int32_t* status) {}
|
||||
|
||||
double HAL_GetREVPHVoltage(HAL_REVPHHandle handle, int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double HAL_GetREVPH5VVoltage(HAL_REVPHHandle handle, int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double HAL_GetREVPHSolenoidCurrent(HAL_REVPHHandle handle, int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double HAL_GetREVPHSolenoidVoltage(HAL_REVPHHandle handle, int32_t* status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HAL_GetREVPHVersion(HAL_REVPHHandle handle, HAL_REVPHVersion* version,
|
||||
int32_t* status) {}
|
||||
|
||||
void HAL_GetREVPHFaults(HAL_REVPHHandle handle, HAL_REVPHFaults* faults,
|
||||
int32_t* status) {}
|
||||
|
||||
void HAL_GetREVPHStickyFaults(HAL_REVPHHandle handle,
|
||||
HAL_REVPHStickyFaults* stickyFaults,
|
||||
int32_t* status) {}
|
||||
|
||||
void HAL_ClearREVPHStickyFaults(HAL_REVPHHandle handle, int32_t* status) {}
|
||||
|
||||
@@ -5,7 +5,7 @@ project(imgui-download NONE)
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(glfw3
|
||||
GIT_REPOSITORY https://github.com/glfw/glfw.git
|
||||
GIT_TAG 3.3.4
|
||||
GIT_TAG 3.3.6
|
||||
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/glfw-src"
|
||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/glfw-build"
|
||||
CONFIGURE_COMMAND ""
|
||||
@@ -15,7 +15,7 @@ ExternalProject_Add(glfw3
|
||||
)
|
||||
ExternalProject_Add(gl3w
|
||||
GIT_REPOSITORY https://github.com/skaslev/gl3w
|
||||
GIT_TAG 8418c1b38d195edbd3b20a8f13ec91de6c8c570c
|
||||
GIT_TAG 3755745085ac2e865fd22270cfe9169c26640f70
|
||||
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/gl3w-src"
|
||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/gl3w-build"
|
||||
INSTALL_COMMAND ""
|
||||
@@ -23,7 +23,7 @@ ExternalProject_Add(gl3w
|
||||
)
|
||||
ExternalProject_Add(imgui
|
||||
GIT_REPOSITORY https://github.com/ocornut/imgui.git
|
||||
GIT_TAG v1.82
|
||||
GIT_TAG v1.86
|
||||
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/imgui-src"
|
||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/imgui-build"
|
||||
CONFIGURE_COMMAND ""
|
||||
@@ -33,7 +33,7 @@ ExternalProject_Add(imgui
|
||||
)
|
||||
ExternalProject_Add(implot
|
||||
GIT_REPOSITORY https://github.com/epezent/implot.git
|
||||
GIT_TAG 555ff688a8134bc0c602123149abe9c17d577475
|
||||
GIT_TAG 4fcc6e01aca406ef17d5a2dabdcbc9e1bd962c0d
|
||||
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/implot-src"
|
||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/implot-build"
|
||||
CONFIGURE_COMMAND ""
|
||||
|
||||
@@ -162,14 +162,16 @@ model {
|
||||
lib project: ':wpilibNewCommands', library: 'wpilibNewCommands', linkage: 'shared'
|
||||
lib project: ':wpilibc', library: 'wpilibc', linkage: 'shared'
|
||||
lib project: ':wpimath', library: 'wpimath', linkage: 'shared'
|
||||
lib project: ':cameraserver', library: 'cameraserver', linkage: 'shared'
|
||||
lib project: ':ntcore', library: 'ntcore', linkage: 'shared'
|
||||
lib project: ':cscore', library: 'cscore', linkage: 'shared'
|
||||
lib project: ':ntcore', library: 'ntcoreJNIShared', linkage: 'shared'
|
||||
lib project: ':cscore', library: 'cscoreJNIShared', linkage: 'shared'
|
||||
lib project: ':wpimath', library: 'wpimathJNIShared', linkage: 'shared'
|
||||
lib project: ':wpiutil', library: 'wpiutilJNIShared', linkage: 'shared'
|
||||
project(':hal').addHalDependency(binary, 'shared')
|
||||
project(':hal').addHalJniDependency(binary)
|
||||
lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared'
|
||||
lib project: ':cameraserver', library: 'cameraserver', linkage: 'shared'
|
||||
if (binary.targetPlatform.name == nativeUtils.wpi.platforms.roborio) {
|
||||
nativeUtils.useRequiredLibrary(binary, 'ni_link_libraries', 'ni_runtime_libraries')
|
||||
} else {
|
||||
@@ -207,11 +209,11 @@ model {
|
||||
lib project: ':wpilibNewCommands', library: 'wpilibNewCommands', linkage: 'static'
|
||||
lib project: ':wpilibc', library: 'wpilibc', linkage: 'static'
|
||||
lib project: ':wpimath', library: 'wpimath', linkage: 'static'
|
||||
lib project: ':cameraserver', library: 'cameraserver', linkage: 'static'
|
||||
lib project: ':ntcore', library: 'ntcore', linkage: 'static'
|
||||
lib project: ':cscore', library: 'cscore', linkage: 'static'
|
||||
project(':hal').addHalDependency(binary, 'static')
|
||||
lib project: ':wpiutil', library: 'wpiutil', linkage: 'static'
|
||||
lib project: ':cameraserver', library: 'cameraserver', linkage: 'static'
|
||||
if (binary.targetPlatform.name == nativeUtils.wpi.platforms.roborio) {
|
||||
nativeUtils.useRequiredLibrary(binary, 'ni_link_libraries', 'ni_runtime_libraries')
|
||||
}
|
||||
|
||||
28
roborioteamnumbersetter/.styleguide
Normal file
@@ -0,0 +1,28 @@
|
||||
cppHeaderFileInclude {
|
||||
\.h$
|
||||
\.inc$
|
||||
\.inl$
|
||||
}
|
||||
|
||||
cppSrcFileInclude {
|
||||
\.cpp$
|
||||
}
|
||||
|
||||
generatedFileExclude {
|
||||
src/main/native/resources/
|
||||
src/main/native/win/roborioteamnumbersetter.ico
|
||||
src/main/native/mac/rtns.icns
|
||||
}
|
||||
|
||||
repoRootNameOverride {
|
||||
roborioteamnumbersetter
|
||||
}
|
||||
|
||||
includeOtherLibs {
|
||||
^GLFW
|
||||
^fmt/
|
||||
^imgui
|
||||
^ntcore
|
||||
^wpi/
|
||||
^wpigui
|
||||
}
|
||||
29
roborioteamnumbersetter/CMakeLists.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
project(roborioteamnumbersetter)
|
||||
|
||||
include(CompileWarnings)
|
||||
include(GenResources)
|
||||
include(LinkMacOSGUI)
|
||||
|
||||
configure_file(src/main/generate/WPILibVersion.cpp.in WPILibVersion.cpp)
|
||||
GENERATE_RESOURCES(src/main/native/resources generated/main/cpp RTNS rtns rtns_resources_src)
|
||||
|
||||
file(GLOB rtns_src src/main/native/cpp/*.cpp ${CMAKE_CURRENT_BINARY_DIR}/WPILibVersion.cpp)
|
||||
|
||||
if (WIN32)
|
||||
set(rtns_rc src/main/native/win/roborioteamnumbersetter.rc)
|
||||
elseif(APPLE)
|
||||
set(MACOSX_BUNDLE_ICON_FILE glass.icns)
|
||||
set(APP_ICON_MACOSX src/main/native/mac/rtns.icns)
|
||||
set_source_files_properties(${APP_ICON_MACOSX} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||
endif()
|
||||
|
||||
add_executable(roborioteamnumbersetter ${rtns_src} ${rtns_resources_src} ${rtns_rc} ${APP_ICON_MACOSX})
|
||||
wpilib_link_macos_gui(roborioteamnumbersetter)
|
||||
target_link_libraries(roborioteamnumbersetter libglass ${LIBSSH_LIBRARIES})
|
||||
target_include_directories(roborioteamnumbersetter PRIVATE ${LIBSSH_INCLUDE_DIRS})
|
||||
|
||||
if (WIN32)
|
||||
set_target_properties(roborioteamnumbersetter PROPERTIES WIN32_EXECUTABLE YES)
|
||||
elseif(APPLE)
|
||||
set_target_properties(roborioteamnumbersetter PROPERTIES MACOSX_BUNDLE YES OUTPUT_NAME "roborioTeamNumberSetter")
|
||||
endif()
|
||||
32
roborioteamnumbersetter/Info.plist
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>roboRIOTeamNumberSetter</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>roborioteamnumbersetter</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>roboRIOTeamNumberSetter</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>edu.wpi.first.tools.roboRIOTeamNumberSetter</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>rtns.icns</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2021</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2021</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.11</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
134
roborioteamnumbersetter/build.gradle
Normal file
@@ -0,0 +1,134 @@
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
|
||||
if (!project.hasProperty('onlylinuxathena') && !project.hasProperty('onlylinuxraspbian') && !project.hasProperty('onlylinuxaarch64bionic')) {
|
||||
|
||||
description = "roboRIO Team Number Setter"
|
||||
|
||||
apply plugin: 'cpp'
|
||||
apply plugin: 'c'
|
||||
apply plugin: 'google-test-test-suite'
|
||||
apply plugin: 'visual-studio'
|
||||
apply plugin: 'edu.wpi.first.NativeUtils'
|
||||
|
||||
if (OperatingSystem.current().isWindows()) {
|
||||
apply plugin: 'windows-resources'
|
||||
}
|
||||
|
||||
ext {
|
||||
nativeName = 'roborioteamnumbersetter'
|
||||
}
|
||||
|
||||
apply from: "${rootDir}/shared/resources.gradle"
|
||||
apply from: "${rootDir}/shared/config.gradle"
|
||||
|
||||
def wpilibVersionFileInput = file("src/main/generate/WPILibVersion.cpp.in")
|
||||
def wpilibVersionFileOutput = file("$buildDir/generated/main/cpp/WPILibVersion.cpp")
|
||||
|
||||
nativeUtils {
|
||||
nativeDependencyContainer {
|
||||
libssh(getNativeDependencyTypeClass('WPIStaticMavenDependency')) {
|
||||
groupId = "edu.wpi.first.thirdparty.frc2022"
|
||||
artifactId = "libssh"
|
||||
headerClassifier = "headers"
|
||||
sourceClassifier = "sources"
|
||||
ext = "zip"
|
||||
version = '0.95-1'
|
||||
targetPlatforms.addAll(nativeUtils.wpi.platforms.desktopPlatforms)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task generateCppVersion() {
|
||||
description = 'Generates the wpilib version class'
|
||||
group = 'WPILib'
|
||||
|
||||
outputs.file wpilibVersionFileOutput
|
||||
inputs.file wpilibVersionFileInput
|
||||
|
||||
if (wpilibVersioning.releaseMode) {
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
// We follow a simple set of checks to determine whether we should generate a new version file:
|
||||
// 1. If the release type is not development, we generate a new version file
|
||||
// 2. If there is no generated version number, we generate a new version file
|
||||
// 3. If there is a generated build number, and the release type is development, then we will
|
||||
// only generate if the publish task is run.
|
||||
doLast {
|
||||
def version = wpilibVersioning.version.get()
|
||||
println "Writing version ${version} to $wpilibVersionFileOutput"
|
||||
|
||||
if (wpilibVersionFileOutput.exists()) {
|
||||
wpilibVersionFileOutput.delete()
|
||||
}
|
||||
def read = wpilibVersionFileInput.text.replace('${wpilib_version}', version)
|
||||
wpilibVersionFileOutput.write(read)
|
||||
}
|
||||
}
|
||||
|
||||
gradle.taskGraph.addTaskExecutionGraphListener { graph ->
|
||||
def willPublish = graph.hasTask(publish)
|
||||
if (willPublish) {
|
||||
generateCppVersion.outputs.upToDateWhen { false }
|
||||
}
|
||||
}
|
||||
|
||||
def generateTask = createGenerateResourcesTask('main', 'RTNS', 'rtns', project)
|
||||
|
||||
project(':').libraryBuild.dependsOn build
|
||||
tasks.withType(CppCompile) {
|
||||
dependsOn generateTask
|
||||
dependsOn generateCppVersion
|
||||
}
|
||||
|
||||
model {
|
||||
components {
|
||||
// By default, a development executable will be generated. This is to help the case of
|
||||
// testing specific functionality of the library.
|
||||
"${nativeName}"(NativeExecutableSpec) {
|
||||
baseName = 'roborioteamnumbersetter'
|
||||
sources {
|
||||
cpp {
|
||||
source {
|
||||
srcDirs 'src/main/native/cpp', "$buildDir/generated/main/cpp"
|
||||
include '**/*.cpp'
|
||||
}
|
||||
exportedHeaders {
|
||||
srcDirs 'src/main/native/include'
|
||||
}
|
||||
}
|
||||
if (OperatingSystem.current().isWindows()) {
|
||||
rc {
|
||||
source {
|
||||
srcDirs 'src/main/native/win'
|
||||
include '*.rc'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
binaries.all {
|
||||
if (it.targetPlatform.name == nativeUtils.wpi.platforms.roborio || it.targetPlatform.name == nativeUtils.wpi.platforms.raspbian || it.targetPlatform.name == nativeUtils.wpi.platforms.aarch64bionic) {
|
||||
it.buildable = false
|
||||
return
|
||||
}
|
||||
it.cppCompiler.define("LIBSSH_STATIC")
|
||||
lib project: ':glass', library: 'glass', linkage: 'static'
|
||||
lib project: ':wpiutil', library: 'wpiutil', linkage: 'static'
|
||||
lib project: ':wpigui', library: 'wpigui', linkage: 'static'
|
||||
nativeUtils.useRequiredLibrary(it, 'imgui_static', 'libssh')
|
||||
if (it.targetPlatform.operatingSystem.isWindows()) {
|
||||
it.linker.args << 'Gdi32.lib' << 'Shell32.lib' << 'd3d11.lib' << 'd3dcompiler.lib'
|
||||
it.linker.args << 'ws2_32.lib' << 'advapi32.lib' << 'crypt32.lib' << 'user32.lib'
|
||||
} else if (it.targetPlatform.operatingSystem.isMacOsX()) {
|
||||
it.linker.args << '-framework' << 'Metal' << '-framework' << 'MetalKit' << '-framework' << 'Cocoa' << '-framework' << 'IOKit' << '-framework' << 'CoreFoundation' << '-framework' << 'CoreVideo' << '-framework' << 'QuartzCore'
|
||||
it.linker.args << '-framework' << 'Kerberos'
|
||||
} else {
|
||||
it.linker.args << '-lX11'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply from: 'publish.gradle'
|
||||
}
|
||||
107
roborioteamnumbersetter/publish.gradle
Normal file
@@ -0,0 +1,107 @@
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
def baseArtifactId = 'roboRIOTeamNumberSetter'
|
||||
def artifactGroupId = 'edu.wpi.first.tools'
|
||||
def zipBaseName = '_GROUP_edu_wpi_first_tools_ID_roboRIOTeamNumberSetter_CLS'
|
||||
|
||||
def outputsFolder = file("$project.buildDir/outputs")
|
||||
|
||||
model {
|
||||
tasks {
|
||||
// Create the run task.
|
||||
$.components.roborioteamnumbersetter.binaries.each { bin ->
|
||||
if (bin.buildable && bin.name.toLowerCase().contains("debug")) {
|
||||
Task run = project.tasks.create("run", Exec) {
|
||||
commandLine bin.tasks.install.runScriptFile.get().asFile.toString()
|
||||
}
|
||||
run.dependsOn bin.tasks.install
|
||||
}
|
||||
}
|
||||
}
|
||||
publishing {
|
||||
def roboRIOTeamNumberSetterTaskList = []
|
||||
$.components.each { component ->
|
||||
component.binaries.each { binary ->
|
||||
if (binary in NativeExecutableBinarySpec && binary.component.name.contains("roborioteamnumbersetter")) {
|
||||
if (binary.buildable && binary.name.contains("Release")) {
|
||||
// We are now in the binary that we want.
|
||||
// This is the default application path for the ZIP task.
|
||||
def applicationPath = binary.executable.file
|
||||
def icon = file("$project.projectDir/src/main/native/mac/rtns.icns")
|
||||
|
||||
// Create the macOS bundle.
|
||||
def bundleTask = project.tasks.create("bundleroboRIOTeamNumberSetterOsxApp", Copy) {
|
||||
description("Creates a macOS application bundle for roboRIO Team Number Setter")
|
||||
from(file("$project.projectDir/Info.plist"))
|
||||
into(file("$project.buildDir/outputs/bundles/roboRIOTeamNumberSetter.app/Contents"))
|
||||
into("MacOS") { with copySpec { from binary.executable.file } }
|
||||
into("Resources") { with copySpec { from icon } }
|
||||
|
||||
doLast {
|
||||
if (project.hasProperty("developerID")) {
|
||||
// Get path to binary.
|
||||
exec {
|
||||
workingDir rootDir
|
||||
def args = [
|
||||
"sh",
|
||||
"-c",
|
||||
"codesign --force --strict --deep " +
|
||||
"--timestamp --options=runtime " +
|
||||
"--verbose -s ${project.findProperty("developerID")} " +
|
||||
"$project.buildDir/outputs/bundles/roboRIOTeamNumberSetter.app/"
|
||||
]
|
||||
commandLine args
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the application path if we are creating a bundle.
|
||||
if (binary.targetPlatform.operatingSystem.isMacOsX()) {
|
||||
applicationPath = file("$project.buildDir/outputs/bundles")
|
||||
project.build.dependsOn bundleTask
|
||||
}
|
||||
|
||||
// Create the ZIP.
|
||||
def task = project.tasks.create("copyroboRIOTeamNumberSetterExecutable", Zip) {
|
||||
description("Copies the roboRIOTeamNumberSetter executable to the outputs directory.")
|
||||
destinationDirectory = outputsFolder
|
||||
|
||||
archiveBaseName = '_M_' + zipBaseName
|
||||
duplicatesStrategy = 'exclude'
|
||||
classifier = nativeUtils.getPublishClassifier(binary)
|
||||
|
||||
from(licenseFile) {
|
||||
into '/'
|
||||
}
|
||||
|
||||
from(applicationPath)
|
||||
into(nativeUtils.getPlatformPath(binary))
|
||||
}
|
||||
|
||||
if (binary.targetPlatform.operatingSystem.isMacOsX()) {
|
||||
bundleTask.dependsOn binary.tasks.link
|
||||
task.dependsOn(bundleTask)
|
||||
}
|
||||
|
||||
task.dependsOn binary.tasks.link
|
||||
roboRIOTeamNumberSetterTaskList.add(task)
|
||||
project.build.dependsOn task
|
||||
project.artifacts { task }
|
||||
addTaskToCopyAllOutputs(task)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publications {
|
||||
roborioteamnumbersetter(MavenPublication) {
|
||||
roboRIOTeamNumberSetterTaskList.each { artifact it }
|
||||
|
||||
artifactId = baseArtifactId
|
||||
groupId = artifactGroupId
|
||||
version wpilibVersioning.version.get()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
* Autogenerated file! Do not manually edit this file. This version is regenerated
|
||||
* any time the publish task is run, or when this file is deleted.
|
||||
*/
|
||||
const char* GetWPILibVersion() {
|
||||
return "${wpilib_version}";
|
||||
}
|
||||
265
roborioteamnumbersetter/src/main/native/cpp/App.cpp
Normal file
@@ -0,0 +1,265 @@
|
||||
// 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 <memory>
|
||||
#include <string_view>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <glass/MainMenuBar.h>
|
||||
#include <glass/Context.h>
|
||||
#include <glass/Storage.h>
|
||||
#include <glass/Window.h>
|
||||
#include <glass/WindowManager.h>
|
||||
#include <glass/other/Log.h>
|
||||
#include <imgui.h>
|
||||
#include <libssh/libssh.h>
|
||||
#include <wpi/Logger.h>
|
||||
#include <wpi/fs.h>
|
||||
#include <wpigui.h>
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
#include "wpi/SmallString.h"
|
||||
#include "DeploySession.h"
|
||||
#include "wpi/MulticastServiceResolver.h"
|
||||
|
||||
namespace gui = wpi::gui;
|
||||
|
||||
const char* GetWPILibVersion();
|
||||
|
||||
#define GLFWAPI extern "C"
|
||||
GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
|
||||
#define GLFW_DONT_CARE -1
|
||||
GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth,
|
||||
int minheight, int maxwidth,
|
||||
int maxheight);
|
||||
GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);
|
||||
|
||||
struct TeamNumberRefHolder {
|
||||
explicit TeamNumberRefHolder(glass::Storage& storage)
|
||||
: teamNumber{storage.GetInt("TeamNumber", 0)} {}
|
||||
int& teamNumber;
|
||||
};
|
||||
|
||||
static std::unique_ptr<TeamNumberRefHolder> teamNumberRef;
|
||||
static std::unordered_map<std::string, std::pair<unsigned int, std::string>>
|
||||
foundDevices;
|
||||
static wpi::Logger logger;
|
||||
static sysid::DeploySession deploySession{logger};
|
||||
static std::unique_ptr<wpi::MulticastServiceResolver> multicastResolver;
|
||||
static glass::MainMenuBar gMainMenu;
|
||||
|
||||
static void FindDevices() {
|
||||
WPI_EventHandle resolveEvent = multicastResolver->GetEventHandle();
|
||||
|
||||
bool timedOut = 0;
|
||||
if (wpi::WaitForObject(resolveEvent, 0, &timedOut)) {
|
||||
auto allData = multicastResolver->GetData();
|
||||
|
||||
for (auto&& data : allData) {
|
||||
// search for MAC
|
||||
auto macKey =
|
||||
std::find_if(data.txt.begin(), data.txt.end(),
|
||||
[](const auto& a) { return a.first == "MAC"; });
|
||||
if (macKey != data.txt.end()) {
|
||||
auto& mac = macKey->second;
|
||||
foundDevices[mac] = std::make_pair(data.ipv4Address, data.hostName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int minWidth = 400;
|
||||
|
||||
static void DisplayGui() {
|
||||
int& teamNumber = teamNumberRef->teamNumber;
|
||||
FindDevices();
|
||||
|
||||
ImGui::GetStyle().WindowRounding = 0;
|
||||
|
||||
// fill entire OS window with this window
|
||||
ImGui::SetNextWindowPos(ImVec2(0, 0));
|
||||
int width, height;
|
||||
glfwGetWindowSize(gui::GetSystemWindow(), &width, &height);
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(width, height));
|
||||
|
||||
ImGui::Begin("Entries", nullptr,
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_MenuBar |
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoCollapse);
|
||||
|
||||
ImGui::BeginMenuBar();
|
||||
gMainMenu.WorkspaceMenu();
|
||||
gui::EmitViewMenu();
|
||||
|
||||
bool about = false;
|
||||
if (ImGui::BeginMenu("Info")) {
|
||||
if (ImGui::MenuItem("About")) {
|
||||
about = true;
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
|
||||
if (about) {
|
||||
ImGui::OpenPopup("About");
|
||||
}
|
||||
if (ImGui::BeginPopupModal("About")) {
|
||||
ImGui::Text("roboRIO Team Number Setter");
|
||||
ImGui::Separator();
|
||||
ImGui::Text("v%s", GetWPILibVersion());
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Has mDNS Implementation: %d",
|
||||
static_cast<int>(multicastResolver->HasImplementation()));
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Save location: %s", glass::GetStorageDir().c_str());
|
||||
if (ImGui::Button("Close")) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (multicastResolver->HasImplementation()) {
|
||||
ImGui::InputInt("Team Number", &teamNumber);
|
||||
|
||||
if (teamNumber < 0) {
|
||||
teamNumber = 0;
|
||||
}
|
||||
|
||||
int nameWidth = ImGui::CalcTextSize("roboRIO2-0000-FRC.local. ").x;
|
||||
int macWidth = ImGui::CalcTextSize("88:88:88:88:88:88").x;
|
||||
int ipAddressWidth = ImGui::CalcTextSize("255.255.255.255").x;
|
||||
int setWidth = ImGui::CalcTextSize(" Set Team To 99999 ").x;
|
||||
int blinkWidth = ImGui::CalcTextSize(" Blink ").x;
|
||||
int rebootWidth = ImGui::CalcTextSize(" Reboot ").x;
|
||||
|
||||
minWidth = nameWidth + macWidth + ipAddressWidth + setWidth + blinkWidth +
|
||||
rebootWidth + 100;
|
||||
|
||||
std::string setString = fmt::format("Set team to {}", teamNumber);
|
||||
|
||||
if (ImGui::BeginTable("Table", 6)) {
|
||||
ImGui::TableSetupColumn(
|
||||
"Name",
|
||||
ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed,
|
||||
nameWidth);
|
||||
ImGui::TableSetupColumn(
|
||||
"MAC Address",
|
||||
ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed,
|
||||
macWidth);
|
||||
ImGui::TableSetupColumn(
|
||||
"IP Address",
|
||||
ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed,
|
||||
ipAddressWidth);
|
||||
ImGui::TableSetupColumn(
|
||||
"Set",
|
||||
ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed,
|
||||
setWidth);
|
||||
ImGui::TableSetupColumn(
|
||||
"Blink",
|
||||
ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed,
|
||||
blinkWidth);
|
||||
ImGui::TableSetupColumn(
|
||||
"Reboot",
|
||||
ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed,
|
||||
rebootWidth);
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (auto&& i : foundDevices) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", i.second.second.c_str());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", i.first.c_str());
|
||||
ImGui::TableNextColumn();
|
||||
struct in_addr in;
|
||||
in.s_addr = i.second.first;
|
||||
ImGui::Text("%s", inet_ntoa(in));
|
||||
ImGui::TableNextColumn();
|
||||
std::future<int>* future = deploySession.GetFuture(i.first);
|
||||
ImGui::PushID(i.first.c_str());
|
||||
if (future) {
|
||||
ImGui::Button("Deploying");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
const auto fs = future->wait_for(std::chrono::seconds(0));
|
||||
if (fs == std::future_status::ready) {
|
||||
deploySession.DestroyFuture(i.first);
|
||||
}
|
||||
} else {
|
||||
if (ImGui::Button(setString.c_str())) {
|
||||
deploySession.ChangeTeamNumber(i.first, teamNumber, i.second.first);
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Blink")) {
|
||||
deploySession.Blink(i.first, i.second.first);
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Reboot")) {
|
||||
deploySession.Reboot(i.first, i.second.first);
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::Columns(6, "Devices");
|
||||
|
||||
// TODO make columns better
|
||||
} else {
|
||||
// Missing MDNS Implementation
|
||||
ImGui::Text("mDNS Implementation is missing.");
|
||||
#ifdef _WIN32
|
||||
ImGui::Text("Windows 10 1809 or newer is required for this tool");
|
||||
#else
|
||||
ImGui::Text("avahi-client 3 and avahi-core 3 are required for this tool");
|
||||
ImGui::Text(
|
||||
"Install libavahi-client3 and libavahi-core3 from your package "
|
||||
"manager");
|
||||
#endif
|
||||
}
|
||||
ImGui::Columns();
|
||||
ImGui::End();
|
||||
|
||||
glfwSetWindowSizeLimits(gui::GetSystemWindow(), minWidth, 200, GLFW_DONT_CARE,
|
||||
GLFW_DONT_CARE);
|
||||
if (width < minWidth) {
|
||||
width = minWidth;
|
||||
glfwSetWindowSize(gui::GetSystemWindow(), width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void Application(std::string_view saveDir) {
|
||||
gui::CreateContext();
|
||||
glass::CreateContext();
|
||||
|
||||
glass::SetStorageName("roborioteamnumbersetter");
|
||||
glass::SetStorageDir(saveDir.empty() ? gui::GetPlatformSaveFileDir()
|
||||
: saveDir);
|
||||
|
||||
ssh_init();
|
||||
|
||||
teamNumberRef =
|
||||
std::make_unique<TeamNumberRefHolder>(glass::GetStorageRoot());
|
||||
|
||||
multicastResolver =
|
||||
std::make_unique<wpi::MulticastServiceResolver>("_ni._tcp");
|
||||
multicastResolver->Start();
|
||||
|
||||
gui::AddLateExecute(DisplayGui);
|
||||
gui::Initialize("roboRIO Team Number Setter", 600, 400);
|
||||
|
||||
gui::Main();
|
||||
multicastResolver->Stop();
|
||||
multicastResolver = nullptr;
|
||||
|
||||
glass::DestroyContext();
|
||||
gui::DestroyContext();
|
||||
}
|
||||
186
roborioteamnumbersetter/src/main/native/cpp/DeploySession.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
// 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 "DeploySession.h"
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <wpi/SmallString.h>
|
||||
#include <wpi/StringExtras.h>
|
||||
#include <wpi/uv/Error.h>
|
||||
#include <wpi/uv/GetAddrInfo.h>
|
||||
#include <wpi/uv/Work.h>
|
||||
#include <wpi/uv/util.h>
|
||||
|
||||
#include "SshSession.h"
|
||||
|
||||
using namespace sysid;
|
||||
|
||||
#ifdef ERROR
|
||||
#undef ERROR
|
||||
#endif
|
||||
|
||||
// Macros to make logging easier.
|
||||
#define INFO(fmt, ...) WPI_INFO(m_logger, fmt, __VA_ARGS__)
|
||||
#define DEBUG(fmt, ...) WPI_DEBUG(m_logger, fmt, __VA_ARGS__)
|
||||
#define ERROR(fmt, ...) WPI_DEBUG(m_logger, fmt, __VA_ARGS__)
|
||||
#define SUCCESS(fmt, ...) WPI_LOG(m_logger, kLogSuccess, fmt, __VA_ARGS__)
|
||||
|
||||
// roboRIO SSH constants.
|
||||
static constexpr int kPort = 22;
|
||||
static constexpr std::string_view kUsername = "admin";
|
||||
static constexpr std::string_view kPassword = "";
|
||||
|
||||
std::unordered_map<std::string, std::future<int>> s_outstanding;
|
||||
|
||||
DeploySession::DeploySession(wpi::Logger& logger) : m_logger{logger} {}
|
||||
|
||||
template <typename T>
|
||||
struct SafeDeleter {
|
||||
explicit SafeDeleter(T d) : deleter(d) {}
|
||||
~SafeDeleter() noexcept { deleter(); }
|
||||
T deleter;
|
||||
};
|
||||
|
||||
std::future<int>* DeploySession::GetFuture(const std::string& macAddress) {
|
||||
auto itr = s_outstanding.find(macAddress);
|
||||
if (itr == s_outstanding.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &itr->second;
|
||||
}
|
||||
|
||||
void DeploySession::DestroyFuture(const std::string& macAddress) {
|
||||
s_outstanding.erase(macAddress);
|
||||
}
|
||||
|
||||
bool DeploySession::ChangeTeamNumber(const std::string& macAddress,
|
||||
int teamNumber, unsigned int ipAddress) {
|
||||
auto itr = s_outstanding.find(macAddress);
|
||||
if (itr != s_outstanding.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::future<int> future = std::async(
|
||||
std::launch::async, [this, ipAddress, teamNumber, mac = macAddress]() {
|
||||
// Convert to IP address.
|
||||
wpi::SmallString<16> ip;
|
||||
in_addr addr;
|
||||
addr.s_addr = ipAddress;
|
||||
wpi::uv::AddrToName(addr, &ip);
|
||||
DEBUG("Trying to establish SSH connection to {}.", ip);
|
||||
try {
|
||||
SshSession session{ip.str(), kPort, kUsername, kPassword, m_logger};
|
||||
session.Open();
|
||||
DEBUG("SSH connection to {} was successful.", ip);
|
||||
|
||||
SUCCESS("{}", "roboRIO Connected!");
|
||||
|
||||
try {
|
||||
session.Execute(fmt::format(
|
||||
"/usr/local/natinst/bin/nirtcfg "
|
||||
"--file=/etc/natinst/share/ni-rt.ini --set "
|
||||
"section=systemsettings,token=host_name,value=roborio-{"
|
||||
"}-FRC ; sync",
|
||||
teamNumber));
|
||||
} catch (const SshSession::SshException& e) {
|
||||
ERROR("An exception occurred: {}", e.what());
|
||||
throw e;
|
||||
}
|
||||
} catch (const SshSession::SshException& e) {
|
||||
DEBUG("SSH connection to {} failed with {}.", ip, e.what());
|
||||
throw e;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
s_outstanding[macAddress] = std::move(future);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeploySession::Reboot(const std::string& macAddress,
|
||||
unsigned int ipAddress) {
|
||||
auto itr = s_outstanding.find(macAddress);
|
||||
if (itr != s_outstanding.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::future<int> future =
|
||||
std::async(std::launch::async, [this, ipAddress, mac = macAddress]() {
|
||||
// Convert to IP address.
|
||||
wpi::SmallString<16> ip;
|
||||
in_addr addr;
|
||||
addr.s_addr = ipAddress;
|
||||
wpi::uv::AddrToName(addr, &ip);
|
||||
DEBUG("Trying to establish SSH connection to {}.", ip);
|
||||
try {
|
||||
SshSession session{ip.str(), kPort, kUsername, kPassword, m_logger};
|
||||
session.Open();
|
||||
DEBUG("SSH connection to {} was successful.", ip);
|
||||
|
||||
SUCCESS("{}", "roboRIO Connected!");
|
||||
|
||||
try {
|
||||
session.Execute(fmt::format("sync ; shutdown -r now"));
|
||||
} catch (const SshSession::SshException& e) {
|
||||
ERROR("An exception occurred: {}", e.what());
|
||||
throw e;
|
||||
}
|
||||
} catch (const SshSession::SshException& e) {
|
||||
DEBUG("SSH connection to {} failed with {}.", ip, e.what());
|
||||
throw e;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
s_outstanding[macAddress] = std::move(future);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeploySession::Blink(const std::string& macAddress,
|
||||
unsigned int ipAddress) {
|
||||
auto itr = s_outstanding.find(macAddress);
|
||||
if (itr != s_outstanding.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::future<int> future =
|
||||
std::async(std::launch::async, [this, ipAddress, mac = macAddress]() {
|
||||
// Convert to IP address.
|
||||
wpi::SmallString<16> ip;
|
||||
in_addr addr;
|
||||
addr.s_addr = ipAddress;
|
||||
wpi::uv::AddrToName(addr, &ip);
|
||||
DEBUG("Trying to establish SSH connection to {}.", ip);
|
||||
try {
|
||||
SshSession session{ip.str(), kPort, kUsername, kPassword, m_logger};
|
||||
session.Open();
|
||||
DEBUG("SSH connection to {} was successful.", ip);
|
||||
|
||||
SUCCESS("{}", "roboRIO Connected!");
|
||||
|
||||
try {
|
||||
session.Execute(fmt::format(
|
||||
"for i in 1 2 3 4 5 ; do ` echo 255 > "
|
||||
"/sys/class/leds/nilrt:wifi:primary/brightness; sleep 0.5; "
|
||||
"echo 0 > /sys/class/leds/nilrt:wifi:primary/brightness; sleep "
|
||||
"0.5 ` ; done"));
|
||||
} catch (const SshSession::SshException& e) {
|
||||
ERROR("An exception occurred: {}", e.what());
|
||||
throw e;
|
||||
}
|
||||
} catch (const SshSession::SshException& e) {
|
||||
DEBUG("SSH connection to {} failed with {}.", ip, e.what());
|
||||
throw e;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
s_outstanding[macAddress] = std::move(future);
|
||||
return true;
|
||||
}
|
||||
70
roborioteamnumbersetter/src/main/native/cpp/DeploySession.h
Normal file
@@ -0,0 +1,70 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <future>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <wpi/Logger.h>
|
||||
|
||||
namespace sysid {
|
||||
// Define an integer for a successful message in the log (shown in green on the
|
||||
// GUI).
|
||||
static constexpr unsigned int kLogSuccess = 31;
|
||||
|
||||
/**
|
||||
* Represents a single deploy session.
|
||||
*
|
||||
* An instance of this class must be kept alive in memory until GetStatus()
|
||||
* returns kDiscoveryFailure or kDone. Otherwise, the deploy will fail!
|
||||
*/
|
||||
class DeploySession {
|
||||
public:
|
||||
/** Represents the status of the deploy session. */
|
||||
enum class Status { kInProgress, kDiscoveryFailure, kDone };
|
||||
|
||||
/**
|
||||
* Constructs an instance of the deploy session.
|
||||
*
|
||||
* @param team The team number (or an IP address/hostname).
|
||||
* @param drive Whether the drive program should be deployed to the roboRIO.
|
||||
* If this is set to false, the mechanism project will be
|
||||
* deployed.
|
||||
* @param config The generation configuration file to be sent to the roboRIO.
|
||||
* @param logger A reference to a logger where log messages should be sent.
|
||||
*/
|
||||
explicit DeploySession(wpi::Logger& logger);
|
||||
|
||||
/**
|
||||
* Executes the deploy. This can be called from any thread.
|
||||
*/
|
||||
bool ChangeTeamNumber(const std::string& macAddress, int team,
|
||||
unsigned int ipAddress);
|
||||
|
||||
bool Blink(const std::string& macAddress, unsigned int ipAddress);
|
||||
|
||||
bool Reboot(const std::string& macAddress, unsigned int ipAddress);
|
||||
|
||||
std::future<int>* GetFuture(const std::string& macAddress);
|
||||
void DestroyFuture(const std::string& macAddress);
|
||||
|
||||
/**
|
||||
* Returns the state of the deploy session.
|
||||
*/
|
||||
Status GetStatus() const;
|
||||
|
||||
private:
|
||||
// Logger reference where log messages will be sent.
|
||||
wpi::Logger& m_logger;
|
||||
|
||||
// The number of hostnames that have completed their resolution/connection
|
||||
// attempts.
|
||||
std::atomic_int m_visited = 0;
|
||||
};
|
||||
} // namespace sysid
|
||||
143
roborioteamnumbersetter/src/main/native/cpp/SshSession.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
// 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 "SshSession.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/sftp.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <wpi/Logger.h>
|
||||
|
||||
using namespace sysid;
|
||||
|
||||
#define INFO(fmt, ...) WPI_INFO(m_logger, fmt, __VA_ARGS__)
|
||||
|
||||
SshSession::SshSession(std::string_view host, int port, std::string_view user,
|
||||
std::string_view pass, wpi::Logger& logger)
|
||||
: m_host{host},
|
||||
m_port{port},
|
||||
m_username{user},
|
||||
m_password{pass},
|
||||
m_logger{logger} {
|
||||
// Create a new SSH session.
|
||||
m_session = ssh_new();
|
||||
if (!m_session) {
|
||||
throw SshException("The SSH session could not be allocated.");
|
||||
}
|
||||
|
||||
// Set the host, user, and port.
|
||||
ssh_options_set(m_session, SSH_OPTIONS_HOST, m_host.c_str());
|
||||
ssh_options_set(m_session, SSH_OPTIONS_USER, m_username.c_str());
|
||||
ssh_options_set(m_session, SSH_OPTIONS_PORT, &m_port);
|
||||
|
||||
// Set timeout to 3 seconds.
|
||||
int64_t timeout = 3L;
|
||||
ssh_options_set(m_session, SSH_OPTIONS_TIMEOUT, &timeout);
|
||||
|
||||
// Set other miscellaneous options.
|
||||
ssh_options_set(m_session, SSH_OPTIONS_STRICTHOSTKEYCHECK, "no");
|
||||
}
|
||||
|
||||
SshSession::~SshSession() {
|
||||
ssh_disconnect(m_session);
|
||||
ssh_free(m_session);
|
||||
}
|
||||
|
||||
void SshSession::Open() {
|
||||
// Connect to the server.
|
||||
int rc = ssh_connect(m_session);
|
||||
if (rc != SSH_OK) {
|
||||
throw SshException(ssh_get_error(m_session));
|
||||
}
|
||||
|
||||
// Authenticate with password.
|
||||
rc = ssh_userauth_password(m_session, nullptr, m_password.c_str());
|
||||
if (rc != SSH_AUTH_SUCCESS) {
|
||||
throw SshException(ssh_get_error(m_session));
|
||||
}
|
||||
}
|
||||
|
||||
void SshSession::Execute(std::string_view cmd) {
|
||||
// Allocate a new channel.
|
||||
ssh_channel channel = ssh_channel_new(m_session);
|
||||
if (!channel) {
|
||||
throw SshException(ssh_get_error(m_session));
|
||||
}
|
||||
|
||||
// Open the channel.
|
||||
int rc = ssh_channel_open_session(channel);
|
||||
if (rc != SSH_OK) {
|
||||
throw SshException(ssh_get_error(m_session));
|
||||
}
|
||||
|
||||
// Execute the command.
|
||||
std::string command{cmd};
|
||||
rc = ssh_channel_request_exec(channel, command.c_str());
|
||||
if (rc != SSH_OK) {
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
throw SshException(ssh_get_error(m_session));
|
||||
}
|
||||
INFO("{}", cmd);
|
||||
|
||||
// Log output.
|
||||
char buf[512];
|
||||
int read = ssh_channel_read(channel, buf, sizeof(buf), 0);
|
||||
if (read != 0) {
|
||||
INFO("{}", cmd);
|
||||
}
|
||||
|
||||
// Close and free channel.
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
}
|
||||
|
||||
void SshSession::Put(std::string_view path, std::string_view contents) {
|
||||
// Allocate the SFTP session.
|
||||
sftp_session sftp = sftp_new(m_session);
|
||||
if (!sftp) {
|
||||
throw SshException(ssh_get_error(m_session));
|
||||
}
|
||||
|
||||
// Initialize.
|
||||
int rc = sftp_init(sftp);
|
||||
if (rc != SSH_OK) {
|
||||
sftp_free(sftp);
|
||||
throw SshException(ssh_get_error(m_session));
|
||||
}
|
||||
|
||||
// Copy.
|
||||
sftp_file file =
|
||||
sftp_open(sftp, path.data(), O_WRONLY | O_CREAT | O_TRUNC, S_IFMT);
|
||||
if (!file) {
|
||||
sftp_free(sftp);
|
||||
throw SshException(ssh_get_error(m_session));
|
||||
}
|
||||
|
||||
// Send 150K at a time.
|
||||
static constexpr size_t kChunkSize = 150000;
|
||||
for (size_t i = 0; i < contents.size(); i += kChunkSize) {
|
||||
size_t len = (std::min)(kChunkSize, contents.size() - i);
|
||||
size_t written = sftp_write(file, contents.data() + i, len);
|
||||
if (written != len) {
|
||||
sftp_close(file);
|
||||
sftp_free(sftp);
|
||||
throw SshException(ssh_get_error(m_session));
|
||||
}
|
||||
}
|
||||
|
||||
INFO("[SFTP] Deployed {}!", path);
|
||||
|
||||
// Close file, free memory.
|
||||
sftp_close(file);
|
||||
sftp_free(sftp);
|
||||
}
|
||||
81
roborioteamnumbersetter/src/main/native/cpp/SshSession.h
Normal file
@@ -0,0 +1,81 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <wpi/Logger.h>
|
||||
|
||||
namespace sysid {
|
||||
/**
|
||||
* This class is a C++ implementation of the SshSessionController in
|
||||
* wpilibsuite/deploy-utils. It handles connecting to an SSH server, running
|
||||
* commands, and transferring files.
|
||||
*/
|
||||
class SshSession {
|
||||
public:
|
||||
/**
|
||||
* This is the exception that will be thrown by any of the methods in this
|
||||
* class if something goes wrong.
|
||||
*/
|
||||
class SshException : public std::runtime_error {
|
||||
public:
|
||||
explicit SshException(const char* msg) : runtime_error(msg) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a new session controller.
|
||||
*
|
||||
* @param host The hostname of the server to connect to.
|
||||
* @param port The port that the sshd server is operating on.
|
||||
* @param user The username to login as.
|
||||
* @param pass The password for the given username.
|
||||
* @param logger A reference to a logger to log messages to.
|
||||
*/
|
||||
SshSession(std::string_view host, int port, std::string_view user,
|
||||
std::string_view pass, wpi::Logger& logger);
|
||||
|
||||
/**
|
||||
* Destroys the controller object. This also disconnects the session from the
|
||||
* server.
|
||||
*/
|
||||
~SshSession();
|
||||
|
||||
/**
|
||||
* Opens the SSH connection to the given host.
|
||||
*/
|
||||
void Open();
|
||||
|
||||
/**
|
||||
* Executes a command and logs the output (if there is any).
|
||||
*
|
||||
* @param cmd The command to execute on the server.
|
||||
*/
|
||||
void Execute(std::string_view cmd);
|
||||
|
||||
/**
|
||||
* Puts a file on the server using SFTP.
|
||||
*
|
||||
* @param path The path to the file to put (on the server).
|
||||
* @param contents The contents of the file.
|
||||
*/
|
||||
void Put(std::string_view path, std::string_view contents);
|
||||
|
||||
private:
|
||||
ssh_session m_session;
|
||||
std::string m_host;
|
||||
|
||||
int m_port;
|
||||
|
||||
std::string m_username;
|
||||
std::string m_password;
|
||||
|
||||
wpi::Logger& m_logger;
|
||||
};
|
||||
} // namespace sysid
|
||||
25
roborioteamnumbersetter/src/main/native/cpp/main.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
// 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 <string_view>
|
||||
|
||||
void Application(std::string_view saveDir);
|
||||
|
||||
#ifdef _WIN32
|
||||
int __stdcall WinMain(void* hInstance, void* hPrevInstance, char* pCmdLine,
|
||||
int nCmdShow) {
|
||||
int argc = __argc;
|
||||
char** argv = __argv;
|
||||
#else
|
||||
int main(int argc, char** argv) {
|
||||
#endif
|
||||
std::string_view saveDir;
|
||||
if (argc == 2) {
|
||||
saveDir = argv[1];
|
||||
}
|
||||
|
||||
Application(saveDir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
roborioteamnumbersetter/src/main/native/mac/rtns.icns
Normal file
BIN
roborioteamnumbersetter/src/main/native/resources/rtns-128.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
roborioteamnumbersetter/src/main/native/resources/rtns-16.png
Normal file
|
After Width: | Height: | Size: 153 B |
BIN
roborioteamnumbersetter/src/main/native/resources/rtns-256.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
BIN
roborioteamnumbersetter/src/main/native/resources/rtns-32.png
Normal file
|
After Width: | Height: | Size: 951 B |
BIN
roborioteamnumbersetter/src/main/native/resources/rtns-48.png
Normal file
|
After Width: | Height: | Size: 974 B |
BIN
roborioteamnumbersetter/src/main/native/resources/rtns-512.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
roborioteamnumbersetter/src/main/native/resources/rtns-64.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 103 KiB |
@@ -0,0 +1 @@
|
||||
IDI_ICON1 ICON "roborioteamnumbersetter.ico"
|
||||
@@ -32,6 +32,7 @@ include 'crossConnIntegrationTests'
|
||||
include 'fieldImages'
|
||||
include 'glass'
|
||||
include 'outlineviewer'
|
||||
include 'roborioteamnumbersetter'
|
||||
include 'simulation:gz_msgs'
|
||||
include 'simulation:frc_gazebo_plugins'
|
||||
include 'simulation:halsim_gazebo'
|
||||
|
||||
@@ -13,7 +13,7 @@ nativeUtils {
|
||||
niLibVersion = "2022.2.3"
|
||||
opencvVersion = "4.5.2-1"
|
||||
googleTestVersion = "1.9.0-5-437e100-1"
|
||||
imguiVersion = "1.82-1"
|
||||
imguiVersion = "1.86-1"
|
||||
wpimathVersion = "-1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,9 +104,9 @@ tasks.withType(JavaCompile).configureEach {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.2'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.4.2'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.2'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.8.2'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
|
||||
|
||||
devImplementation sourceSets.main.output
|
||||
}
|
||||
@@ -120,7 +120,7 @@ task run(type: JavaExec) {
|
||||
build.dependsOn devClasses
|
||||
|
||||
jacoco {
|
||||
toolVersion = "0.8.4"
|
||||
toolVersion = "0.8.7"
|
||||
}
|
||||
|
||||
jacocoTestReport {
|
||||
|
||||
@@ -2,7 +2,7 @@ if (!project.hasProperty('skipJavaFormat')) {
|
||||
apply plugin: 'checkstyle'
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "8.38"
|
||||
toolVersion = "9.2"
|
||||
configDirectory = file("${project.rootDir}/styleguide")
|
||||
config = resources.text.fromFile(new File(configDirectory.get().getAsFile(), "checkstyle.xml"))
|
||||
}
|
||||
@@ -10,7 +10,7 @@ if (!project.hasProperty('skipJavaFormat')) {
|
||||
apply plugin: 'pmd'
|
||||
|
||||
pmd {
|
||||
toolVersion = '6.7.0'
|
||||
toolVersion = '6.41.0'
|
||||
consoleOutput = true
|
||||
reportsDir = file("$project.buildDir/reports/pmd")
|
||||
ruleSetFiles = files(new File(rootDir, "styleguide/pmd-ruleset.xml"))
|
||||
|
||||
@@ -24,6 +24,8 @@ try {
|
||||
} catch(Exception ex) {
|
||||
}
|
||||
|
||||
ext.skip_gz_msgs = false
|
||||
|
||||
if (project.hasProperty("forceGazebo")) {
|
||||
if (!protobuf_version?.trim()) {
|
||||
println "Protobuf is not available. (pkg-config --modversion protobuf failed)"
|
||||
@@ -38,9 +40,11 @@ tasks.whenTaskAdded { task ->
|
||||
task.onlyIf { !project.hasProperty('skip_gz_msgs') }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "com.google.protobuf:protobuf-java:${protobuf_version}"
|
||||
implementation "com.google.protobuf:protoc:${protobuf_version}"
|
||||
if (!ext.skip_gz_msgs) {
|
||||
dependencies {
|
||||
implementation "com.google.protobuf:protobuf-java:${protobuf_version}"
|
||||
implementation "com.google.protobuf:protoc:${protobuf_version}"
|
||||
}
|
||||
}
|
||||
|
||||
/* There is a nice gradle plugin for protobuf, and the protoc tool
|
||||
|
||||
@@ -266,7 +266,7 @@ module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF" />
|
||||
</module>
|
||||
<module name="JavadocMethod">
|
||||
<property name="scope" value="public" />
|
||||
<property name="accessModifiers" value="public" />
|
||||
<property name="allowMissingParamTags" value="true" />
|
||||
<property name="allowMissingReturnTag" value="true" />
|
||||
<property name="allowedAnnotations" value="Override, Test" />
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
<rule ref="category/java/design.xml">
|
||||
<exclude name="AvoidThrowingRawExceptionTypes" />
|
||||
<exclude name="CognitiveComplexity" />
|
||||
<exclude name="CyclomaticComplexity" />
|
||||
<exclude name="DataClass" />
|
||||
<exclude name="ExcessiveClassLength" />
|
||||
@@ -60,9 +61,10 @@
|
||||
<exclude name="AvoidDuplicateLiterals" />
|
||||
<exclude name="AvoidLiteralsInIfCondition" />
|
||||
<exclude name="BeanMembersShouldSerialize" />
|
||||
<exclude name="CloseResource" />
|
||||
<exclude name="ConstructorCallsOverridableMethod" />
|
||||
<exclude name="DataflowAnomalyAnalysis" />
|
||||
<exclude name="DoNotCallSystemExit" />
|
||||
<exclude name="DoNotTerminateVM" />
|
||||
<exclude name="FinalizeDoesNotCallSuperFinalize" />
|
||||
<exclude name="JUnitSpelling" />
|
||||
<exclude name="MissingSerialVersionUID" />
|
||||
@@ -83,8 +85,8 @@
|
||||
|
||||
<rule name="UnnecessaryCastRule" language="java"
|
||||
message="Avoid unnecessary casts"
|
||||
class="net.sourceforge.pmd.lang.java.rule.migrating.UnnecessaryCastRule"
|
||||
externalInfoUrl="https://github.com/pmd/pmd/blob/master/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/migrating/UnnecessaryCastRule.java" />
|
||||
class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryCastRule"
|
||||
externalInfoUrl="https://github.com/pmd/pmd/blob/master/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java" />
|
||||
|
||||
<!-- Custom Rules -->
|
||||
<rule name="UseRequireNonNull"
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<FindBugsFilter>
|
||||
<Match>
|
||||
<Bug pattern="DCN_NULLPOINTER_EXCEPTION" />
|
||||
<Class name="edu.wpi.first.wpilibj.test.TestSuite" />
|
||||
</Match>
|
||||
<Match>
|
||||
<Bug pattern="DM_DEFAULT_ENCODING" />
|
||||
</Match>
|
||||
@@ -15,6 +19,10 @@
|
||||
<Match>
|
||||
<Bug pattern="EI_EXPOSE_REP2" />
|
||||
</Match>
|
||||
<Match>
|
||||
<Bug pattern="IS2_INCONSISTENT_SYNC" />
|
||||
<Source name="MechanismLigament2d.java" />
|
||||
</Match>
|
||||
<Match>
|
||||
<Bug pattern="MS_CANNOT_BE_FINAL" />
|
||||
<Class name="edu.wpi.first.wpilibj.examples.pacgoat.Robot" />
|
||||
@@ -72,6 +80,14 @@
|
||||
<Bug pattern="UC_USELESS_VOID_METHOD" />
|
||||
<Class name="edu.wpi.first.wpilibj.templates.timed.Robot" />
|
||||
</Match>
|
||||
<Match>
|
||||
<Bug pattern="URF_UNREAD_FIELD" />
|
||||
<Class name="edu.wpi.first.wpilibj.ADIS16448_IMU" />
|
||||
</Match>
|
||||
<Match>
|
||||
<Bug pattern="URF_UNREAD_FIELD" />
|
||||
<Class name="edu.wpi.first.wpilibj.ADIS16470_IMU" />
|
||||
</Match>
|
||||
<Match>
|
||||
<Bug pattern="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD" />
|
||||
</Match>
|
||||
|
||||
42
upstream_utils/fmt-dont-throw-on-write-failure.patch
Normal file
@@ -0,0 +1,42 @@
|
||||
diff --git a/wpiutil/src/main/native/fmtlib/include/fmt/format-inl.h b/wpiutil/src/main/native/fmtlib/include/fmt/format-inl.h
|
||||
index 2c51c50ae..cc89abdd3 100644
|
||||
--- a/wpiutil/src/main/native/fmtlib/include/fmt/format-inl.h
|
||||
+++ b/wpiutil/src/main/native/fmtlib/include/fmt/format-inl.h
|
||||
@@ -92,8 +92,7 @@ FMT_FUNC void report_error(format_func func, int error_code,
|
||||
// A wrapper around fwrite that throws on error.
|
||||
inline void fwrite_fully(const void* ptr, size_t size, size_t count,
|
||||
FILE* stream) {
|
||||
- size_t written = std::fwrite(ptr, size, count, stream);
|
||||
- if (written < count) FMT_THROW(system_error(errno, "cannot write to file"));
|
||||
+ std::fwrite(ptr, size, count, stream);
|
||||
}
|
||||
|
||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||
diff --git a/wpiutil/src/main/native/fmtlib/include/fmt/xchar.h b/wpiutil/src/main/native/fmtlib/include/fmt/xchar.h
|
||||
index 55825077f..9acb893fa 100644
|
||||
--- a/wpiutil/src/main/native/fmtlib/include/fmt/xchar.h
|
||||
+++ b/wpiutil/src/main/native/fmtlib/include/fmt/xchar.h
|
||||
@@ -207,8 +207,7 @@ inline void vprint(std::FILE* f, wstring_view fmt, wformat_args args) {
|
||||
wmemory_buffer buffer;
|
||||
detail::vformat_to(buffer, fmt, args);
|
||||
buffer.push_back(L'\0');
|
||||
- if (std::fputws(buffer.data(), f) == -1)
|
||||
- FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
|
||||
+ std::fputws(buffer.data(), f);
|
||||
}
|
||||
|
||||
inline void vprint(wstring_view fmt, wformat_args args) {
|
||||
diff --git a/wpiutil/src/main/native/fmtlib/src/os.cpp b/wpiutil/src/main/native/fmtlib/src/os.cpp
|
||||
index 04b4dc506..4eb3e1fdd 100644
|
||||
--- a/wpiutil/src/main/native/fmtlib/src/os.cpp
|
||||
+++ b/wpiutil/src/main/native/fmtlib/src/os.cpp
|
||||
@@ -277,8 +277,7 @@ std::size_t file::read(void* buffer, std::size_t count) {
|
||||
std::size_t file::write(const void* buffer, std::size_t count) {
|
||||
rwresult result = 0;
|
||||
FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));
|
||||
- if (result < 0) FMT_THROW(system_error(errno, "cannot write to file"));
|
||||
- return detail::to_unsigned(result);
|
||||
+ return count;
|
||||
}
|
||||
|
||||
file file::dup(int fd) {
|
||||
@@ -8,7 +8,7 @@ from upstream_utils import setup_upstream_repo, comment_out_invalid_includes, wa
|
||||
|
||||
def main():
|
||||
root, repo = setup_upstream_repo("https://github.com/RobotLocomotion/drake",
|
||||
"v0.36.0")
|
||||
"v0.37.0")
|
||||
wpimath = os.path.join(root, "wpimath")
|
||||
|
||||
# Delete old install
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from upstream_utils import setup_upstream_repo, comment_out_invalid_includes, walk_cwd_and_copy_if
|
||||
from upstream_utils import setup_upstream_repo, comment_out_invalid_includes, walk_cwd_and_copy_if, apply_patches
|
||||
|
||||
|
||||
def main():
|
||||
root, repo = setup_upstream_repo("https://github.com/fmtlib/fmt", "8.0.1")
|
||||
root, repo = setup_upstream_repo("https://github.com/fmtlib/fmt", "8.1.1")
|
||||
wpiutil = os.path.join(root, "wpiutil")
|
||||
|
||||
# Delete old install
|
||||
@@ -31,6 +31,9 @@ def main():
|
||||
comment_out_invalid_includes(
|
||||
f, [os.path.join(wpiutil, "src/main/native/fmtlib/include")])
|
||||
|
||||
apply_patches(root,
|
||||
["upstream_utils/fmt-dont-throw-on-write-failure.patch"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -27,5 +27,4 @@ includeOtherLibs {
|
||||
^imgui
|
||||
^implot
|
||||
^stb
|
||||
^wpi/
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ set_property(TARGET wpigui PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET wpigui PROPERTY FOLDER "libraries")
|
||||
|
||||
wpilib_target_warnings(wpigui)
|
||||
target_link_libraries(wpigui PUBLIC imgui wpiutil)
|
||||
target_link_libraries(wpigui PUBLIC imgui)
|
||||
|
||||
target_include_directories(wpigui PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/main/native/include>
|
||||
|
||||