From 173bfc0079115c89ec98df339991dd0969eeb048 Mon Sep 17 00:00:00 2001 From: mimi980 <90112270+mimi980@users.noreply.github.com> Date: Fri, 26 Jan 2024 21:20:51 +0100 Subject: [PATCH] =?UTF-8?q?=C3=A7a=20marche=20!!!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 178 ++++ .vscode/launch.json | 21 + .vscode/settings.json | 21 + .wpilib/wpilib_preferences.json | 6 + WPILib-License.md | 24 + build.gradle | 99 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43462 bytes gradle/wrapper/gradle-wrapper.properties | 7 + gradlew | 249 +++++ gradlew.bat | 92 ++ settings.gradle | 30 + src/main/cpp/Joystick.cpp | 280 ++++++ src/main/cpp/Robot.cpp | 296 ++++++ src/main/cpp/lib/LogFile.cpp | 64 ++ src/main/cpp/lib/N/Containers/NArray.cpp | 914 ++++++++++++++++++ src/main/cpp/lib/N/Core/NMemory.cpp | 103 ++ .../NLCharacterizationTable.cpp | 179 ++++ .../NLCharacterization_Tests.cpp | 341 +++++++ .../NLMotorCharacterization.cpp | 29 + src/main/cpp/lib/NL/NLKin.cpp | 578 +++++++++++ src/main/cpp/lib/NL/NLTrajectoryStateS.cpp | 22 + .../cpp/lib/NL/NLTrajectoryStateSPack.cpp | 167 ++++ src/main/cpp/lib/Utils.cpp | 19 + src/main/cpp/lib/newCSVLogFile.cpp | 27 + src/main/deploy/paths/0_8Great2UJ30A1_5V1.tsp | Bin 0 -> 788 bytes src/main/deploy/paths/0_8GreatUJ30A1_5V1.tsp | Bin 0 -> 788 bytes src/main/deploy/paths/0_8GreatUJ45A3V2.tsp | Bin 0 -> 788 bytes .../deploy/paths/0_8lineA1A7_J30A1_5V1.tsp | Bin 0 -> 212 bytes src/main/deploy/paths/NEWWAVE_bridge.tsp | Bin 0 -> 1196 bytes src/main/deploy/paths/NEWWAVE_fastloop.tsp | Bin 0 -> 1004 bytes src/main/deploy/paths/NEWWAVE_longway.tsp | Bin 0 -> 1556 bytes src/main/deploy/paths/NEWWAVE_openlink.tsp | Bin 0 -> 1028 bytes src/main/deploy/paths/NEWWAVE_snake.tsp | Bin 0 -> 908 bytes src/main/deploy/paths/NEWWAVE_snake_4wp.tsp | Bin 0 -> 1796 bytes src/main/deploy/paths/NEWWAVE_superS.tsp | Bin 0 -> 1220 bytes src/main/deploy/paths/New2_U_J30A1_5V1.tsp | Bin 0 -> 788 bytes src/main/deploy/paths/New_U_J30A1V0_5.tsp | Bin 0 -> 788 bytes src/main/deploy/paths/New_U_J30A1_5V1.tsp | Bin 0 -> 788 bytes src/main/deploy/paths/New_U_J45A3V2.tsp | Bin 0 -> 788 bytes src/main/deploy/paths/New_U_J60A5V3.tsp | Bin 0 -> 788 bytes .../deploy/paths/S_[3_348mlong]J45A2V1.tsp | Bin 0 -> 740 bytes src/main/deploy/paths/S_highspeed.tsp | Bin 0 -> 740 bytes src/main/deploy/paths/SlalomPathJ30A1_5V1 | Bin 0 -> 2468 bytes src/main/deploy/paths/Snake_J30A3V1_75.tsp | Bin 0 -> 1634 bytes src/main/deploy/paths/Traj.tsp | Bin 0 -> 1463 bytes src/main/deploy/paths/Traj10.tsp | Bin 0 -> 1329 bytes src/main/deploy/paths/Traj11.tsp | Bin 0 -> 622 bytes src/main/deploy/paths/Traj2.tsp | Bin 0 -> 1488 bytes src/main/deploy/paths/Traj3.tsp | Bin 0 -> 1004 bytes src/main/deploy/paths/Traj4.tsp | Bin 0 -> 766 bytes src/main/deploy/paths/Traj5.tsp | Bin 0 -> 742 bytes src/main/deploy/paths/Traj6.tsp | Bin 0 -> 740 bytes src/main/deploy/paths/Traj7.tsp | Bin 0 -> 764 bytes src/main/deploy/paths/Traj8.tsp | Bin 0 -> 1316 bytes src/main/deploy/paths/Traj9.tsp | Bin 0 -> 1329 bytes src/main/deploy/paths/U_2mx1mJ45A2V1.tsp | Bin 0 -> 764 bytes src/main/deploy/paths/U_grand_J30A3V1_5.tsp | Bin 0 -> 789 bytes src/main/deploy/paths/V_J30A2V1.tsp | Bin 0 -> 1344 bytes src/main/deploy/paths/example.txt | 4 + src/main/deploy/paths/infiniti_J30A3V1_5.tsp | Bin 0 -> 2087 bytes src/main/deploy/paths/ligne_1_505mJ45A2V1.tsp | Bin 0 -> 212 bytes src/main/deploy/paths/ligne_1_metre.tsp | Bin 0 -> 212 bytes src/main/deploy/paths/lineA1A10-J30A1_5V1.tsp | Bin 0 -> 212 bytes src/main/deploy/paths/lineA1A10-J45A3V2.tsp | Bin 0 -> 212 bytes src/main/deploy/paths/lineA1A6-J30A1V0_5.tsp | Bin 0 -> 212 bytes src/main/deploy/paths/lineA1A6-J30A1_5V1.tsp | Bin 0 -> 212 bytes src/main/deploy/paths/lineA1A6-J45A3V2.tsp | Bin 0 -> 212 bytes src/main/deploy/paths/lineA1A6-J60A5V3.tsp | Bin 0 -> 212 bytes src/main/deploy/paths/lineA1A7_J30A1_5V1.tsp | Bin 0 -> 212 bytes src/main/deploy/paths/testU.tsp | Bin 0 -> 620 bytes src/main/include/Constants.h | 7 + src/main/include/Joystick.h | 7 + src/main/include/Robot.h | 171 ++++ src/main/include/lib/CSVLogFile.h | 121 +++ src/main/include/lib/CustomMaths.h | 3 + src/main/include/lib/LogFile.h | 93 ++ src/main/include/lib/N/Containers/NArray.h | 118 +++ src/main/include/lib/N/Core/NLimits.h | 49 + src/main/include/lib/N/NCStandard.h | 53 + src/main/include/lib/N/NCompilerPragma.h | 14 + src/main/include/lib/N/NErrorHandling.h | 548 +++++++++++ src/main/include/lib/N/NFlags.h | 100 ++ src/main/include/lib/N/NMath.h | 195 ++++ src/main/include/lib/N/NMemory.h | 67 ++ src/main/include/lib/N/NType.h | 118 +++ .../NLCharacterizationTable.h | 46 + .../NLCharacterization_Tests.h | 88 ++ .../NLMotorCharacterization.h | 42 + src/main/include/lib/NL/NLKin.h | 122 +++ src/main/include/lib/NL/NLOdometry.h | 14 + src/main/include/lib/NL/NLPid.h | 25 + src/main/include/lib/NL/NLTrajectoryStateS.h | 18 + .../include/lib/NL/NLTrajectoryStateSPack.h | 29 + src/main/include/lib/Utils.h | 22 + src/main/include/lib/newCSVLogFile.h | 15 + src/test/cpp/main.cpp | 10 + vendordeps/Phoenix5.json | 151 +++ vendordeps/Phoenix6.json | 339 +++++++ vendordeps/WPILibNewCommands.json | 38 + 99 files changed, 6373 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 .wpilib/wpilib_preferences.json create mode 100644 WPILib-License.md create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle create mode 100644 src/main/cpp/Joystick.cpp create mode 100644 src/main/cpp/Robot.cpp create mode 100644 src/main/cpp/lib/LogFile.cpp create mode 100644 src/main/cpp/lib/N/Containers/NArray.cpp create mode 100644 src/main/cpp/lib/N/Core/NMemory.cpp create mode 100644 src/main/cpp/lib/NL/Characterization/NLCharacterizationTable.cpp create mode 100644 src/main/cpp/lib/NL/Characterization/NLCharacterization_Tests.cpp create mode 100644 src/main/cpp/lib/NL/Characterization/NLMotorCharacterization.cpp create mode 100644 src/main/cpp/lib/NL/NLKin.cpp create mode 100644 src/main/cpp/lib/NL/NLTrajectoryStateS.cpp create mode 100644 src/main/cpp/lib/NL/NLTrajectoryStateSPack.cpp create mode 100644 src/main/cpp/lib/Utils.cpp create mode 100644 src/main/cpp/lib/newCSVLogFile.cpp create mode 100644 src/main/deploy/paths/0_8Great2UJ30A1_5V1.tsp create mode 100644 src/main/deploy/paths/0_8GreatUJ30A1_5V1.tsp create mode 100644 src/main/deploy/paths/0_8GreatUJ45A3V2.tsp create mode 100644 src/main/deploy/paths/0_8lineA1A7_J30A1_5V1.tsp create mode 100644 src/main/deploy/paths/NEWWAVE_bridge.tsp create mode 100644 src/main/deploy/paths/NEWWAVE_fastloop.tsp create mode 100644 src/main/deploy/paths/NEWWAVE_longway.tsp create mode 100644 src/main/deploy/paths/NEWWAVE_openlink.tsp create mode 100644 src/main/deploy/paths/NEWWAVE_snake.tsp create mode 100644 src/main/deploy/paths/NEWWAVE_snake_4wp.tsp create mode 100644 src/main/deploy/paths/NEWWAVE_superS.tsp create mode 100644 src/main/deploy/paths/New2_U_J30A1_5V1.tsp create mode 100644 src/main/deploy/paths/New_U_J30A1V0_5.tsp create mode 100644 src/main/deploy/paths/New_U_J30A1_5V1.tsp create mode 100644 src/main/deploy/paths/New_U_J45A3V2.tsp create mode 100644 src/main/deploy/paths/New_U_J60A5V3.tsp create mode 100644 src/main/deploy/paths/S_[3_348mlong]J45A2V1.tsp create mode 100644 src/main/deploy/paths/S_highspeed.tsp create mode 100644 src/main/deploy/paths/SlalomPathJ30A1_5V1 create mode 100644 src/main/deploy/paths/Snake_J30A3V1_75.tsp create mode 100644 src/main/deploy/paths/Traj.tsp create mode 100644 src/main/deploy/paths/Traj10.tsp create mode 100644 src/main/deploy/paths/Traj11.tsp create mode 100644 src/main/deploy/paths/Traj2.tsp create mode 100644 src/main/deploy/paths/Traj3.tsp create mode 100644 src/main/deploy/paths/Traj4.tsp create mode 100644 src/main/deploy/paths/Traj5.tsp create mode 100644 src/main/deploy/paths/Traj6.tsp create mode 100644 src/main/deploy/paths/Traj7.tsp create mode 100644 src/main/deploy/paths/Traj8.tsp create mode 100644 src/main/deploy/paths/Traj9.tsp create mode 100644 src/main/deploy/paths/U_2mx1mJ45A2V1.tsp create mode 100644 src/main/deploy/paths/U_grand_J30A3V1_5.tsp create mode 100644 src/main/deploy/paths/V_J30A2V1.tsp create mode 100644 src/main/deploy/paths/example.txt create mode 100644 src/main/deploy/paths/infiniti_J30A3V1_5.tsp create mode 100644 src/main/deploy/paths/ligne_1_505mJ45A2V1.tsp create mode 100644 src/main/deploy/paths/ligne_1_metre.tsp create mode 100644 src/main/deploy/paths/lineA1A10-J30A1_5V1.tsp create mode 100644 src/main/deploy/paths/lineA1A10-J45A3V2.tsp create mode 100644 src/main/deploy/paths/lineA1A6-J30A1V0_5.tsp create mode 100644 src/main/deploy/paths/lineA1A6-J30A1_5V1.tsp create mode 100644 src/main/deploy/paths/lineA1A6-J45A3V2.tsp create mode 100644 src/main/deploy/paths/lineA1A6-J60A5V3.tsp create mode 100644 src/main/deploy/paths/lineA1A7_J30A1_5V1.tsp create mode 100644 src/main/deploy/paths/testU.tsp create mode 100644 src/main/include/Constants.h create mode 100644 src/main/include/Joystick.h create mode 100644 src/main/include/Robot.h create mode 100644 src/main/include/lib/CSVLogFile.h create mode 100644 src/main/include/lib/CustomMaths.h create mode 100644 src/main/include/lib/LogFile.h create mode 100644 src/main/include/lib/N/Containers/NArray.h create mode 100644 src/main/include/lib/N/Core/NLimits.h create mode 100644 src/main/include/lib/N/NCStandard.h create mode 100644 src/main/include/lib/N/NCompilerPragma.h create mode 100644 src/main/include/lib/N/NErrorHandling.h create mode 100644 src/main/include/lib/N/NFlags.h create mode 100644 src/main/include/lib/N/NMath.h create mode 100644 src/main/include/lib/N/NMemory.h create mode 100644 src/main/include/lib/N/NType.h create mode 100644 src/main/include/lib/NL/Characterization/NLCharacterizationTable.h create mode 100644 src/main/include/lib/NL/Characterization/NLCharacterization_Tests.h create mode 100644 src/main/include/lib/NL/Characterization/NLMotorCharacterization.h create mode 100644 src/main/include/lib/NL/NLKin.h create mode 100644 src/main/include/lib/NL/NLOdometry.h create mode 100644 src/main/include/lib/NL/NLPid.h create mode 100644 src/main/include/lib/NL/NLTrajectoryStateS.h create mode 100644 src/main/include/lib/NL/NLTrajectoryStateSPack.h create mode 100644 src/main/include/lib/Utils.h create mode 100644 src/main/include/lib/newCSVLogFile.h create mode 100644 src/test/cpp/main.cpp create mode 100644 vendordeps/Phoenix5.json create mode 100644 vendordeps/Phoenix6.json create mode 100644 vendordeps/WPILibNewCommands.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5528d4f --- /dev/null +++ b/.gitignore @@ -0,0 +1,178 @@ +# This gitignore has been specially created by the WPILib team. +# If you remove items from this file, intellisense might break. + +### C++ ### +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### Gradle ### +.gradle +/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +# # VS Code Specific Java Settings +# DO NOT REMOVE .classpath and .project +.classpath +.project +.settings/ +bin/ + +# IntelliJ +*.iml +*.ipr +*.iws +.idea/ +out/ + +# Fleet +.fleet + +# Simulation GUI and other tools window save file +*-window.json + +# Simulation data log directory +logs/ + +# Folder that has CTRE Phoenix Sim device config storage +ctre_sim/ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c9c9713 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "type": "wpilib", + "name": "WPILib Desktop Debug", + "request": "launch", + "desktop": true, + }, + { + "type": "wpilib", + "name": "WPILib roboRIO Debug", + "request": "launch", + "desktop": false, + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..99fb0a6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,21 @@ +{ + "java.configuration.updateBuildConfiguration": "disabled", + "java.import.gradle.enabled": false, + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "bin/": true, + "**/.classpath": true, + "**/.project": true, + "**/.settings": true, + "**/.factorypath": true, + "**/*~": true + }, + "C_Cpp.default.configurationProvider": "vscode-wpilib", + "files.associations": { + "iostream": "cpp" + } +} diff --git a/.wpilib/wpilib_preferences.json b/.wpilib/wpilib_preferences.json new file mode 100644 index 0000000..dd8732a --- /dev/null +++ b/.wpilib/wpilib_preferences.json @@ -0,0 +1,6 @@ +{ + "enableCppIntellisense": true, + "currentLanguage": "cpp", + "projectYear": "2024", + "teamNumber": 5553 +} \ No newline at end of file diff --git a/WPILib-License.md b/WPILib-License.md new file mode 100644 index 0000000..645e542 --- /dev/null +++ b/WPILib-License.md @@ -0,0 +1,24 @@ +Copyright (c) 2009-2024 FIRST and other WPILib contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of FIRST, WPILib, nor the names of other WPILib + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY FIRST AND OTHER WPILIB CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS 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. diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..749489b --- /dev/null +++ b/build.gradle @@ -0,0 +1,99 @@ +plugins { + id "cpp" + id "google-test-test-suite" + id "edu.wpi.first.GradleRIO" version "2024.2.1" +} + +// Define my targets (RoboRIO) and artifacts (deployable files) +// This is added by GradleRIO's backing project DeployUtils. +deploy { + targets { + roborio(getTargetTypeClass('RoboRIO')) { + // Team number is loaded either from the .wpilib/wpilib_preferences.json + // or from command line. If not found an exception will be thrown. + // You can use getTeamOrDefault(team) instead of getTeamNumber if you + // want to store a team number in this file. + team = project.frc.getTeamNumber() + debug = project.frc.getDebugOrDefault(false) + + artifacts { + // First part is artifact name, 2nd is artifact type + // getTargetTypeClass is a shortcut to get the class type using a string + + frcCpp(getArtifactTypeClass('FRCNativeArtifact')) { + } + + // Static files artifact + frcStaticFileDeploy(getArtifactTypeClass('FileTreeArtifact')) { + files = project.fileTree('src/main/deploy') + directory = '/home/lvuser/deploy' + } + } + } + } +} + +def deployArtifact = deploy.targets.roborio.artifacts.frcCpp + +// Set this to true to enable desktop support. +def includeDesktopSupport = false + +// Set to true to run simulation in debug mode +wpi.cpp.debugSimulation = false + +// Default enable simgui +wpi.sim.addGui().defaultEnabled = true +// Enable DS but not by default +wpi.sim.addDriverstation() + +model { + components { + frcUserProgram(NativeExecutableSpec) { + targetPlatform wpi.platforms.roborio + if (includeDesktopSupport) { + targetPlatform wpi.platforms.desktop + } + + sources.cpp { + source { + srcDir 'src/main/cpp' + include '**/*.cpp', '**/*.cc' + } + exportedHeaders { + srcDir 'src/main/include' + } + } + + // Set deploy task to deploy this component + deployArtifact.component = it + + // Enable run tasks for this component + wpi.cpp.enableExternalTasks(it) + + // Enable simulation for this component + wpi.sim.enable(it) + // Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries. + wpi.cpp.vendor.cpp(it) + wpi.cpp.deps.wpilib(it) + } + } + testSuites { + frcUserProgramTest(GoogleTestTestSuiteSpec) { + testing $.components.frcUserProgram + + sources.cpp { + source { + srcDir 'src/test/cpp' + include '**/*.cpp' + } + } + + // Enable run tasks for this component + wpi.cpp.enableExternalTasks(it) + + wpi.cpp.vendor.cpp(it) + wpi.cpp.deps.wpilib(it) + wpi.cpp.deps.googleTest(it) + } + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..d64cd4917707c1f8861d8cb53dd15194d4248596 GIT binary patch literal 43462 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 literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..5e82d67 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=permwrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=permwrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..1aa94a4 --- /dev/null +++ b/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# 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. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# 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/HEAD/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 +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 + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +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 ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +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 + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + 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 +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# 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. + +# 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 + + +# 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"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# 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" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..d94f73c --- /dev/null +++ b/settings.gradle @@ -0,0 +1,30 @@ +import org.gradle.internal.os.OperatingSystem + +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + String frcYear = '2024' + File frcHome + if (OperatingSystem.current().isWindows()) { + String publicFolder = System.getenv('PUBLIC') + if (publicFolder == null) { + publicFolder = "C:\\Users\\Public" + } + def homeRoot = new File(publicFolder, "wpilib") + frcHome = new File(homeRoot, frcYear) + } else { + def userFolder = System.getProperty("user.home") + def homeRoot = new File(userFolder, "wpilib") + frcHome = new File(homeRoot, frcYear) + } + def frcHomeMaven = new File(frcHome, 'maven') + maven { + name 'frcHome' + url frcHomeMaven + } + } +} + +Properties props = System.getProperties(); +props.setProperty("org.gradle.internal.native.headers.unresolved.dependencies.ignore", "true"); diff --git a/src/main/cpp/Joystick.cpp b/src/main/cpp/Joystick.cpp new file mode 100644 index 0000000..bb14b29 --- /dev/null +++ b/src/main/cpp/Joystick.cpp @@ -0,0 +1,280 @@ +#include "Joystick.h" +#include +#include + +#define TRACKWIDTH 0.61f +#define HALF_TRACKWIDTH (TRACKWIDTH / 2.0f) + +#define AMAX 5.1 // Acceleration Max au PIF .. à définir aux encodeurs +#define VMAX 3.4 // vitesse Max théorique (3,395472 sur JVN-DT) .. à vérifier aux encodeurs +#define WMAX \ + (((2.0 * VMAX) / TRACKWIDTH) / \ + 1.7) // vitesse angulaire Max theorique .. à modifier avec Garice + +// Flags Manipulation +#define FLAG_TOGGLE(val, flag) ((val) ^= (flag)) +#define FLAG_ON(val, flag) ((val) |= (flag)) +#define FLAG_OFF(val, flag) ((val) &= ~(flag)) +#define ISFLAG_ON(val, flag) ((val) & (flag)) // !! ZERO or NON ZERO value !!! BE AWARE THAT NON ZERO DOESN'T MEAN 1 !!! +#define ISFLAG_OFF(val, flag) (!((val) & (flag))) // !! ZERO or NON ZERO value !!! BE AWARE THAT NON ZERO DOESN'T MEAN 1 !!! +#define FLAGS_TEST(val, bmask, flags) (((val) & (bmask)) == (flags)) // NFALSE or NTRUE +#define SET_FLAGS(val, bmask, flags) ((val) = (((val) & (~(bmask))) | (flags))) // RESET FLAGS BITS and Set them all like flags. +#define RESET_FLAGS(val, bmask) ((val)&=~(bmask))) // Set all FLAGS BITS to ZERO + +#define VOLTAGE_COMPENSATION_VALUE 11.5 +// TEST ********************************************* +#define TEST_LOWVOLTAGE_NB 10 // Nombre de tests ( subdivisions ) sur l'intervalle ]0,TEST_LOWVOLTAGE_MAX] volts ... 10 ou 20 ? +#define TEST_LOWVOLTAGE_MAX 0.15 // Volts + +#define TEST_MEDIUMVOLTAGE_NB 5 // Nombre de tests ( subdivisions ) sur l'intervalle ]TEST_LOWVOLTAGE_MAX,TEST_MEDIUMVOLTAGE_MAX] volts ... 20 ou 25 ? +#define TEST_MEDIUMVOLTAGE_MAX 1.0 // Volts + +#define TEST_HIGHVOLTAGE_NB 44 // Nombre de tests ( subdivisions ) sur l'intervalle ]TEST_MEDIUMVOLTAGE_MAX,TEST_HIGHVOLTAGE_MAX] volts... 12 ou 24 ? +#define TEST_HIGHVOLTAGE_MAX 12.0 // Volts + +#define TEST_TOTAL_NB (TEST_LOWVOLTAGE_NB + TEST_MEDIUMVOLTAGE_NB + TEST_HIGHVOLTAGE_NB) + +#define FLAG_TestSpecs_Done 1 + +#define TIME_RAMP 0.6 + +#define EPSILON 0.0000001 + +// Differential Steering Joystick Algorithm +// ======================================== +// Converts a single dual-axis joystick into a differential +// drive motor control, with support for both drive, turn +// and pivot operations. +// +double getSign(double number) +{ + if (number < 0) + { + return -1; + } + else + { + return 1; + } +} +void getSpeedsAndAccelerations(VA *pva_left, VA *pva_right, const VA *pvamax, const double jx, const double jy) +{ + double premix_left; // (left) premixed output(-1.. + 1) + double premix_right; // (right)premixed output(-1.. + 1) + + double omega; // pivot speed + double blend; + + // blend_threshold : The threshold at which the pivot action starts + // This threshold is measured in units on the Y-axis + // away from the X-axis (Y=0). A greater value will assign + // more of the joystick's range to pivot actions. + // Allowable range: (0..1) + double blend_threshold = 0.5; + + if (jy >= 0) + { + // Forward + premix_left = (jx >= 0.0) ? 1.0 : (1.0 + jx); + premix_right = (jx >= 0.0) ? (1.0 - jx) : 1.0; + } + else + { + // Reverse + premix_left = (jx >= 0.0) ? (1.0 - jx) : 1.0; + premix_right = (jx >= 0.0) ? 1.0 : (1.0 + jx); + } + + // Scale Drive output due to Joystick Y input (throttle) + premix_left *= jy; + premix_right *= jy; + + // Now calculate pivot amount + // - Strength of pivot (nPivSpeed) based on Joystick X input + // - Blending of pivot vs drive (blend) based on Joystick Y input + omega = jx; + blend = (NABS(jy) > blend_threshold) ? 0.0 : (1.0 - (NABS(jy) / blend_threshold)); + std::cout << blend << std::endl; + double mix_left; + double mix_right; + + // Calculate final mix of Drive and Pivot + mix_left = (1.0 - blend) * premix_left + blend * (omega); + mix_right = (1.0 - blend) * premix_right + blend * (-omega); + + double target_left_speed; + double target_right_speed; + + target_left_speed = mix_left * pvamax->m_speed; + target_right_speed = mix_right * pvamax->m_speed; + + double acc; + double v_diff; + + //Left side + acc = pvamax->m_acceleration * 0.02; + v_diff = target_left_speed - pva_left->m_speed; + + if (v_diff < -acc) + { + pva_left->m_speed -= acc; + pva_left->m_acceleration = pvamax->m_acceleration; + } + else if (v_diff > acc) + { + pva_left->m_speed += acc; + pva_left->m_acceleration = pvamax->m_acceleration; + } + else + { + pva_left->m_speed = target_left_speed; + pva_left->m_acceleration = 0; + } + + //Right side + acc = pvamax->m_acceleration * 0.02; + v_diff = target_right_speed - pva_right->m_speed; + + if (v_diff < -acc) + { + pva_right->m_speed -= acc; + pva_right->m_acceleration = pvamax->m_acceleration; + } + else if (v_diff > acc) + { + pva_right->m_speed += acc; + pva_right->m_acceleration = pvamax->m_acceleration; + } + else + { + pva_right->m_speed = target_right_speed; + pva_right->m_acceleration = 0; + } +} + +void getSpeedsAndAccelerationsNew(VA *pva_left, VA *pva_right, const VA *pva_max, const double jx, const double jy) +{ + double target_left_speed; + double target_right_speed; + + double v = jx * VMAX; + double w = jy * WMAX; + + // w = m_drivetrain->CalculateTurn(forward, w); + + double lwheel = v + (w * HALF_TRACKWIDTH); + double rwheel = v - (w * HALF_TRACKWIDTH); + + double k; + k = 1.0 / (NMAX(VMAX, NMAX(NABS(lwheel), NABS(rwheel)))); + lwheel *= k; + rwheel *= k; + + target_left_speed = lwheel * VMAX; + target_right_speed = rwheel * VMAX; + + updateVelocityAndAcceleration(pva_left, pva_max, target_left_speed, 0.02); + updateVelocityAndAcceleration(pva_right, pva_max, target_right_speed, 0.02); +} + +void updateVelocityAndAcceleration(VA *pva, const VA *pva_max, const double target_speed, const double dt) +{ + double dv0v1 = target_speed - pva->m_speed; + double dv_a = getSign(pva->m_acceleration) * pva->m_acceleration * pva->m_acceleration / (2.0f * pva_max->m_jerk); + double d_v = dv0v1 - dv_a; + + if (d_v < 0) + { + if (pva->m_acceleration <= -pva_max->m_acceleration) + { + pva->m_jerk = 0.0; + } + else + { + pva->m_jerk = -pva_max->m_jerk; + } + } + else if (d_v > 0) + { + if (pva->m_acceleration >= pva_max->m_acceleration) + { + pva->m_jerk = 0.0; + } + else + { + pva->m_jerk = pva_max->m_jerk; + } + } + else + { + pva->m_jerk = 0.0f; + } + + double a = pva->m_acceleration + pva->m_jerk * dt; + + if (a > pva_max->m_acceleration) + { + a = pva_max->m_acceleration; + } + else if (a < -pva_max->m_acceleration) + { + a = -pva_max->m_acceleration; + } + + double t = abs(a - pva->m_acceleration) / pva_max->m_jerk; + + double da = pva->m_acceleration * t + 0.5 * t * t * pva->m_jerk + a * (dt - t); + if (getSign(dv0v1) != getSign(dv0v1 - da)) + { + pva->m_acceleration = 0.0; + pva->m_jerk = 0.0; + pva->m_speed = target_speed; + } + else + { + pva->m_speed += da; + pva->m_acceleration = a; + } + //std::cout << pva->m_speed << std::endl; + /* + if (dv0v1 < 0) + { + if (dv0v1 < getSign(pva->m_acceleration) * pva->m_acceleration * pva->m_acceleration / (2.0f * pva_max->m_jerk)) + { + pva->m_acceleration -= pva_max->m_jerk * dt; + if (pva->m_acceleration < -pva_max->m_acceleration) + { + std::cout << "dommage" << std::endl; + pva->m_acceleration = -pva_max->m_acceleration; + } + } + else + { + pva->m_acceleration += pva_max->m_jerk * dt; + } + } + else if (dv0v1 > 0) + { + if (dv0v1 > getSign(pva->m_acceleration) * pva->m_acceleration * pva->m_acceleration / (2.0f * pva_max->m_jerk)) + { + pva->m_acceleration += pva_max->m_jerk * dt; + if (pva->m_acceleration > pva_max->m_acceleration) + { + std::cout << "banane" << std::endl; + pva->m_acceleration = pva_max->m_acceleration; + } + } + else + { + pva->m_acceleration -= pva_max->m_jerk * dt; + } + } + else + { + //std::cout << pva->m_acceleration << " alors qu'elle devrait être nulle" << std::endl; + return; + } + + pva->m_speed += pva->m_acceleration * dt; + std::cout << pva->m_acceleration << " " << pva->m_speed << " " << target_speed << " " << dv0v1 << std::endl;*/ +} \ No newline at end of file diff --git a/src/main/cpp/Robot.cpp b/src/main/cpp/Robot.cpp new file mode 100644 index 0000000..cc28da3 --- /dev/null +++ b/src/main/cpp/Robot.cpp @@ -0,0 +1,296 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2018 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +#include "Constants.h" +#include "Robot.h" +#include "lib/NL/NLOdometry.h" +#include +#include +#include +// #include + +#include +#include +#include + +double Deadband(double value, double deadband = 0.1) +{ + if (std::abs(value) < deadband) + return 0; + else + return value < 0 ? (value + deadband) / (1.0 - deadband) : (value - deadband) / (1.0 - deadband); +} + +void Robot::Drive(double forward, double turn) +{ + // cout<Drive(forward * ((c + 1) / (1 - c)), forward); + } else { + m_drivetrain->Drive(forward, forward * ((1 - c) / (c + 1))); + }*/ + + double v = forward * VMAX; + double w = turn * WMAX * m_turnAdjustFactor; + + // w = m_drivetrain->CalculateTurn(forward, w); + + double lwheel = v + (w * HALF_TRACKWIDTH); + double rwheel = v - (w * HALF_TRACKWIDTH); + + double k; + k = 1.0 / (NMAX(VMAX, NMAX(NABS(lwheel), NABS(rwheel)))); + lwheel *= k; + rwheel *= k; + + // cout<SetString(infos); + } + } + + if (m_driverController.GetXButtonPressed()) + { + if (m_motorCharacterizationTests.getState() == NLCharacterization_Tests::State::Stopped) + { + + m_motorCharacterizationTests.previousTest(); + sprintf(infos, "%s En Attente ... Appuyer sur A pour Démarrer.", m_motorCharacterizationTests.getCurrentTestDescription(desc, 256)); + m_customEntry->SetString(infos); + } + } + + if (m_driverController.GetAButtonPressed()) + { + if (m_motorCharacterizationTests.getState() == NLCharacterization_Tests::State::Started) + { + m_motorCharacterizationTests.stop(); + m_motorCharacterizationTests.nextTest(); + sprintf(infos, "%s En Attente ... Appuyer sur A pour Démarrer.", m_motorCharacterizationTests.getCurrentTestDescription(desc, 256)); + m_customEntry->SetString(infos); + } + else if (m_motorCharacterizationTests.getState() == NLCharacterization_Tests::State::Stopped) + { + m_motorCharacterizationTests.start(); + sprintf(infos, "%s En Cours ... Appuyer sur A pour Arrêter.", m_motorCharacterizationTests.getCurrentTestDescription(desc, 256)); + m_customEntry->SetString(infos); + } + } + + m_LogFileName->SetString(m_motorCharacterizationTests.getCurrentFileLogName(infos, 256)); +} + +void Robot::TestInit() +{ +} +void Robot::TestPeriodic() {} + +#ifndef RUNNING_FRC_TESTS +int main() +{ + return frc::StartRobot(); +} +#endif \ No newline at end of file diff --git a/src/main/cpp/lib/LogFile.cpp b/src/main/cpp/lib/LogFile.cpp new file mode 100644 index 0000000..00b008d --- /dev/null +++ b/src/main/cpp/lib/LogFile.cpp @@ -0,0 +1,64 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2019 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +#include "lib/LogFile.h" + +#include +#include + +#include + +LogFile::LogFile(std::string_view filePrefix, std::string_view fileExtension) + : m_filePrefix(filePrefix), m_fileExtension(fileExtension) +{ + m_time = std::time(0); + std::string filename = CreateFilename(m_time); + + m_file.open(filename); + + if (m_file.fail()) + { + wpi::outs() << "Could not open file `" << filename << "` for writing." << '\n'; + return; + } +} + +void LogFile::Log(const std::string_view &text) { *this << text; } + +void LogFile::Logln(const std::string_view &text) { *this << text << '\n'; } + +const std::string LogFile::GetFileName() const { return CreateFilename(m_time); } + +void LogFile::SetTimeIntervalBeforeRenaming(units::second_t duration) +{ + m_timeIntervalBeforeRenaming = duration; +} + +void LogFile::UpdateFilename() +{ + std::time_t newTime = std::time(0); + // If the difference between the two timestamps is too long + if (units::second_t{std::difftime(newTime, m_time)} > m_timeIntervalBeforeRenaming) + { + std::string newName = CreateFilename(newTime); + m_file.close(); + std::rename(CreateFilename(m_time).c_str(), newName.c_str()); + m_file.open(newName); + } + + m_time = newTime; +} + +const std::string LogFile::CreateFilename(std::time_t time) const +{ + // Get current date/time, format is YYYY-MM-DD.HH_mm_ss + struct tm localTime = *std::localtime(&time); + char datetime[80]; + std::strftime(datetime, sizeof(datetime), "%d-%m-%Y-%H_%M_%S", &localTime); + + return m_filePrefix + "-" + datetime + "." + m_fileExtension; +} diff --git a/src/main/cpp/lib/N/Containers/NArray.cpp b/src/main/cpp/lib/N/Containers/NArray.cpp new file mode 100644 index 0000000..727876f --- /dev/null +++ b/src/main/cpp/lib/N/Containers/NArray.cpp @@ -0,0 +1,914 @@ +#include "lib/N/NCStandard.h" +#include "lib/N/NType.h" +#include "lib/N/NMath.h" +#include "lib/N/NFlags.h" +#include "lib/N/NErrorHandling.h" +#include "lib/N/Containers/NArray.h" +// ------------------------------------------------------------------------------------------ +// NClearArray +// ------------------------------------------------------------------------------------------ +// Description : +// Clear content +// All the elements of the array are dropped. +// for each of them the "destructor_callback" function is called (if any) and then, +// they are removed from the Array container, leaving the container with a size of 0. +// All the others parameters are reset to 0, ElementSize included ! +// ------------------------------------------------------------------------------------------ +// In : +// parray a Ptr on the array to clear. +// +// destructor_callback a function called for each element before removing them +// it can be NULL (in that case there is no function call) +// Out : +// +// ------------------------------------------------------------------------------------------ +void NClearArray(NARRAY* parray,const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback) +{ + if(destructor_callback) + { + NBYTE *ptr = parray->pFirst; + for(Nu32 i=parray->Size;i!=0;i--,ptr+=parray->ElementSize) + { + destructor_callback(ptr); + } + } + // Free memory + Nfree(parray->pFirst); + //... and set all parameters to 0 ... + parray->pFirst = NULL; + parray->Capacity = 0; + parray->Size = 0; + parray->ElementSize = 0; // Added 2013-01-24 ... oups! +} +// ------------------------------------------------------------------------------------------ +// NCreateArray +// ------------------------------------------------------------------------------------------ +// Description : +// Create an Array and initialize its container and structure members. +// Memory space for one NARRAY is reserved by a malloc and memory is also allocated for the +// container by a simple call of "NSetupArray" Function with the parameters of "capacity" +// and "element_size" +// +// ------------------------------------------------------------------------------------------ +// In : +// capacity Max Number of elements that the array container can store. +// +// element_size size (in NBYTE) of one element of the array (usually returned +// by "sizeof(element)" ) +// +// Out : +// a valid NARRAY* pointer on the created and initalized NARRAY structure. +// NULL pointer in case of trouble. +// ------------------------------------------------------------------------------------------ +NARRAY* NCreateArray(const Nu32 capacity,const Nu32 element_size) +{ + return NSetupArray(NEW(NARRAY),capacity,element_size); +} + +// ------------------------------------------------------------------------------------------ +// NDeleteArray +// ------------------------------------------------------------------------------------------ +// Description : +// Delete an Array created with "NCreateArray" +// Memory allocated by the container is freed by a call of "NClearArray" and the memory +// allocated for the NARRAY structure is freed too. +// If any, before clearing the container, each element is destroyed by a call of +// the callback function "destructor_callback" +// ------------------------------------------------------------------------------------------ +// In : +// parray a VALID POINTER of a NARRAY structure created with "NArrayCreate" +// +// destructor_callback NARRAY_CALLBACK function called for each element before clearing +// the container. +// It can be NULL; In that case, no callback function is called. +// +// Out : +// ------------------------------------------------------------------------------------------ +void NDeleteArray(NARRAY* parray,const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback) +{ + NClearArray(parray, destructor_callback); + Nfree(parray); +} +// ------------------------------------------------------------------------------------------ +// NSetupArray +// ------------------------------------------------------------------------------------------ +// Description : +// Initialize an Array +// Reserve enough Memory for the container that it can store a max number of "capacity" element +// with a memory size of "element_size" for each of them. +// +// ------------------------------------------------------------------------------------------- +// In : +// parray a VALID POINTER of a NARRAY structure. +// which IS NOT created +// by a call of "NArrayCreated" +// +// capacity Max Number of elements that the array container can store. +// +// element_size size (in NBYTE) of one element of the array (usually returned +// by "sizeof(element)" ) +// +// Out : +// a valid NARRAY* pointer on the created and initalized NARRAY structure. +// NULL pointer in case of trouble. +// ------------------------------------------------------------------------------------------ +NARRAY* NSetupArray(NARRAY *parray, const Nu32 capacity,const Nu32 element_size ) +{ + if(capacity) + { + parray->pFirst = (NBYTE*)Nmalloc(capacity*element_size); + memset(parray->pFirst,0,capacity*element_size); + } + else + parray->pFirst = NULL; // We don't allocate any memory if capacity == 0 ! + + parray->ElementSize = element_size; + parray->Capacity = capacity; + parray->Size = 0; + return parray; +} + +// ------------------------------------------------------------------------------------------ +// NEraseArrayElement +// ------------------------------------------------------------------------------------------ +// Description : +// Erase a specific element of an array +// if any the destructor_callback function is called before destroying the element. +// At the end of the function process, element is destroyed, all the elements at the right +// of the destroyed element are shifted to the left, and size of the container is decrease +// by one. +// +// ------------------------------------------------------------------------------------------- +// In : +// parray a VALID POINTER on an NARRAY structure. +// +// index Index of the element to erase (first = 0, last = size-1). +// +// destructor_callback NARRAY_CALLBACK function called before destroying the element +// It can be NULL; In that case, no callback function is called. +// +// Out : +// -1 if there is a problem, like an invalid index. +// 1 success +// ------------------------------------------------------------------------------------------ +Nbool NEraseArrayElement(NARRAY *parray,const Nu32 index, const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback) +{ + NErrorIf(index >= parray->Size,NERROR_ARRAY_INDEX_BEYOND_LIMITS); + + NBYTE *ptr = parray->pFirst + index*parray->ElementSize; + // call the callback destruction function (if any) + if(destructor_callback) + destructor_callback(ptr); + // Shift the part of the array which is at the right of the erased element + if( index != (parray->Size-1) )// if not, the element is the last one of the array. there is no shifting to do. + { + memcpy(ptr,ptr + parray->ElementSize,(parray->Size - index - 1)*parray->ElementSize); + } + parray->Size-=1; + return NTRUE; +} +void NQuickEraseArrayElement(NARRAY *parray,const Nu32 index, const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback) +{ + NErrorIf(index >= parray->Size,NERROR_ARRAY_INDEX_BEYOND_LIMITS); + NBYTE *ptr = parray->pFirst + index*parray->ElementSize; + // call the callback destruction function (if any) + if(destructor_callback) + destructor_callback(ptr); + // Replace the Erased element by the last one + if( index != (parray->Size-1) )// if not, the element is the last one of the array. there is no replacing to do. + { + memcpy( ptr,parray->pFirst+(parray->Size-1)*parray->ElementSize,parray->ElementSize ); + } + parray->Size-=1; +} +void NEraseArrayElementPtr(NARRAY *parray,const NBYTE* ptr, const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback) +{ + NErrorIf(ptr >= parray->pFirst + parray->Size*parray->ElementSize ,NERROR_ARRAY_PTR_BEYOND_LIMITS); + NErrorIf(ptr < parray->pFirst,NERROR_ARRAY_PTR_BEYOND_LIMITS); +#ifdef _DEBUG + Nu32 debug_id = (ptr-parray->pFirst)/parray->ElementSize; + NErrorIf(parray->pFirst + debug_id *parray->ElementSize != ptr, NERROR_ARRAY_CORRUPTED_PTR); +#endif + // call the callback destruction function (if any) + if(destructor_callback) + destructor_callback((void*)ptr); + // Shift the part of the array which is at the right of the erased element + if( ptr != parray->pFirst + (parray->Size-1)*parray->ElementSize )// if not, the element is the last one of the array. there is no shifting to do. + { + memcpy((void*)ptr,ptr + parray->ElementSize, parray->pFirst + (parray->Size*parray->ElementSize) - ptr ); + } + parray->Size-=1; +} +void NQuickEraseArrayElementPtr(NARRAY *parray,const NBYTE* ptr, const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback) +{ + NErrorIf(ptr >= parray->pFirst + parray->Size*parray->ElementSize ,NERROR_ARRAY_PTR_BEYOND_LIMITS); + NErrorIf(ptr < parray->pFirst,NERROR_ARRAY_PTR_BEYOND_LIMITS); + + // call the callback destruction function (if any) + if(destructor_callback) + destructor_callback((void*)ptr); + // Shift the part of the array which is at the right of the erased element + NBYTE *ptr2 = parray->pFirst + (parray->Size-1)*parray->ElementSize; + if( ptr != ptr2 )// if not, the element is the last one of the array. there is no shifting to do. + { + memcpy((void*)ptr,ptr2,parray->ElementSize ); + } + parray->Size-=1; +} + + +// ------------------------------------------------------------------------------------------ +// NEraseArrayRange +// ------------------------------------------------------------------------------------------ +// Description : +// Erase a range of elements of an array +// if any, the destructor_callback function is called before destroying each element. +// At the end of the function process, all the elements in the range are destroyed, +// all the elements at the right of the last destroyed element are shifted to the left, and size +// of the container is decrease by the destroyed range size. +// +// ------------------------------------------------------------------------------------------- +// In : +// parray a VALID POINTER on an NARRAY structure. +// +// index Index of the first element to erase. +// +// rangesize number of elements to destroyed (the first one included) +// +// destructor_callback NARRAY_CALLBACK function called for each element before clearing +// the container. +// It can be NULL; In that case, no callback function is called. +// +// Out : +// -1 if there is a problem, like an invalid index or an invalid range. +// 0 nothing to do, because rangesize == 0 +// 1 success +// ------------------------------------------------------------------------------------------ +Nbool NEraseArrayRange(NARRAY *parray,const Nu32 index,const Nu32 rangesize,const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback) +{ + NErrorIf((index+rangesize) > parray->Size,NERROR_ARRAY_INDEX_BEYOND_LIMITS); + + // Nothing to do + if(rangesize == 0) + return NTRUE; + + NBYTE *ptr = parray->pFirst + index*parray->ElementSize; + Nu32 right_index = index + rangesize; + + // call the callback destruction function (if any) + if(destructor_callback) + { + NBYTE *ptr2 = ptr; + for(Nu32 i=rangesize;i!=0;i--,ptr2 += parray->ElementSize) + { + destructor_callback(ptr2); + } + } + // Shift the part of the array which is at the right of the last erased element + if(right_index < parray->Size)// if not, the element is the last one of the array. there is no shifting to do. + { + memcpy(ptr,parray->pFirst + right_index*parray->ElementSize,(parray->Size - right_index)*parray->ElementSize); + } + parray->Size -= rangesize; + return NTRUE; +} +void NEraseArrayRangePtr(NARRAY *parray,const NBYTE *ptr ,const Nu32 rangesize,const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback) +{ + NErrorIf(ptr >= parray->pFirst + parray->Size*parray->ElementSize ,NERROR_ARRAY_INDEX_BEYOND_LIMITS); + NErrorIf(ptr < parray->pFirst,NERROR_ARRAY_INDEX_BEYOND_LIMITS); + // Some Checks ... + // Nothing to do + if(rangesize == 0) + return; + + // call the callback destruction function (if any) + if(destructor_callback) + { + NBYTE *ptr2 = (NBYTE*)ptr; + for(Nu32 i=rangesize;i!=0;i--,ptr2 += parray->ElementSize) + { + destructor_callback(ptr2); + } + } + // Shift the part of the array which is at the right of the last erased element + NBYTE *ptr_right = (NBYTE*)ptr + rangesize*parray->ElementSize; + if(ptr_right < parray->pFirst + parray->Size*parray->ElementSize)// if not, the element is the last one of the array. there is no shifting to do. + { + memcpy((void*)ptr,ptr_right,(NBYTE*)(parray->Size*parray->ElementSize) - ptr_right); + } + parray->Size -= rangesize; +} + +void NEraseArrayElementsBatch(NARRAY *parray,const Nu32 *pNu32_bitfield,const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback) +{ + NBYTE *pel = parray->pFirst; + Nu32 array_size = parray->Size; + Nu32 n = 0; + Nu32 size = 0; + NBYTE *pdst,*psrc; + + // Look for the first "to delete" element. + while(!Nu32FIELD_BITGET(pNu32_bitfield,n) || nElementSize;n++;}; + pdst = pel; + + while(nElementSize;n++;}; + psrc = pel;size = n; + // Look for the Next "to delete" element and Size to copy + while(!Nu32FIELD_BITGET(pNu32_bitfield,n) || nElementSize;n++;}; + size = n-size; + + memcpy(pdst,psrc,size*parray->ElementSize); + pdst += size*parray->ElementSize; + // add size to pdst at the end ! Like this, at the loop end + // 'pdst' is going to be the next address after the last valid One !!! + // It seems weird but it's not ! + // We are going to use it to calculate the final size of the Array... + } + // Calculate new size... + parray->Size = (Nu32)( (pdst - parray->pFirst)/parray->ElementSize ); +} +// ------------------------------------------------------------------------------------------ +// NEraseArray +// ------------------------------------------------------------------------------------------ +// Description : +// Erase All the elements of an array without changing CAPACITY +// if any, the destructor_callback function is called before destroying each element. +// At the end of the function process, all the elements in the range are destroyed, +// and the size is 0; +// ------------------------------------------------------------------------------------------- +// In : +// parray a VALID POINTER on an NARRAY structure. +// +// destructor_callback NARRAY_CALLBACK function called for each element before clearing +// the container. +// It can be NULL; In that case, no callback function is called. +// +// Out : +// ------------------------------------------------------------------------------------------ +void NEraseArray(NARRAY *parray,const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback) +{ + // Some elements have to be dropped + if(destructor_callback) + { + NBYTE *ptr = NGetFirstArrayPtr(parray); + for(Nu32 i=parray->Size;i!=0;i--,ptr+=parray->ElementSize) + { + destructor_callback(ptr); + } + } + parray->Size = 0; +} +// ------------------------------------------------------------------------------------------ +// NInsertArrayElement +// ------------------------------------------------------------------------------------------ +// Description : +// Insert a new element in an array +// The container is extended by inserting the new element before the element "refindex". +// Size of the container is going to be increase by one, and if it's necessay capacity of +// ------------------------------------------------------------------------------------------- +// In : +// parray a VALID POINTER on an NARRAY structure. +// +// refindex A valid Index in the Container. The new element will be inserted before it. +// +// pelement A valid pointer of an element structure casted like a (NBYTE*). +// the function will perform a copy of this element into the new one inserted in +// the container. +// +// Out : +// A pointer casted like a (NBYTE*) on the new element inserted in the container +// ------------------------------------------------------------------------------------------ +NBYTE* NInsertArrayElement(NARRAY *parray, const Nu32 refindex,const NBYTE *pelement) +{ + NErrorIf(refindex >= parray->Size, NERROR_ARRAY_INDEX_BEYOND_LIMITS); + NErrorIf(!pelement, NERROR_NULL_POINTER); + + NBYTE *ptr,*ptr2; + Nu32 newcapacity,delta; + + if(parray->Size == parray->Capacity) + { + newcapacity = (Nu32)( (Nf32)parray->Capacity*(1.0f + NARRAY_INCREASE_CAPACITY_RATIO) + 1.0f ); + delta = newcapacity - parray->Capacity; + parray->pFirst = (NBYTE*)Nrealloc(parray->pFirst,newcapacity*parray->ElementSize); + + ptr = parray->pFirst + parray->Capacity * parray->ElementSize; + memset(ptr,0,delta*parray->ElementSize); + parray->Capacity = newcapacity; + } + + // Shifting to the right + ptr = parray->pFirst + refindex*parray->ElementSize; + ptr2 = ptr + parray->ElementSize; + memcpy(ptr2,ptr,( parray->Size - refindex )*parray->ElementSize); + + // Insert and copy the new element + memcpy(ptr,pelement,parray->ElementSize); + parray->Size += 1; + return ptr; +} + +// ------------------------------------------------------------------------------------------ +// NIncreaseArrayCapacity +// ------------------------------------------------------------------------------------------ +// Description : +// Increase the capacity of an array container. +// It doesn't change the current size of the container and doesn't remove any element. +// The new amount of memory reallocated is filled with 0. +// ------------------------------------------------------------------------------------------- +// In : +// parray a VALID POINTER on an NARRAY structure. +// +// add_capacity Additional capacity, added to the current capacity. +// +// Out : +// 0 nothing to do, because add_capacity = 0 +// 1 success +// ------------------------------------------------------------------------------------------ +Ns32 NIncreaseArrayCapacity(NARRAY *parray,const Nu32 add_capacity) +{ + Nu32 newcapacity; + NBYTE *ptr; + + if(add_capacity == 0) + return 0; + + newcapacity = parray->Capacity+add_capacity; + parray->pFirst = (NBYTE*)Nrealloc(parray->pFirst,newcapacity*parray->ElementSize); + + ptr = parray->pFirst + parray->Capacity * parray->ElementSize; + memset(ptr,0,add_capacity*parray->ElementSize); + parray->Capacity = newcapacity; + + return 1; +} +// ------------------------------------------------------------------------------------------ +// NDecreaseArrayCapacity +// ------------------------------------------------------------------------------------------ +// Description : +// Decrease the capacity of an array container. +// WARNING !! It Can change the current size of the container and possibly remove some elements ! +// In that case the destructot_Callback function is called (if any) for each deleted element +// ------------------------------------------------------------------------------------------- +// In : +// parray a VALID POINTER on an NARRAY structure. +// +// sub_capacity subtract capacity, subtracted to the current capacity. +// +// destructor_callback NARRAY_CALLBACK function called for each element before deleting it +// only if it's necessary. (It happens only if the new capacity is less +// than the current size of the container.) +// It can be NULL; In that case, no callback function is called. +// +// Out : +// 0 nothing to do, because add_capacity = 0 +// -1 error. Sub_capacity is bigger than capacity +// 1 success +// ------------------------------------------------------------------------------------------ +Ns32 NDecreaseArrayCapacity(NARRAY *parray,const Nu32 sub_capacity, const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback ) +{ + Nu32 i; + Ns32 newcapacity; + NBYTE *ptr; + + if(sub_capacity == 0) + return 0; + + newcapacity = (Ns32)parray->Capacity - (Ns32)sub_capacity; + if(newcapacity < 0) + return -1; + + // Maybe some Element have to be destroyed + if((Nu32)newcapacity < parray->Size) + { + if(destructor_callback) + { + ptr = parray->pFirst + (parray->Size-1)*parray->ElementSize; + for(i=0;i<(parray->Size-newcapacity);i++) + { + destructor_callback(ptr); + ptr -= parray->ElementSize; + } + } + parray->Size = newcapacity; + } + + parray->pFirst = (NBYTE*)Nrealloc(parray->pFirst,newcapacity*parray->ElementSize); // if newcapacity = 0 then realloc works like 'free' + parray->Capacity = newcapacity; + return 1; +} + +// ------------------------------------------------------------------------------------------ +// NSetArrayCapacity +// ------------------------------------------------------------------------------------------ +// Description : +// Decrease or Increase the capacity of an array container to reach "new_capacity" +// WARNING !! It Can change the current size of the container and possibly remove some elements ! +// ------------------------------------------------------------------------------------------- +// In : +// parray a VALID POINTER on an NARRAY structure. +// +// new_capacity New capacity of the container. +// +// destructor_callback NARRAY_CALLBACK function called for each element before deleting it +// only if it's necessary. (It happens only if the new capacity is less +// than the current size of the container.) +// It can be NULL; In that case, no callback function is called. +// +// Out : +// 0 nothing to do, because add_capacity = 0 +// -1 error. Sub_capacity is bigger than capacity +// 1 success +// ------------------------------------------------------------------------------------------ +Ns32 NSetArrayCapacity(NARRAY *parray,const Nu32 new_capacity, const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback ) +{ + Ns32 diff = (Ns32)new_capacity - (Ns32)parray->Capacity; + if(diff >= 0) + return NIncreaseArrayCapacity(parray,(Nu32)diff); + else + return NDecreaseArrayCapacity(parray,(Nu32)NABS(diff),destructor_callback); +} + +// ------------------------------------------------------------------------------------------ +// NOptimizeArrayCapacity +// ------------------------------------------------------------------------------------------ +// Description : +// Adjust the capacity of an array container to match the exact size of the container. +// It doesn't change the current size of the container and doesn't remove any element ! +// ------------------------------------------------------------------------------------------- +// In : +// parray a VALID POINTER on an NARRAY structure. +// +// Out : +// 0 nothing to do, because capacity already equal to the size +// 1 success +// ------------------------------------------------------------------------------------------ +Ns32 NOptimizeArrayCapacity(NARRAY *parray) +{ + // Notice : + // There is no need to call "NARRAY_CALLBACK destructor_callback" in that case, + // because all the element which are going to be removed are just pre-allocated but not initialized ! + if(parray->Size!=parray->Capacity) + { + parray->pFirst = (NBYTE*)Nrealloc(parray->pFirst,parray->Size*parray->ElementSize); + parray->Capacity = parray->Size; + return 1; + } + else + return 0; +} + +// ------------------------------------------------------------------------------------------ +// NResizeArray +// ------------------------------------------------------------------------------------------ +// Description : +// Change size +// Resizes the Array Container to contain new_size elements. +// If new_size is smaller than the current size, the content is reduced to its first new_size elements, +// the rest being dropped, and the destructor_callback function (if any) is called for each dropped element. +// If new_size is greater than the current size, the content is expanded by inserting at the end as many copies +// of pelement as needed to reach a size of new_size elements. This may cause a reallocation. +// Notice that this function changes the actual content of the array container by inserting or erasing elements. +// It does not only change its storage capacity. +// To direct a change only in storage capacity, use 'NSetArrayCapacity' instead. +// ------------------------------------------------------------------------------------------- +// In : +// parray a VALID POINTER on an NARRAY structure. +// +// new_size size requested +// +// pelement a Valid Pointer on an element which will be copy as many times as needed +// to reach a size of new_size elements. It's happening only if new_size is +// greater than current size. +// There is no copies if pelement is a NULL pointer +// +// destructor_callback NARRAY_CALLBACK function called for each element before deleting it. +// It happens only if the new_size is smaller than the current size. +// It can be NULL; In that case, no callback function is called. +// Out : +// 0 nothing to do, because capacity already equal to the size +// 1 success +// ------------------------------------------------------------------------------------------ +Ns32 NResizeArray(NARRAY *parray, const Nu32 new_size, const NBYTE *pelement, const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback ) +{ + NBYTE *ptr; + Nu32 i; + + // Nothing to do + if(new_size == parray->Size) + { + return 0; + } + else if (new_size < parray->Size ) + { + // Some elements have to be dropped + if(destructor_callback) + { + ptr = NGetArrayIndexPtr(parray,new_size); + for(i=(parray->Size - new_size);i!=0;i--,ptr+=parray->ElementSize) + { + destructor_callback(ptr); + } + } + parray->Size = new_size; + return 1; + } + else// Beyond this point we are sure that new_size > parray->Size + { + // Increasing Capacity, Only if it's necessary + if(new_size > parray->Capacity) + { + NIncreaseArrayCapacity(parray,new_size-parray->Capacity); + } + + // duplicate the content of pelement in each new element created (if pelement is not NULL Pointer ) + if(pelement) + { + ptr = parray->pFirst+parray->Size*parray->ElementSize; // We don't use, NGetArrayIndexPtr(parray,parray->Size) because this function + // Can only work into the actual size of the table + for(i=new_size-parray->Size;i!=0;i--,ptr += parray->ElementSize) + { + memcpy(ptr,pelement,parray->ElementSize); + } + } + parray->Size = new_size; + return 1; + } +} + +// ------------------------------------------------------------------------------------------ +// NArrayPopBack +// ------------------------------------------------------------------------------------------ +// Description : +// returns the last element in the array container, effectively reducing the size by one. +// This calls the "destructor_callback" function (if any). +// ------------------------------------------------------------------------------------------- +// In : +// parray a VALID POINTER on an NARRAY structure. +// +// pelement A valid pointer of an element structure casted like a (NBYTE*). +// the function will perform a copy of the last element to this incoming element +// Out : +// ------------------------------------------------------------------------------------------ +void NArrayPopBack(NARRAY *parray, NBYTE*pelement) +{ + NErrorIf(!pelement, NERROR_ARRAY_NULL_ADDRESS); + NErrorIf(!parray->Size, NERROR_ARRAY_IS_EMPTY); + + if(parray->Size) + { + NBYTE *plast = parray->pFirst + (parray->Size-1)*parray->ElementSize; + memcpy(pelement,plast,parray->ElementSize); + parray->Size -= 1; + } +} +// ------------------------------------------------------------------------------------------ +// NArrayPushBack +// ------------------------------------------------------------------------------------------ +// Description : +// Adds a new element at the end of the array container, right after its current last element. +// The content of this new element is initialized to a copy of "pelement". +// This effectively increases the array size by one. +// ------------------------------------------------------------------------------------------- +// In : +// parray a VALID POINTER on an NARRAY structure. +// +// pelement A valid pointer of an element structure casted like a (NBYTE*). +// the function will perform a copy of this element into +// the new one inserted in the container. +// Out : +// A pointer casted like a (NBYTE*) on the new element added a the end of the container +// ------------------------------------------------------------------------------------------ +NBYTE* NArrayPushBack(NARRAY*parray,const NBYTE*pelement) +{ + NErrorIf(!parray, NERROR_NULL_POINTER); + NErrorIf(!pelement, NERROR_NULL_POINTER); // Prefer using "NArrayAllocBack" to retrieve a new element from array without incoming pelement + + if(parray->Size == parray->Capacity) + { + Nu32 newcapacity,delta; + + newcapacity = (Nu32)( (Nf32)parray->Capacity*(1.0f + NARRAY_INCREASE_CAPACITY_RATIO) + 1.0f ); + delta = newcapacity - parray->Capacity; + parray->pFirst = (NBYTE*)Nrealloc(parray->pFirst,newcapacity*parray->ElementSize); + memset(parray->pFirst + parray->Capacity * parray->ElementSize,0,delta*parray->ElementSize); + parray->Capacity = newcapacity; + } + + NBYTE *ptr = parray->pFirst + parray->Size*parray->ElementSize; + memcpy(ptr,pelement,parray->ElementSize); + parray->Size += 1; + + return ptr; +} +// ------------------------------------------------------------------------------------------ +// NArrayAllocBack +// ------------------------------------------------------------------------------------------ +// Description : +// Close to NArrayPushBack, excepted that the content of the new element still uninitialized. +// Adds a new element at the end of the array container, right after its current last element. +// This effectively increases the array size by one. +// ------------------------------------------------------------------------------------------- +// In : +// parray a VALID POINTER on an NARRAY structure. +// +// Out : +// A pointer casted like a (NBYTE*) on the new element added a the end of the container. +// !!! THE NEW ELEMENT IS NOT INITIALIZED !!!! +// ------------------------------------------------------------------------------------------ +NBYTE* NArrayAllocBack(NARRAY*parray) +{ + NErrorIf(!parray, NERROR_NULL_POINTER); + + if(parray->Size == parray->Capacity) + { + Nu32 newcapacity,delta; + + newcapacity = (Nu32)( (Nf32)parray->Capacity*(1.0f + NARRAY_INCREASE_CAPACITY_RATIO) + 1.0f ); + delta = newcapacity - parray->Capacity; + parray->pFirst = (NBYTE*)Nrealloc(parray->pFirst,newcapacity*parray->ElementSize); + memset(parray->pFirst + parray->Capacity * parray->ElementSize,0,delta*parray->ElementSize); + parray->Capacity = newcapacity; + } + + NBYTE *ptr = parray->pFirst + parray->Size*parray->ElementSize; + parray->Size += 1; + return ptr; +} +// ------------------------------------------------------------------------------------------ +// NCopyArray +// ------------------------------------------------------------------------------------------ +// Description : +// Copy an entire ARRAY to an another one. +// After the copy both ARRAY are identical in term of content... +// Except for the memory addresses : for sure, these 2 ARRAYS have their own memory allocations +// +// !!!! WARNING !!!! +// This function doesn't perform any previous destinations array elements erasing. +// All the previous destination data are going to be lost. +// a non proper use of this function may cause memory corruption ! +// ------------------------------------------------------------------------------------------- +// In : +// pdst a VALID POINTER on an NARRAY structure. +// as a destination ARRAY +// +// psrc a VALID POINTER on an NARRAY structure. +// as a source ARRAY +// +// Out : +// ------------------------------------------------------------------------------------------ +void NCopyArray(NARRAY*pdst,const NARRAY*psrc) +{ + Nu32 memsize = psrc->Capacity*psrc->ElementSize; + if( (pdst->Capacity*pdst->ElementSize) != memsize ) + pdst->pFirst = (NBYTE*)Nrealloc(pdst->pFirst,memsize ); + pdst->Capacity = psrc->Capacity; + pdst->ElementSize = psrc->ElementSize; + pdst->Size = psrc->Size; + memcpy(pdst->pFirst,psrc->pFirst,memsize); +} + +void NMoveArrayElementBack( NARRAY*parray,const Nu32 index ) +{ + NErrorIf(index >= parray->Size,NERROR_ARRAY_INDEX_BEYOND_LIMITS); + + // already at the back !! + if( index == parray->Size-1 ) + return; + + // from this point we are sure that index < parray->Size-1 + NBYTE *ptr = parray->pFirst + index*parray->ElementSize; + NBYTE *ptmp = (NBYTE*)Nmalloc(parray->ElementSize); + memcpy(ptmp,ptr,parray->ElementSize); + memcpy(ptr,ptr + parray->ElementSize,(parray->Size - index - 1)*parray->ElementSize); + ptr = parray->pFirst + (parray->Size-1)*parray->ElementSize; // Get the last one Adr + memcpy(ptr,ptmp,parray->ElementSize); + Nfree(ptmp); +} + +// ------------------------------------------------------------------------------------------ +// void NSwapArrayContent +// ------------------------------------------------------------------------------------------ +// Description : +// Very low level function. Use it carefully. +// It literally swaps all the content between 2 arrays +// +// ------------------------------------------------------------------------------------------ +// In : +// array1 and array2 +// +// Out : +// nothing. +// +// ------------------------------------------------------------------------------------------ +void NSwapArrayContent(NARRAY *parray1, NARRAY *parray2) +{ + NARRAY tmp; + + tmp = *parray1; + *parray1=*parray2; + *parray2=tmp; +} + + + +void _QuickSortArrayOfNu32Ptr( void **pstart, void **pend, const NARRAY_QSORT_COMPARE compare) +{ + void *ptemp; + void **pleft = pstart - 1; + void **pright= pend + 1; + //void *pivot = pstart; // + + // Nothing to do if array size is null + if(pstart >= pend) + return; + + // Otherwise, parsing array one time from right to left, and another time from left to right + // to look for some miss placed element which swap. If these to process crossing each other, we stop. + while(1) + { + do pright--; while( compare(*pright,*pstart)>0 ); + do pleft ++; while( compare(*pleft,*pstart)<0 ); + + if(pleft < pright) + { + ptemp = *pleft; + *pleft = *pright; + *pright = ptemp; + } + else break; + } + + // Now all the element lower than the pivot are before the ones greater than the pivot. + // So, we have 2 groups to sort again. To do that, we are going to use quicksort itself ! + _QuickSortArrayOfNu32Ptr( pstart, pright, compare ); + _QuickSortArrayOfNu32Ptr( pright+1, pend, compare ); +} +void _QuickSortArray(NBYTE *pstart, NBYTE *pend, Nu32 size, const NARRAY_QSORT_COMPARE compare ) +{ + NBYTE *ptemp; + NBYTE *pleft = pstart - size; + NBYTE *pright = pend + size; + //void *pivot = pstart; // + + // Nothing to do if array size is null + if(pstart >= pend) + return; + + // Otherwise, parsing array one time from right to left, and another time from left to right + // to look for some miss placed element which swap. If these to process crossing each other, we stop. + while(1) + { + do pright-=size; while( compare(pright,pstart)>0 ); + do pleft +=size; while( compare(pleft,pstart)<0 ); + + if(pleft < pright) + { + ptemp = (NBYTE*)Nmalloc(size); + memcpy(ptemp,pleft,size); + memcpy(pleft,pright,size); + memcpy(pright,ptemp,size); + Nfree(ptemp); + } + else break; + } + + // Now all the element lower than the pivot are before the ones greater than the pivot. + // So, we have 2 groups to sort again. To do that, we are going to use quicksort itself ! + _QuickSortArray( pstart, pright, size, compare); + _QuickSortArray( pright+size, pend, size, compare); +} + + +void NQuickSortArrayOfPtr(NARRAY *parray, const NARRAY_QSORT_COMPARE compare) +{ + NErrorIf(parray->ElementSize != sizeof(void*), NERROR_ARRAY_WRONG_ELEMENT_SIZE); + if(parray->Size < 2) + return; + _QuickSortArrayOfNu32Ptr( (void**)(parray->pFirst), (void**)(parray->pFirst+(parray->Size-1)*sizeof(void*)),compare ); +} + +void NQuickSortArray(NARRAY *parray, const NARRAY_QSORT_COMPARE compare) +{ + if(parray->Size < 2) + return; + _QuickSortArray( parray->pFirst, parray->pFirst+(parray->Size-1)*parray->ElementSize, parray->ElementSize, compare ); +} + +void NQuickSortArrayOfPtrEx(NARRAY *parray, const Nu32 first, const Nu32 last, const NARRAY_QSORT_COMPARE compare) +{ + NErrorIf(parray->ElementSize != sizeof(void*), NERROR_ARRAY_WRONG_ELEMENT_SIZE); + if(last-first == 0) + return; + _QuickSortArrayOfNu32Ptr( (void**)NGetArrayIndexPtr(parray,first),(void**)NGetArrayIndexPtr(parray,last),compare ); +} + +void NQuickSortArrayEx(NARRAY *parray, const Nu32 first, const Nu32 last, const NARRAY_QSORT_COMPARE compare) +{ + if(last-first == 0) + return; + _QuickSortArray( NGetArrayIndexPtr(parray,first),NGetArrayIndexPtr(parray,last), parray->ElementSize, compare ); +} diff --git a/src/main/cpp/lib/N/Core/NMemory.cpp b/src/main/cpp/lib/N/Core/NMemory.cpp new file mode 100644 index 0000000..4d2d02d --- /dev/null +++ b/src/main/cpp/lib/N/Core/NMemory.cpp @@ -0,0 +1,103 @@ +// *************************************************************************************** +// *************************************************************************************** +// ** ** +// ** NMemory.cpp ** +// ** ** +// *************************************************************************************** +// *************************************************************************************** + +// ....................................................................................... +// All these functions are only working into DEBUG mode. +// in Release mode, Nmalloc and Nfree are inline functions and simply call malloc and free. +#if defined _DEBUG// && defined _NWINDOWS + +#include "lib/N/NCStandard.h" +#include "lib/N/NMemory.h" +#include "lib/N/NErrorHandling.h" + +static Nu32 NMalloc_AllocatedMemory_Size; +static Nu32 NMalloc_Calls_Nb; +static Nu32 NRealloc_Calls_Nb; +static Nu32 NFree_Calls_Nb; + +void* Nmalloc_debug(Nu32 size,const char *pfname,int nbline) +{ + void* ret_alloc; + + ret_alloc = _malloc_dbg(size,_NORMAL_BLOCK,pfname,nbline); + if(!ret_alloc) + { + NErrorIf(1,NERROR_NULL_MALLOC); + } + else + { + NMalloc_AllocatedMemory_Size += _msize_dbg(ret_alloc,_NORMAL_BLOCK); + NMalloc_Calls_Nb ++; + } + return ret_alloc; +} + +void* Nrealloc_debug(void* ptr,Nu32 newsize,const char *pfname,int nbline) +{ + void* ret_alloc = ptr; + + if(!newsize) + { + Nfree_debug(ptr); + return NULL; + } + else if(!ptr) + { + return Nmalloc_debug(newsize,pfname,nbline); + } + else + { + NMalloc_AllocatedMemory_Size -= _msize_dbg(ptr,_NORMAL_BLOCK); + ret_alloc = _realloc_dbg(ptr,newsize,_NORMAL_BLOCK,pfname,nbline); + if(!ret_alloc) + { + NErrorIf(1,NERROR_NULL_REALLOC); + } + else + { + NMalloc_AllocatedMemory_Size += _msize_dbg(ret_alloc,_NORMAL_BLOCK); + NRealloc_Calls_Nb ++; + } + + return ret_alloc; + } +} + +void Nfree_debug(void* ptr) +{ + NFree_Calls_Nb ++; + NMalloc_AllocatedMemory_Size -= _msize_dbg(ptr,_NORMAL_BLOCK); + _free_dbg(ptr,_NORMAL_BLOCK); +} + +void NMemoryStats_Debug() +{ + printf("\n--------------------MEMORY STATS---------------------------------"); + printf("\n NmallocAllocatedMemory = %d bytes = %2f Ko = %2f Mo",NMalloc_AllocatedMemory_Size,(Nf32)NMalloc_AllocatedMemory_Size/1024.0f,(Nf32)NMalloc_AllocatedMemory_Size/(1024.0f*1024.0f)); + printf("\n NmallocCalls = %d calls",NMalloc_Calls_Nb); + printf("\n NReallocCalls = %d calls",NRealloc_Calls_Nb); + printf("\n NfreeCalls = %d calls",NFree_Calls_Nb); + printf("\n-----------------------------------------------------------------"); +} + +void NMemoryCheck_Debug(const void *ptr,const Nu32 memory_size, const Nu8 check_u8 ) +{ + Nu32 i; + Nu8 *ptr_u8; + + ptr_u8 = (Nu8*)ptr; + for(i=0;i 0) + { + m_CurrentTestID--; + } +} +void NLCharacterization_Tests::setCurrentTest(uint8_t testId) +{ + assert(m_state == State::Stopped); + assert((testId > 0) && (testId < (m_nbTotalTest - 1))); + m_CurrentTestID = testId; +} + +void NLCharacterization_Tests::start() +{ + assert(m_state == State::Stopped); + assert(m_CurrentTestID <= m_nbTotalTest); + + std::cout << "ramp : " << TestData[m_CurrentTestID].m_ramp << std::endl; + + m_rightMotor->ConfigOpenloopRamp(TestData[m_CurrentTestID].m_ramp); + m_rightMotorFollower->ConfigOpenloopRamp(TestData[m_CurrentTestID].m_ramp); + m_rightMotorFollower2->ConfigOpenloopRamp(TestData[m_CurrentTestID].m_ramp); + m_leftMotor->ConfigOpenloopRamp(TestData[m_CurrentTestID].m_ramp); + m_leftMotorFollower->ConfigOpenloopRamp(TestData[m_CurrentTestID].m_ramp); + m_leftMotorFollower2->ConfigOpenloopRamp(TestData[m_CurrentTestID].m_ramp); + + // setting ramp + m_oldRamp = TestData[m_CurrentTestID].m_ramp; + + // std::cout << "left ramp" << m_leftMotor->ramp() << std::endl; + // std::cout << "leftfolow ramp" << m_leftMotorFollower->GetOpenLoopRampRate() << std::endl; + // std::cout << "leftfollow2 ramp" << m_leftMotorFollower2->GetOpenLoopRampRate() << std::endl; + // std::cout << "right ramp" << m_leftMotor->GetOpenLoopRampRate() << std::endl; + // std::cout << "rightfollow ramp" << m_leftMotorFollower->GetOpenLoopRampRate() << std::endl; + // std::cout << "rightfollow2 ramp" << m_leftMotorFollower2->GetOpenLoopRampRate() << std::endl; + + m_externalEncoderLeft->Reset(); + m_externalEncoderRight->Reset(); + + // set state of test + m_state = State::AskForStart; +} +void NLCharacterization_Tests::stop() +{ + assert(m_state == State::Started); + + // setting ramp + m_rightMotor->ConfigOpenloopRamp(m_oldRamp); + m_rightMotorFollower->ConfigOpenloopRamp(m_oldRamp); + m_rightMotorFollower2->ConfigOpenloopRamp(m_oldRamp); + m_leftMotor->ConfigOpenloopRamp(m_oldRamp); + m_leftMotorFollower->ConfigOpenloopRamp(m_oldRamp); + m_leftMotorFollower2->ConfigOpenloopRamp(m_oldRamp); + + // set state of test + m_state = State::AskForStop; +} + +NLCharacterization_Tests::State NLCharacterization_Tests::getState() +{ + return m_state; +} + +uint8_t NLCharacterization_Tests::getCurrentTestId() +{ + return m_CurrentTestID; +} + +char *NLCharacterization_Tests::getCurrentTestDescription(char *pmessage, uint size_terminated_null_char_included) +{ + char desc[256]; + sprintf(desc, "TEST %d / %d [ %.2f Volts || Rampe : %.2f ]", m_CurrentTestID + 1, m_nbTotalTest, TestData[m_CurrentTestID].m_voltage, TestData[m_CurrentTestID].m_ramp); + std::cout << "sprintf passé" << std::endl; + uint sizetocopy = (NMIN(size_terminated_null_char_included, 256) - 1); + std::cout << "uint passé" << std::endl; + strncpy(pmessage, desc, sizetocopy); + std::cout << "strncpy passé" << std::endl; + pmessage[sizetocopy] = 0; + std::cout << "pmessage passé" << sizetocopy << std::endl; + return pmessage; +} + +uint NLCharacterization_Tests::getTestsCounter() +{ + uint counter = 0; + for (uint i = 0; i < m_nbTotalTest; i++) + { + if (BITGET(TestData[i].m_flags, 0)) + { + counter++; + } + } + return counter; +} + +uint NLCharacterization_Tests::areAllTestsDone() +{ + uint counter = 0; + for (uint i = 0; i < m_nbTotalTest; i++) + { + if (BITGET(TestData[i].m_flags, 0)) + { + counter++; + } + else + { + break; + } + } + return (counter == m_nbTotalTest) ? 1 : 0; +} + +char *NLCharacterization_Tests::getCurrentFileLogName(char *pbuffer, uint size_terminated_null_char_included) +{ + if (m_LogFile) + { + uint sizecopied = m_LogFile->GetFileName().copy(pbuffer, size_terminated_null_char_included - 1); + pbuffer[sizecopied] = 0; + } + else + { + uint sizetocopy = NMIN(14, size_terminated_null_char_included - 1); + strncpy(pbuffer, "No file opened", sizetocopy); + pbuffer[sizetocopy] = 0; + } + return pbuffer; +} +void NLCharacterization_Tests::fastLoop() +{ + switch (m_state) + { + /*case State::Stopped: + //Do nothing + break;*/ + + case State::AskForStart: + char prefix[512]; + char invertedPrefix[8]; + sprintf(invertedPrefix, "L%d%dR%d%d", (int)m_leftMotor->GetInverted(), (int)m_leftMotorFollower->GetInverted(), m_leftMotorFollower2->GetInverted(), (int)m_rightMotor->GetInverted(), (int)m_rightMotorFollower->GetInverted(), m_rightMotorFollower2->GetInverted()); + + if (TestData[m_CurrentTestID].m_voltage < 0) + { + sprintf(prefix, "/home/lvuser/logs/-_%s_%d_%.2fvolts_", invertedPrefix, m_CurrentTestID, TestData[m_CurrentTestID].m_voltage); + } + else + { + sprintf(prefix, "/home/lvuser/logs/+_%s_%d_%.2fvolts_", invertedPrefix, m_CurrentTestID, TestData[m_CurrentTestID].m_voltage); + } + std::cout << "avant logfile" << std::endl; + m_LogFile = new CSVLogFile(prefix, "encoderGetD", "encoderGetG", "encoderGetRawD", "encoderGetRawG", "Theorical Voltage", "BusVoltageD1", "BusVoltageD2", "BusVoltageD3", "BusVoltageG1", "BusVoltageG2", "BusVoltageG3", "AppliedOutputD1", "AppliedOutputD2", "AppliedOutputD3", "AppliedOutputG1", "AppliedOutputG2", "AppliedOutputG3", "currentD1", "currentD2", "currentD3", "currentG1", "currentG2", "currentG3", "rampActive"); + + BITSET(TestData[m_CurrentTestID].m_flags, 0); + m_time0 = std::time(0); + + m_leftMotor->Set(ctre::phoenix::motorcontrol::ControlMode::PercentOutput, TestData[m_CurrentTestID].m_voltage / m_leftMotor->GetBusVoltage()); + m_leftMotorFollower->Set(ctre::phoenix::motorcontrol::ControlMode::PercentOutput, TestData[m_CurrentTestID].m_voltage / m_leftMotorFollower->GetBusVoltage()); + m_leftMotorFollower2->Set(ctre::phoenix::motorcontrol::ControlMode::PercentOutput, TestData[m_CurrentTestID].m_voltage / m_leftMotorFollower2->GetBusVoltage()); + m_rightMotor->Set(ctre::phoenix::motorcontrol::ControlMode::PercentOutput, TestData[m_CurrentTestID].m_voltage / m_rightMotor->GetBusVoltage()); + m_rightMotorFollower->Set(ctre::phoenix::motorcontrol::ControlMode::PercentOutput, TestData[m_CurrentTestID].m_voltage / m_rightMotorFollower->GetBusVoltage()); + m_rightMotorFollower2->Set(ctre::phoenix::motorcontrol::ControlMode::PercentOutput, TestData[m_CurrentTestID].m_voltage / m_rightMotorFollower2->GetBusVoltage()); + + m_state = State::Started; + break; + + case State::Started: + if (TestData[m_CurrentTestID].m_voltage > 0) + { + std::cout << m_externalEncoderRight->Get() << std::endl; + assert(m_externalEncoderLeft->Get() > -2048); + assert(m_externalEncoderRight->Get() > -2048); + } + else + { + assert(m_externalEncoderLeft->Get() < 2048); + assert(m_externalEncoderRight->Get() < 2048); + } + if (std::time(0) - m_time0 < TestData[m_CurrentTestID].m_ramp) + { + m_ramp = TestData[m_CurrentTestID].m_ramp; + } + else + { + m_ramp = 0; + } + m_LogFile->Log(m_externalEncoderRight->Get(), + m_externalEncoderLeft->Get(), + m_externalEncoderRight->GetRaw(), + m_externalEncoderLeft->GetRaw(), + TestData[m_CurrentTestID].m_voltage, + m_rightMotor->GetBusVoltage(), + m_rightMotorFollower->GetBusVoltage(), + m_rightMotorFollower2->GetBusVoltage(), + m_leftMotor->GetBusVoltage(), + m_leftMotorFollower->GetBusVoltage(), + m_leftMotorFollower2->GetBusVoltage(), + m_rightMotor->GetMotorOutputPercent(), + m_rightMotorFollower->GetMotorOutputPercent(), + m_rightMotorFollower2->GetMotorOutputPercent(), + m_leftMotor->GetMotorOutputPercent(), + m_leftMotorFollower->GetMotorOutputPercent(), + m_leftMotorFollower2->GetMotorOutputPercent(), + m_rightMotor->GetStatorCurrent(), + m_rightMotorFollower->GetStatorCurrent(), + m_rightMotorFollower2->GetStatorCurrent(), + m_leftMotor->GetStatorCurrent(), + m_leftMotorFollower->GetStatorCurrent(), + m_leftMotorFollower2->GetStatorCurrent(), + TestData[m_CurrentTestID].m_ramp); + break; + + case State::AskForStop: + m_leftMotor->Set(ctre::phoenix::motorcontrol::ControlMode::PercentOutput, 0.0); + m_leftMotorFollower->Set(ctre::phoenix::motorcontrol::ControlMode::PercentOutput, 0.0); + m_leftMotorFollower2->Set(ctre::phoenix::motorcontrol::ControlMode::PercentOutput, 0.0); + m_rightMotor->Set(ctre::phoenix::motorcontrol::ControlMode::PercentOutput, 0.0); + m_rightMotorFollower->Set(ctre::phoenix::motorcontrol::ControlMode::PercentOutput, 0.0); + m_rightMotorFollower2->Set(ctre::phoenix::motorcontrol::ControlMode::PercentOutput, 0.0); + delete m_LogFile; + m_LogFile = nullptr; + m_state = State::Stopped; + break; + + default: + // Do nothing + break; + } +} \ No newline at end of file diff --git a/src/main/cpp/lib/NL/Characterization/NLMotorCharacterization.cpp b/src/main/cpp/lib/NL/Characterization/NLMotorCharacterization.cpp new file mode 100644 index 0000000..5d3083f --- /dev/null +++ b/src/main/cpp/lib/NL/Characterization/NLMotorCharacterization.cpp @@ -0,0 +1,29 @@ +//#include "../../../N/File/NFile.h" +//#include "../../../N/NString.h" + +#include "lib/NL/Characterization/NLMotorCharacterization.h" +/* +Nchar* NLMOTOR_CHARACTERIZATION::read(Nchar * pstr) +{ + // Forward Kv, Ka, et intercept + pstr = NStrGet_Nf32_AfterLabel(pstr, "_kv+= ", &m_kv[0]); + pstr = NStrGet_Nf32_AfterLabel(pstr, "_ka+= ", &m_ka[0]); + pstr = NStrGet_Nf32_AfterLabel(pstr, "_intercept+= ", &m_intercept[0]); + + // Backward Kv, Ka, et intercept + pstr = NStrGet_Nf32_AfterLabel(pstr, "_kv-= ", &m_kv[1]); + pstr = NStrGet_Nf32_AfterLabel(pstr, "_ka-= ", &m_ka[1]); + pstr = NStrGet_Nf32_AfterLabel(pstr, "_intercept-= ", &m_intercept[1]); + + return pstr; +} +*/ +void NLMOTOR_CHARACTERIZATION::setFrom(const NLMOTOR_CHARACTERIZATION * psrc, const Nf32 scalefactor) +{ + m_forwardKv = psrc->m_forwardKv*scalefactor; + m_backwardKv = psrc->m_backwardKv*scalefactor; + m_forwardKa = psrc->m_forwardKa*scalefactor; + m_backwardKa = psrc->m_backwardKa*scalefactor; + m_forwardIntercept = psrc->m_forwardIntercept; + m_backwardIntercept = psrc->m_backwardIntercept; +} diff --git a/src/main/cpp/lib/NL/NLKin.cpp b/src/main/cpp/lib/NL/NLKin.cpp new file mode 100644 index 0000000..2cc2eab --- /dev/null +++ b/src/main/cpp/lib/NL/NLKin.cpp @@ -0,0 +1,578 @@ +#include "lib/N/NMemory.h" +#include "lib/N/NMath.h" +#include "lib/N/NErrorHandling.h" +#ifdef _NEDITOR +#include "../../N/Utilities/Draw/NUT_Draw.h" +#include "../../N/Utilities/Draw/NUT_DrawPencil.h" +#include "../NL2DOrthogonalCoordinateSystem_MotionProfileFlags.h" +#endif +#include "lib/NL/NLKin.h" + + + +/* +NLKIN::~NLKIN() +{ +} +*/ + +// ------------------------------------------------------------------------------------------ +/** + * @brief Calcule les valeurs de KIN depuis le KIN pk0 en appliquant 'jerk' sur une duree "dt" + * + * @param pk0 est le Kin "origine" + * @param jerk est le Jerk a appliquer ( m/s/s/s ) + * @param dt est la Duree separant pk0 et KIN + */ + // ------------------------------------------------------------------------------------------ +void NLKIN::from(const NLKIN *pk0, const Nf32 jerk, const Nf32 dt) +{ + Nf32 dt2 = dt * dt; + + m_t = pk0->m_t + dt; + m_a = pk0->m_a + jerk*dt; + m_v = pk0->m_v + pk0->m_a*dt + (jerk*dt2) / 2.0f; + m_s = pk0->m_s + pk0->m_v*dt + (pk0->m_a*dt2) / 2.0f + (jerk*dt2*dt) / 6.0f; + m_j = jerk; +} + +// ------------------------------------------------------------------------------------------ +/** + * @brief Calcule les valeurs de KIN depuis le KIN pk0 en appliquant un \b Jerk nul sur une duree "dt" + * Cette fonction fait la meme chose que NLKIN::from(pk0, 0, dt) de maniere plus optimisee. + * @param pk0 est le Kin "origine" + * @param dt est la Duree separant pk0 et KIN + */ + // ------------------------------------------------------------------------------------------ +void NLKIN::from(const NLKIN *pk0, const Nf32 dt) +{ + Nf32 dt2 = dt * dt; + + m_t = pk0->m_t + dt; + m_a = pk0->m_a; + m_v = pk0->m_v + pk0->m_a*dt; + m_s = pk0->m_s + pk0->m_v*dt + (pk0->m_a*dt2) / 2.0f; + m_j = 0.0f; +} + +// ------------------------------------------------------------------------------------------ +/** + * @brief Calcule les valeurs de pk1 depuis KIN en appliquant 'jerk' sur une duree "dt" + * + * @param pk1 est le Kin "cible". Son contenu ( position,vitesse, acceleration,et date ) seront calcules et mis a jour a partir de KIN. + * @param jerk est le Jerk a appliquer ( m/s/s/s ) + * @param dt est la Duree separant KIN et pk1 + * @return le pointeur pk1 passe en argument est simplement retourne en sortie de fonction + */ + // ------------------------------------------------------------------------------------------ +NLKIN* NLKIN::to(NLKIN *pk1, const Nf32 jerk, const Nf32 dt) +{ + Nf32 dt2 = dt * dt; + + pk1->m_t = m_t + dt; + pk1->m_a = m_a + jerk * dt; + pk1->m_v = m_v + m_a * dt + (jerk*dt2) / 2.0f; + pk1->m_s = m_s + m_v * dt + (m_a*dt2) / 2.0f + (jerk*dt2*dt) / 6.0f; + pk1->m_j = jerk; + + return pk1; +} + +// ------------------------------------------------------------------------------------------ +/** + * @brief Calcule les valeurs de pk1 depuis KIN en appliquant un \bJerk nul sur une duree "dt" + * Cette fonction fait la meme chose que NLKIN::to(pk1, 0, dt) de maniere plus optimisee. + * @param pk1 est le Kin "cible" + * @param dt est la Duree separant KIN et pk1 + * @return le pointeur pk1 passe en argument est simplement retourne en sortie de fonction + */ + // ------------------------------------------------------------------------------------------ +NLKIN* NLKIN::to(NLKIN *pk1, const Nf32 dt) +{ + Nf32 dt2 = dt * dt; + + pk1->m_t = m_t + dt; + pk1->m_a = m_a; + pk1->m_v = m_v + m_a * dt; + pk1->m_s = m_s + m_v * dt + (m_a*dt2) / 2.0f; + pk1->m_j = 0.0f; + + return pk1; +} + + +// ------------------------------------------------------------------------------------------ +/** + * @brief Verifie que les valeurs d'Acceleration et de Vitesse contenues dans KIN respectent les limites fixees par NLKINLIMITS passee en argument. + * \b ATTENTION! Cette fonction ne fait rien de plus que tester si l'acceleration et potentiellement la vitesse actuelle(s) du KIN sont superieure(s), ou pas, aux limites fix�es. + * L'acceleration est testee en premier. La vitesse est testee dans un second temps si et seulement si l'acceleration est OK. + * @param pkmax regroupe les valeurs maximales d'Acceleration, de Vitesse ( ou Velocite ) et de Jerk d'un systeme. + * @return Une des valeurs de l'enum NLKIN::CHECKS. + * VELOCITY_ACCELERATION_OK (= 0) Signifie que la vitesse et l'acceleration respectent toutes les deux les limites. + * ACCELERATION_OVERSHOOT Signifie que l'acceleration actuelle est hors limite. La velocite n'a pas ete testee car le resultat du test de l'acceleration est negatif. + * VELOCITY_OVERSHOOT Signifie que la vitesse actuelle est hors limite. L'acceleration est alors obligatoirement OK car testee avant la vitesse. + */ + // ------------------------------------------------------------------------------------------ +/* +const Nu32 NLKIN::accVelfastCheck(const NLKINLIMITS * pkmax) +{ + if (NABS(m_a) > pkmax->m_a) + return NLKIN::ACCELERATION_OVERSHOOT; + + if (NABS(m_v) > pkmax->m_v) + return NLKIN::VELOCITY_OVERSHOOT; + + return NLKIN::VELOCITY_ACCELERATION_OK; +}*/ +// ------------------------------------------------------------------------------------------ +/** + * @brief Verifie que les valeurs d'Acceleration et de Vitesse contenues dans KIN respectent les limites fixees par NLKINLIMITS passee en argument. + * \b ATTENTION! Cette fonction ne fait rien de plus que tester si l'acceleration et la vitesse actuelle(s) du KIN sont superieure(s), ou pas, aux limites fixees. + * L'acceleration et la vitesse sont systematiquement testees toutes les deux. + * @param pkmax regroupe les valeurs maximales d'Acceleration, de Vitesse ( ou Velocite ) et de Jerk d'un systeme. + * @return Une \b combinaison des valeurs de l'enum NLKIN::CHECKS. + * + \b VELOCITY_ACCELERATION_OK (= 0) Signifie que la vitesse et l'acceleration respectent toutes les deux les limites. + * + \b ACCELERATION_OVERSHOOT Signifie que l'acceleration actuelle est hors limite, la velocite est OK. + * + \b VELOCITY_OVERSHOOT Signifie que la vitesse actuelle est hors limite. L'acceleration est OK. + * + \b ACCELERATION_OVERSHOOT|VELOCITY_OVERSHOOT Signifie que l'acceleration et la vitesse actuelles sont hors limite. + */ + // ------------------------------------------------------------------------------------------ +/* +const Nu32 NLKIN::accVelCheck(const NLKINLIMITS * pkmax) +{ + Nu32 ret = 0; + if (NABS(m_a) > pkmax->m_a) + ret |= NLKIN::ACCELERATION_OVERSHOOT; + + if (NABS(m_v) > pkmax->m_v) + ret |= NLKIN::VELOCITY_OVERSHOOT; + + return ret; +} +*/ +// ------------------------------------------------------------------------------------------ +/** + * @brief Verifie que les valeurs d'Acceleration et de Vitesse contenues dans KIN respectent les limites fixees par NLKINLIMITS passee en argument. + * Cette fonction, en plus de tester si l'acceleration et la vitesse actuelle(s) du KIN sont superieure(s), ou pas, aux limites fixees, va verifier la coh�rence de l'acceleration et de la vitesse au regard de ces limites. + * L'acceleration est testee en premier. La vitesse est testee dans un second temps si et seulement si l'acceleration est OK. + * + * ## Precision sur les tests effectues + * Si la vitesse de pk0 est proche de la limite sup�rieure de vitesse, plus precisement dans la zone ou l'acceleration evolue de amax � -amax en passant par 0... + * Il est important de verifier la coh�rence acceleration / vitesse de pk0. En effet, + * + si, pk0->m_a > 0 il faut veiller a ce que la reduction de m_a � 0 n'entraine pas du meme coup un d�passement de vitesse. + * Ce qui revient a dire que les valeurs de m_a et de m_v sont incoherentes. + * + si, pk0->m_a < 0 il faut verifier la valeur de la vitesse quand a etait nulle ! Elle doit etre inferieure a la vitesse max autorisee. + * En effet, imaginons une valeur de vitesse egale a la vitesse max ou presque ( donc pas de depassement ) et une valeur d'acceleration negative.( pas de depassement non plus ) + * ce cas de figure est des plus etrange, et signifie une chose: la vitesse 'fut' en d�passement. + * Pour verifier ce cas de figure, on recherche la valeur de la vitesse d'origine "dans le passe" quand l'acceleration "etait" nulle. + * ## Dans un premier temps, la fonction verifie: + * + -vmax <= v <= vmax + * + -amax <= a <= amax + * + * Plus precisement, si v est comprise dans l'intervalle [ (-vmax + vx ), (vmax-vx) ] il n'y a aucun probl�me possible. Car,l'acceleration,respectant ses valeurs limites ne pourra jamais amener la vitesse en dehors de ses propres limites. + * car, vx = amax*amax/2j + * Par contre, si v est proche de vmax ou de -vmax et plus exactement si v est dans ] vmax-vx, vmax] ou dans ]-vmax + vx, -vmax ], alors il est possible qu'une valeur incoherente d'acceleration entraine la vitesse vers une valeur hors limite. + * + * dvatozero = | a*a/2j | + * + * SI v > vmax - vx, + * on veut donc s'assurer que, + * v + dvatozero <= vmax quand 'a' est positive ( sinon OVERSHOOT dans le futur ! ) + * v + dvatozero <= vmax quand 'a' est negative ( sinon OVERSHOOTED dans le pass� ! ) + * v + a*a/2j <= vmax + * a*a/2j <= vmax-v + * a*a <= (vmax-v)*2j + * + * Donc la vitesse sera hors limite si, + * a*a > (vmax-v)*2j + * + * SI v < -vmax + vx, + * on veut donc s'assurer que, v - dvatozero >= -vmax + * v - a*a/2j >= -vmax + * - a*a/2j >= -vmax-v + * - a*a/2j >= -( vmax+v ) + * a*a <= ( vmax+v )*2j + * + * Donc la vitesse sera hors limite si, + * a*a > (vmax+v)*2j + * + * @param pkmax regroupe les valeurs maximales d'Acceleration, de Vitesse ( ou Velocite ) et de Jerk d'un systeme. + * @return Une des valeurs de l'enum NLKIN::CHECKS. + * + \b VELOCITY_ACCELERATION_OK (= 0) Signifie que la vitesse et l'acceleration respectent toutes les deux les limites. + * + \b ACCELERATION_OVERSHOOT Signifie que l'acceleration actuelle est hors limite, la velocite est OK. + * + \b VELOCITY_OVERSHOOT Signifie que la vitesse actuelle est hors limite. L'acceleration est OK. + * + \b VELOCITY_WAS_OVERSHOOTED Signifie que la vitesse et l'acceleration actuelle "semblent" OK. Mais qu'il y a une incoh�rence entre les 2 qui ne s'explique que si la vitesse "etait" hors limite. + * + \b VELOCITY_WILL_OVERSHOOT Signifie que la vitesse et l'acceleration actuelle "semblent" OK. Mais qu'il y a une incoh�rence entre les 2 qui entrainera forcement la vitesse hors des limites fixees. + */ + // ------------------------------------------------------------------------------------------ +/*const Nu32 NLKIN::accVelFastFullCheck(const NLKINLIMITS *pkmax) +{ + if (NABS(m_a) > pkmax->m_a) + return NLKIN::ACCELERATION_OVERSHOOT; // retourne immediatement le code d'erreur approprie si l'Acceleration actuelle est hors limite. Les tests plus avanc�s et les tests sur la vitesse ne sont pas effectu�s. + + if (NABS(m_v) > pkmax->m_v) + return NLKIN::VELOCITY_OVERSHOOT; // retourne immediatement le code d'erreur approprie si la vitesse actuelle est hors limite. Les tests plus avanc�s ne sont pas effectu�s. + + + if (m_v > pkmax->m_vmvx) + { + if ((m_a*m_a) > ((pkmax->m_v - m_v)*pkmax->m_2j)) + return ((m_a > 0.0f) ? NLKIN::VELOCITY_WILL_OVERSHOOT : NLKIN::VELOCITY_WAS_OVERSHOOTED); + } + else if (m_v < -pkmax->m_vmvx ) + { + if ((m_a*m_a) > ((pkmax->m_v + m_v)*pkmax->m_2j)) + return ((m_a > 0.0f) ? NLKIN::VELOCITY_WAS_OVERSHOOTED : NLKIN::VELOCITY_WILL_OVERSHOOT); + } + + return NLKIN::VELOCITY_ACCELERATION_OK; +}*/ + +// ------------------------------------------------------------------------------------------ +/** + * @brief Verifie que les valeurs d'Acceleration et de Vitesse contenues dans KIN respectent les limites fixees par NLKINLIMITS passee en argument. + * \b ATTENTION! Cette fonction ne fait rien de plus que tester si l'acceleration et la vitesse actuelle(s) du KIN sont superieure(s), ou pas, aux limites fixees. + * L'acceleration et la vitesse sont systematiquement testees toutes les deux. + * @param pkmax regroupe les valeurs maximales d'Acceleration, de Vitesse ( ou Velocite ) et de Jerk d'un systeme. + * @return Une \b combinaison des valeurs de l'enum NLKIN::CHECKS. + * + \b VELOCITY_ACCELERATION_OK (= 0) Signifie que la vitesse et l'acceleration respectent toutes les deux les limites. + * + \b ACCELERATION_OVERSHOOT Signifie que l'acceleration actuelle est hors limite, la velocite est OK. + * + \b VELOCITY_OVERSHOOT Signifie que la vitesse actuelle est hors limite. L'acceleration est OK. + * + \b VELOCITY_WAS_OVERSHOOTED Signifie que la vitesse et l'acceleration actuelle "semblent" OK. Mais qu'il y a une incoh�rence entre les 2 qui ne s'explique que si la vitesse "etait" hors limite. + * + \b VELOCITY_WILL_OVERSHOOT Signifie que la vitesse et l'acceleration actuelle "semblent" OK. Mais qu'il y a une incoh�rence entre les 2 qui entrainera forcement la vitesse hors des limites fixees.. +*/ +// ------------------------------------------------------------------------------------------ +/*const Nu32 NLKIN::accVelFullCheck(const NLKINLIMITS *pkmax) +{ + Nu32 ret = 0; + + if (NABS(m_a) > pkmax->m_a) + ret |= NLKIN::ACCELERATION_OVERSHOOT; + + if (NABS(m_v) > pkmax->m_v) + ret |= NLKIN::VELOCITY_OVERSHOOT; + + if (m_v > pkmax->m_vmvx) + { + if ((m_a*m_a) > ((pkmax->m_v - m_v)*pkmax->m_2j)) + ret |= ((m_a > 0.0f) ? NLKIN::VELOCITY_WILL_OVERSHOOT : NLKIN::VELOCITY_WAS_OVERSHOOTED); + } + else if (m_v < (-pkmax->m_vmvx)) + { + if ((m_a*m_a) > ((pkmax->m_v + m_v)*pkmax->m_2j)) + ret |= ((m_a > 0.0f) ? NLKIN::VELOCITY_WAS_OVERSHOOTED : NLKIN::VELOCITY_WILL_OVERSHOOT); + } + return ret; +}*/ + +// ------------------------------------------------------------------------------------------ +/** + * @brief Verifie l'evolution de la vitesse du KIN. + * Cette fonction ne teste ni l'acceleration ni la vitesse actuelles. + * + * Plus exactement la fonction verifie la valeur de la vitesse apres avoir ramene l'acceleration a 0 depuis sa valeur actuelle. + * Si la vitesse est alors hors limite alors la fonction renvoie un code d'erreur \b VELOCITY_WILL_OVERSHOOT + * Sinon la valeur VELOCITY_ACCELERATION_OK est retournee ( = 0 ) + * + * Le temps necessaire pour amener l'acceleration a 0 est calcule \n + * \li t = pk0->m_a / jmax ( jmax etant la valeur de jerk maximum et constante. jmax = pkmax->m_j ) + * + * La quantite de vitesse generee pendant cette duree \e t vaut: + * \li dvatozero = a * t = pk0->m_a * pk0->m_a / jmax + * + * Si \e a est positive alors cette quantite de vitesse sera ajoutee a la vitesse initiale pour obtenir la valeur de la vitesse quand \e a sera nulle. + * A l'inverse, si \e a est negative alors cette quantite de vitesse sera soustraite a la vitesse initiale pour obtenir la valeur de la vitesse quand \e a sera nulle. + * \li a < 0, v_azero = v - dvatozero + * \li a > 0, v_azero = v + dvatozero + * \li a = 0, v_azero = v + * + * La fonction teste alors la vitesse obtenue qui, pour etre valide, doit rester comprise entre -vmax et vmax. + * @param pkmax regroupe les valeurs maximales d'Acceleration, de Vitesse ( ou Velocite ) et de Jerk d'un systeme. + * @return Une des valeurs de l'enum NLKIN::CHECKS. + * + \b VELOCITY_ACCELERATION_OK (= 0) Signifie que la vitesse et l'acceleration respectent toutes les deux les limites. + * + \b VELOCITY_WILL_OVERSHOOT Signifie que la vitesse sera forcement entrainee hors des limites fixees par l'acceleration actuelle qui est donc incoherente. +*/ +// ------------------------------------------------------------------------------------------ +/*const Nu32 NLKIN::velForwardCheck(const NLKINLIMITS *pkmax) +{ + // Calcul de "dvatozero", c'est � dire du differentiel ( gain ou perte) de vitesse acquise/perdue lors de la transition de la valeur courante de l'acceleration a ZERO. + // ( le signe de "a" permet de signer dvatozero ) + Nf32 dvatozero = (m_a < 0.0f) ? -(m_a*m_a) / pkmax->m_2j : (m_a*m_a) / pkmax->m_2j; + + if (NABS(m_v + dvatozero) > pkmax->m_v) + return NLKIN::VELOCITY_WILL_OVERSHOOT; + + return NLKIN::VELOCITY_ACCELERATION_OK; +}*/ + +// ------------------------------------------------------------------------------------------ +/** + * @brief Verifie l'evolution de la vitesse du KIN. + * Cette fonction ne teste ni l'acceleration ni la vitesse actuelles. + * + * Plus exactement la fonction va verifier la valeur que la vitesse "a eut" quand l'acceleration "valait" 0. + * Si la vitesse �tait alors hors limite alors la fonction "backward check" renvoie un code d'erreur "VELOCITY_WAS_OVERSHOOTED" + * Sinon la valeur ZERO est retourn�e ( 0 = OK ) + * + * ## Details + * le temps n�c�ssaire pour revenir en arriere ( dans le temps) � l'instant o� l'acceleration �tait nulle est d'abord calcule \n + * \li t = pk0->m_a / jmax ( jmax �tant la valeur de jerk maximum et constante. jmax = pkmax->m_j ) + * + * La quantit� de vitesse g�n�r�e pendant cette dur�e \e t vaut: + * \li dvatozero = a * t = pk0->m_a * pk0->m_a / jmax + * + * Si \e a est positive alors cette quantite de vitesse sera enlevee a la vitesse initiale pour obtenir la valeur de la vitesse quand \e a \b etait nulle. + * A l'inverse, si \e a est negative alors cette quantite de vitesse sera ajoutee a la vitesse initiale pour obtenir la valeur de la vitesse quand \e a \b etait nulle. + * \li a < 0, v_azero = v + dvatozero + * \li a > 0, v_azero = v - dvatozero + * \li a = 0, v_azero = v + * + * Reste alors � tester la vitesse obtenue qui, pour �tre valide doit rester comprise entre -vmax et vmax. + * @param pkmax regroupe les valeurs maximales d'Acceleration, de Vitesse ( ou Velocite ) et de Jerk d'un systeme. + * @return Une des valeurs de l'enum NLKIN::CHECKS. + * + \b VELOCITY_ACCELERATION_OK (= 0) Signifie que la vitesse et l'acceleration respectent toutes les deux les limites. + * + \b VELOCITY_WAS_OVERSHOOTED Signifie que la vitesse etait forcement hors des limites fixees au regard de l'acceleration. +*/ +// ------------------------------------------------------------------------------------------ +/*const Nu32 NLKIN::velBackwardCheck(const NLKINLIMITS *pkmax) +{ + // Calcul de "dvafromzero", c'est � dire le diff�rentiel ( gain ou perte) de vitesse acquise/perdue lors de la transition de l'acceleration nulle � la valeur courante de l'acceleration. + // ( le signe de "a" permet de signer dvafromzero ) + Nf32 dvafromzero = (m_a < 0.0f) ? (m_a*m_a) / pkmax->m_2j : -(m_a*m_a) / pkmax->m_2j; + + if (NABS(m_v + dvafromzero) > pkmax->m_v) + return NLKIN::VELOCITY_WAS_OVERSHOOTED; + + return NLKIN::VELOCITY_ACCELERATION_OK; +}*/ + +#ifdef _NEDITOR +// ------------------------------------------------------------------------------------------ +/** + * @brief Dessine un Kin. + * + * @param + * @return + */ +// ------------------------------------------------------------------------------------------ +void NLKIN::draw(NL2DOCS * p2docs, const NLKIN * pk0) +{ + Nf32 a0, v0, s0,t0,t; + Nu32 i; + Nu32 iter = 32; + NUTDRAWVERTEX p,o; + NVEC2 xt = { 0.005f,0.005f }; + Nf32 dt = m_t - pk0->m_t; + + if (dt) + { + // z + o.Position_3f.z = p.Position_3f.z = 0.0f; + + // Couleurs + if (m_j > 0.0f) + p.Color0_4f = p2docs->m_color[NL2DOCS_COLOR_1];//NSetColorf(&p.Color0_4f, NCOLOR_PRESET3F_GREEN_SPRING, 1); + else if (m_j == 0.0f) + p.Color0_4f = p2docs->m_color[NL2DOCS_COLOR_3];//NSetColorf(&p.Color0_4f, NCOLOR_PRESET3F_YELLOW, 1); + else + p.Color0_4f = p2docs->m_color[NL2DOCS_COLOR_4];//NSetColorf(&p.Color0_4f, NCOLOR_PRESET3F_PINK_BRILLIANT, 1); + o.Color0_4f = p.Color0_4f; + + // On dessine par rapport � T + if (ISFLAG_ON(p2docs->m_Flags, FLAG_NL2DOCS_MOTIONPROFILE_LAYER_VIEW_FT)) + { + // t: + if (p2docs->isCoordsValueVisible(NL2DOCS_COORDS_STYLE_0)) + o.Position_3f.x = p2docs->transformX(m_t, NL2DOCS_COORDS_STYLE_0); + else + o.Position_3f.x = p2docs->transformX(m_t); + + // V(t): + if (ISFLAG_ON(p2docs->m_Flags, FLAG_NL2DOCS_MOTIONPROFILE_LAYER_VIEW_VEL)) + { + // M�thode B: + if (p2docs->isCoordsValueVisible(NL2DOCS_COORDS_STYLE_1)) + o.Position_3f.y = p2docs->transformY(m_v, NL2DOCS_COORDS_STYLE_1); + else + o.Position_3f.y = p2docs->transformY(m_v); + + NUT_Draw_Mark(&o.Position_3f, &xt, &o.Color0_4f); + NUT_DrawPencil_From(&o); + + for (i = 0; i <= iter; i++) + { + t = dt * (Nf32)i / (Nf32)iter; + v0 = m_v - m_a * t + 0.5f*m_j*t*t; + //s0 = m_s - m_v * t + 0.5f*m_a*t*t - m_j * t*t*t / 6.0f; + t0 = m_t - t; + p.Position_3f.x = p2docs->transformX(t0); + p.Position_3f.y = p2docs->transformY(v0); + NUT_DrawPencil_LineTo(&p); + } + } + // A(t): + if (ISFLAG_ON(p2docs->m_Flags, FLAG_NL2DOCS_MOTIONPROFILE_LAYER_VIEW_ACCEL)) + { + // M�thode B: + if (p2docs->isCoordsValueVisible(NL2DOCS_COORDS_STYLE_1)) + o.Position_3f.y = p2docs->transformY(m_a, NL2DOCS_SUBSCALE_0, NL2DOCS_COORDS_STYLE_1); + else + o.Position_3f.y = p2docs->transformY(m_a, NL2DOCS_SUBSCALE_0); + + NUT_Draw_Mark(&o.Position_3f, &xt, &o.Color0_4f); + NUT_DrawPencil_From(&o); + + for (i = 0; i <= iter; i++) + { + t = dt * (Nf32)i / (Nf32)iter; + a0 = m_a - m_j * t; + //s0 = m_s - m_v * t + 0.5f*m_a*t*t - m_j * t*t*t / 6.0f; + t0 = m_t - t; + p.Position_3f.x = p2docs->transformX(t0); + p.Position_3f.y = p2docs->transformY(a0, NL2DOCS_SUBSCALE_0); + NUT_DrawPencil_LineTo(&p); + } + } + // J(t): + if (ISFLAG_ON(p2docs->m_Flags, FLAG_NL2DOCS_MOTIONPROFILE_LAYER_VIEW_JERK)) + { + // M�thode B: + if (p2docs->isCoordsValueVisible(NL2DOCS_COORDS_STYLE_1)) + o.Position_3f.y = p2docs->transformY(m_j, NL2DOCS_SUBSCALE_1, NL2DOCS_COORDS_STYLE_1); + else + o.Position_3f.y = p2docs->transformY(m_j, NL2DOCS_SUBSCALE_1); + + NUT_Draw_Mark(&o.Position_3f, &xt, &o.Color0_4f); + NUT_DrawPencil_From(&o); + + for (i = 0; i <= iter; i++) + { + t = dt * (Nf32)i / (Nf32)iter; + //a0 = m_a - m_j * t; + //s0 = m_s - m_v * t + 0.5f*m_a*t*t - m_j * t*t*t / 6.0f; + t0 = m_t - t; + p.Position_3f.x = p2docs->transformX(t0); + p.Position_3f.y = p2docs->transformY(m_j, NL2DOCS_SUBSCALE_1); + NUT_DrawPencil_LineTo(&p); + } + } + } + else // On dessine par rapport � S (par defaut) + { + // s: + if (p2docs->isCoordsValueVisible(NL2DOCS_COORDS_STYLE_0)) + o.Position_3f.x = p2docs->transformX(m_s, NL2DOCS_COORDS_STYLE_0); + else + o.Position_3f.x = p2docs->transformX(m_s); + + // V(s): + if (ISFLAG_ON(p2docs->m_Flags, FLAG_NL2DOCS_MOTIONPROFILE_LAYER_VIEW_VEL)) + { + // M�thode B: + if (p2docs->isCoordsValueVisible(NL2DOCS_COORDS_STYLE_1)) + o.Position_3f.y = p2docs->transformY(m_v, NL2DOCS_COORDS_STYLE_1); + else + o.Position_3f.y = p2docs->transformY(m_v); + + NUT_Draw_Mark(&o.Position_3f, &xt, &o.Color0_4f); + NUT_DrawPencil_From(&o); + + for (i = 0; i <= iter; i++) + { + t = dt * (Nf32)i / (Nf32)iter; + v0 = m_v - m_a * t + 0.5f*m_j*t*t; + s0 = m_s - m_v * t + 0.5f*m_a*t*t - m_j * t*t*t / 6.0f; + p.Position_3f.x = p2docs->transformX(s0); + p.Position_3f.y = p2docs->transformY(v0); + NUT_DrawPencil_LineTo(&p); + } + } + // A(s): + if (ISFLAG_ON(p2docs->m_Flags, FLAG_NL2DOCS_MOTIONPROFILE_LAYER_VIEW_ACCEL)) + { + // M�thode B: + if (p2docs->isCoordsValueVisible(NL2DOCS_COORDS_STYLE_1)) + o.Position_3f.y = p2docs->transformY(m_a, NL2DOCS_SUBSCALE_0, NL2DOCS_COORDS_STYLE_1); + else + o.Position_3f.y = p2docs->transformY(m_a, NL2DOCS_SUBSCALE_0); + + NUT_Draw_Mark(&o.Position_3f, &xt, &o.Color0_4f); + NUT_DrawPencil_From(&o); + + for (i = 0; i <= iter; i++) + { + t = dt * (Nf32)i / (Nf32)iter; + a0 = m_a - m_j * t; + s0 = m_s - m_v * t + 0.5f*m_a*t*t - m_j * t*t*t / 6.0f; + p.Position_3f.x = p2docs->transformX(s0); + p.Position_3f.y = p2docs->transformY(a0, NL2DOCS_SUBSCALE_0); + NUT_DrawPencil_LineTo(&p); + } + } + // J(s): + if (ISFLAG_ON(p2docs->m_Flags, FLAG_NL2DOCS_MOTIONPROFILE_LAYER_VIEW_JERK)) + { + // M�thode B: + if (p2docs->isCoordsValueVisible(NL2DOCS_COORDS_STYLE_1)) + o.Position_3f.y = p2docs->transformY(m_j, NL2DOCS_SUBSCALE_1, NL2DOCS_COORDS_STYLE_1); + else + o.Position_3f.y = p2docs->transformY(m_j, NL2DOCS_SUBSCALE_1); + + NUT_Draw_Mark(&o.Position_3f, &xt, &o.Color0_4f); + NUT_DrawPencil_From(&o); + + for (i = 0; i <= iter; i++) + { + t = dt * (Nf32)i / (Nf32)iter; + //a0 = m_a - m_j * t; + s0 = m_s - m_v * t + 0.5f*m_a*t*t - m_j * t*t*t / 6.0f; + p.Position_3f.x = p2docs->transformX(s0); + p.Position_3f.y = p2docs->transformY(m_j, NL2DOCS_SUBSCALE_1); + NUT_DrawPencil_LineTo(&p); + } + } + } + } + +// legacy + /* + // Kin(s,v) + NVEC3 v3; + v3.x = p2docs->transformX(m_s); + v3.y = p2docs->transformY(m_v); + v3.z = 0.0f; + NUT_Draw_Mark(&v3, &xt, &p.Color0_4f); + + for (i = 0; i <= iter; i++) + { + t = dt * (Nf32)i / (Nf32)iter; + v0 = m_v - m_a * t + 0.5f*m_j*t*t; + s0 = m_s - m_v * t + 0.5f*m_a*t*t - m_j * t*t*t / 6.0f; + v3.x = p2docs->transformX(s0); + v3.y = p2docs->transformY(v0); + NUT_Draw_Mark(&v3, &xt, &p.Color0_4f); + } + */ + /* + // M�thode A: + p.Position_3f.x = p2docs->transformX(pk0->m_s); + p.Position_3f.y = p2docs->transformY(pk0->m_v); + p.Position_3f.z = 0.0f; + NUT_Draw_Mark(&p.Position_3f, &xt, &p.Color0_4f); + NUT_DrawPencil_From(&p); + + for (i = 0; i <= iter; i++) + { + t = dt * (Nf32)i / (Nf32)iter; + v = pk0->m_v + pk0->m_a * t + 0.5f*m_j*t*t; + s = pk0->m_s + pk0->m_v * t + pk0->m_a*t*t*0.5f + m_j * t*t*t / 6.0f; + p.Position_3f.x = p2docs->transformX(s); + p.Position_3f.y = p2docs->transformY(v); + NUT_DrawPencil_LineTo(&p); + } + */ + + +} + +#endif \ No newline at end of file diff --git a/src/main/cpp/lib/NL/NLTrajectoryStateS.cpp b/src/main/cpp/lib/NL/NLTrajectoryStateS.cpp new file mode 100644 index 0000000..a914dee --- /dev/null +++ b/src/main/cpp/lib/NL/NLTrajectoryStateS.cpp @@ -0,0 +1,22 @@ +#include "lib/N/NMemory.h" +#include "lib/N/NMath.h" +#include "lib/N/NErrorHandling.h" + +#include "lib/NL/NLTrajectoryStateS.h" + +/* +void NLTRAJECTORY_STATE_S::set(NLKIN *pkin, const Nf32 curvature) +{ + m_localCurvature = curvature; + m_kin = *pkin; +} +*/ +/* +void NLTRAJECTORY_STATE::set(NLKIN * pkin, const Nf32 curvature, NVEC2f32 * ppos, NVEC2f32 * ptgt) +{ + m_state.m_localCurvature = curvature; + m_state.m_kin = *pkin; + m_position = *ppos; + m_tangent = *ptgt; +} +*/ \ No newline at end of file diff --git a/src/main/cpp/lib/NL/NLTrajectoryStateSPack.cpp b/src/main/cpp/lib/NL/NLTrajectoryStateSPack.cpp new file mode 100644 index 0000000..52a5c5c --- /dev/null +++ b/src/main/cpp/lib/NL/NLTrajectoryStateSPack.cpp @@ -0,0 +1,167 @@ +#include "lib/NL/NLKin.h" +#include "lib/NL/NLTrajectoryStateSPack.h" +#include + +NLTRAJECTORY_STATE_S_PACK::NLTRAJECTORY_STATE_S_PACK() +{ + NSetupArray(&m_trajectoryStateSArray, 0, sizeof(NLTRAJECTORY_STATE_S)); +} + +NLTRAJECTORY_STATE_S_PACK::~NLTRAJECTORY_STATE_S_PACK() +{ + NClearArray(&m_trajectoryStateSArray, NULL); +} + +Nu32 NLTRAJECTORY_STATE_S_PACK::read(FILE *pfile) +{ + // Pas de gestion de version pour le moment ! + // on ecrit � la main, direct, pour s'affranchir de la lib NFILE... + // --> extrait de NFile: NFileWrite(pfile, parray->pFirst, parray->ElementSize, parray->Size) != parray->Size + // --> (Nu32)fwrite(ptr, element_size_in_byte, element_count, pfile->pFile); + Nu32 ret = 0; + ret += (Nu32)fread(&m_ds, sizeof(Nf32), 1, pfile); + ret += (Nu32)fread(&m_dt, sizeof(Nf32), 1, pfile); + + Nu32 capacity, elementsize, size; + ret += (Nu32)fread(&capacity, sizeof(Nu32), 1, pfile); + ret += (Nu32)fread(&elementsize, sizeof(Nu32), 1, pfile); + ret += (Nu32)fread(&size, sizeof(Nu32), 1, pfile); + + NErrorIf(elementsize != m_trajectoryStateSArray.ElementSize, NERROR_INCONSISTENT_VALUES); + if (size > m_trajectoryStateSArray.Capacity) // !! on se fiche de 'capacity' en fait !!! + { + std::cout << size << std::endl; + + m_trajectoryStateSArray.pFirst = (NBYTE *)realloc(m_trajectoryStateSArray.pFirst, size*m_trajectoryStateSArray.ElementSize); + NErrorIf(!m_trajectoryStateSArray.pFirst, NERROR_NULL_POINTER); + m_trajectoryStateSArray.Capacity = size; + } + + ret += (Nu32)fread(m_trajectoryStateSArray.pFirst, m_trajectoryStateSArray.ElementSize, size, pfile); + m_trajectoryStateSArray.Size = size; + return ret; +} + +Nu32 NLTRAJECTORY_STATE_S_PACK::write(FILE *pfile) +{ + // Pas de gestion de version pour le moment ! + // on ecrit � la main, direct, pour s'affranchir de la lib NFILE... + // --> extrait de NFile: NFileWrite(pfile, parray->pFirst, parray->ElementSize, parray->Size) != parray->Size + // --> (Nu32)fwrite(ptr, element_size_in_byte, element_count, pfile->pFile); + Nu32 ret = 0; + ret += (Nu32)fwrite(&m_ds, sizeof(Nf32), 1, pfile); + ret += (Nu32)fwrite(&m_dt, sizeof(Nf32), 1, pfile); + + ret += (Nu32)fwrite(&m_trajectoryStateSArray.Capacity, sizeof(Nu32), 1, pfile); + ret += (Nu32)fwrite(&m_trajectoryStateSArray.ElementSize, sizeof(Nu32), 1, pfile); + ret += (Nu32)fwrite(&m_trajectoryStateSArray.Size, sizeof(Nu32), 1, pfile); + ret += (Nu32)fwrite(m_trajectoryStateSArray.pFirst, m_trajectoryStateSArray.ElementSize, m_trajectoryStateSArray.Size, pfile); + return ret; +} + +NLTRAJECTORY_STATE_S *NLTRAJECTORY_STATE_S_PACK::getState(NLTRAJECTORY_STATE_S *pstate, const Nf32 t) +{ + if (t <= 0.0f) + { + pstate->null(); + } + else if (t < m_dt) + { + NLTRAJECTORY_STATE_S *ps1 = (NLTRAJECTORY_STATE_S *)m_trajectoryStateSArray.pFirst; + while (ps1->m_kin.m_t < t) + { + ps1++; + } + NLTRAJECTORY_STATE_S *ps0 = ps1 - 1; + pstate->m_kin.from(&ps0->m_kin,ps1->m_kin.m_j, t - ps0->m_kin.m_t); + pstate->m_localCurvature = ps0->m_localCurvature + (ps1->m_localCurvature - ps0->m_localCurvature) * (pstate->m_kin.m_s - ps0->m_kin.m_s) / (ps1->m_kin.m_s - ps0->m_kin.m_s); + } + else // t >= m_dt + { + *pstate = *(NLTRAJECTORY_STATE_S *)NGetLastArrayPtr(&m_trajectoryStateSArray); + } + return pstate; +} +#ifdef _NEDITOR +void NLTRAJECTORY_STATE_S_PACK::drawTrajectoryStateSArray(NL2DOCS *p2docs) +{ + NLTRAJECTORY_STATE_S *pstate = (NLTRAJECTORY_STATE_S *)m_trajectoryStateSArray.pFirst; + pstate++; + + for (Nu32 i = 1; i < m_trajectoryStateSArray.Size; i++, pstate++) + { + pstate->m_kin.draw(p2docs, &(pstate - 1)->m_kin); + } +} +#endif + +/* +void NLTRAJECTORY_TRACKER::build(NLPATH_GEOMETRY * ppath_geometry, const NLDRIVETRAINSPECS * pdtspecs) +{ + NLDIFFERENTIAL_DRIVETRAIN_POSE d2tp; + + NLKIN kin; + NLKIN *pkin0 = (NLKIN*)m_kinsArray.pFirst; + NLKIN *pkin1 = pkin0; + Nu32 kin1_id = 0; + + NLPATH_POINT *pkp0 = (NLPATH_POINT*)ppath->m_geometry.m_keyPointsArray.pFirst; + NLPATH_POINT *pkp1 = pkp0 + 1; + NLPATH_PRIMITIVE *pprim = (NLPATH_PRIMITIVE*)ppath->m_geometry.m_primitivesArray.pFirst; + + Nf32 curvature; + Nf32 slocal; + + NResizeArray(&m_differentialDriveTrainPosesArray, 0, NULL, NULL); + + for (Nu32 i = 0; i < ppath->m_geometry.m_primitivesArray.Size; i++, pkp0 = pkp1, pkp1++, pprim++) + { + while ((kin1_id < m_kinsArray.Size) && (pkin1->m_s < pkp1->s)) + { + // on recup�re la courbure en pkin->m_s + // ( on sait que pkin->m_s est situ� "entre" pkp0 et pkp1 sur la primitive pprim ... + if (pprim->m_core.m_id == NLPATH_PRIMITIVE_ID_CLOTHOID) + { + slocal = pkin1->m_s - pkp0->s; + curvature = ISFLAG_ON(pprim->m_core.m_flags, FLAG_NLPATH_CLOTHOID_SECOND) ? (pprim->m_core.m_l - slocal) * pkp0->k / pprim->m_core.m_l : slocal * pkp1->k / pprim->m_core.m_l; + } + else // pprim->m_core.m_id == NLPATH_PRIMITIVE_ID_SEGMENT ou pprim->m_core.m_id == NLPATH_PRIMITIVE_ID_ARC + { + curvature = pkp1->k; + } + d2tp.set(pkin1, curvature); + NArrayPushBack(&m_differentialDriveTrainPosesArray, (NBYTE*)&d2tp); + + // Kin suivant + // !!! ATTENTION !!! � la toute fin, "kin1_id = m_kinsArray.Size" et le pointeur pkin1 pointe en dehors de m_kinsArray !!! + pkin0 = pkin1; + pkin1++; + kin1_id++; + } + + // A partir d'ici nous savons: + // pkin1->m_s >= pkp1->s + // OU + // kin1_id == m_kinsArray.Size, + // ce qui signifie que l'abscisse curviligne du dernier Kin de m_kinsArray est inf�rieure � longueur totale du chemin... + // ... et que le pointeur pkin1 courant est invalide ( hors array ) + if (kin1_id < m_kinsArray.Size) + { + // on calcule et on ins�re une pose issue de "pkp1" + getKinAtS(&kin, pkin0, pkin1, pkp1->s); + d2tp.set(&kin, pkp1->k); + NArrayPushBack(&m_differentialDriveTrainPosesArray, (NBYTE*)&d2tp); + } + else + { + break; + } + } + // Une derni�re chose, + // il est possible que l'abscisse curviligne du dernier kin soit l�g�rement sup�rieure � la longueur totale du chemin. + if (kin1_id < m_kinsArray.Size) + { + kin1_id++; + } +} +*/ \ No newline at end of file diff --git a/src/main/cpp/lib/Utils.cpp b/src/main/cpp/lib/Utils.cpp new file mode 100644 index 0000000..6fd74e7 --- /dev/null +++ b/src/main/cpp/lib/Utils.cpp @@ -0,0 +1,19 @@ +#include "lib/Utils.h" +#include "iostream" + +void KineticToVoltage::SetMotorCoefficients(uint motorID, uint isBackward, double kv, double ka, double vintersept) +{ + k_lut[motorID][isBackward][0] = kv; + k_lut[motorID][isBackward][1] = ka; + k_lut[motorID][isBackward][2] = vintersept; +} + +double KineticToVoltage::getVoltage(uint motorID, const VA *pva) +{ + int isBackward = (pva->m_speed < 0) ? 1 : 0; + if (-0.05 < pva->m_speed && pva->m_speed < 0.05) + { + return 0; + } + return k_lut[motorID][isBackward][0] * pva->m_speed + k_lut[motorID][isBackward][1] * pva->m_acceleration + k_lut[motorID][isBackward][2]; +} \ No newline at end of file diff --git a/src/main/cpp/lib/newCSVLogFile.cpp b/src/main/cpp/lib/newCSVLogFile.cpp new file mode 100644 index 0000000..8404ef3 --- /dev/null +++ b/src/main/cpp/lib/newCSVLogFile.cpp @@ -0,0 +1,27 @@ +#include "lib/newCSVLogFile.h" + +newCSVLogFile::newCSVLogFile(char *filename, char *head) +{ + m_file = fopen(filename, "w+"); + fwrite(head, sizeof(char), sizeof(head), m_file); +} + +newCSVLogFile::~newCSVLogFile() +{ + fclose(m_file); +} +void newCSVLogFile::log(double value[3], int arraySize) + +{ + char monChar[17] = {0}; + sprintf(monChar, "%.15lf", value[0]); + fwrite(monChar, sizeof(char), 17, m_file); + for (int i = 1; i < arraySize; i++) + { + char comma[1] = {','}; + fwrite(comma, sizeof(char), 1, m_file); + sprintf(monChar, "%.15lf", value[i]); + fwrite(monChar, sizeof(char), 17, m_file); + } + char end[1] = {'\n'}; +} \ No newline at end of file diff --git a/src/main/deploy/paths/0_8Great2UJ30A1_5V1.tsp b/src/main/deploy/paths/0_8Great2UJ30A1_5V1.tsp new file mode 100644 index 0000000000000000000000000000000000000000..f7a3e8d59c5863f035e8cd868161f1976b17a7c8 GIT binary patch literal 788 zcmX@K$`BeVkAOSX_S3N{7;StM|SzT;U*bO$aOw(m!j`HV4+% zatD~jRyrKZ;{n?RG{@0IXNSYYbvii3A9rqms|T5*a_A^nJudNoxf@~j+JnsB7k%7; z325(%xZN;!g6+06y5b-KbmzwHyB!RH{@NAl4pM(mu=k1s$etTt_5f)}_<+POoxTbd zx3{_n7Y8b1uoV0b7EdX^@9G!EN^-;>H{N9HHqJ Y91c_Vq=D5R0;YYCJrM8#oDV>30HbU9kN^Mx literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/0_8GreatUJ30A1_5V1.tsp b/src/main/deploy/paths/0_8GreatUJ30A1_5V1.tsp new file mode 100644 index 0000000000000000000000000000000000000000..e3e77dbfddc17117bacdae37518790514fbd0126 GIT binary patch literal 788 zcmeb32yv8|n(J84z`!5@#0o%+3vgXmwwg6l(w2eYfIS1l2gkE#e1L2QhEw|U?9$T8 zfMOtV28PwEw7_&l`F1-7h6XSjsQzF@xjC4v;ylLzA~LX2aB7AtaSJ_BWG`G-%5wtYf@lwkp3d69S#gG zTnDx{ta7kgA_}$(XpSTImYojqDxx^W52|g3s|T60v;G8FJudOj5?f&Q+JnpwmOSO~ z*O}`;{n`C6cY^JnaQ}vb2+*Aue7^bgaa0Jm;8(uo7Zmh8v2vFO9bZOJU4sS-VxaQ@T4%)}6>}@y$!Qv^U zjE*n(^Y-2-{puibMG7nq(w}{n!*P-~*Ma}(-yEE0LBa=Uj-&Z3PDc+LQJmt^O#k8P zLFR;i69B8nCGPa)Kg?cxkohWy1s(f=_Ew%|b%eST96s98l8)Xyd3zUsVRaM-`YSC^ z4W#}ctE(i~Uk|6T0clA1fW*H)hlux`@q>$l+_OYB39SCiG=E2EI@}LRZ-uWQ;=5Zz d9HHqJD9*s(eHUKU#^Q`~? literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/0_8GreatUJ45A3V2.tsp b/src/main/deploy/paths/0_8GreatUJ45A3V2.tsp new file mode 100644 index 0000000000000000000000000000000000000000..36d6b5183ba74cd97c5cf18c2f8b7202aec85c15 GIT binary patch literal 788 zcmeA&3v_(&=BI-_0|SEu5Gw#NF0f^hp!L}^XKWc592^)JOq@D9I)H2j1{-ZDdt>9z zKqEln3=FGQX@QJm*uC2tL_2`kK=p^9e1@`FGaP^dAPffY1PvTOjJ7j#9H8bL0I4?$ zGXaZxaV~IBzi=01K2V&2Vaqdfu(vElBDa7}PQ%!0K^{&*Rz-vlr+N6Q`^-F%G|g_D(;t59Us=`}T9E zgXw6-Lok1V`Hpk4z;w3pF%S)AgZ$g}AP>wA-*g8_oPlBI`X;b=`jZDRa}I#i-@e!a z7PtBL*rDg(J$N|$Yi$FIKfdwW;r>cQ_+q2bFkuzFnL3{Jmc_5$5u;Oy}^Bqj-3#9g55VeVjh^blV)~A zPCxs27J$XwOjsQmkizGo-XgI0xhhvAaR!FW(nnzNYm?n!<{SWpPxtgEVDSRoKu2i0 b1&T8;>^t=xEZzl7`yf69m^gv*0f-F%ew@}L literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/0_8lineA1A7_J30A1_5V1.tsp b/src/main/deploy/paths/0_8lineA1A7_J30A1_5V1.tsp new file mode 100644 index 0000000000000000000000000000000000000000..0055b15ad2634e0523a51d1aa9568ed56d893eda GIT binary patch literal 212 zcmaDeJ;~vzRfj`80|SEu5OV-AF2HqN*=p8INm~Yn1NICI9~{q~@d2_K7*6TWvr9`W z1B!vf85mZt(gM>J<=gET7#hHAp!$Oq<>p}a-xb~t2yq66H$XQ4wK06Y=;r`6XFo{2 i{OMG%`1;-?2dKS3aRvtOg>7JQm_Cpg$UPu`fLH(o^Dztn literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/NEWWAVE_bridge.tsp b/src/main/deploy/paths/NEWWAVE_bridge.tsp new file mode 100644 index 0000000000000000000000000000000000000000..65ab2d13f121c7dbf533e1cece3c3a65b894e5a1 GIT binary patch literal 1196 zcmZ{kdq@;f6vj`k`K(n_a+NJ3k)+nZFfG^Jd#{p~mPAJHCmNLz1wn;M8=+<73yEqC z{3F54%*5=mh|X*#W^5@Ky>u5dArrGHEi=^Z-qF$7KlZ?7=KeVIec!nZ*ERs8($|+D z08r5tNtd(odS9U}GY07aFa{9FYl}t4dJk#Fb!EogRDyAU`_AK>IVoe($PIY)9`8s z9`rc@t5edrb&9oEKCdAu8Mj4ua4l{zc;kF6)tsKUyK6JHe-gNEA1&@H4-mar{`lB5 zoV`4lcgFi_kgOlzhGwtW?~MO@oFMtqyaJghJ&Y%)Z=Pv`l#_CRT_G8`mF9#uDReK* zE10>wOst}F*_UmTae(Fzr|BLbOkd@|UCW+|yv9)Dzzez?v5S|H`*!uAHPzSrT5v5498(e(28uSU(^d0CGqOWbGA=b--!yeLoSlpm{TkaVcOKuQza@Cen} z0z2#?;O#t&-9*`{QOTEQ^ImRJ5Jis*F3$OlZNKK`-CpTRRBmdVxN{7jFPNKm7`YKcsm>{% zj2xGAsJ}q+Ke`h?s?(J$B^#!t;`C8k&=cuT$(WkZy^n*xbSPF%KA!-lVP4bCQ zEg_2p;v>yq)Aa7W-qMsd=!@m6pwI{jiXbausb$t4EmjcUi8mmaV6ZaYAf&_X=#iX|>W7fbFUN zY5C4f&NY@^*y4m#Yq!xeA@`3BL3v{iWF)?ktBlu_!jT=Er-VL$_D%z=SUz$7J}Urp zwZmfP%p@ck;yGvW&)36XqIpT`o1TX87yEfE^}#H^D2O7-vMSeXc=gODd@yfQufm-^ ze>`~w=5L)n3J#k0tWJadvYyq$?-|u_97+qWN@k}Ye%58c4|6~+yVso%Gq0^RdOJqy zGdy)FZ8kI1pBxs&;w{eV=~^(u*KW7Co*#%dTMD?HbF%olT=D&03cphA(#*gf^cO-o zXZoN1H856ID_8Yt(K;9ej8Q#S#$AS8-M3YF@5N}Zp2cKU)N#EUFRqF4a|;yWxxTr&lCv#3(*Y2&H=a6zii@lOGyN jI;7fs2mbFz$_dGS7Kj(tA5B_lPqXvpNY7*a&G!EQ9_m9E literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/NEWWAVE_longway.tsp b/src/main/deploy/paths/NEWWAVE_longway.tsp new file mode 100644 index 0000000000000000000000000000000000000000..9d7c1c0fe9dacb8900eba0731f2a8d98f62280de GIT binary patch literal 1556 zcmZ{leM}Tb7{*82lBQMQw1^5OXrrcz*c>QLIdYn=AM<09A!mu!k`=SG-)jde2H*lgVuEk{GMyj17aszD)EPJG61H!IxZTh4Q*Cr{e&QY3t{cvP!L z{k^`9R}6M1g{_$4n49OXt?wB}FyV9L6}9m4iL)Y?Z>|ia`B!0@bFa}v$(`c zXk7PH-aHziENv)NYjQ)0TZ${e9y=z_zx_J#oD-oi+h=nXZQKtDFZU3~`JV6ys7aoo ze6X(?dK2zYjlzfTxE=|O_a$AP)qgUmM<3R_ob-D9oq1=pTp9fx#c^;>)>R#EgOFDq%P+if zs_EjR3u^xIRkRQD%D#h+zQ5#NQ?7!1{B$CCTb=GKV;y8>HV{Xj2%7}Ij?^d>GaXPG zeT8y`o-6MH1m-mB^0xjdJ^G9tNFlu*A64tMTp9h(8`na&$c@Tz!or(RupY`@n3N9g zx5}D+R-9nT9+Ue5NvKyxZRxZw>%=u|Ic6en?av^->&-hsj^FAdKPG-OzXRHD{2{L# z%2q9N-JVMy77@2PJHYPglBez3O?->D2)q^LQdCa|d~xhHarB9QSOgaeuS%Vn1Q zi&UfVf!=S6VdwM#S&zSW+OPR=)E|Trn7{q1s<@v$8Sxh4<2(S9_qO2T V_hZ;gyg=OjIDYmF)BgbW{|B5b60!gQ literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/NEWWAVE_openlink.tsp b/src/main/deploy/paths/NEWWAVE_openlink.tsp new file mode 100644 index 0000000000000000000000000000000000000000..2747d448b649dd92c17b842e70a83464a6e101a8 GIT binary patch literal 1028 zcmZ{jZAcVB7{`|aDLONSEF}x22#&mngOs(~org<&L&(0AmZ+&oWEm)xNhF+E(F=xk zT2`Jflwz2c*WtM@7lmS-eK3@xEJIVFFO`yIdDc8*clKo$hMoD%fByexmw7z(X6R3w zf^!_lt*1jzht{*YB!eGtyLZujk>hNH&P}L&M+yX^aYk6=NXqFx#|^lz{KsrAx@J7Z z9Yg3go1^Yiem}0cl50E}^LPbkT%UYOSEa7hyBRN>=gH}fUSa>4NygXRa+5S;g|s{{ zgFNIV#__z`_?6gC)TqXsgJes3H)eCxN1Ps-At##}HM!;2dA}adn0vzk^;*1c^95h7 z3H{$^ZGbMCtFzu9v3cLI9`;`{#cd#&cPMJ4mAK-6`sz_ZnzADP@*P~Bx%RZ*p;#rALeYpbqw?R6T(pxw0@S;}I%?yFZpS=R#a-Z?C+-7iCW2Eji5pcOyW}NzQ zdbtBqURJBg40vceA940lC#)T=)8y@Ov3@=J)V>*FdMz#v#`Q_e3NgVEXl(BK3)&&z{3eC5BmBKCpnbx}OYV9>~AzYhUiU2rhna{R*)B`OMGuvu6H;ivzVdfb^xMv4Ln1 z1_FhHP(Fi`kgNkx0EEFHWRIW&h_Q0Ex`VIgANx%+EcdT9#-9ICKiH28)CA3#GU^WL93XU%#xz;Z*rju-kytR8rT*(EMk5KG9PS~XHtbj%;D8`I|P?IB+mZ~GymZF6Lk(u z+H-7!!V%&i_gogNcX0M>vAug^g@c6kXZ!f@+I^sKm=@gN0Fu9*u-4(X#ao~`4f{dj zvU{2wCQj?vxBT^Khea~;pyCV+#?8|l4ydyna6WS0!DicZu)U!8O4~NmVf#`coZ|QA zT!xtg)T7`y^W_|e{XlbCSAKMm)OZ6jA8b~6&ISj$!s+`~uK(sBll;j(a*3K9$URX~ zo5Ak1TJznZzV8#v-h->=L&T>%K^A9VNZ$()_j>*pX8wMVIkP@&1DoSk&f@6!^b*Kk zpg03Vfa6}UxSt!p&NxKs3pjih6Ld@#><5a2fP&-0^XDC=q-x+4_c$o% z=U7Y|k=b(wfC5K6q#2l_oKo)0UXv@Fkuzrh( zLuI6hJ(}~SYsnI4H1PnP!c8xmbA~??Q8eP?##~KefGQ0^L@U% z@21lL_41+=MxOj)sxDQ-<=>K?FHo z`;zH<;YVM0vcqqyu%{-GAd~dg#Hj^j-ans^{_I@N@mx@?hNQ-olOqog3nv$CA`z#v zMAQrFrDQm-iPVgq7g`U7%XJ_kHGoXJb}MpgUo`p3rpNjXUiD0`#Jgs;l5^$R%s-Vs^e%ozHVXZoXek$zs>`sKC9PW1YB` zL)2XxE7q*tFV|-|{6s3Lq3pQ0sj`rl_-C>}>EhV1yU<@Xq$n?Gj91Nz3P{^n|uwEIuFFUzOZ_>kro zO6%z41obiH^5(Spg1CD@tB|d+x z1K9eqd|Z5-AyVplw#xzjzm6_6JHrQ(&s%RgfxIp-p9j-(VYM_@ddD-IW8aSM`G7}5 zgNq$sk*9&>zU_i(g+{K=a>!{}2*c@Hh=*AN+2<`hhbWaBEX&O#Y37Bn<3c>o;nPqL zh~7}I$X#Z=xE_6MiCn_;O58ZRSnkVmICan)?&o9@r*NI@lVY8MJKiuP`SkBz!so&q zt~~bwER*J%cgdS`)CXRDk>!wk2JHCpAFda!;1Xdi_u(nUWg@-n_3Alf|^9*h=?X&EsvGLtIzwU$_7;e_{2vA*mn$NF(~vGBw{Ph6T62Y>y& shWTgf>s~y3c1a~_G7`Y{o$5sWN=p)yW!-L5OW!*Dj~n*I?;igC7s$L_(f|Me literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/NEWWAVE_superS.tsp b/src/main/deploy/paths/NEWWAVE_superS.tsp new file mode 100644 index 0000000000000000000000000000000000000000..14a33ed3a4a9070afa0f0fe58aa2eecab2721a81 GIT binary patch literal 1220 zcmZ{kYe4?A#ppYuEa_y0WSJ?A~6Emo|R zO0bj=BB4E&c28~nnWbx8@rDFKj6jH7v&!&6#k9ja64b8vNXi%|E#|f#sC!u3P9%|cR!pF+=l1>@tRj=A%V^9Q*jg%9zPrZ=Fge*37 zLC?8R*spL2tR8b`80SZX9*9hu&tt|N>ERHrOBOuwx;c(1dP4T}FXMVo+$-!2yrg-T zDO_|ta?SCg6+Bnzg*Pw;Qh2^*IvvY3i9IX8>H69%j&#C{*zuYvw?~+xp?OzDi(leY zPDoQnG-y9owsCW}S-mU%6+vv-4QI6f$RdBtr+9Pi( z2t>D@(3X85m+L+8=>;M98zd0?It#e}=|afVtrj-x7oan5CFjgXUsDE(-L;kyu?&lo zl~Ao)$Mm*8qHA|{Qo#cHE}NYEyU1a1)M6| zX3Y%~+igoMoM*l(#DTLhaO872=S3C^3>^$f(0P^NLx&IN)Smd*?2r{uqwZ=g$1T0T z_}QaA8ccc&-o*nRdA+F;QzrDxXQZQt>pgM*+>`FS!2A`NuOXf0-Be+4*9pw$QTAJy zOY3~!XFw@k*Rir~Om9Cl{Fcu6nm3w!66bQ#?$I z6kERpH`^|r_u+iQ+(uk>p=yGvY*O)8-2~w=5WyF+}%;{nv84Y-~0rS%ZY{*Q_{k&rnWCMQRXsy(@1XrFRt@ Mk2kr7-CHdF3!#&M{r~^~ literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/New2_U_J30A1_5V1.tsp b/src/main/deploy/paths/New2_U_J30A1_5V1.tsp new file mode 100644 index 0000000000000000000000000000000000000000..f8147e7ee5e682af5872bad4d08a7bddecf0e64c GIT binary patch literal 788 zcmezOI>6B*KFhJ5fq_8+h!ubs7vQ?CY&C19q%8x(0ec394~}Qg_yE}q45#$x*`=kG z0mVS#3=FGRX@TjA^6hpE3=Lp5Q2oJ*a&s`dCS{%jLY#r&^X-*DJ_Ey^pFEw+gGl;){OGcQ9(Jv=?b<1dI2Uu6D3kJZ*2f?MjEu9a3O%kp7j1+a1(G zxepxBUFGnUPXufi&>Tmn(>oj#e@oyLKeBlXTs_E~h`*=6>T!w7F4+pR*B)g4r)g&# z^nmt0dbSVdPO#m4!8aTfmrUDx%yPd&KG0uoExsW22iGpY;Q+FSqxJxhhJ+7DeEFN3 zVDZwokKy7#Weg&*f5GBA44yi$zpu9UVD#O8uy)}={zd=5;&YpyI)rpp+NT>fg2mT; z`{xjBJ8kdzGw&R>0>cL+4l*Yrmeo-(g!_Qb-uDii!jSL*n&W7q#pd|;g9J|Tg`U6Q z>OtmA@Zbll$0h#H@;A(0dyx6Dq5_WGKznC6GC4xs2@apU@1l;KHq-WUW-~edc~@=k z&EyMGe{ip&m?OxZH9X8f8WKJrajPQ`aVGM01Jxe{^1)e9XE;tUM8_NzJq`3y177dp(C|IcpC6!PSHGIBUCt)#DOZxV{Z$uN}zzGn-u^=Z< zC)n=4) z;!bJ5VfNaA%ojb~?Pv(Jmvs}9Bh;PX@cAP*$we< UAA{A40@FT-4*?&*`2fTQ047xV!~g&Q literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/New_U_J30A1_5V1.tsp b/src/main/deploy/paths/New_U_J30A1_5V1.tsp new file mode 100644 index 0000000000000000000000000000000000000000..f2513a7f38779e2d1f585c681f3098720e7bfde2 GIT binary patch literal 788 zcmWgD4sx89knL#Cz`!5@#0o%+3vgXmwwg6l(w2eY08se{$FpaAfNTbaQ~LAl($dO+ zVjyt_hSjUIz;s3Vb~^@!1~40_{$NG9Ihf70WPt-hoPnWHdJT}zz!39%p@YixYWu1s zf%_MTFFiOdVJ%o()@qSMX=5y}D_TH!04>(8x{nfHG5TyQ~#owC_AbTvO4*_XN_<+RyoNfd8 z3=BaGPvPPqe!BWUAfJI@lk+o&_J`H>Qz!fHKUTE(U~A5Quz3EoXAWLvmG%~gn!w_W z2md>GNX^>2V9$Gp>j$L3;voI^SF<{1EAbw1TKmC4(Hs&!Kyw_|RIoX2SC+;pep&1{ zTs_E~wPpNZ^|-`K+5f=owFjAB|lTXaiNOsm!A4uk-q`pv z&%tm1Js-YAob@` z%)sI?&lfs)%HIc>4-{u$DBWub7Pnfv(joct0=T%el#4^G#H;;X=4%|LsZ9a90p!kv zI1h)rKGFwpiSKCNhNPZ>q1_+~tR9y*htN)#y+C)EIGrwubI1nT`|SDw2Oo$#!R{-% zm;t60o*ahx3(S|$$^p{`VkbZ}m<{r8Y+eDFZLe@2Nt}VfY)>;-+&}0s%$x%t^%3`4 z!Qva8pE;bkjtC#0>UOaBYNdA$@0b_D!)M<19*5eVSNomTesEAUM}*ITn|%)3m8B2h z62C0=8%aF_!@=v*!Rm2|XD$2-vlr+N6Q{>NXF3!B?KL{Up(U~2Bh%u{<;V(9+~fkB+kIFQ|K{RJh8(AX3han_}n&m3KsvZ7~}{| bw?J_Q2EL3RU~y4k+6VC=z{ClZ4?t`HLE*{) literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/New_U_J60A5V3.tsp b/src/main/deploy/paths/New_U_J60A5V3.tsp new file mode 100644 index 0000000000000000000000000000000000000000..bbed585bca935e40215780e321cf8ba6739a60d7 GIT binary patch literal 788 zcmWgD4sw(b*x+E#z`!5@#0o%+3+ON0YaJRIYRAB^z=46Gz-jfWRkk3tD;~PruU=&Y z6a$GfFwC4O2{Mks*ti);J2-&YK=p^-ztaPY$LycvfDmV3=t+GK7XQ*e%K>W60g!rg zfnN~y&lft#ii!dCEC7l#FwEP}|kMsdt;yc>6A*p9z_#!3=R*y?OG-5Z*UZ6V)oIG>n95R6RKD&OvK?>qd zu={THD1&J~{Sz>Mf%&m6nqd0b|MNf^5k8w|>Vd_7nq5Z{XJ8P`GzN=LWWNtH=Kv^t zvi4bk#Wy-Xb8zcKgwMt}JFvLoo!1Vre-YusJjK}|a__SJPHR6nYzjhzPsB?PhwaMJ z2XKjB7W<8)o`GTgvk`i%pb+571tt15A!kcY@s)Ru~Vao#NOW zk<-sy!Bnt#pBtAWa`=2o%L0q9KjMfa&cI-0Gz%>LdyOm1oCBcnd3t9KSUgcU$Pt=u af#M7dd8uo`;-bK`58^{WffFbnfY<=RA=J?T literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/S_[3_348mlong]J45A2V1.tsp b/src/main/deploy/paths/S_[3_348mlong]J45A2V1.tsp new file mode 100644 index 0000000000000000000000000000000000000000..99afa5a6a76777654d3fba9eb7e297b514542964 GIT binary patch literal 740 zcmZp433Hfyexrju0|SEu5X%8E4$$yomX1{-x0x+a-hqL^#0kWnD$%z)r2@(ealS39U5A2vqC+;r^vqBPQU|3i4%x+KG%>A_w zV(s=dyVy7LrtWXxU3gH+?yudV72EbtaouFM)JFm=4l?Nsr-A+TLqZ2wn)cgGHx&k( z4^;2ilx1xnxk47FIMej`_AvDza{~VIJAl;V5|?|n$R291J;?mJt3nPSdq20Iwl6(j z3UUwFZr5)*4jgg*`5>;bnl7Ss)OHaA>xtx*X`GQEVDn$X|x|C&i&EIVf9)! zyX-w|4olNS!QvouN*Ti(T-QiCJdEXVI9DhLwil@0aq-OvhrJp~IK@k(&Ee`n=Gga7 z1*^v;{%Vf}%wBtt`C-4OIXDCDJyPKA(EQIIm coPnV>d4t2{2?^GXz_bkFLx71BC|!ft0N$tSZU6uP literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/S_highspeed.tsp b/src/main/deploy/paths/S_highspeed.tsp new file mode 100644 index 0000000000000000000000000000000000000000..c4ba30068f874f8a591f94106b2192a2bb99b0a1 GIT binary patch literal 740 zcmccn&c)G*aixPj0|SEu5X%8EE}*|~uXSi>s2u~t0tW_$0;kohR@wH7pRt-{u5G_4 zR23)&5@%r0dCzBG?Pg)O+AG!m`zj-_7*PG8Mi&+P^y6iA&z7bmi8C-vlTo!_5>RQk zw{@butBs+2aj3Dtj+B2I$XS9=de=fmmSFcx(+rDAo&@MPk^)om<5ZghwdWF{VV%r9A)oFfb{~+aV&GLb(mZqg;U&Zmp)uQ z$ee_AePH$2#3upG$$4)Cv)3MEK6m6qhkl^FQ(a6QkKa}Rxd$9RcGi;}YBLr0d#ti> ztkF?{x#!@Er&ArWF8tYdWFtZxWbeM$Qyuio{_I=9YU8MWT@0vx!2wYE$(%OBVeX>s l`!uh+I6~7QP#hS(Vapt@+L!FU3rx!(J_HmvfzmaI4FE&~?z#W~ literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/SlalomPathJ30A1_5V1 b/src/main/deploy/paths/SlalomPathJ30A1_5V1 new file mode 100644 index 0000000000000000000000000000000000000000..c84c1dfdc484ea8b85226426822e6c046709bb6f GIT binary patch literal 2468 zcmZ{mdr(wW9LG;8Dx|Q2pf;v}v0|v8;{cMo=ll><1fdMA5lvASWJK_h3O+_xL{}8B za8#0K0y&65CQ9 zn3M~_#g(uRAvB(TqUcBJuxXv*_gUry1wuNEkO7+XA&S)rIq$T4J1Td0Orwl(gq&9P zDeo^mj;+Fdm9pB|oKd~d_V-Y{E$AXH()w9&gi6|m;o7`Qxc%Q%%Jyj?6jJ& zoaO^TbT!R~@i!hFpyvq1$|7-I5M4-9Wadl!(o}Iq9k9*;Em1LN*JPdT6R$qO^5GIY7Z4%ph!^^#OjpP;;Gtsm8&StH}TU*6Ai zjRC2gCnd`uZJAo}R|tYxbUuu;>l?>8!cWbe_}UEwzYorb`oO6kN2qr-O7aO_R%Si( ziD;Y1_5a7eqdpHVT8X)s`MVds2~{+AO!!C`?X{lu;qy6b;{xiI(Ri(`H7p?;Ib-{Z zZ*_qcJ~7Hb*(=U+_qMx$SBpv+f7}|ns-tk;sU*5DgK%5r%IEM~gEf3z6iIz_oG&hN z1(|%cG69c*w!3zN9H9(bIkc6_$<_;_K)GNzbm-e_l`N2s@PI@e3_ zcwd>AOEU~`<F@_=1V(Gd{Mwy`oH+R7=+2i zv$;O*wwnbA-S=)7m*enoPyowo=7lI^5r+vc)TV+VJ9grYW6QPd{^{`0aNgam66eqPm$NkREUC9DBx3{2*dwQ1 z*nNf2{f;9LuJ6{aa)^P9Unf$|4g&=Hr@)_e!*x=8Y-p^79wB|tF|L>5Za>6|xirH7 zvx8G%Ce2OT8!z_c*)h-4;O$+#RSlYWFl^t6r#qH2y)e(1#`mRPxY=S32H{3TI_CwE z$rc=;)XXf-zpYCa{k6>J*?@`L?LPz?W`#oT$o4IAgwp%UIbUXzE&6ELe4dA2=DbOr e3xn@blq1wLzmjuD`Yy&tz`y8yLf^~S&;I~*h9Hjs literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/Snake_J30A3V1_75.tsp b/src/main/deploy/paths/Snake_J30A3V1_75.tsp new file mode 100644 index 0000000000000000000000000000000000000000..8fd8f8634455ccda14a553e877ca8c87644c9953 GIT binary patch literal 1634 zcmZ{laZFQ39LG;)+{T8fVmE4lbx@5VJf9#4-hTccr!a<6ZLd?tOmW z`~H6S?%umy?Hb;g7lcxTPy)HK$R*SE$Hn&6tvUXKibDthA&K{PcCO9Ozwb;}FXeRl zQXJw4&Hb&7`%7sMcDEY2w+2jv(N&5LI`u}<5~U><4@!+0`gW!AKY}t)zkkn zp5j;xiX&|^9HD*jQ;cU6q=QCbi}0$k7}&8*gS{J8!2Lcm)6h5lApdDtT+S2ZW)OqlvK10 zig!B0^@zEvbujtS9xlE%nj=*Ht_}>rGEU#V6U<3A+`1&yJv!PU4mn?g?$QG|Z~tzX z*l?0@>f2to8piLO$6dER2h}Vi^Cx;fEiM)yEA^p#K)vu_WCV3mCah-zdQ1C_O@dW}ISrIqrWi09ir<{$v$L>XZ0=AD)K7 z)=a_U>xXaZ9e9Z^jpUZZK%kz)5$YNE1Fjx>ydzXcEikHl!<9V}%@Ha#Tj2J<+b)w~ z5XSFWagt5v*7Wv?=R3~9#FeiF(~Cne={&(W^*y%03W?K=!aL#!q|Xn1ZA8y^^n?JC}9sUn;L@)z z6$^%$KC?{CA2?lw*G!yhp$pviQivbdrts_j{vuMSBj+C2-9|iiLBr1+0&bc)KV=+l UR6o0R7dc7jbErw|RH6O<02i%0_5c6? literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/Traj.tsp b/src/main/deploy/paths/Traj.tsp new file mode 100644 index 0000000000000000000000000000000000000000..693bc13cc6c86200efe94c11d6bf910cdc31ddc1 GIT binary patch literal 1463 zcmZ{kX-HK;6vt0lMAmb|$}qIe48vYzep26@TM}6sWJsaWN(lGq%Y8q*ZaD2=Tl{Mus$2gs-_ z;rgoPce0O2{iPj-dz@dNH%v6Pfflx)0f3=|M?4_7+vBu11>=11P6t`EwWY?dcP8rW zFL4bkv^McGfftUV8jmcUuh0Y3`v2y7HNG>^OU{eTzuqtzy=dMj*8u!Ey_Myq9KgoW z37hv_seZ1p)nWD$3pw_>hX(0M0}P&a!K}MQ zx^2Z9F(SI19CN-=lQlb3iumS+Z$Ekyx9|I~H@Td1mU#baEru06B-Z#NXmGp1{i$Af zS>}sFQ{Jia;JxYNdggP%cQe#Mw)l}oHER~G|cMZxd%$)Fh*|( z*tFmljxPL3N`upwUJ|R~k>xQQG_jF&V0`J+Bt9?hs$(Oc(-FkL6h1dEZ@{q|C$jVG zk4@uz;@VDOxQFE--l{y#I!X4S^%;eZRS)nS z^;r?D5!zh(m=CWz*n|H+XiwD$$`>L#@-Np{I0&+q)%i5Ho`3h{>nsHaSl`;rd90JG z>?1P$361S@9&ihFl@rqdKx4>XZmC=#7s|PxwgXe6?eJuZ$A23>u=71ugm|m+ya}E{ zLtQ56X=$OGGYSR2KcH!cGj7RVEI?4cd~j0R^)BeolFvD-%YrKS%FxrOz|fjx{5Hs@dWXvj)U) literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/Traj10.tsp b/src/main/deploy/paths/Traj10.tsp new file mode 100644 index 0000000000000000000000000000000000000000..bd2c3be4d5b7d7d64e2dd8558f257754fbecff24 GIT binary patch literal 1329 zcmZ{kYe-Z<6vwBBJ(gXSgb+RSuIl6w3ZF?fsfLX zjBvL$sdP2mFQtXMceRWPCDZz1+LP)-f<4U03YwYQ-TZO~E_3g1{^$J994=?hV>^r| zcmN}W0_n4cJ_^g?n>QTQ-?v4NkcG;%(BIdme;(R&cYU5qI1`jg8RH10e9Xp4g*EQt zm7fImF6Gm97m-u=vbEjqD4v|gX;jK-JkPh&U1nN<=T02LYc;Ax?uY7oV&bwo+~^v1 zkKM83uY>W@0n1idKZUL3N5yrQTCwd_9Cx4rxYap}cotg}xkmLPg2(|Zku|!A2Phsy zd|XXrYk^tJ+-@N@YJJA1gtV#6ye5IAin84#&Tx&YD8_h(cI)4(67}DMKyFxwcxFLR!<=a9c22S9y z&t}f6+J=ZLt2Aa`_C4Y#Ae^&ASwFv!fzV1^@Tivz$Lo2UXdZGg{5#QSUr^)&mq)#N zmdF2=Mg=TD@!$h`EjtU$!Ld~hL)7_g@|0XDZ_>j2U^sBFG)Cx|A{u(LL_<2$dv>)1 z19NJx{6pjxG4AvY;k>mWlVxfx3!?{NazTpQ zy$%SX#wExKYLAf>LP8gH}h0Ji8C-vPZqSlKP}%r z_eF|*(r*q2)`GRz%B97W-ZJl2apEG-)Z)CK$E5(<8f#(wgA}-Hth47dG=PNQ*62a z@H^-fS~)Z@zqJRs$m+=gpf4F1eq2-ps&fFV1&LpKx&|!1;!7c19H@-JJLnNu{4HaX z!{b6zhvh*r2V%DKANn@+9awxzVzYziIYWm#b@gCzz3vb8n-<>PdrG3$LDg9pEDkcK z;>Lgb-bwNMXC0X0kSECM01^Y5gY;OK^MTdl5`ULB7e#$s z62F7@whjAr>X$eyp7IRn<^=~pF?pd*%%Pkmcz@`kbq>%J0TgFoDEY7Hkd%I9&s<=t O0`Vch#0iwbKx_b$mBupw literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/Traj2.tsp b/src/main/deploy/paths/Traj2.tsp new file mode 100644 index 0000000000000000000000000000000000000000..724d850bd8685c0466b0c361416e7e862040a264 GIT binary patch literal 1488 zcmZ{keN0nV7{+gaC?f4ZJ1lgmwG$B>bP?G`+3k7Xu`p4H*l5K?XN+cZljz0ejqFxiLz;eB8sy8RcL#WZ3#<@B53?rARD88Yy)N-B5ujfdzx1NxhJ_f&F?(t zdEPho_6;i*%u9S5nIuVi{>c1MTiTCqT0_AyE~(>k6NZ98A-@H;ZTa~haz>n1WDfp)x%~r$u<-jTsz+qMyru@i-+br4qDiuWcXth|47_Kf#wg$~>&^tfSS~aB{7>XC%HQf*9lv=jdS0eae zUIHfO4*DF*FYscfS#Y|)aYB=XYj#fsq>dr57eqc4ZUmE_WXy7=Dr)@ZJHN;DWVC8s zs?e)(_xf-&n34b8i8;8M=Z@x#Lon@KDoDH>ZHpcUgTwx--oK&kN;T839FeK9^cfkV zvB%l>p>+oR#UzP%3uNGbr?>mYtxq_eHI!!H%D#QRJoz6O(^RnwJ7xzqt~jSyMhwUd zWBz%TIJ6h)1SfsP!%V!cGb)#L@z@9&;m`GO?@$(=FV9uwp6U3g4q{Ds#~oy)MR$Lq^4(_mw_i!~p)VWWCN&lZTj;`VF#9(nP^H?4h1@CqIE9UUi< zbaog8H`)#OHTQYt$PNEnT+ikg3%<0~AaXl+zr^2g7GqkESMEKrP}E7B`t@j%R^foo z2zx!5v4;5tFrTcz3+1`0ylCg5s1YN5mu$yt+~?EMY-}j8G9Dlr{-Vi&<(qFY$(4hv zS!51SL0JWr=pOB0rC&bbRM7D^D{(ZlowfY91l`rkxJMl?)YM)0U_E{{cORSMweUGB bX0B-9=#H(JcJ6jjn9psxA6X_b!|C_`px59M literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/Traj3.tsp b/src/main/deploy/paths/Traj3.tsp new file mode 100644 index 0000000000000000000000000000000000000000..bb3e028e1cee9d52c6727a9c2692d2fc8100098f GIT binary patch literal 1004 zcmd0Ab#P2E&vC40U|^5{Voe~%0UG#9Zdsi@<73Of&|uHNpx}7+%o*D^_LF!0TzSAQ z{aY+h3?$CLU~)Li{=nVFeKCjM*@4&)^ArxI>owVTeORzh%H=zfI0M7Q`WE|>tC#It z!y{~O|0Bb`B8Pw94EN3Z=lM*uH?cjoZ|V7!_E$AL!QvpZR^>7}%z2Zt-{Aaa`v+LF6sbN4>Bj`R0vo-E^+beQVvji?Lg*VGKhAV3$(YHH{XHV zv<~DRJCHf%ALcleYrNn6a$ml~?8$ZZ52ydP1-ZY{bFKqOUaX)LNJGK~B%Yd{{EL&UV+6g9zW`^?NF^fkGe5fe2VF7 zhb8XnHdQlTI{Z8B0u~49_x!@?=vG=|U(ET&VN0JAIDCNS*gxv!c5L6*hEx2?^gnR* zAag>B#K7utiJ#^853|<}Wd1vD39!AJ_VPR4`C0*T4>)}C*J(NOU%z0R?I-A{W?T(( z&wdUM9Y^iP4x0^g5aJ+v&rH{G1kqn#p^8svZJFVFdWL?syJ?ih67N&y~|!F#};5X;1XY9q6=3KGH2UD zU$A;y;;OlNFnjGl<_B2&gY8{2-`w%lwPcWcz~SH+6y<2__QP%#pQWRTNE$dCK<>Zw zI@+?g=Y?RR8cXa{0L%u_gMY#Cv1^0IgTy4WR1;tUL5tD@|u-=DBw zlJS%se~7vLrDuZs+Y+`N=ocxm59Zmle~s}2yM9+ausFyp|38iPf94$Bzk!#F(Vpd( z8rTA$1_zmwefE4+k8w*}5DbTF0GU*|`vO=4F7Z`N8TL?{?Lii}b=(Epyx{Xn`_e5H zAQwS=oW<{OEIxOy9p4)J<}X$D_A5Wxfqc+bC*T0G$9Lg2pgKtCfW#Rtih{*|d^Z5n z5OI*Ypo(m;c(sw4Lp4*Cy>O%8{uxj19Ejdq02XicHh19DDz|^I%>XRE<6fb|JdruJ zd8d6H4#{bQ#X;uuZ)tOgTz}F2*_%Lz3m!^fHv-LZIQ+cR;a&1KoZ=$qV;#;z)q~8j zcb^Pak4^k7(43wRi7>9_+FM#s0dptV?xpri91a5A+0a?(PzUta^9DhX z`U4>smNLtaR{G+Tu{pz`!5@#BxB412piJ+_E}*#>bX{p~0SkLBa9tnKQOeyASN1R9+a?LcgZc?t)OEhFqrUiR)^7rO*WoPptMRh0eo`xEv{ zGM=*I4>7mD^h|JnTf(*j{URmy!91JxuQ7gL*YBza76+N-|EJOZ&zz(CH}G;X+Ozyp z16u&p;2?9d&z`U9F>Z+qg5hutAd@P0UjS>sCBBL&!yan0J;(yLj=Nx+7kpl6U%I6N z2` zA`Vg)RFMr9uQoDssAj6N7j6{XKjX=r1JQd6z~Zgm<_>&X<@OJ@8Gyxi+$(gLCo;!2 z@3gPOAvtZZILMs-Eo}~w>o3|rdlTqz!9xk`MxZ$kho5&kyi5LuQ(WYHtiySzdXPEx z?vuglv5CJ0n$zQZ7YEsU%Vn0s#*>Tek1xq~uxQl)h24H&iaW?#G1npeWtqJ} jUZn#xB?8467^L2Ba9FhZlXX2XHG}vNpx_8f*&sFmcsKzV literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/Traj6.tsp b/src/main/deploy/paths/Traj6.tsp new file mode 100644 index 0000000000000000000000000000000000000000..29fc806c983e99a0f7ba372c3df18a05055b8811 GIT binary patch literal 740 zcmY$`v(2Hx@QZ^y0|SEu5X%8E4$#0?a?9%M86R5)h6Z~E1_j5nXU^DO^mEw#&t;aK z_jEU)7)TswPD-%7&pGz}hc+Iz1F<3IDIDDRH^=^(tIqyIGRKj`85mml^X+9k^!Lw{ z{AgFe;cssiv~J&#XORc`Lt5;s?Lzh^&lR(u^34$}4l+x*ZMyyHX)XK9cWBzbnPm$$ zAE@5pL(mfYn2f17#jV)Z!_|Y#xy;V*08)=j{K(`TFnjGl=3C~8I)LmIP-Aq6SW*pg zj~&RIcag%?g59-m&D5s(GR2S_qMEZcy%cV=AHu@ zQ?EH3a51reJOLpNviHT}YYsINjqUHNu62-Q1E;I~!1Q)d`ua_WljXejmFu=SK+_>m coPojh-v6JAU|I(8AwabX{p#i8|!SU>wGqxA~9CrV6nPula z-3=%P5(k=-5^V2tj(z{3jfd?(Y>0UZ2RHuBvA^c3v;UCHaU^jDh8F&Odl?V?{WB#$ z+7)p4+nWWg+jrzy7W-0t52Q%fE8&8e{$zc+iIj&#C-qsp_u;?Wsp4pUmH?LT;IhKTpga(EDa$i{k0 zuS4Dvd$2gjoR)X%9rkr}+rQ18SHHP3AX47Idu4#xZ)`Vl;bH0{Q$}Q8ZM#`lhDW;k75-K4lEh;El&Nc<#n`^X`F;0Evll7us#P z0`m{e_8=_R&EJV^Z!Tc<2+Sw_5hib6-0TROa3U4PLL8A&%k-9(YC_omrKNJZOS56T zFIda@ahF^>r!sV2SHpQzRUR=n6k_FYy*X$>ilx`5j&t4Kd{SvBz~hm(Bwk)e-X(Rd z4ZD4YWH)2ZnUBGGotRIY#$$>KA`1-T^PxVZ&FdB!wKh29)AX0@dginLOCQ%e;-)7} zwp@YvH+v5dk>>Wqn{0JT^C=l28MIDShl$*$ec|DHrnjVxjS!ZztoSb7rTH*kedhz` z4ex*1IhCOjm)XGf0O!9XB;+9Nt4O5hu+y`}gY(0?5hw$6lN_M|KPBhURsY)y3a)&OfLAoP zBf%eBq&j)Fu`!a@>2+fXO!me3u0@+T|F|xY?$Uf%zdzeHb3V8wW(r5>-Gf}tv#!QM z@r+~GZKcL+Svu2_>V1IoZ=@-myqB0u5T6`aGqkIRSuIl6w3ZF?fsfLX zjBvL$sdP2mFQtXMceRWPCDZz1+LP)-f<4U03YwYQ-TZO~E_3g1{^$J994=?hV>^r| zcmN}W0_n4cJ_^g?n>QTQ-?v4NkcG;%(BIdme;(R&cYU5qI1`jg8RH10e9Xp4g*EQt zm7fImF6Gm97m-u=vbEjqD4v|gX;jK-JkPh&U1nN<=T02LYc;Ax?uY7oV&bwo+~^v1 zkKM83uY>W@0n1idKZUL3N5yrQTCwd_9Cx4rxYap}cotg}xkmLPg2(|Zku|!A2Phsy zd|XXrYk^tJ+-@N@YJJA1gtV#6ye5IAin84#&Tx&YD8_h(cI)4(67}DMKyFxwcxFLR!<=a9c22S9y z&t}f6+J=ZLt2Aa`_C4Y#Ae^&ASwFv!fzV1^@Tivz$Lo2UXdZGg{5#QSUr^)&mq)#N zmdF2=Mg=TD@!$h`EjtU$!Ld~hL)7_g@|0XDZ_>j2U^sBFG)Cx|A{u(LL_<2$dv>)1 z19NJx{6pjxG4AvY;k>mWlVxfx3!?{NazTpQ zy$%SX#wExKYLAf>LT#AKI3{4Q8L4aR5le#2FZV7d!@wd$FED5ih^{&c2$hcfZhri}q0S z4}i?M)ceJLyV<4vWe1>{2Ft{DzaG21MeW1SRrG3=$S3tW#z{II|4!6T> z)f$}QuUC9VQqRD!<$xGiJudMtk>6nUI)Kc7G(*y1642f?ds!Wj!@*8W!(lhjodVq) zKy@(xnjFe`r{z!w^p~F_ACfo&!>T0)Kt2OQ&v#)I@fT5M4xn)Oa6}Ad{sB-ph#6Zt zfWl!>sGa9Ggc1@;#%@z|5;tUMeC*%Y9 z3=I4Cw4jI!WX%JM7b>^G%s&7M2lZ?7!QyGTy$;Yc2^42w5Xf2w7C!|{;~+i+m^gvb HJBSScVr0xN literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/U_grand_J30A3V1_5.tsp b/src/main/deploy/paths/U_grand_J30A3V1_5.tsp new file mode 100644 index 0000000000000000000000000000000000000000..78c121f9377116ce993064160e9cced1a94cab8a GIT binary patch literal 789 zcmWfs_jNpFF5_s=z`!5@#0o%+3-EGXUu->VrlcJMgM$MD!w1K+XU^Dy6o1p0V|Vt< z8lV{@(45;=1mfL0U^%7z*dxVFV4}iqw8&*182>!qC?)|3@vBIrDJ0amS z`TQD(yLS%mU-4)j-r`7NNEJ{)v>bqp+@|C+%O zIebp+J^>bg;O&Ma&cI+WPYB3oU^qM11DGbk>F@x^oKxl^VDXt*zK+mz3ls;bmja86 Q024om4*?&*83Duw01u1#*Z=?k literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/V_J30A2V1.tsp b/src/main/deploy/paths/V_J30A2V1.tsp new file mode 100644 index 0000000000000000000000000000000000000000..93d11db2e7c305d8566af8753c03012036901815 GIT binary patch literal 1344 zcmZ{kYe-Z<6vq#1;2PJ*x{JA5u4N&q`O2_-?A`;Jrc`2mNuxqS6E}NM+QY&XB?Sw` zM>H~FH;C)E-{hhxgi%Hqj94`4$_3^AD(v`dS5bPK{+qcJEHRa$@|78CuDLZM)B zM%!zCiv#HU-;psux~YqI>|>_-$5VZb8)ZkC*wd(^w2cM8;b+y7=c4o1aqr6>)&IFERwuZpc>o?pK96 zt~}F3Yczh`iSfX=Ret8{UER}>3dZ+jJE2^gVSJJVxOPV4-~hSxa?IsqX6F{b>0qDD z5>Lp}#oN8M3BJU`h9$q<@EY;$9B{^e$=7K<%zL3yiLO!g zgK;Tx+<7x!$Y;niP=&QqZpI_2Vookthzh$FEbm>;%aOaBuk(uiW~6m^7NcTyxV0k3 zkoK#(wwxCx%Jq{foc8V*)JJgm@u!c21MK6}IBez26?Gg=s#St7ruC|^PVXzpXR_Qy zdVqpjKc<)BPUG%^FY&NpGiq>@_%;_R(Iff}&4+mxE(YLjS(7pQxe|Z$-P3*crFX(M zB=g+M&Xr8+A-*SV^>*Iqc0j}dHVpAh->42n@xSC+t!3Q$CKPw1oTZ*-dY?jg9pfF# zVHmg^u*ugKc${ywm~v{u(aY+|a-{il8;GZi{LE5(WFkVO2e=Y+l~$p zViWN2ON;4b&p`xxo`eIO_;rlsS#>H(I2Ysk>O?zFKScVi|LA^865~yI#Uc(+r>tPy lf2CO1$4u+2X|VI}oh8D%MmW`1GW{%hC+XPUZ0yaX@qdr4c@6*o literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/example.txt b/src/main/deploy/paths/example.txt new file mode 100644 index 0000000..6839539 --- /dev/null +++ b/src/main/deploy/paths/example.txt @@ -0,0 +1,4 @@ +Files placed in this directory will be deployed to the RoboRIO into the + 'deploy' directory in the home folder. Use the 'frc::filesystem::GetDeployDirectory' + function from the 'frc/Filesystem.h' header to get a proper path relative to the deploy + directory. \ No newline at end of file diff --git a/src/main/deploy/paths/infiniti_J30A3V1_5.tsp b/src/main/deploy/paths/infiniti_J30A3V1_5.tsp new file mode 100644 index 0000000000000000000000000000000000000000..7cc0552485f930ad3baf0b3c5f026c586457e09c GIT binary patch literal 2087 zcmZ{m2~1Q+7{|w2*Q0I&f)y1iVogAovY?R|+~E?y@ix^BE0i4G5x;WUe3cGx`1nBK5YZ#gjAHh;`|3! zcX(2=WRNe*lR;a_ER(TR0SSwza}CS0bc7tLwrXv1S+KXo2bkVw1Ip^%+=KGD$fUw$fI59vM!RLRwsVDWyvu=2jjRJ`Jubh{w~w(CS8 z(8maEMPZyXAA|1!2);KCc3v@o{2cJWRF4le2Vq|MQk(qrvMUxJVES>nhhaJOX)#{| zyP<{5pXWC=<|rt#By~h%6*M)M2#KNgOfS8ieT=_n-n+^Z- zDHO-M2_3h`;_RTamH?99kPgW8ny((&V&yEM*CRV1*dNq}+E4I$c9Af}E>3*vAWF3x zJAsV{k9NXtS-wzq$H~OFQuQ2;jDDcjU35Z^ZI+BkmL0C&YdGx`Q>P={r>4XVx1p?D6>y;S!EK3}6D;)pwPP6z(hibfWRplZv?H?;= zam`P>ar$GGSYfZhjPgWbZcn?&Zrq|)A6(dW&L}v3i+fM(=05C3%y>M5uj~JK*2N|< zb?*158`Kl>YVsVk#aaC5_HDQ$F@yRKyd;^IRNUV#a65fftS?DJotpFhoG4mbZ`Oz{ zz`1T!!h4*MJ#~vX_XyHrQ&g$&JWeOxtPGawoC7%bOxEIq$n(NNSpnzcw*;Wuitfux zdy??Gf^D3${H}bq1Z&s!h@HRgMc@4!`94q|Ty6XcJC2Vr+2UW$O~G03^vvga)k?0n z#h>)2SmFxIfAhxG_y>)9SD%XW(-T=fJa*vT5DdR*7X2gAaD$89l8^Lg@>+a6G*fIz zuyPi+Yu;LHyO$~+U8Bb}H+HanHnH>FcXu6n+k1$O+3EQ1C8wN_Siewgt|%yTq`w2K MKTtaPuK{cS3t3LqMgRZ+ literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/ligne_1_505mJ45A2V1.tsp b/src/main/deploy/paths/ligne_1_505mJ45A2V1.tsp new file mode 100644 index 0000000000000000000000000000000000000000..8ff93f855f6e06cb4b2edc81609fada7779ced48 GIT binary patch literal 212 zcmX>%#Oe z#Aeu*&~3-S&;Vuw)gRiHzzt?EI4~DT!^9aF&H>#3QlAmM*dA)m0g!r4&tqV5tL6jt YP`iNQ3=HW$Ao~&eKx~kEK>h%+08AAmzyJUM literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/ligne_1_metre.tsp b/src/main/deploy/paths/ligne_1_metre.tsp new file mode 100644 index 0000000000000000000000000000000000000000..4bc1d9cec48c4cea6b7bb8097dae00a120287f5b GIT binary patch literal 212 zcmdO1-{hd$@xxx8fq_8+h&g~57ue-@)%y6}G`qC4WeyAs1y0^|8*M>qk2X};@6+{m zfQU0Nlqad%gT%KhEwrCCGtvRX2C6^gILQ_){_Bj1145jEfpz~(u(*nyy93mm10eOU kt}OwJU$1O(fZ7WbXJBwFcncQS2D%-@hkybnkUv0d0Ki%^2LJ#7 literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/lineA1A10-J30A1_5V1.tsp b/src/main/deploy/paths/lineA1A10-J30A1_5V1.tsp new file mode 100644 index 0000000000000000000000000000000000000000..e8dc21e4fcfe02523d910ce08e747bec0e349a24 GIT binary patch literal 212 zcmY!{-{sJI_kx2w0|SEu5OV-AF0f_MM9Z^h&e$+89I$6#FmdYa;IIX$?RHyaH*01k zPz)r_z_5Ci7MM0R-fYLf&;Vuw)gLl8HU_i5IInj=h%+##1Kj}9w=Zae1Js=TAoUg< hyTRfQN_IIw?FEW6Fw~qm4;F{%1Brp$1M&xm1psR7FaQ7m literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/lineA1A10-J45A3V2.tsp b/src/main/deploy/paths/lineA1A10-J45A3V2.tsp new file mode 100644 index 0000000000000000000000000000000000000000..d5cc299568ebc13fd5fe1bda8fe0e31851b1bc19 GIT binary patch literal 212 zcmY!{-{l~lmgykRz`!5@#2i433v5{=Xnpp~8CwPh2L}cQ6Q|CO4j`L>!A4uk-q`rF zJw%*=Vbv-vAe(_<_ik$t?Eqo})gOZL88-Z1XRvL literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/lineA1A6-J30A1V0_5.tsp b/src/main/deploy/paths/lineA1A6-J30A1V0_5.tsp new file mode 100644 index 0000000000000000000000000000000000000000..5d3e7026a3d5fbd104eabd05a1755c69804ea075 GIT binary patch literal 212 zcmWe-D{+|I&EzQ0z`!5@#2i433%KezS$1}G*f20O*fTJEaO~{hum!2*2zYN>UjE$< zA`aFKlxJW7$^*q1z-*xUgFrr*-BX+GfDmV35MlcQ;xkO?&T)X6vmc~hRs1VhoQJu@ d0ctN$oPmLhnaL4Eivryaq9NdeBgh{hHUK6+B-H=_ literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/lineA1A6-J30A1_5V1.tsp b/src/main/deploy/paths/lineA1A6-J30A1_5V1.tsp new file mode 100644 index 0000000000000000000000000000000000000000..1eb555f0e0f904ac0fe79b49aa3657ad0ad5d8d0 GIT binary patch literal 212 zcmWe-D{=Vsae{+90|SEu5OV-AF2HqN*=p8INm~Yn1NICI9~{q~@d2_K7*6TWvr9`W z1B!vf85mZt(gM>J<=gET7#hHAp!$Oq<>p|vns}@OLY#p?6zB$!J{gAu2dFvwLFzp$ h%faF|eiu7H?FEW6FeF6ugT-O`Kw=>Gfcybs0RZeyE6e}@ literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/lineA1A6-J45A3V2.tsp b/src/main/deploy/paths/lineA1A6-J45A3V2.tsp new file mode 100644 index 0000000000000000000000000000000000000000..6ed6e573f45b5f7eba6df9af300026519bb0dbb4 GIT binary patch literal 212 zcmWe-D{=VwQNux=fq_8+h&g~57ud2$(E99|Gqwy24h{?qCQh9l9Y8h%gN?S7y|M9U zdx$s#!>UzUKsE!z?%mcP+5yA{sy_tfGpLEXIsgSg7z{+%zJS%cRr@+X%{c&4Kez7> iSbWXHVh5m>t|;sP literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/lineA1A6-J60A5V3.tsp b/src/main/deploy/paths/lineA1A6-J60A5V3.tsp new file mode 100644 index 0000000000000000000000000000000000000000..3fc5bbce979ee402bc83338b93ca6359e90219c9 GIT binary patch literal 212 zcmWe*D{(MT`(-cBz`!5@#2i433+ON0YaJRIYRAB^z=46Gz-jfWRkk3tD;~PruU=&Y z6a$GfFwC4OX%C`}jhlhAg9C^SRDbCGJ3X*?O%6ycOq_vX=ek8;@zuOe4p4IrfYhf% qt_6#`E-!X~+6xqCU}&p;4;B{zx}CwN$J<=gET7#hHAp!$Oq<>p}a-xb~t2yq66H$XQ4wK06Y=;r`6XFo{2 i{OMG%`1;-?2dKS3aRvtOg>7JQm_Cpg$UPu`fLH(o^Dztn literal 0 HcmV?d00001 diff --git a/src/main/deploy/paths/testU.tsp b/src/main/deploy/paths/testU.tsp new file mode 100644 index 0000000000000000000000000000000000000000..b07c2bb7303e11ff883cab21c3daa063b5178aa7 GIT binary patch literal 620 zcmd=3SLCotXtP5-0|SEu5K96vE?~v-&U)7iCOZa(1NLXn@Hj5+)&sH`7_RJZvb*FO zZx0d&@mH_X0@G7`uL0#7z-*xUgHwFN!0ZoK*c@QuAoYvpDFXQn3@h9O9iZmy2dR%~ z*8z)j^NTnvxAF$+J+L37uJ4{cSp3v9aR;teJ-B%7aubIedkXh2kdSk@eTo-s7s#C! z6YL#UT+u#&OT4Sb60RO({u|~(uzFnLMoe}N$M(tD-_!2`hr_G86%K7z_v{b0bavRd zNgrnK!7tGb4&TC->{Vz(h=a_3KDogGL`z>r75{U(!69nm*=5NsN0*Aw| z9W4%AH}>p*)bH!?5y@ZQmv%U01O0_d-2F=iTs_D>n}mg6^|-_hb2CxYC!byDuymjD z0cOU0hgQW~pm+zn=YZpK2m9`h{T%H@4$$-fju)SKYaJ>V|J%z2Oj98HKmZi}p!5Y| F0|0h&$Atg@ literal 0 HcmV?d00001 diff --git a/src/main/include/Constants.h b/src/main/include/Constants.h new file mode 100644 index 0000000..72cc2ad --- /dev/null +++ b/src/main/include/Constants.h @@ -0,0 +1,7 @@ +#define XBOX_CONTROLLER true +#define IMU false + +#define VOLTAGE_COMPENSATION true +#define VOLTAGE_COMPENSATION_VALUE 12.0 + +#define WHEEL_RADIUS 0.08f \ No newline at end of file diff --git a/src/main/include/Joystick.h b/src/main/include/Joystick.h new file mode 100644 index 0000000..075ef4a --- /dev/null +++ b/src/main/include/Joystick.h @@ -0,0 +1,7 @@ +#include "lib/CustomMaths.h" +#include "lib/Utils.h" + +void getSpeedsAndAccelerations(VA *pva_left, VA *pva_right, const VA *pvamax, const double jx, const double jy); +void getSpeedsAndAccelerationsNew(VA *pva_left, VA *pva_right, const VA *pvamax, const double jx, const double jy); +void updateVelocityAndAcceleration(VA *pva, const VA *pva_max, const double target_speed, const double dt); +double getSign(double number); \ No newline at end of file diff --git a/src/main/include/Robot.h b/src/main/include/Robot.h new file mode 100644 index 0000000..ab3cc3d --- /dev/null +++ b/src/main/include/Robot.h @@ -0,0 +1,171 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2018 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +#pragma once + +#include +#include +#if XBOX_CONTROLLER +#include +#else +#include +#endif +#include +#include +#include +#include + +#include "lib/CSVLogFile.h" +#include "lib/CustomMaths.h" +#include "lib/NL/NLPid.h" +#include "lib/NL/Characterization/NLMotorCharacterization.h" +#include "lib/NL/Characterization/NLCharacterization_Tests.h" +#include "Joystick.h" +#if IMU +#include +#endif +#include +#include "lib/NL/NLTrajectoryStateSPack.h" + +#include "lib/newCSVLogFile.h" +#include + +#define TRACKWIDTH 0.61f +#define HALF_TRACKWIDTH (TRACKWIDTH / 2.0f) + +#define AMAX 7 // Acceleration Max au PIF .. à définir aux encodeurs +#define VMAX 3.4 // vitesse Max théorique (3,395472 sur JVN-DT) .. à vérifier aux encodeurs +#define JMAX 45 +#define WMAX ((2.0 * VMAX) / TRACKWIDTH) // vitesse angulaire Max theorique +#define PATHNAME "0_8Great2UJ30A1_5V1" + +// TEST ********************************************* +#define TEST_LOWVOLTAGE_NB 10 // Nombre de tests ( subdivisions ) sur l'intervalle ]0,TEST_LOWVOLTAGE_MAX] volts ... 10 ou 20 ? +#define TEST_LOWVOLTAGE_MAX 0.15 // Volts + +#define TEST_MEDIUMVOLTAGE_NB 5 // Nombre de tests ( subdivisions ) sur l'intervalle ]TEST_LOWVOLTAGE_MAX,TEST_MEDIUMVOLTAGE_MAX] volts ... 20 ou 25 ? +#define TEST_MEDIUMVOLTAGE_MAX 1.0 // Volts + +#define TEST_HIGHVOLTAGE_NB 44 // Nombre de tests ( subdivisions ) sur l'intervalle ]TEST_MEDIUMVOLTAGE_MAX,TEST_HIGHVOLTAGE_MAX] volts... 12 ou 24 ? +#define TEST_HIGHVOLTAGE_MAX 12.0 // Volts + +#define TIME_RAMP_CHARACTERIZATION 0.6 +#define TIME_RAMP_VOLTAGE_CHARACTERIZATION 8 + +class Robot : public frc::TimedRobot +{ +public: + void RobotInit() override; + + void AutonomousInit() override; + void AutonomousPeriodic() override; + + void TeleopInit() override; + void TeleopPeriodic() override; + + void TestInit() override; + void TestPeriodic() override; + + void Drive(double forward, double turn); + +private: + NLPID m_pid; + NLPID_ERROR m_errorLeft; + NLPID_ERROR m_errorRight; + + Nf32 m_leftErrorVoltage; + Nf32 m_rightErrorVoltage; + Nf32 m_refLeftS; + Nf32 m_refRightS; + Nf32 m_prevS; + Nf32 m_prevK; + Nf32 m_estimatedAngle; + Nf32 m_dsLeftWheel; + Nf32 m_dsRightWheel; + NLTRAJECTORY_STATE_S_PACK m_trajectoryStatesPack; + NLTRAJECTORY_STATE_S m_currrentSState; + NLMOTOR_CHARACTERIZATION m_motorCharacterization[4]; // droite: 0,1 gauche: 2,3 + + double m_targetLeftSpeed; + double m_targetRightSpeed; + VA m_va_left; + VA m_va_right; + VA m_va_max; + KineticToVoltage m_kv; + + CSVLogFile *m_LogFile, *m_LogFileDriving; + nt::GenericEntry *m_LogFileName, *m_PowerEntry, *m_logGyro, *m_LogFilenameDriving, *m_speedY, *m_speedX, *m_customEntry; + + ctre::phoenix::motorcontrol::can::TalonFX m_moteurDroite{1}; + ctre::phoenix::motorcontrol::can::TalonFX m_moteurDroiteFollower{2}; + ctre::phoenix::motorcontrol::can::TalonFX m_moteurDroiteFollower2{3}; + ctre::phoenix::motorcontrol::can::TalonFX m_moteurGauche{4}; + ctre::phoenix::motorcontrol::can::TalonFX m_moteurGaucheFollower{5}; + ctre::phoenix::motorcontrol::can::TalonFX m_moteurGaucheFollower2{6}; + + frc::PowerDistribution m_pdp; + + frc::Encoder m_encodeurExterneDroite{2, 3, false, frc::Encoder::k4X}; + frc::Encoder m_encodeurExterneGauche{0, 1, true, frc::Encoder::k4X}; + +#if IMU + frc::ADIS16470_IMU m_imu{}; + frc::LinearFilter filterX = frc::LinearFilter::MovingAverage(64); + frc::LinearFilter filterY = frc::LinearFilter::MovingAverage(64); +#endif + + char m_invertedPrefix[8]; + + bool modeClimberJF = false; + bool doigtLeve; + bool shooterOn = false; + bool m_override = false; + bool m_isLogging = false; + bool m_isPathFollowing = false; + double m_ramp = 0; + double m_time0; + + int m_logState = 0; + char m_prefix[512]; + + double init_x; + double init_y; + + /*m_IsEnabledEntry = frc::Shuffleboard::GetTab("Shooter").Add("Is Shooter enabled", false).WithWidget(frc::BuiltInWidgets::kBooleanBox).GetEntry(); + m_PowerEntry = frc::Shuffleboard::GetTab("Shooter").Add("Power", 0.0).WithWidget(frc::BuiltInWidgets::kNumberSlider).GetEntry(); + m_LogEntry = frc::Shuffleboard::GetTab("Shooter").Add("Logging", false).WithWidget(frc::BuiltInWidgets::kToggleButton).GetEntry(); + m_LogFilename = frc::Shuffleboard::GetTab("Shooter").Add("Logfile Name", "").WithWidget(frc::BuiltInWidgets::kTextView).GetEntry(); + */ + + void LogData(); + double m_turnAdjustFactor = 1; + +#if XBOX_CONTROLLER + frc::XboxController m_driverController{0}; +#else + frc::Joystick m_leftHandController{0}; + frc::Joystick m_rightHandController{1}; +#endif + + NLCharacterization_Tests m_motorCharacterizationTests{ + &m_moteurGauche, + &m_moteurGaucheFollower, + &m_moteurGaucheFollower2, + &m_moteurDroite, + &m_moteurDroiteFollower, + &m_moteurDroiteFollower2, + &m_encodeurExterneGauche, + &m_encodeurExterneDroite, + TEST_LOWVOLTAGE_NB, + TEST_LOWVOLTAGE_MAX, + TEST_MEDIUMVOLTAGE_NB, + TEST_MEDIUMVOLTAGE_MAX, + TEST_HIGHVOLTAGE_NB, + TEST_HIGHVOLTAGE_MAX, + TIME_RAMP_CHARACTERIZATION, + TIME_RAMP_VOLTAGE_CHARACTERIZATION}; +}; \ No newline at end of file diff --git a/src/main/include/lib/CSVLogFile.h b/src/main/include/lib/CSVLogFile.h new file mode 100644 index 0000000..78b1444 --- /dev/null +++ b/src/main/include/lib/CSVLogFile.h @@ -0,0 +1,121 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2019 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +#pragma once + +#include +#include +#include +#include + +#include "lib/LogFile.h" + +/** + * A CSVLogFile writes values to a csv file + * + * For the CSVLogFile to write log informations, you must call Log() + * periodically. + */ +class CSVLogFile +{ +public: + /** + * Instantiate a LogFile passing in its prefix and its column headings. + * + * If you want the file to be saved in a existing directory, you can add + * its path before the file prefix. Exemple : to save the file in a usb stick + * on the roborio ("/media/sda1/") : LogFile("/media/sda1/log"). + * + * @param filePrefix The prefix of the LogFile. + * @param columnHeading Title of 1st CSVLogFile column. + * @param columnHeadings Titles of other CSVLogFile columns. + */ + template + CSVLogFile(std::string_view filePrefix, Value columnHeading, + Values... columnHeadings) + : m_logFile(filePrefix, "csv") + { + m_logFile << "\"Timestamp (ms)\","; + LogValues(columnHeading, columnHeadings...); + } + + /** + * Print a new line of values in the CSVLogFile. + * + * @param value 1st value to log in the file. + * @param values Other values to log in the file in the order. + */ + template + void Log(Value value, Values... values) + { + using namespace std::chrono; + auto timestamp = + duration_cast(system_clock::now().time_since_epoch()); + m_logFile << timestamp.count() << ','; + + LogValues(value, values...); + } + + /** + * Get the name the file. + * + * @return The name of the file. + */ + const std::string GetFileName() const { return m_logFile.GetFileName(); } + +private: + /** + * Print a new line of values in the CSVLogFile without timestamp. + * + * @param value 1st value to log in the file. + * @param values Other values to log in the file in the order. + */ + template + void LogValues(Value value, Values... values) + { + if constexpr (std::is_convertible_v) + { + m_logFile << '\"' << EscapeDoubleQuotes(value) << '\"'; + } + else + { + m_logFile << value; + } + + if constexpr (sizeof...(values) > 0) + { + m_logFile << ','; + LogValues(values...); + } + else + { + m_logFile << '\n'; + } + } + + /** + * Escape double quotes in a text by duplicating them. + * + * @param text Text to escape. + * @return The text with all its double quotes escaped. + */ + const std::string EscapeDoubleQuotes(std::string_view text) const + { + std::string textString = text.data(); + for (std::string::size_type i = 0; i < text.size(); i++) + { + if (text[i] == '\"') + { + i++; + textString.insert(i, "\""); + } + } + return textString; + } + + LogFile m_logFile; +}; diff --git a/src/main/include/lib/CustomMaths.h b/src/main/include/lib/CustomMaths.h new file mode 100644 index 0000000..4069886 --- /dev/null +++ b/src/main/include/lib/CustomMaths.h @@ -0,0 +1,3 @@ +#define NABS(a) (((a) < 0) ? -(a) : (a)) // VALEUR ABSOLUE +#define NMAX(a, b) (((a) > (b)) ? (a) : (b)) // Max +#define NMIN(a, b) (((a) < (b)) ? (a) : (b)) // Min diff --git a/src/main/include/lib/LogFile.h b/src/main/include/lib/LogFile.h new file mode 100644 index 0000000..7d68b97 --- /dev/null +++ b/src/main/include/lib/LogFile.h @@ -0,0 +1,93 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2019 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +#pragma once + +#include +#include +#include +#include + +// #include + +/** + * A LogFile writes text to log in a file. + */ +class LogFile +{ +public: + /** + * Instantiate a LogFile passing in its prefix and its extension. + * + * If you want the file to be saved in a existing directory, you can add + * its path before the file prefix. Exemple : to save the file in a usb stick + * on the roborio ("/media/sda1/") : LogFile("/media/sda1/log"). + * + * @param filePrefix The prefix of the LogFile. + * @param fileExtension The extension of the LogFile (without dot). + */ + explicit LogFile(std::string_view filePrefix = "log", + std::string_view fileExtension = "txt"); + + /** + * Write text in the LogFile. + * + * @param text The text to be logged in the file. + */ + void Log(const std::string_view &text); + + /** + * Write text in the LogFile and add a new line. + * + * @param text The text to be logged in the file. + */ + void Logln(const std::string_view &text); + + /** + * Get the name the file. + * + * @return The name of the file. + */ + const std::string GetFileName() const; + + /** + * Set the time interval after which the file will be renamed in seconds. + * + * @param seconds The time interval after which the file will be renamed in + * seconds. + */ + void SetTimeIntervalBeforeRenaming(units::second_t duration); + + template + friend LogFile &operator<<(LogFile &file, const Value &value) + { + file.m_file << value; + file.UpdateFilename(); + return file; + } + +private: + /** + * Check if the time has changed of more than 24 hours. Change the filename if + * the condition is met. + */ + void UpdateFilename(); + + /** + * Create a filename with a time. + * + * @param time The time that is saved in the filename. + * @return The filename at the format "{filePrefix}-{date/time}.txt". + */ + const std::string CreateFilename(std::time_t time) const; + + std::string m_filePrefix; + std::string m_fileExtension; + std::ofstream m_file; + std::time_t m_time; + units::second_t m_timeIntervalBeforeRenaming = 1_d; +}; diff --git a/src/main/include/lib/N/Containers/NArray.h b/src/main/include/lib/N/Containers/NArray.h new file mode 100644 index 0000000..58df2bb --- /dev/null +++ b/src/main/include/lib/N/Containers/NArray.h @@ -0,0 +1,118 @@ +#ifndef __NARRAY_H +#define __NARRAY_H + + +// *************************************************************************************** +// *************************************************************************************** +// ** ** +// ** NArray.h ** +// ** ** +// *************************************************************************************** +// *************************************************************************************** +//#include "../assert.h" +#include "lib/N/NCStandard.h" +#include "lib/N/NType.h" +#include "lib/N/NErrorHandling.h" + +#ifdef __cplusplus +extern "C" +{ +#endif +// -------------------------------------------------------------------------------------------------------------------------------------------------------------- + +// *************************************************************************************** +// ** Structures ** +// *************************************************************************************** +#define NARRAY_INCREASE_CAPACITY_RATIO 1.0f // new capacity = oldcapacity + oldcapacity * NARRAY_INCREASE_CAPACITY_RATIO + 1 + +// an Array of something +typedef struct +{ + NBYTE *pFirst; // Ptr on the Array (on the first element of...) + Nu32 Size; // current size of the Array ( = current number of elements in the Array ) + Nu32 Capacity; // Max possible size of the Array ( pre-allocated and bigger than Size ) + Nu32 ElementSize; // size of one element of the Array + + //void (*Destructor_CallBack)(NBYTE*pelement); +}NARRAY; + +// *************************************************************************************** +// ** Functions ** +// *************************************************************************************** +// a Callback function prototype used for operation on elements ( destruction, ... ) +//typedef void (*NARRAY_CALLBACK)(NBYTE*pelement); +typedef void (*NARRAY_ELEMENT_DESTRUCTOR_CALLBACK)(void*pelement)/*(NBYTE*pelement)*/; + +//inline void NArraySetDestructorCallBack(NARRAY* parray,NARRAY_CALLBACK destructor_callback){parray->Destructor_CallBack = destructor_callback;}; +NARRAY* NSetupArray(NARRAY *parray, const Nu32 capacity,const Nu32 element_size ); +NARRAY* NCreateArray(const Nu32 capacity,const Nu32 element_size); +void NClearArray(NARRAY* parray,const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback); +void NDeleteArray(NARRAY* parray,const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback); + +void NCopyArray(NARRAY*pdst,const NARRAY*psrc); +void NSwapArrayContent(NARRAY *parray1, NARRAY *parray2); + +void NEraseArray(NARRAY *parray,const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback); +Nbool NEraseArrayElement(NARRAY *parray,const Nu32 index,const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback); +Nbool NEraseArrayRange(NARRAY *parray,const Nu32 index,const Nu32 rangesize,const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback); + +void NEraseArrayElementPtr(NARRAY *parray,const NBYTE* ptr, const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback); +void NEraseArrayRangePtr(NARRAY *parray,const NBYTE *ptr ,const Nu32 rangesize,const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback); + +void NQuickEraseArrayElement(NARRAY *parray,const Nu32 index, const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback); +void NQuickEraseArrayElementPtr(NARRAY *parray,const NBYTE* ptr, const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback); + + +NBYTE* NInsertArrayElement(NARRAY *parray, const Nu32 refindex,const NBYTE* pelement); + +inline Nu32 NGetArrayCapacity(const NARRAY *parray){ return parray->Capacity;} +inline Nbool NIsValidArrayElementPtr(const NARRAY *parray,const NBYTE*ptr) +{ + if(ptrpFirst)return NFALSE; + if(!parray->Size)return NFALSE; + if(!parray->ElementSize)return NFALSE; + Nu32 id = (ptr-parray->pFirst)/parray->ElementSize; + if(id>(parray->Size-1))return NFALSE; + if(ptr != (parray->pFirst+id*parray->ElementSize))return NFALSE; + return NTRUE; +} + +inline Nbool NIsValidArrayElementIndex(const NARRAY *parray,const Nu32 id){if(idSize)return NTRUE;else return NFALSE;} +inline NBYTE* NGetFirstArrayPtr(const NARRAY *parray){return parray->pFirst;} +inline NBYTE* NGetLastArrayPtr(const NARRAY *parray){if(parray->Size)return parray->pFirst+(parray->Size-1)*parray->ElementSize;else return NULL;} +inline NBYTE* NGetArrayIndexPtr(const NARRAY *parray,const Nu32 index){ NErrorIf(index>=parray->Size,NERROR_ARRAY_INDEX_BEYOND_LIMITS);return parray->pFirst+index*parray->ElementSize; } +//inline Nu32 NGetArrayPtrIndex(const NARRAY *parray,NBYTE*ptr){Nu32 i; NBYTE*ptrb; ptrb = parray->pFirst; for(i=0;iSize;i++){if(ptrb==ptr){return i;}ptrb+=parray->ElementSize;} assert(iSize); return NVOID;} +inline Nu32 NGetArrayPtrIndex(const NARRAY *parray,const NBYTE*ptr){NErrorIf(!NIsValidArrayElementPtr(parray,ptr),NERROR_ARRAY_INDEX_BEYOND_LIMITS);return ( (ptr - parray->pFirst)/parray->ElementSize );} + + +inline Nu32 NGetArraySize(const NARRAY *parray){ return parray->Size; } +inline Nu32 NGetArrayElementSize(const NARRAY *parray){ return parray->ElementSize; } +Ns32 NDecreaseArrayCapacity(NARRAY *parray,const Nu32 sub_capacity, const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback ); +Ns32 NIncreaseArrayCapacity(NARRAY *parray,const Nu32 add_capacity); +Ns32 NOptimizeArrayCapacity(NARRAY *parray); +Ns32 NSetArrayCapacity(NARRAY *parray,const Nu32 new_capacity, const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback ); +Ns32 NResizeArray(NARRAY *parray, const Nu32 new_size, const NBYTE *pelement, const NARRAY_ELEMENT_DESTRUCTOR_CALLBACK destructor_callback ); +inline Ns32 NUpSizeArray(NARRAY *parray, Nu32 up_size, const NBYTE *pelement ){return NResizeArray( parray, (parray->Size + up_size), pelement, NULL );} +inline Nbool NIsArrayFull(const NARRAY *parray){if(parray->Capacity==parray->Size)return NTRUE;else return NFALSE;} +inline Nbool NIsArrayCleared(const NARRAY *parray){if( NGetArrayCapacity(parray)||NGetArraySize(parray)||NGetFirstArrayPtr(parray)||NGetArrayElementSize(parray) ){return NFALSE;}else{return NTRUE;}} + +void NArrayPopBack(NARRAY *parray, NBYTE*pelement); +NBYTE* NArrayPushBack(NARRAY*parray,const NBYTE* pelement); +NBYTE* NArrayAllocBack(NARRAY*parray); +#define NArrayAllocBack0(parray) memset(NArrayAllocBack(parray),0,(parray)->ElementSize) + +void NMoveArrayElementBack( NARRAY*parray,const Nu32 index ); + +typedef Ns32 (*NARRAY_QSORT_COMPARE)(const void *pa, const void *pb); // return values: papb return 1, pa==pb return 0 +void NQuickSortArray(NARRAY *parray, const NARRAY_QSORT_COMPARE compare); +void NQuickSortArrayEx(NARRAY *parray, const Nu32 first, const Nu32 last, const NARRAY_QSORT_COMPARE compare); +void NQuickSortArrayOfPtr(NARRAY *parray, const NARRAY_QSORT_COMPARE compare); +void NQuickSortArrayOfPtrEx(NARRAY *parray, const Nu32 first, const Nu32 last, const NARRAY_QSORT_COMPARE compare); + + +// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +#ifdef __cplusplus +} +#endif // __cpluplus +#endif // __NARRAY_H + diff --git a/src/main/include/lib/N/Core/NLimits.h b/src/main/include/lib/N/Core/NLimits.h new file mode 100644 index 0000000..d46c96f --- /dev/null +++ b/src/main/include/lib/N/Core/NLimits.h @@ -0,0 +1,49 @@ +#ifndef __NLIMITS_H +#define __NLIMITS_H + +#ifdef __cplusplus +extern "C" +{ +#endif +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// + GLOBAL LIMITS +// + +// + Minimum Positive Values +#define NU8_MIN (Nu8)0 +#define NU16_MIN (Nu16)0 +#define NU32_MIN (Nu32)0 +#define NU64_MIN (Nu64)0 + +#define NS8_MIN (Ns8)0 +#define NS16_MIN (Ns16)0 +#define NS32_MIN (Ns32)0 +#define NS64_MIN (Ns64)0 + +#define NF32_MIN 1.175494351e-38F +#define NF64_MIN 1.175494351e-38 +// + +// + Maximum Positive Values +// + +#define NU8_MAX (Nu8)255 +#define NU16_MAX (Nu16)65535 +#define NU32_MAX (Nu32)4294967295 +#define NU64_MAX (Nu64)18446744073709551615 + +#define NS8_MAX (Ns8)127 +#define NS16_MAX (Ns16)32767 +#define NS32_MAX (Ns32)2147483647 +#define NS64_MAX (Ns64)9223372036854775807 + +#define NF32_MAX 3.402823466e+38F +#define NF64_MAX 1.7976931348623158e+308 + +#define NF32_EPSILON 1.192092896e-07F // old used was ... 0.00001f // small Nf32 (=small float) +#define NF64_EPSILON 2.2204460492503131e-016 + + +// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +#ifdef __cplusplus +} +#endif // __cpluplus +#endif // __NLIMITS_H + diff --git a/src/main/include/lib/N/NCStandard.h b/src/main/include/lib/N/NCStandard.h new file mode 100644 index 0000000..64dd211 --- /dev/null +++ b/src/main/include/lib/N/NCStandard.h @@ -0,0 +1,53 @@ +//#ifndef __NCSTANDARD_H +//#define __NCSTANDARD_H +#pragma once + +#include "NCompilerPragma.h" + +//#ifdef _NWINDOWS +// standard libraries for WINDOWS + +//#include +//#include + +#include +#include +#include +#include +//#endif +/* +#ifdef _NIOS +// standard libraries for IOS +#include +#include +#include +#include +#include +#include +#endif + +#ifdef _NANDROID +// standard libraries for Android +#include +#include +#include +#include +#include +#include +#endif +*/ +#include "NMemory.h" + +/* +#ifdef __cplusplus +extern "C" +{ +#endif +// -------------------------------------------------------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +#ifdef __cplusplus +} +#endif // __cpluplus +*/ +//#endif // __NCSTANDARD_H + diff --git a/src/main/include/lib/N/NCompilerPragma.h b/src/main/include/lib/N/NCompilerPragma.h new file mode 100644 index 0000000..1a9e0d8 --- /dev/null +++ b/src/main/include/lib/N/NCompilerPragma.h @@ -0,0 +1,14 @@ +#ifndef __NCOMPILER_PRAGMA_H +#define __NCOMPILER_PRAGMA_H + + +//#ifdef _NWINDOWS +// Disable some compilation Warnings: + +//#pragma warning (disable : 4201) // union ... +//#pragma warning (disable : 4100) // unreferenced formal parameter + +//#endif + +#endif // __NCOMPILER_PRAGMA_H + diff --git a/src/main/include/lib/N/NErrorHandling.h b/src/main/include/lib/N/NErrorHandling.h new file mode 100644 index 0000000..b8a20ec --- /dev/null +++ b/src/main/include/lib/N/NErrorHandling.h @@ -0,0 +1,548 @@ +#ifndef __NERRORHANDLING_H +#define __NERRORHANDLING_H + +#include "NType.h" +#include + +#ifdef __cplusplus +extern "C" +{ +#endif +// -------------------------------------------------------------------------------------------------------------------------------------------------------------- + + // There are 2 ways to manage error in N. + // ----------------------------------------------------------------------------------------------------------- + // 1) NErrorIf() function. + // This function works like an Assert, but the program ends if the test is true ( opposite of assert ). + // This function is effective in debug mode only, and is totally ignored in release mode. + // Use NErrorIf() to check for errors that should never occur. + // +#ifdef _DEBUG +#define NErrorIf(tst,error_code) assert(!(tst)) +#endif + +#ifndef _DEBUG +#define NErrorIf(tst,error_code) +#endif + // 2) specific error code return by some functions. They are negative numbers or NULL pointer. + // Use/Check for errors that might occur. Notice that there are only a few number of function that return error code. + // Each case is unique and documented by function. + +// Error codes +// ----------- +#define NERROR_GENERIC -1 + +#define NERROR_SYSTEM_CLEARGRADIENT_COLOR_OUTOFRANGE -2 +#define NERROR_SYSTEM_CLEARGRADIENT_UNEXPECTED_ARRAY -3 + +#define NERROR_SYSTEM_NENGINEVERSION_CONFLICT -4 +#define NERROR_SYSTEM_INVALID_CONSTANT -5 +#define NERROR_SYSTEM_MEMORY_CORRUPTION -6 +#define NERROR_SYSTEM_DATASTRUCTURE_CORRUPTION -7 +#define NERROR_SYSTEM_GURU_MEDITATION -8 // Something bad happens due to a BIG mistake...for fun, AMIGA ... you remember ? +#define NERROR_SYSTEM_USELESS_CALL -9 // Engine specific, an useless function call happens ... check and optimize !!! +#define NERROR_SYSTEM_TODO -10 // Engine Specific. Temporary Error, something has to be finished ... +#define NERROR_SYSTEM_CHECK -11 // Engine Specific. Temporary Error, something has to be check ... (it's done, but N wants a human check on the case ... to validate the algorithm ) +#define NERROR_SYSTEM_RESERVED_VALUE -12 // User try to use a system reserved value to setup a variable or a structure member. + +// ----------------------------------------------------------------------------------------- +#define NERROR_NULL_MALLOC -20 +#define NERROR_NULL_REALLOC -21 +#define NERROR_NULL_POINTER -22 +#define NERROR_NULL_VALUE -23 // A no NULL value is requested, and its not the case. +#define NERROR_NULL_VECTOR -24 +#define NERROR_NULL_SIZE -25 +#define NERROR_NON_NULL_POINTER -26 +#define NERROR_NON_NULL_VALUE -27 +#define NERROR_VALUE_CLOSE_TO_ZERO -28 +// ----------------------------------------------------------------------------------------- +#define NERROR_ADDRESS_OUTOFRANGE -50 +#define NERROR_VALUE_OUTOFRANGE -51 +#define NERROR_4BITS_VALUE_OUTOFRANGE -52 +#define NERROR_NU8_OUTOFRANGE -53 +#define NERROR_NS8_OUTOFRANGE -54 +#define NERROR_NU16_OUTOFRANGE -55 +#define NERROR_NS32_OUTOFRANGE -56 +#define NERROR_ENUM_OUTOFRANGE -57 +#define NERROR_NU32_NEGATIVE_VALUE_OUTOFRANGE -58 // User try to assign a negative value to a Nu32 +// ----------------------------------------------------------------------------------------- +#define NERROR_STACK_OVERFLOW -75 +#define NERROR_MEMORY_UNEXPECTED_REALLOCATION_WILL_OCCUR -76 // a memory reallocation (by a array capacity increase for example) is going to happen and it's not suppose to be the case !!! +// ----------------------------------------------------------------------------------------- +#define NERROR_INVALID_DESCRIPTION -100 +#define NERROR_INVALID_PARAMETER -101 +#define NERROR_INVALID_RESULT -102 +#define NERROR_INVALID_CASE -103 // Case doesn't exist. +#define NERROR_INCONSISTENT_PARAMETERS -104 +#define NERROR_INCONSISTENT_VALUES -105 +#define NERROR_INCONSISTENT_FLAGS -106 +#define NERROR_INCONSISTENT_REQUEST -107 +#define NERROR_UNEXPECTED_RESULT -108 +// ----------------------------------------------------------------------------------------- +#define NERROR_UNAUTHORIZED_ACTION -200 +#define NERROR_UNAUTHORIZED_REQUEST -201 +#define NERROR_UNAUTHORIZED_VALUE -202 +#define NERROR_UNAUTHORIZED_CASE -203 // Case exist, but is not authorized here ! +#define NERROR_UNAUTHORIZED_FLAG -204 // Flag exist, but is not authorized here ! +// ----------------------------------------------------------------------------------------- +#define NERROR_ALREADY_DONE -250 +#define NERROR_IN_USE -251 +// ----------------------------------------------------------------------------------------- +//#define NERROR_BEYOND_TYPE_LIMITS -300 +//#define NERROR_BEYOND_Nbool_LIMITS -301 +//#define NERROR_BEYOND_Nu8_LIMITS -302 +//#define NERROR_BEYOND_Nchar_LIMITS -303 +//#define NERROR_BEYOND_Nu16_LIMITS -304 +//#define NERROR_BEYOND_Ns16_LIMITS -305 +// ----------------------------------------------------------------------------------------- +#define NERROR_NVOID_VALUE -400 // A no NVOID value is requested, and its not the case. +#define NERROR_ODD_NUMBER -401 // An Even number is requested, and it's not the case. +#define NERROR_WRONG_VALUE -402 // A value is not what is suppose to be +#define NERROR_VALUES_HAVE_TO_BE_DIFFERENT -403 +#define NERROR_INDEX_OUTOFRANGE -404 +#define NERROR_WRONG_SIZE -405 +// ----------------------------------------------------------------------------------------- +#define NERROR_WRONG_STRING -500 // A string of characters is not what is suppose to be +#define NERROR_STRING_TOO_LONG -501 // A string of characters is too long ! +#define NERROR_STRING_TOO_SHORT -502 // A string of characters is too short ! +#define NERROR_STRING_NULL -503 // A string of characters is requested and its not the case ! +#define NERROR_STRING_SIZEMAX_HAS_TO_BE_EQUAL_OR_GREATER_THAN_1 -504 + +// ----------------------------------------------------------------------------------------- +#define NERROR_MEMORY_CHECK_FAILED -600 +#define NERROR_CLEAR_NOT_ALLOWED_STILL_LINKED_DATA -601 + +// ----------------------------------------------------------------------------------------- +#define NERROR_TRY_TO_DELETE_REFERENCED_TRANSFORM_NODE -650 + +// ----------------------------------------------------------------------------------------- +#define NERROR_GAMESTATE_UNAUTHORIZED_STATE_USE -700 +#define NERROR_GAMESTATE_STATE_ALREADY_ACTIVE -701 +#define NERROR_GAMESTATE_USELESS_PARENT -702 +#define NERROR_GAMESTATE_MACHINE_ACTIVE -703 +#define NERROR_GAMESTATE_CYCLIC_HIERARCHY -704 +#define NERROR_GAMESTATE_INVALID_NON_ROOT_TOUCHCOUNTMAX -705 +#define NERROR_GAMESTATE_IS_NOT_ROOT -706 +#define NERROR_GAMESTATE_MACHINE_LISTENED_TOUCH_ARRAY_MUST_BE_EMPTY -707 +// ----------------------------------------------------------------------------------------- +#define NERROR_RINGBUFFER_OVERFLOW -725 +#define NERROR_RINGBUFFER_IS_EMPTY -726 +#define NERROR_RINGBUFFER_INDEX_OUTOFRANGE -727 +#define NERROR_RINGBUFFER_SIZE_OUTOFRANGE -728 + +// ----------------------------------------------------------------------------------------- +#define NERROR_ARRAY_UNCLEARED -800 +#define NERROR_ARRAY_INDEX_BEYOND_LIMITS -801 +#define NERROR_ARRAY_WRONG_SIZE -802 +#define NERROR_ARRAY_WRONG_CAPACITY -803 +#define NERROR_ARRAY_NOT_EMPTY -804 +#define NERROR_ARRAY_ATTEMPT_TO_CLEAR_USED_ELEMENT -805 +#define NERROR_ARRAY_ELEMENT_NOT_FOUND -806 +#define NERROR_ARRAY_ELEMENT_ALREADY_EXIST -807 +#define NERROR_ARRAY_ADRESS_BEYOND_LIMITS -808 +#define NERROR_ARRAY_WRONG_ELEMENT_SIZE -809 +#define NERROR_ARRAY_REALLOCATION_FAILURE -810 +#define NERROR_ARRAY_PTR_BEYOND_LIMITS -811 +#define NERROR_ARRAY_CORRUPTED -812 +#define NERROR_ARRAY_CORRUPTED_PTR -813 +#define NERROR_ARRAY_IS_EMPTY -814 +#define NERROR_ARRAY_NULL_ADDRESS -815 +// ----------------------------------------------------------------------------------------- +#define NERROR_HASHMAP_WRONG_BUCKETCOUNT -825 +#define NERROR_HASHMAP_INVALID_KEY -826 +#define NERROR_HASHMAP_INDEX_BEYOND_LIMITS -827 + +// ----------------------------------------------------------------------------------------- +#define NERROR_NXNODELIST_NOT_EMPTY -850 +// ----------------------------------------------------------------------------------------- +#define NERROR_NNODE_INVALID_INDEX -900 +#define NERROR_NNODE_INVALID_NODE -901 +#define NERROR_NNODE_ORPHAN -902 +#define NERROR_NNODELIST_NOT_EMPTY -903 +#define NERROR_NODE_IS_NOT_ORPHAN -904 +#define NERROR_NODE_IS_ORPHAN -905 +#define NERROR_NODE_POINTER_INCONSISTENCY -906 + +// ----------------------------------------------------------------------------------------- +#define NERROR_NHIERARCHY_NODE_INVALID_HIERARCHY -950 +// ----------------------------------------------------------------------------------------- +#define NERROR_POOL_ENABLE_XNODELIST_MISSING -1001 +#define NERROR_POOL_UNAUTHORIZED_CLEAR_REQUEST -1002 +#define NERROR_POOLTAG_MISSING -1003 +#define NERROR_POOLTAG_LIST_HAS_TO_BE_EMPTY -1004 +// ----------------------------------------------------------------------------------------- +#define NERROR_PHYSICSTRUCTURE_CLEARREQUEST_UNAUTHORIZED_WITH_EXISTING_COLLISION_REF -1100 +#define NERROR_PHYSICSTRUCTURE_INVALID_NUMBER_OF_CONSTRAINTS -1101 +#define NERROR_PHYSICSTRUCTURE_INVALID_NUMBER_OF_JOINTS -1102 + +#define NERROR_STRUCTURE_SKIN_VALID_GEOMETRY_REQUESTED -1150 +#define NERROR_STRUCTURE_SKIN_VALID_RENDERABLE_REQUESTED -1151 +#define NERROR_STRUCTURE_SKIN_UNKNOWN_GEOMETRY -1152 +#define NERROR_STRUCTURE_SKIN_UNAUTHORIZED_STRUCTURE_ELEMENT_TYPE -1153 +#define NERROR_STRUCTURE_SKIN_NOT_ENOUGH_REF_ELEMENT_TO_BUILD_REQUESTED_SKIN -1154 +#define NERROR_STRUCTURE_SKIN_UNEXPECTED_VALUE -1155 + +// ----------------------------------------------------------------------------------------- +#define NERROR_RENDERABLE_GEOMETRY_ARRAY_SETUP_FAILED -1200 +#define NERROR_RENDERABLE_UPDATE_FCT_INVALID -1201 +#define NERROR_RENDERABLE_UPDATE_FCT_ID_INVALID -1202 +#define NERROR_RENDERABLE_UPDATE_FCT_ALREADY_EXISTS -1203 +#define NERROR_RENDERABLE_UPDATE_FCT_LUT_CORRUPTED -1204 +#define NERROR_RENDERABLE_EXTRACT_FCT_INVALID -1205 +#define NERROR_RENDERABLE_EXTRACT_FCT_ID_INVALID -1206 +#define NERROR_RENDERABLE_EXTRACT_FCT_ALREADY_EXISTS -1207 +#define NERROR_RENDERABLE_EXTRACT_FCT_LUT_CORRUPTED -1208 + +#define NERROR_RENDERABLE_EXTRACTSET_INVALID -1209 +#define NERROR_RENDERABLE_EXTRACTSET_ALREADY_EXISTS -1210 +#define NERROR_RENDERABLE_EXTRACTSET_UNAUTHORIZED_FLAGS_USING -1211 +// ----------------------------------------------------------------------------------------- +#define NERROR_TEXT_FONT_MISSING -1300 + +// ----------------------------------------------------------------------------------------- +#define NERROR_SPLINE_NOT_ENOUGH_SPLINEKNOTS -1400 +#define NERROR_SPLINE_WRONG_ACCURACY -1401 +#define NERROR_SPLINE_INVALID_SPLINEKNOT -1402 +// + --------------------------------------------------------------------------------------- +// + EVENT +//#define NERROR_EVENT_IS_NOT_AUTHORIZED_TO_BE_QUEUED -1450 +//#define NERROR_EVENT_PRIVATE_EVENT_CAN_NOT_BE_PUBLIC -1451 +// #define NERROR_EVENT_IS_NOT_UI -1452 +// #define NERROR_EVENT_IS_NOT_GS -1453 +#define NERROR_EVENT_HAS_NOT_RECIPIENT -1454 +#define NERROR_EVENT_INCONSISTENT_RECIPIENT -1455 +#define NERROR_EVENT_INCONSISTENT_TYPE -1456 +#define NERROR_EVENT_TOUCH_CANCEL_MUST_BE_DISPATCHED -1457 +#define NERROR_EVENT_DISPATCH_UNAUTHORIZED -1458 +#define NERROR_EVENT_UNAUTHORIZED_MAIN_TYPE -1459 +#define NERROR_EVENT_UI_RECIPIENT_MUST_BE_ACTIVE -1460 +// + --------------------------------------------------------------------------------------- +// + UI +#define NERROR_UI_STYLE_MISSING -1500 +#define NERROR_UI_FRAME_CLEAR_PROC_MISSING -1501 +#define NERROR_UI_QUAD_FRAME_BACKGROUND_IS_NECESSARY -1502 // a UI needs to have a Simple Quad mesh as background, and doesn't have... +#define NERROR_UI_QUAD_FRAME_ICON_IS_NECESSARY -1503 +#define NERROR_UI_FRAME_CUSTOM_PICKING_GEOMETRYMESH_TRIANGLE_ONLY -1504 // a UI picking mesh has to use triangle as geometry primitives ! + +#define NERROR_UI_OVERLOADED_GEOMETRY_CAPACITY -1505 +#define NERROR_UI_OVERSIZED_GEOMETRY_CAPACITY -1506 +#define NERROR_UI_ATLAS_ELEMENT_MISSING -1507 +#define NERROR_UI_SHOULD_BE_ACTIVE_UIROOT -1508 +#define NERROR_UI_CYCLIC_HIERARCHY -1509 +#define NERROR_UI_ATTEMPT_TOMODIFY_ACTIVE_FRAME_HIERARCHY -1510 +#define NERROR_UIGEOMETRYDESC_TEXTURE_REQUESTED -1511 +#define NERROR_UIGEOMETRYDESC_CUSTOM_GEOMETRY_REQUESTED -1512 +#define NERROR_UI_PLACEMENTDESC_HAS_TO_BE_FULLY_DEFINED -1513 +#define NERROR_UI_ROOTFRAME_REQUESTED -1514 +#define NERROR_UI_UNAUTHORIZED_NUIRESULT -1515 +#define NERROR_UI_ROOT_SHOULD_HAVE_CHILD_WITH_FOCUS -1516 +#define NERROR_UIGEOMETRYDESC_SIZE_REQUESTED -1517 +#define NERROR_UI_FRAME_CUSTOM_PICKING_GEOMETRYMESH_REQUESTED -1518 +#define NERROR_UI_FRAME_BACKGROUND_GEOMETRY_REQUESTED -1519 +#define NERROR_UI_FRAME_ICON_GEOMETRY_REQUESTED -1520 +#define NERROR_UI_FRAME_NAME_TOO_LONG -1521 +#define NERROR_UI_FRAME_NAME_MISSING -1522 +#define NERROR_UI_WRONG_TRANSFORMED_VERTEX_ARRAY_SIZE -1523 +#define NERROR_UI_FRAME_WRONG_TEXT_UPDATE_AND_EXTRACT_FCT -1524 +#define NERROR_UI_FRAME_TEXT_DISPLAY_DEVICE_MISSING -1525 +#define NERROR_UI_UNKNOWN_SLIDINGLAYER_CONSTRAINT_CONTEXT -1526 +#define NERROR_UI_TEXCOORD_CONTEXT_HAS_TO_BE_FULLY_DEFINED -1527 +#define NERROR_UI_NAME_IS_LOCKED -1528 +#define NERROR_UI_SHOULD_BE_UIROOT -1529 +#define NERROR_UI_SHOULD_BE_UNACTIVE -1530 +#define NERROR_UI_IS_UNDER_CLEAR_PROCESS -1531 + +#define NERROR_UI_TOUCH_KILL_EVENT_IGNORED -1532 +#define NERROR_UI_HIDE_EVENT_IGNORED -1533 +#define NERROR_UI_SHOW_EVENT_IGNORED -1534 +#define NERROR_UI_DISABLE_EVENT_IGNORED -1535 +#define NERROR_UI_ENABLE_EVENT_IGNORED -1536 +#define NERROR_UI_NESTED_CLEAR -1537 +#define NERROR_UI_NESTED_DELETE -1538 +#define NERROR_UI_NESTED_ENABLE -1539 +#define NERROR_UI_NESTED_DISABLE -1540 +#define NERROR_UI_NESTED_SHOW -1541 +#define NERROR_UI_NESTED_HIDE -1542 +#define NERROR_UI_ENABLE_UI_PARENT_MUST_BE_ENABLE -1543 +#define NERROR_UI_PARENT_OF_VISIBLE_UI_MUST_BE_VISIBLE -1544 +#define NERROR_UI_SHOWED_MUST_HAVE_HIDDEN_RENDER_UPDATE_FCT -1545 +#define NERROR_UI_SETUPPROCESS_STACK_CORRUPTED -1546 +#define NERROR_UI_COLOR_UPDATE_IS_OFF -1547 +#define NERROR_UI_UNAUTHORIZED_TOUCHCOUNTMAX -1548 +#define NERROR_UI_INCOMPATIBLE_STATES -1549 +// + --------------------------------------------------------------------------------------- +// + NTIMER +#define NERROR_TIMER_WRONG_ID -1580 +#define NERROR_TIMER_UNKNOWN_ID -1581 +// + --------------------------------------------------------------------------------------- +// + FILE +#define NERROR_FILE_FSEEK_ERROR -1600 +#define NERROR_FILE_ELEMENT_SIZE_IS_NULL -1601 +#define NERROR_FILE_ELEMENT_COUNT_IS_NULL -1602 +#define NERROR_FILE_READ_ERROR -1603 +#define NERROR_FILE_WRITE_ERROR -1604 +#define NERROR_FILE_OPENING_ERROR -1605 +#define NERROR_FILE_UNKNOWN_SIGNATURE -1606 +#define NERROR_FILE_UNKNOWN_VERSIONTAG -1607 +#define NERROR_FILE_UNEXPECTED_READ_VALUE -1608 +#define NERROR_FILE_INCONSISTENT_FLAGS -1609 +#define NERROR_FILE_INVALID_EXTENSION -1610 +#define NERROR_FILE_INCONSISTENT_FILENAME -1611 +#define NERROR_FILE_FILENAME_MUST_BE_ROOT_RELATIVE -1612 +#define NERROR_FILE_FILENAME_MUST_BE_ABSOLUT -1613 +#define NERROR_UNAUTHORIZED_DRIVE_ROOT_FILENAME -1614 +#define NERROR_FILESYSTEM_UNDEFINED_PATH_MODE -1615 +#define NERROR_FILE_ALREADY_DETECTED_ERROR -1616 +// ----------------------------------------------------------------------------------------- +#define NERROR_TOUCH_ALREADY_LISTEN -1650 +#define NERROR_TOUCH_INCONSISTENT_PHASE -1651 +#define NERROR_TOUCH_LISTENER_HAS_TO_BE_CLEAN_UP -1652 +#define NERROR_TOUCH_LISTENER_IS_ALREADY_CLEAN -1653 +#define NERROR_TOUCH_LISTENER_HAS_TO_BE_NULL -1654 + +#define NERROR_TOUCH_EMUL_HAS_TO_BE_UNUSED -1655 +// ----------------------------------------------------------------------------------------- +#define NERROR_CLEAR_SURFACE_NULL -1700 + +// ----------------------------------------------------------------------------------------- +#define NERROR_ACCUMULATOR_MULTIPLE_RESULTS -1801 +#define NERROR_ACCUMULATOR_INVALID -1803 +#define NERROR_ACCUMULATOR_NOT_FOUND -1804 +#define NERROR_ACCUMULATOR_INCONSISTENCY -1805 +#define NERROR_STATESET_UNAUTHORIZED_FLAGS_USING -1806 +// + --------------------------------------------------------------------------------------- +// + GEOMETRY +#define NERROR_GEOMETRY_WRONG_PRIMITIVE_ARRAY_SIZE -1900 +#define NERROR_GEOMETRY_TOTAL_CLONES_NUMBER_HAS_TO_BE_GREATER_THAN_ONE -1901 +#define NERROR_GEOMETRY_NOT_ENOUGH_PRIMITIVE -1902 +#define NERROR_GEOMETRY_WRONG_COLOR_ARRAY_SIZE -1903 +#define NERROR_GEOMETRY_WRONG_UVUNIT_NUMBER -1904 +#define NERROR_GEOMETRY_OUTOFRANGE_UVSETID -1905 +#define NERROR_GEOMETRY_MISSING_UVSET -1906 +#define NERROR_GEOMETRY_MISSING_TEXTURE -1907 +#define NERROR_GEOMETRY_UNKNOWN_ID -1908 +#define NERROR_GEOMETRY_NOT_ENOUGH_UVSET -1909 +#define NERROR_GEOMETRY_DESCRIPTION_FLAGS_NOT_SUPPORTED -1910 +#define NERROR_GEOMETRY_WRONG_TEXTURE_NUMBER -1911 +#define NERROR_GEOMETRY_NOT_ENOUGH_TEXUNIT -1912 +#define NERROR_GEOMETRY_INCONSISTENT_PARAMETER -1913 +//#define NERROR_GEOMETRY_NOT_ENOUGH_TRIANGLE -903 +//#define NERROR_GEOMETRY_NOT_ENOUGH_QUAD -904 +#define NERROR_GEOMETRY_NOT_ENOUGH_VERTEX -1914 +#define NERROR_GEOMETRY_UNKNOWN_RENDER_FUNCTION -1915 +//#define NERROR_GEOMETRY_NOT_ENOUGH_UV -906 +//#define NERROR_GEOMETRY_NOT_ENOUGH_COLOR -907 +#define NERROR_GEOMETRY_OUTOFRANGE_TEXUNIT -1916 +#define NERROR_GEOMETRY_INCOMPATIBLE_TYPE -1917 +#define NERROR_GEOMETRY_NOT_UNLINKED -1918 +#define NERROR_GEOMETRY_WRONG_LINKCOUNT -1919 +#define NERROR_GEOMETRY_VERTEX_UVS_SIZE_INCONSISTENCY -1920 +#define NERROR_GEOMETRY_STRUCTURE_CORRUPTED -1921 +#define NERROR_GEOMETRY_COMPONENT_NOT_INCLUDED -1922 +#define NERROR_GEOMETRY_NULL_UVSETSIZE -1923 +#define NERROR_GEOMETRY_NO_UVSET -1924 +#define NERROR_GEOMETRY_NO_TEXTUREUNIT -1925 +#define NERROR_GEOMETRY_VERTEX_UVS_CAPACITY_INCONSISTENCY -1926 +#define NERROR_GEOMETRY_LINKCOUNT_OVERLOADED -1927 +#define NERROR_GEOMETRY_WRONG_VERTEX_FORMAT -1928 +#define NERROR_GEOMETRY_MAPS_NEEDS_ONE_TEXTUREUNIT_AT_LEAST -1929 +#define NERROR_GEOMETRY_MAPS_ALREADY_CLEARED -1930 +#define NERROR_GEOMETRY_TEXTUREUNIT_OUTOFRANGE -1931 +#define NERROR_GEOMETRY_OUTOFRANGE_RENDERFCTID -1932 +#define NERROR_GEOMETRY_WRONG_VERTEX_STRUCTURESIZE -1933 +#define NERROR_GEOMETRY_WRONG_PRIMITIVE_STRUCTURESIZE -1934 + +#define NERROR_GEOMETRY_UNSUPPORTED_GEOMETRY_FORMAT -1935 +#define NERROR_GEOMETRY_UNSUPPORTED_PRIMITIVE_FORMAT -1936 +#define NERROR_GEOMETRY_UNSUPPORTED_VERTEX_FORMAT -1937 +#define NERROR_GEOMETRY_UNSUPPORTED_APPEARANCE_FORMAT -1938 +#define NERROR_GEOMETRY_UNSUPPORTED_TEXTUREUNIT_FORMAT -1939 +#define NERROR_GEOMETRY_UNSUPPORTED_TEXTUREUNIT_NUMBER -1940 +#define NERROR_GEOMETRY_UNSUPPORTED_BLEND_FORMAT -1941 +#define NERROR_GEOMETRY_UNSUPPORTED_MATERIAL_FORMAT -1942 + +#define NERROR_GEOMETRY_APPEARANCE_INCOMPATIBLE_TYPE -1943 +#define NERROR_GEOMETRY_TEXTUREUNIT_INCOMPATIBLE_TYPE -1944 +#define NERROR_GEOMETRY_UNSUPPORTED_MESH_DESCRIPTION -1945 +#define NERROR_GEOMETRY_UNSUPPORTED_APPEARANCE_DESCRIPTION -1946 +#define NERROR_GEOMETRY_DESCRIPTION_STRUCTURE_INCONSISTENCY -1947 +#define NERROR_GEOMETRY_INCONSISTENT_VERTEX_STRIDES -1948 +#define NERROR_GEOMETRY_UNEXPECTED_VERTEX_FORMAT -1949 +#define NERROR_GEOMETRY_UNEXPECTED_PRIMITIVE_FORMAT -1940 +#define NERROR_GEOMETRY_UNEXPECTED_APPEARANCE_FORMAT -1951 +#define NERROR_GEOMETRY_UNEXPECTED_TEXTUREUNIT_FORMAT -1952 +#define NERROR_GEOMETRY_UNEXPECTED_TEXTUREUNIT_NUMBER -1953 +#define NERROR_GEOMETRY_UNEXPECTED_VERTEX_DATA -1954 +#define NERROR_GEOMETRY_UNEXPECTED_TEXTURE -1955 +#define NERROR_GEOMETRY_APPEARANCE_NOT_INCLUDED -1956 +#define NERROR_GEOMETRY_MATERIAL_NOT_SUPPORTED -1957 +#define NERROR_GEOMETRY_BLENDPARAMS_NOT_SUPPORTED -1958 +#define NERROR_GEOMETRY_TEXTURE_NOT_SUPPORTED -1959 +#define NERROR_GEOMETRY_OUTOFRANGE_VERTEXID -1960 +#define NERROR_GEOMETRY_OUTOFRANGE_PRIMITIVEID -1961 +#define NERROR_GEOMETRY_TEXCOORD0_2f_NOT_SUPPORTED -1962 +#define NERROR_GEOMETRY_TEXCOORD1_2f_NOT_SUPPORTED -1963 +#define NERROR_GEOMETRY_COLOR0_4f_NOT_SUPPORTED -1964 +#define NERROR_GEOMETRY_COLOR1_4f_NOT_SUPPORTED -1965 +#define NERROR_GEOMETRY_UNEXPECTED_VERTEX_STRUCTURE_SIZE -1966 +#define NERROR_GEOMETRY_UNEXPECTED_PRIMITIVE_STRUCTURE_SIZE -1967 + +#define NERROR_PRIMITIVE_DEGENERATED_TRIANGLE -1990 +#define NERROR_PRIMITIVE_INCONSISTENT_WINDING_ORDER -1991 +// + --------------------------------------------------------------------------------------- +// + MATHS +#define NERROR_DIVIDE_BY_ZERO -2000 + + +#define NERROR_MATRIX_NULL_W -2050 +#define NERROR_MATRIX_NULL_Z -2051 +#define NERROR_MATRIX_IN_OUT_MATRIX_POINTERS_HAS_TO_BE_DIFFERENT -2052 +#define NERROR_MATRIX_IN_OUT_VECTOR4_POINTERS_HAS_TO_BE_DIFFERENT -2053 +#define NERROR_MATRIX_IN_OUT_VECTOR3_POINTERS_HAS_TO_BE_DIFFERENT -2054 +#define NERROR_MATRIX_IN_OUT_VECTOR2_POINTERS_HAS_TO_BE_DIFFERENT -2055 + +// + --------------------------------------------------------------------------------------- +// + IMAGE +#define NERROR_IMAGE_INVALID_IMAGEID -2100 +#define NERROR_IMAGE_NULL_WIDTH -2101 +#define NERROR_IMAGE_NULL_HEIGHT -2102 +#define NERROR_IMAGE_NULL_BPP -2103 +#define NERROR_IMAGE_NULL_COLORMAP_DEPTH -2104 +#define NERROR_TGA_INCONSISTENT_COLORMAP_DEPTH -2105 +#define NERROR_IMAGE_INVALID_BPP -2106 +#define NERROR_IMAGE_INVALID_COLORMAP_SIZE -2107 +#define NERROR_IMAGE_INVALID_WIDTH -2108 +#define NERROR_IMAGE_INVALID_HEIGHT -2109 +#define NERROR_IMAGE_INVALID_CHANNEL -2110 +#define NERROR_IMAGE_SURFACE_ALREADY_ALLOCATED -2111 +#define NERROR_IMAGE_CONVERT_TARGETFORMAT_EQUAL_SOURCEFORMAT -2112 + +// + --------------------------------------------------------------------------------------- +// + TGA FILE +#define NERROR_TGA_UNKNOWN_TYPE -2200 +#define NERROR_TGA_UNKNOWN_BPP -2201 +#define NERROR_TGA_UNKNOWN_COLORMAP_DEPTH -2202 +#define NERROR_TGA_COLORMAP_MISSING -2203 +#define NERROR_TGA_IMAGEDATA_MISSING -2204 +#define NERROR_TGA_COLORMAP_SIZE_OUTOFRANGE -2205 +#define NERROR_TGA_COLORMAP_SIZE_NULL -2206 +#define NERROR_TGA_COLORMAP_TYPE_SHOULD_HAVE_8BPP -2207 +#define NERROR_TGA_INCONSISTENT_TYPE_AND_BPP -2208 +#define NERROR_TGA_GRAYSCALE_SHOULDNT_HAVE_COLORMAP -2209 +#define NERROR_TGA_RGB16_SHOULDNT_HAVE_COLORMAP -2210 +#define NERROR_TGA_RGB24_SHOULDNT_HAVE_COLORMAP -2211 +#define NERROR_TGA_RGB32_SHOULDNT_HAVE_COLORMAP -2212 + +#define NERROR_TGA_COLORMAP_LENGTH_SHOULD_BE_NULL -2213 +#define NERROR_TGA_COLORMAP_DEPTH_SHOULD_BE_NULL -2214 +#define NERROR_TGA_TYPE0 -2215 +#define NERROR_TGA_LOADING_ERROR -2216 +// + --------------------------------------------------------------------------------------- +// + TEXTURE +#define NERROR_TEXTURE_UNSUPPORTED_IMAGEID -2300 +#define NERROR_TEXTURE_INVALID_LIST -2301 +#define NERROR_TEXTURE_BANK_TEXTURE_NAME_DOESNT_EXIST -2302 + +// + --------------------------------------------------------------------------------------- +// + ATLAS ELEMENT +#define NERROR_ATLAS_ELEMENT_NAME_DOESNT_EXIST -2350 + +// + --------------------------------------------------------------------------------------- +// + MATRIX +#define NERROR_MATRIX_INVALID_VALUE -2500 + +// + --------------------------------------------------------------------------------------- +// + FLAGs +#define NERROR_FLAG_INCONSISTENCY -2600 + +// + --------------------------------------------------------------------------------------- +// + MISC +#define NERROR_COLLINEAR_VECTORS -2700 +#define NERROR_NON_UNIT_VECTOR -2701 +#define NERROR_INVALID_EXTENT -2702 + +// + --------------------------------------------------------------------------------------- +// + MISC +#define NERROR_NLIBRARY_KEYNAME_AND_PATHFILESYSTEM_INCONSISTENCY -3000 +#define NERROR_NLIBRARY_NON_UNIQUE_ENTRY -3001 +#define NERROR_NUT_UIDESK_PANEL_IS_OPEN -3500 +#define NERROR_NUT_UIDESK_PANEL_IS_CLOSE -3501 +#define NERROR_NUT_UIDESK_PANEL_UI_MUST_HAVE_THE_SAME_THN_HIERARCHY -3502 +//#define NERROR_NUT_UIDESK_PANEL_REQUIRES_CONSISTENT_SIZE -3503 +#define NERROR_RECT_IS_OAARECT -3503 +#define NERROR_FASTRAND_SIZE_OUTOFRANGE -3504 +#define NERROR_BATCHLOAD_TEXTURES_SYNTAX_ERROR -3505 +#define NERROR_NUT_Nf32SET_BUILDER_ID_OUTOFRANGE -3508 +#define NERROR_NUT_Nf32SET_BUILDER_IS_NOT_COMPOSITE -3512 +#define NERROR_NUT_Nf32SET_BUILDER_IS_COMPOSITE -3513 + +#define NERROR_NUT_Nf32SET_SEQUENCE_STRIDE_OVERLAPING -3514 +#define NERROR_NUT_Nf32SET_BUILDER_OPERAND_OUTOFRANGE -3515 + +#define NERROR_NUT_Nf32SET_FILTER_IS_COMPOSITE -3516 +#define NERROR_NUT_Nf32SET_FILTER_IS_NOT_COMPOSITE -3517 +#define NERROR_NUT_Nf32SET_FILTER_ID_OUTOFRANGE -3518 +#define NERROR_NUT_Nf32SET_FILTER_REFERENCE_FOR_SPREADOUT_OUTOFRANGE -3519 + +#define NERROR_NUT_Nf32SET_PROCESS_ID_OUTOFRANGE -3520 +#define NERROR_NUT_Nf32SET_SEQUENCE_SIZE_TOO_SHORT -3521 + +// + --------------------------------------------------------------------------------------- +// + N AUDIO +#define NERROR_AUDIO_OPEN_DEVICE_FAIL -3700 +#define NERROR_AUDIO_CONTEXT_CREATION_FAIL -3701 +#define NERROR_AUDIO_CONTEXT_FAIL -3702 +#define NERROR_AUDIO_FILE_IS_NOT_A_RIFF_FILE -3703 +#define NERROR_AUDIO_RIFF_FILE_IS_NOT_A_WAVE -3704 +#define NERROR_AUDIO_RIFF_WAVE_FILE_UNEXPECTED_FORMAT -3705 +#define NERROR_AUDIO_RIFF_WAVE_FILE_CORRUPTED -3706 +#define NERROR_AUDIO_RIFF_WAVE_FILE_UNEXPECTED_DATA_ID -3707 +#define NERROR_AUDIO_RIFF_WAVE_FILE_UNEXPECTED_DATA_SIZE -3708 +#define NERROR_AUDIO_RIFF_WAVE_FILE_IS_NOT_PCM -3709 +#define NERROR_AUDIO_WAVE_UNEXPECTED_BPS -3710 +#define NERROR_AUDIO_WAVE_UNEXPECTED_CHANNEL_NUMBER -3711 +#define NERROR_AUDIOBUFFER_STILL_IN_USE -3712 +#define NERROR_AUDIOBUFFER_INVALID_NAME -3713 +#define NERROR_AUDIOBUFFER_INVALID_REQUESTED_BUFFER_NB -3714 +#define NERROR_AUDIOBUFFER_UNEXPECTED_CASE -3715 +#define NERROR_AUDIOSOURCE_NO_CONTEXT -3716 +#define NERROR_AUDIOSOURCE_OUT_OF_MEMORY -3717 +#define NERROR_AUDIOSOURCE_OUT_OF_RESOURCES -3718 +#define NERROR_AUDIOSOURCE_UNEXPECTED_CASE -3719 +#define NERROR_AUDIOSOURCE_INVALID_NAME -3720 +#define NERROR_AUDIO -3721 +// + --------------------------------------------------------------------------------------- +// + NUT LIBRARIES +#define NERROR_UNKNOWN_BLENDPRESET -4000 + +// + --------------------------------------------------------------------------------------- +// + Functions Specific +#define NERROR_NCOPYVERTEX_PREFER_USING_EQUALITY_INSTEAD -10000 // 'NCopyVertex' function tells an advice: prefer using 'Vertex_dst = Vertex_src', because the 2 have the same format + + +#define NERROR_XTRI_ALREADY_USED -20001 +#define NERROR_XTRI_NO_ADJACENT_XTRI -20002 +#define NERROR_XTRI_ALREADY_LOCKED -20003 +#define NERROR_XTRI_UNLOCKED -20004 + +#define NERROR_XQUAD_ALREADY_IN_AREA -20010 +#define NERROR_XQUAD_ALREADY_IN_RPOLY -20011 +#define NERROR_XQUAD_ALREADY_LOCKED -20012 +#define NERROR_XQUAD_UNLOCKED -20013 +#define NERROR_XQUAD_EDGE_IS_DIAGONAL -20014 +#define NERROR_XQUAD_NOT_IN_AREA -20015 +#define NERROR_XQUAD_NOT_IN_RPOLY -20016 +#define NERROR_XQUAD_GRIDCOORDS_NON_NULL -20017 +#define NERROR_XMESH_INCONSISTENCY -20018 +#define NERROR_XMESH_RPOLY_PROCESSING_QUEUE_NOT_EMPTY -20019 +#define NERROR_XMESH_RPOLY_PROCESSING_RPOLY_NOT_EMPTY -20020 +#define NERROR_XMESH_RPOLY_PROCESSING_RPOLY_EMPTY -20021 +#define NERROR_XMESH_XQUAD_ALREADY_INSERTED_IN -20022 +#define NERROR_XMESH_RPOLY_TEXCOORD_PROCESSING_INCONSISTENCY -20023 + +// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +#ifdef __cplusplus +} +#endif // __cpluplus +#endif // __NERRORHANDLING_H + diff --git a/src/main/include/lib/N/NFlags.h b/src/main/include/lib/N/NFlags.h new file mode 100644 index 0000000..151b1d1 --- /dev/null +++ b/src/main/include/lib/N/NFlags.h @@ -0,0 +1,100 @@ +#ifndef __NFLAGS_H +#define __NFLAGS_H + +#include "NType.h" + +#ifdef __cplusplus +extern "C" +{ +#endif +// -------------------------------------------------------------------------------------------------------------------------------------------------------------- +// BIT Manipulation +#define BITSET(val,bit_id) ((val) |= (1 << (bit_id))) +#define BITCLEAR(val,bit_id) ((val) &=~(1 << (bit_id))) +//#define BITGET(val,bit_id) ((val) & (1 << (bit_id))) +#define BITGET(val,bit_id) (((val) >> (bit_id)) & 1) // 0 or 1 + + + +#define BITTOGLE(val,bit_id) ((val) ^= (1 << (bit_id))) + +// BYTE BIT FIELD +// pbytefield is a valid pointer on Nu8 list. [ Nu8 *pbytefield = (Nu8*)Nmalloc(number_of_wishes_Nu8*sizeof(Nu8); ] +#define BYTEFIELD_SIZE(bit_nb) ( ((bit_nb)>>3) + 1 ) // Number of BYTE(Nu8) for a BITS FIELD with a bits number of "bit_nb" +#define BYTEFIELD_BITSET(pbytefield,bit_id) ( (pbytefield[(bit_id)>>3]) |= (1 << ((bit_id)&0x7)) ) +#define BYTEFIELD_BITCLEAR(pbytefield,bit_id) ( (pbytefield[(bit_id)>>3]) &=~ (1 << ((bit_id)&0x7)) ) +//#define BYTEFIELD_BITGET(pbytefield,bit_id) ( (pbytefield[(bit_id)>>3]) & (1 << ((bit_id)&0x7)) ) +#define BYTEFIELD_BITGET(pbytefield,bit_id) (( (pbytefield[(bit_id)>>3]) >> ((bit_id)&0x7)) & 1 ) // 0 or 1 +#define BYTEFIELD_BITTOGLE(pbytefield,bit_id) ( (pbytefield[(bit_id)>>3]) ^= (1 << ((bit_id)&0x7)) ) + +// Nu32 BIT FIELD +// pNu32field is a valid pointer on Nu32 list. [ Nu32 *pNu32field = (Nu32*)Nmalloc(number_of_wishes_Nu32*sizeof(Nu32); ] +#define Nu32FIELD_SIZE(bit_nb) ( ((bit_nb)>>5) + 1 ) // Number of Nu32 for a BITS FIELD with a bits number of "bit_nb" +#define Nu32FIELD_BITSET(pnu32field,bit_id) ( (pnu32field[(bit_id)>>5]) |= (1 << ((bit_id)&0x1F)) ) +#define Nu32FIELD_BITCLEAR(pnu32field,bit_id) ( (pnu32field[(bit_id)>>5]) &=~ (1 << ((bit_id)&0x1F)) ) +//#define Nu32FIELD_BITGET(pnu32field,bit_id) ( (pnu32field[(bit_id)>>5]) & (1 << ((bit_id)&0x1F)) ) +#define Nu32FIELD_BITGET(pnu32field,bit_id) ( ((pnu32field[(bit_id)>>5]) >> ((bit_id)&0x1F)) & 1 ) + +#define Nu32FIELD_BITTOGLE(pnu32field,bit_id) ( (pnu32field[(bit_id)>>5]) ^= (1 << ((bit_id)&0x1F)) ) + +// Flags Manipulation +#define FLAG_TOGGLE(val,flag) ((val) ^= (flag)) +#define FLAG_ON(val,flag) ((val) |= (flag)) +#define FLAG_OFF(val,flag) ((val) &= ~(flag)) +#define ISFLAG_ON(val,flag) ((val) & (flag)) // !! ZERO or NON ZERO value !!! BE AWARE THAT NON ZERO DOESN'T MEAN 1 !!! +#define ISFLAG_OFF(val,flag) (!((val) & (flag))) // !! ZERO or NON ZERO value !!! BE AWARE THAT NON ZERO DOESN'T MEAN 1 !!! +#define FLAGS_TEST(val,bmask,flags) (((val)&(bmask))==(flags)) // NFALSE or NTRUE +#define SET_FLAGS(val,bmask,flags) ((val)=(((val)&(~(bmask)))|(flags))) // RESET FLAGS BITS and Set them all like flags. +#define RESET_FLAGS(val,bmask) ((val)&=~(bmask))) // Set all FLAGS BITS to ZERO + +inline Nu32 NGetNu32SetBITCount(Nu32 val){Nu32 nb=0;for(Nu32 i=0;i<32;i++){if(BITGET(val,i))nb++;}return nb;} +inline Nu32 NGetNu16SetBITCount(Nu16 val){Nu32 nb=0;for(Nu32 i=0;i<16;i++){if(BITGET(val,i))nb++;}return nb;} +inline Nu32 NGetNu8SetBITCount(Nu8 val){Nu32 nb=0;for(Nu32 i=0;i<8;i++){if(BITGET(val,i))nb++;}return nb;} + +// |___________|.|___________|.|___________|.|___________|.|___________|.|___________|.|___________|.|___________| +// |31|30|29|28|.|27|26|25|24|.|23|22|21|20|.|19|18|17|16|.|15|14|13|12|.|11|10|09|08|.|07|06|05|04|.|03|02|01|00| +// --------------------------------------------------------------- ----------------------------------------------- +// | |.| | +// --------------------------------------------------------------- ----------------------------------------------- +// | | | | |.| | | | |.| | | | |.| | | | |.| | | | |.| | | | |.| | | | |.| | | | | +// |0 |0 |0 |0 |.|0 |0 |0 |0 |.|0 |0 |0 |0 |.|0 |0 |0 |0 |.|0 |0 |0 |0 |.|0 |0 |0 |0 |.|0 |0 |0 |0 |.|0 |0 |0 |0 | + +// BIT definitions +#define BIT_0 1 +#define BIT_1 2 +#define BIT_2 4 +#define BIT_3 8 +#define BIT_4 16 +#define BIT_5 32 +#define BIT_6 64 +#define BIT_7 128 +#define BIT_8 256 +#define BIT_9 512 +#define BIT_10 1024 +#define BIT_11 2048 +#define BIT_12 4096 +#define BIT_13 8192 +#define BIT_14 16384 +#define BIT_15 32768 +#define BIT_16 65536 +#define BIT_17 131072 +#define BIT_18 262144 +#define BIT_19 524288 +#define BIT_20 1048576 +#define BIT_21 2097152 +#define BIT_22 4194304 +#define BIT_23 8388608 +#define BIT_24 16777216 +#define BIT_25 33554432 +#define BIT_26 67108864 +#define BIT_27 134217728 +#define BIT_28 268435456 +#define BIT_29 536870912 +#define BIT_30 1073741824 +#define BIT_31 2147483648 +// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +#ifdef __cplusplus +} +#endif // __cpluplus +#endif // __N_H + diff --git a/src/main/include/lib/N/NMath.h b/src/main/include/lib/N/NMath.h new file mode 100644 index 0000000..b7f359f --- /dev/null +++ b/src/main/include/lib/N/NMath.h @@ -0,0 +1,195 @@ +#ifndef __NMATH_H +#define __NMATH_H + + +#include +#include "NType.h" + +#ifdef __cplusplus +extern "C" +{ +#endif +// -------------------------------------------------------------------------------------------------------------------------------------------------------------- + +// *************************************************************************************** +// *************************************************************************************** +// ** ** +// ** NMath.h ** +// ** ** +// *************************************************************************************** +// *************************************************************************************** + +// *************************************************************************************** +// ** Structures & Defines ** +// *************************************************************************************** + // Init Math LUTs +#define RANDLUT_SIZE 16384 // Number of pre-calculated Rand float number stored in the RandLUT + // !! power of two !! +#define NANGLELUT_SIZE 4096 // for 360.00�, so with around 0.09 precision. + // !! power of two !! +#define NANGLE0 0 +#define NANGLE5 (NANGLELUT_SIZE / 72) +#define NANGLE10 (NANGLELUT_SIZE / 36) +#define NANGLE15 (NANGLELUT_SIZE / 24) +#define NANGLE20 (NANGLELUT_SIZE / 18) +#define NANGLE30 (NANGLELUT_SIZE / 12) +#define NANGLE36 (NANGLELUT_SIZE / 10) +#define NANGLE45 (NANGLELUT_SIZE / 8) +#define NANGLE60 (NANGLELUT_SIZE / 6) +#define NANGLE72 (NANGLELUT_SIZE / 5) +#define NANGLE90 (NANGLELUT_SIZE / 4) // 1024 +#define NANGLE120 (NANGLELUT_SIZE / 3) +#define NANGLE180 (NANGLELUT_SIZE / 2) // 2048 +#define NANGLE225 ( (Nu32)( (Nf32)NANGLELUT_SIZE*(5.0f/8.0f) ) ) +#define NANGLE270 (NANGLELUT_SIZE - NANGLE90) +#define NANGLE315 (NANGLELUT_SIZE - NANGLE45) +#define NANGLE360 NANGLELUT_SIZE + +#define NANGLEMAX (NANGLELUT_SIZE - 1) // represents the last available index into the ANGLE LUT + +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// + USEFUL MATHEMATICAL CONSTANTS +// + +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// + NF32 +// + +// +--+ PI +#define NF32_PI 3.1415927f // PI +#define NF32_2PI 6.2831853f // 2*PI +#define NF32_PI_2 1.5707963f // PI/2 +#define NF32_PI_3 1.0471976f // PI/3 +#define NF32_PI_4 0.7853982f // PI/4 +#define NF32_1_PI 0.3183099f // 1/PI +#define NF32_1_2PI 0.1591549f // 1/(2*PI) +#define NF32_2_PI 0.6366198f // 2/PI +#define NF32_1_SQRTPI 0.5641896f // 1/sqrt(PI) +#define NF32_2_SQRTPI 1.1283792f // 2/sqrt(PI) +// + +// +--+ SQRT(2) +// + +#define NF32_SQRT2 1.4142136f // Sqrt(2) +#define NF32_1_SQRT2 0.7071068f // 1/Sqrt(2) +#define NF32_SQRT2_2 0.7071068f // Sqrt(2)/2 + +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// + NF64 +// + +// +--+ PI +#define NF64_PI 3.14159265358979323846 // PI +#define NF64_2PI 6.28318530717958647693 // 2*PI +#define NF64_PI_2 1.57079632679489661923 // PI/2 +#define NF64_PI_3 1.04719755119659774615 // PI/3 +#define NF64_PI_4 0.78539816339744830962 // PI/4 +#define NF64_1_PI 0.31830988618379067154 // 1/PI +#define NF64_1_2PI 0.15915494309189533577 // 1/(2*PI) +#define NF64_2_PI 0.63661977236758134308 // 2/PI +#define NF64_1_SQRTPI 0.56418958354775628695 // 1/sqrt(PI) +#define NF64_2_SQRTPI 1.12837916709551257390 // 2/sqrt(PI) +// + +// +--+ SQRT(2) +// + +#define NF64_SQRT2 1.41421356237309504880 // Sqrt(2) +#define NF64_1_SQRT2 0.70710678118654752440 // 1/Sqrt(2) +#define NF64_SQRT2_2 0.70710678118654752440 // Sqrt(2)/2 + +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// + Quick MACROS functions +#define NDEGtoRAD(deg) ((NF32_PI / 180.0f) * (deg)) // Deg -> Radian +#define NRADtoDEG(rad) ((180.0f / NF32_PI) * (rad)) // Radian -> Deg +#define NDEGtoANGLE(deg) ( (Nu32)( (deg)*( (Nf32)NANGLELUT_SIZE / 360.0f ) ) ) +#define NRADtoANGLE(rad) ( (Nu32)( (rad)*( (Nf32)NANGLELUT_SIZE /NF32_2PI ) ) ) +#define NANGLEtoDEG(ang) ( ( (Nf32)(ang)*360.0f )/ (Nf32)NANGLELUT_SIZE ) +#define NANGLEtoRAD(ang) ( ( (Nf32)(ang)*NF32_2PI )/ (Nf32)NANGLELUT_SIZE ) + +#define NPOW2(a) ((a)*(a)) // a^2 +#define NPOW3(a) ((a)*(a)*(a)) // a^3 +#define NPOW4(a) ((a)*(a)*(a)*(a)) // a^4 + +#define NABS(a) (((a) < 0) ? -(a) : (a)) // Absolute value +#define NMAX(a,b) (((a) > (b)) ? (a) : (b)) // Maximum between 2 values +#define NMIN(a,b) (((a) < (b)) ? (a) : (b)) // Minimum between 2 values +//#define NCLAMP(_min,_val,_max) ( NMIN( NMAX(_min,_val),_max ) ) // Clamp a value against min,max values +#define NROUND(fval) ( ( (fval) >= 0.0f ) ? ((Ns32)((fval) + 0.5f)) : ((Ns32)((fval) - 0.5f)) ) +#define NSIGN(a) (((a)<0) ? -1:1) // Sign of a reel + +#define NCLAMP(mn,a,mx) ( ((a)<(mn)) ? (mn) : ((a)>(mx)) ? (mx) : (a) ) + +#define NLERP(a,b,t) ( a + (b - a)*t ) + +// #define ZERO_IFNEG(a) (((a) < 0) ? 0 : (a)) // 0 if negative value +// #define ZERO_IFPOS(a) (((a) > 0) ?(a) : 0 ) // 0 if positive value + +#define NISODD(a) ((a)&1) // Test if a number is a Odd number (2xn + 1 ) if not is Even (2xn) ! + +#define NBOOL(a) (((a)==0) ? 0:1) // return 1 if a is non zero, return 0 otherwise +// FUNCTIONS +void NInitializeMathLUTs(); + +// Math +inline void NCosSin(Nf32 angle_rad,Nf32 *cosangle,Nf32 *sinangle) +{ +//*cosangle = cos(angle); *sinangle = sin(angle); // Temporaire. On doit ici trouver le code assembleur pour renvoyer Sin et cos en m�me temps ! +#ifdef _NWINDOWS + __asm + { + fld angle_rad + fsincos + mov edx,cosangle + mov ecx,sinangle + fstp dword ptr [edx] + fstp dword ptr [ecx] + } +#endif +#ifdef _NIOS + *cosangle=cosf(angle_rad); + *sinangle=sinf(angle_rad); +#endif + +#ifdef _NANDROID + *cosangle=cosf(angle_rad); + *sinangle=sinf(angle_rad); +#endif + + /* + __asm + { + fld dword ptr [esp + 4] + fsincos + mov edx, [esp + 8] + mov ecx, [esp + 12] + fstp dword ptr [edx] + fstp dword ptr [ecx] + } + */ +} + +#define NNEWTON_METHOD_MAX_ITER 32 +Nf32 NNewtoncbrtf32(const Nf32 x, const Nf32 err); + +inline Nf32 Ncbrtf32(const Nf32 x) {return (x < 0) ? -powf(-x, 1.0f / 3.0f) : powf(x, 1.0f / 3.0f); } +inline Nf64 Ncbrtf64(const Nf64 x) { return (x < 0) ? -pow(-x, 1.0 / 3.0) : pow(x, 1.0 / 3.0); } + +inline Nbool NIsPowerOfTwo(const Nu32 n){ return ( n && ( (n & (n - 1)) == 0 ) ); } +Nf32 NFastSqrt(const Nf32 f); +// TRIGONOMETRY +Nf32 NFastSin(const Nu32 a); +Nf32 NFastCos(const Nu32 a); +void NFastCosSin(Nu32 a,Nf32* co,Nf32* si); +void NFastVCosSin(Nu32 a,Nf32* cossin); // "cossin" is a pointer on 2 successive Nf32: cossin[0] and cossin[1] +// RANDOMIZE +Nf32 NFastRand(); +void NFastRandRange(Nf32 *pfirst,const Nu32 size); +Nf32* NGetFastRandRangePtr(const Nu32 size); +void NRewindFastRandLUT(); // To replace FastRandLut headReader to index 0 (beginning of the table) + +inline Nf32 NEllipsePerimeterRamanujanApprox(const Nf32 radius_a, const Nf32 radius_b){return NF32_PI*(3.0f*(radius_a+radius_b)-NFastSqrt((3*radius_a+radius_b)*(radius_a+3*radius_b)));} +inline Nf32 NCirclePerimeter(const Nf32 radius){return NF32_2PI*radius;} + +void NFresnelIntegralsf32(const Nf32 s, Nf32 *cf, Nf32 *sf); +void NFresnelIntegralsf64(const Nf64 s, Nf64 *cf, Nf64 *sf); +// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +#ifdef __cplusplus +} +#endif // __cpluplus +#endif // __NMATH_H + diff --git a/src/main/include/lib/N/NMemory.h b/src/main/include/lib/N/NMemory.h new file mode 100644 index 0000000..2e45d7e --- /dev/null +++ b/src/main/include/lib/N/NMemory.h @@ -0,0 +1,67 @@ +//#ifndef __NMEMORY_H +//#define __NMEMORY_H +#pragma once +// *************************************************************************************** +// *************************************************************************************** +// ** ** +// ** NMemory.h ** +// ** ** +// *************************************************************************************** +// *************************************************************************************** +#include "lib/N/NCStandard.h" +#include "lib/N/NType.h" + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif +// -------------------------------------------------------------------------------------------------------------------------------------------------------------- + +#if defined ( _DEBUG ) + +//#ifdef _NWINDOWS +#include +// !!! WARNING !!! +// !!! Don't use these functions USE the #define just below !!! +void* Nmalloc_debug(Nu32 size,const char *pfname,int nbline); +void* Nrealloc_debug(void* ptr,Nu32 newsize,const char *pfname,int nbline); +void Nfree_debug(void *ptr); +void NMemoryStats_Debug(); +void NMemoryCheck_Debug(const void *ptr,const Nu32 memory_size, const Nu8 check_u8 ); +// + +#define Nmalloc(size) Nmalloc_debug(size,__FILE__,__LINE__) +#define Nmalloc_mem0(size) memset(Nmalloc_debug(size,__FILE__,__LINE__),0,size) +#define Nrealloc(ptr,newsize) Nrealloc_debug(ptr,newsize,__FILE__,__LINE__) +#define Nfree(ptr) if(ptr){Nfree_debug(ptr);} +#define Nfree_NULL(ptr) if(ptr){Nfree_debug(ptr);(ptr) = NULL;} +#define NMemoryStats() NMemoryStats_Debug() +#define NMemoryCheck(ptr,memory_size,check_u8) NMemoryCheck_Debug(ptr, memory_size, check_u8 ) + +#define Nmem0(ptr,type) memset((ptr),0,sizeof(type)) + +#endif + +#if !defined ( _DEBUG ) +#define Nmalloc(size) malloc(size) +#define Nmalloc_mem0(size) memset(malloc(size),0,size) +#define Nrealloc(ptr,newsize) realloc(ptr,newsize) +#define Nfree(ptr) if(ptr){free(ptr);} +#define Nfree_NULL(ptr) if(ptr){free(ptr);(ptr) = NULL;} +#define NMemoryStats() +#define NMemoryCheck(ptr,memory_size,check_u8) + +#define Nmem0(ptr,type) memset((ptr),0,sizeof(type)) +#endif + + +#define NEW(base) ( (base*)Nmalloc(sizeof(base)) ) +// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +#ifdef __cplusplus +} +#endif // __cpluplus +//#endif // __NMEMORY_H + diff --git a/src/main/include/lib/N/NType.h b/src/main/include/lib/N/NType.h new file mode 100644 index 0000000..4ddbb22 --- /dev/null +++ b/src/main/include/lib/N/NType.h @@ -0,0 +1,118 @@ +#ifndef __NTYPE_H +#define __NTYPE_H + +#include "NCompilerPragma.h" + +#ifdef __cplusplus +extern "C" +{ +#endif +// -------------------------------------------------------------------------------------------------------------------------------------------------------------- +#ifdef _NIOS +//typedef long long int __int64; +#define __int64 long long int +typedef unsigned long DWORD; +typedef unsigned short WORD; +typedef unsigned char NBYTE; +#endif + +// On Android NULL is not defined +#ifndef NULL +#define NULL 0 +#endif + +// On ANDROID and IOS __int64 is not defined ... +#ifndef __int64 + #ifdef _X64 + #define __int64 long + #else // _X64 + #define __int64 long long int + #endif // _X64 +#endif // __int64 + +// type redefinition +typedef int Nint; + +typedef char Nchar; +typedef unsigned char Nbool; +typedef unsigned char NBYTE; + +typedef unsigned char Nu8; +typedef unsigned short Nu16; +typedef unsigned long Nu32; +typedef unsigned __int64 Nu64; + +typedef signed char Ns8; +typedef signed short Ns16; +typedef signed long Ns32; // 'signed long' is a synonym of 'long' +typedef signed __int64 Ns64; + +typedef float Nf32; +typedef double Nf64; + + + +// boolean +#define NTRUE 1 +#define NFALSE 0 + +// a useful "VOID" value +#define NVOID 0xFFFFFFFF // = NU32_MAX + + + +// WORD, LONG, NBYTE manipulations +// ------------------------------------------------------------------------------------------------- +// Versions with bits masks... (are they really necessary here ? ) +// .......................................................... +// #define NLOWORD(l) ( (Nu16)( ((Nu16)(l)) & 0xFFFF ) ) +// #define NHIWORD(l) ( (Nu16)( (((Nu32)(l)) >> 16) & 0xFFFF) ) +// #define NMAKELONG(lo,hi) ((Nu32) ((((Nu32)((Nu16)(lo))) & 0xFFFF)|( (((Nu32)((Nu16)(hi)))& 0xFFFF) << 16) )) +// +// #define NLOBYTE(w) ( (Nu8)( ((Nu8)(w)) & 0xFF ) ) +// #define NHIBYTE(w) ( (Nu8)( (((Nu16)(w)) >> 8) & 0xFF ) ) +// #define NMAKEWORD(lo,hi)( (Nu16) (( ((Nu16)((Nu8)(lo))) & 0xFF ) | ( ( ((Nu16)((Nu8)(hi))) & 0xFF ) << 8 )) ) + +// Versions without bits masks... +// .......................................................... +#define NLOWORD(l) ( (l)&0xFFFF ) +#define NHIWORD(l) ( ((l)&0xFFFF0000)>>16 ) +#define NMAKELONG(lo,hi) ( ((lo)&0xFFFF)|(((hi)&0xFFFF)<<16) ) + +#define NLOBYTE(w) ( (w)&0xFF ) +#define NHIBYTE(w) ( ((w)&0xFF00) >> 8 ) +#define NMAKEWORD(lo,hi) ( ((lo)&0xFF)|(((hi)&0xFF)<<8) ) + +#define NLONIBBLE(b) ( (b)&0xF ) +#define NHINIBBLE(b) ( ((b)&0xF0)>>4 ) +#define NMAKEBYTE(lonibble,hinibble) ( ((lonibble)&0xF) | (((hinibble)&0xF)<<4) ) + +/* +// Old Syntax, for memory ... +//--------------------------- +#define LOWORD(l) ((WORD)(l)) +#define HIWORD(l) ((WORD)(((DWORD)(l) >> 16) & 0xFFFF)) +#define MAKELONG(lo,hi) ( (LONG) (((WORD) (low)) | ((DWORD) ((WORD) (hi))) << 16)) +#define LOBYTE(w) ((NBYTE)(w)) +#define HIBYTE(w) ((NBYTE)(((WORD)(w) >> 8) & 0xFF)) +#define MAKELONG(loword, hiword) (loword & 0xffff) | ((hiword & 0xffff) << 16) +#define MAKEWORD(lobyte, hibyte)(lobyte & 0xff) | ((hibyte & 0xff) << 8) + +// And some other syntaxes ... +//---------------------------- +#define MAKEWORD(a, b) ((WORD)(((NBYTE)(((DWORD_PTR)(a)) & 0xff)) | ((WORD)((NBYTE)(((DWORD_PTR)(b)) & 0xff))) << 8)) +#define MAKELONG(a, b) ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16)) +#define LOWORD(l) ((WORD)(((DWORD_PTR)(l)) & 0xffff)) +#define HIWORD(l) ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff)) +#define LOBYTE(w) ((NBYTE)(((DWORD_PTR)(w)) & 0xff )) +#define HIBYTE(w) ((NBYTE)((((DWORD_PTR)(w)) >> 8) & 0xff)) +*/ + + + +// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +#ifdef __cplusplus +} +#endif // __cpluplus +#endif // __NTYPE_H + diff --git a/src/main/include/lib/NL/Characterization/NLCharacterizationTable.h b/src/main/include/lib/NL/Characterization/NLCharacterizationTable.h new file mode 100644 index 0000000..6f5f403 --- /dev/null +++ b/src/main/include/lib/NL/Characterization/NLCharacterizationTable.h @@ -0,0 +1,46 @@ +#pragma once + +#include "lib/N/NType.h" +#include "lib/N/Containers/NArray.h" +//#include "../../../N/Maths/NVec3f32.h" +#include "lib/NL/Characterization/NLMotorCharacterization.h" + +#ifdef _NEDITOR +#endif + +#define EXTENSION_NLCHARACTERIZATION_TABLE_TXT ".txt" // extention des noms de fichiers de characterization (format texte) +#define EXTENSION_NLCHARACTERIZATION_TABLE_BIN ".czt" // extention des noms de fichiers de characterization (format binaire) + +#define FLAG_NLCHARACTERIZATION_TABLE_ROW_IS_INVERTED BIT_0 +typedef struct NLCHARACTERIZATION_TABLE_ROW NLCHARACTERIZATION_TABLE_ROW; +struct NLCHARACTERIZATION_TABLE_ROW +{ + Nu16 m_flags; + Nu8 m_gearboxId; // de 0 � n + Nu8 m_motorId; // 'gearbox relative' c'est � dire que pour chaque Gearbox les moteurs sont num�rot�s de 0 � n + Nchar m_motorName[8]; // nom du moteur 7 lettres max (+ caractere null de fin ). + NLMOTOR_CHARACTERIZATION m_characterization; // Kv, Ka, Intercept en forward et backward. + Nf32 m_gearRatio; // Gearbox ratio = Driven / Drive + Nf32 m_angularVelocityScaleFactor; // = traction wheel radius ! Kangv = kv*m_angularVelocityScaleFactor Kanga = ka*m_angularVelocityScaleFactor + Nf32 m_forwardVelocityMax; // m/s + Nf32 m_forwardAccelerationMax; // m/s� + Nf32 m_backwardVelocityMax; // m/s + Nf32 m_backwardAccelerationMax; // m/s� + +}; + +typedef struct NLCHARACTERIZATION_TABLE NLCHARACTERIZATION_TABLE; +struct NLCHARACTERIZATION_TABLE +{ + NLCHARACTERIZATION_TABLE(); + NLCHARACTERIZATION_TABLE(const Nu8 capacity); + + ~NLCHARACTERIZATION_TABLE(); + + void load(const Nchar *pfilename, const Nbool bclear_table_before_loading=NFALSE); + NLMOTOR_CHARACTERIZATION* get(NLMOTOR_CHARACTERIZATION *pdst, const Nu8 table_index, const Nbool angular_velocity_scaled_coef); + NLMOTOR_CHARACTERIZATION* get(NLMOTOR_CHARACTERIZATION *pdst, const Nu8 gearboxid,const Nu8 motorid, const Nbool angular_velocity_scaled_coef); + NLMOTOR_CHARACTERIZATION* get(NLMOTOR_CHARACTERIZATION *pdst, const Nchar *pmotorname, const Nbool angular_velocity_scaled_coef); + + NARRAY m_table; +}; diff --git a/src/main/include/lib/NL/Characterization/NLCharacterization_Tests.h b/src/main/include/lib/NL/Characterization/NLCharacterization_Tests.h new file mode 100644 index 0000000..516ea25 --- /dev/null +++ b/src/main/include/lib/NL/Characterization/NLCharacterization_Tests.h @@ -0,0 +1,88 @@ +// 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 +#include +#include +#include "lib/CSVLogFile.h" +#include "lib/N/NMath.h" +#include "lib/N/NType.h" +#include "lib/N/NFlags.h" +#include +#include +// #include +#include + +typedef struct TestSpecs TestSpecs; +struct TestSpecs +{ + unsigned long m_flags; + double m_voltage; + double m_ramp; +}; + +class NLCharacterization_Tests +{ + +public: + enum class State + { + Stopped = 0, + AskForStart = 1, + Started = 2, + AskForStop = 3 + }; + NLCharacterization_Tests(ctre::phoenix::motorcontrol::can::TalonFX *leftMotor, + ctre::phoenix::motorcontrol::can::TalonFX *leftMotorFollower, + ctre::phoenix::motorcontrol::can::TalonFX *leftMotorFollower2, + ctre::phoenix::motorcontrol::can::TalonFX *rightMotor, + ctre::phoenix::motorcontrol::can::TalonFX *rightMotorFollower, + ctre::phoenix::motorcontrol::can::TalonFX *rightMotorFollower2, + frc::Encoder *externalEncoderLeft, + frc::Encoder *externalEncoderRight, + long nbTestLow, + double endVoltageLow, + long nbTestMedium, + double endVoltageMedium, + long nbTestHigh, + double endVoltageHigh, + double rampValue, + double rampVoltage); + ~NLCharacterization_Tests(); + void nextTest(); + void previousTest(); + void setCurrentTest(uint8_t testId); + void start(); + void stop(); + void fastLoop(); + State getState(); + uint8_t getCurrentTestId(); + char *getCurrentFileLogName(char *pbuffer, uint size); + char *getCurrentTestDescription(char *pmessage, uint size_terminated_null_char_included); + uint getTestsCounter(); + uint areAllTestsDone(); + +private: + ctre::phoenix::motorcontrol::can::TalonFX *m_rightMotor; + ctre::phoenix::motorcontrol::can::TalonFX *m_rightMotorFollower; + ctre::phoenix::motorcontrol::can::TalonFX *m_rightMotorFollower2; + ctre::phoenix::motorcontrol::can::TalonFX *m_leftMotor; + ctre::phoenix::motorcontrol::can::TalonFX *m_leftMotorFollower; + ctre::phoenix::motorcontrol::can::TalonFX *m_leftMotorFollower2; + + frc::Encoder *m_externalEncoderRight; + frc::Encoder *m_externalEncoderLeft; + + TestSpecs *TestData; + State m_state = State::Stopped; + uint8_t m_CurrentTestID = 0; + double m_oldRamp; + uint8_t m_nbTotalTest; + + CSVLogFile *m_LogFile; + + double m_ramp = 0; + double m_time0; +}; diff --git a/src/main/include/lib/NL/Characterization/NLMotorCharacterization.h b/src/main/include/lib/NL/Characterization/NLMotorCharacterization.h new file mode 100644 index 0000000..41eeae2 --- /dev/null +++ b/src/main/include/lib/NL/Characterization/NLMotorCharacterization.h @@ -0,0 +1,42 @@ +#pragma once + +#include "lib/N/NType.h" +#include "lib/N/NMemory.h" +//#include "../../../N/Maths/NVec3f32.h" + +#ifdef _NEDITOR +#endif + +typedef struct NLMOTOR_CHARACTERIZATION NLMOTOR_CHARACTERIZATION; +struct NLMOTOR_CHARACTERIZATION +{ + NLMOTOR_CHARACTERIZATION() { Nmem0(this, NLMOTOR_CHARACTERIZATION); } + + // Nchar* read(Nchar *pstr); + inline void setFrom(const NLMOTOR_CHARACTERIZATION *psrc) { *this = *psrc; }; + void setFrom(const NLMOTOR_CHARACTERIZATION *psrc, const Nf32 scalefactor); + inline void setForwardConst(const Nf32 kv, const Nf32 ka, const Nf32 intercept){m_forwardKv = kv; m_forwardKa = ka; m_forwardIntercept = intercept;} + inline void setBackwardConst(const Nf32 kv, const Nf32 ka, const Nf32 intercept) { m_backwardKv = kv; m_backwardKa = ka; m_backwardIntercept = intercept; } + + inline Nf32 getVoltage(const Nf32 velocity, const Nf32 acceleration){return (velocity < 0.0f)?(m_backwardKv * velocity + m_backwardKa * acceleration + m_backwardIntercept):(m_forwardKv * velocity + m_forwardKa * acceleration + m_forwardIntercept);} + + union + { + struct + { + Nf32 m_kv[2]; // m_kv[0] = "kv pour un voltage POSITIF" // m_kv[1] = "kv pour un voltage NEGATIF" + Nf32 m_ka[2]; // m_ka[0] = "ka pour un voltage POSITIF" // m_ka[1] = "ka pour un voltage NEGATIF" + Nf32 m_intercept[2]; // m_intercept[0] = "intercept pour un voltage POSITIF" // m_intercept[1] = "intercept pour un voltage NEGATIF" + }; + struct + { + Nf32 m_forwardKv; // = m_kv[0] + Nf32 m_backwardKv; // = m_kv[1] + Nf32 m_forwardKa; // = m_ka[0] + Nf32 m_backwardKa; // = m_ka[1] + Nf32 m_forwardIntercept; // = m_intercept[0] + Nf32 m_backwardIntercept; // = m_intercept[1] + }; + }; +}; + diff --git a/src/main/include/lib/NL/NLKin.h b/src/main/include/lib/NL/NLKin.h new file mode 100644 index 0000000..e5c7577 --- /dev/null +++ b/src/main/include/lib/NL/NLKin.h @@ -0,0 +1,122 @@ +#pragma once +#include "lib/N/NMath.h" +#include "lib/N/NType.h" +#include "lib/N/NFlags.h" +#include "lib/N/NMemory.h" + +#ifdef _NEDITOR +#include "../NL2DOrthogonalCoordinateSystem.h" +#endif + +//#include "NLKinLimits.h" + +// EPSILON(s) +// Les calculs en Nf32 engendre des erreurs d'arrondi qui rendent les tests d'�galit� "d�licats". +// On consid�rera que deux valeurs sont distinctes si leur diff�rence est sup�rieure � un certain seuil ( EPSILON ) +// Dans le cas contraire ( diff�rence inf�rieure ou �gale au seuil ) on consid�rera les deux valeurs comme �gales. +// Chaque grandeur poss�de son propre seuil (EPSILON) +#define NLKIN_EPSILON_S 0.00001f ///< 10E-5 m 1 centi�me de mm soit 10 microm�tres +#define NLKIN_EPSILON_V 0.00001f ///< 10E-5 m/s 1 centi�me de mm/s +#define NLKIN_EPSILON_A 0.00001f ///< 10E-5 m/s/s 1 centi�me de mm/s/s +#define NLKIN_EPSILON_J 0.00001f ///< 10E-5 ms/s/s 1 centi�me de mm/s/s/s +#define NLKIN_EPSILON_T 0.0001f ///< 10E-4 s 1 dix milli�me de seconde + +// MACROS � utiliser pour tester l'�galit� de deux valeurs: +// "if( !NLKIN_?_DISTINCT(valeur0,valeur1) )" � utiliser � la place de "if( valeur0 == valeur1 )" +#define NLKIN_S_DISTINCT(s0,s1) ( NABS((s0)-(s1)) > NLKIN_EPSILON_S ) +#define NLKIN_V_DISTINCT(v0,v1) ( NABS((v0)-(v1)) > NLKIN_EPSILON_V ) +#define NLKIN_A_DISTINCT(a0,a1) ( NABS((a0)-(a1)) > NLKIN_EPSILON_A ) +#define NLKIN_J_DISTINCT(j0,j1) ( NABS((j0)-(j1)) > NLKIN_EPSILON_J ) +#define NLKIN_T_DISTINCT(t0,t1) ( NABS((t0)-(t1)) > NLKIN_EPSILON_T ) + +// Dur�e minimum d'int�gration d'un KIN. ( � ne pas confondre avec le seuil NLKIN_EPSILON_T ! ) +#define NLKIN_MIN_T 0.002f ///< s.dur�e minimum d'un bloc kinematic + +// MACROS � utiliser pour calculer/int�grer manuellement et s�parement les composantes d'un NLKIN : +#define NLKIN_S(s0,v0,a0,j0,dt,dt2) ( (s0) + (v0)*(dt) + ((a0)*(dt2))/2.0f + ((j0)*(dt2)*(dt))/6.0f ) ///< S, l'abscisse s0 en t0 + la distance parcourue par integration des composantes j0,a0,v0 pendant un laps de temps dt +#define NLKIN_V(v0,a0,j0,dt,dt2) ( (v0) + (a0)*(dt) + ((j0)*(dt2))/2.0f ) ///< V, la vitesse v0 en t0 + la vitesse additionnelle obtenue par integration des composantes j0,a0 pendant un laps de temps dt +#define NLKIN_A(a0,j0,dt) ( (a0) + (j0)*(dt) ) ///< A, l'accel. a0 en t0 + l'accel. additionnelle obtenue par integration de la composante j0 pendant un laps de temps dt + +#define NLKIN_DS(v0,a0,j0,dt,dt2) ( (v0)*(dt) + ((a0)*(dt2))/2.0f + ((j0)*(dt2)*(dt))/6.0f ) ///< DS la distance parcourue par integration des composantes j0,a0,v0 pendant un laps de temps dt +#define NLKIN_DV(a0,j0,dt,dt2) ( (a0)*(dt) + ((j0)*(dt2))/2.0f ) ///< DV la vitesse additionnelle obtenue par integration des composantes j0,a0 pendant un laps de temps dt +#define NLKIN_DA(j0,dt) ( (j0)*(dt) ) ///< DA l'accel. additionnelle obtenue par integration de la composante j0 pendant un laps de temps dt + + // Membres +enum KIN_PARAM_ID +{ + ABSCISSE = 0, ///< index of \e abscisse member in "m_param[]" Kin static table + VELOCITY, ///< index of \e velocity member in "m_param[]" Kin static table + ACCELERATION, ///< index of \e acceleration member in "m_param[]" Kin static table + JERK, ///< index of \e jerk member in "m_param[]" Kin static table + TIME ///< index of \e time stamp member in "m_param[]" Kin static table +}; + +class NLKIN3 +{ +public: + union + { + struct + { + Nf32 m_s; ///< abscisse curviligne. + Nf32 m_v; ///< Velocit�. + Nf32 m_a; ///< Acc�l�ration. + }; + + Nf32 m_param[3]; ///< an another way to access kin values with \b KIN_PARAM_ID @see KIN_PARAM_ID + }; +}; + +class NLKIN +{ +public: + /** Liste des differentes valeurs retourn�es par les differentes fonctions Check ( AccVelFastCheck, AccVelCheck, ... ). + * Ces valeurs sont potentiellement combinees entre elles avec l'operateur |. + * Par exemple, ACCELERATION_OVERSHOOT|VELOCITY_WAS_OVERSHOOTED. + */ + enum CHECKS + { + VELOCITY_ACCELERATION_OK = 0, ///< Vitesse et Acceleration sont ok. + VELOCITY_WAS_OVERSHOOTED = BIT_0, ///< La Vitesse "�tait" en d�passement. + VELOCITY_OVERSHOOT = BIT_1, ///< La Vitesse est en d�passement. + VELOCITY_WILL_OVERSHOOT = BIT_2, ///< La Vitesse sera en d�passement. + ACCELERATION_OVERSHOOT = BIT_3 ///< L'acceleration est en d�passement. + }; + + inline NLKIN() { Nmem0(this, NLKIN);} + inline NLKIN(const Nf32 s, const Nf32 v, const Nf32 a, const Nf32 j, const Nf32 t){m_s = s;m_v = v;m_a = a;m_j = j;m_t = t;} + inline void null() { Nmem0(this, NLKIN); } + inline void tjavs_set(const Nf32 t, const Nf32 j, const Nf32 a, const Nf32 v, const Nf32 s) { m_t = t; m_a = a; m_v = v; m_s = s; m_j = j; } + inline void setAsKinX(const Nf32 j, const Nf32 a) { m_j = j; m_a = a; m_t = a / j; m_v = (a*a) / (2 * j); m_s = m_j*NPOW3(m_t) / 6.0f; } + + void from(const NLKIN *pk0, const Nf32 dt); + void from(const NLKIN *pk0, const Nf32 jerk, const Nf32 dt); + NLKIN* to(NLKIN *pk1, const Nf32 dt); + NLKIN* to(NLKIN *pk1, const Nf32 jerk, const Nf32 dt); +/* + const Nu32 accVelfastCheck(const NLKINLIMITS * pkmax); + const Nu32 accVelCheck(const NLKINLIMITS * pkmax); + const Nu32 accVelFastFullCheck(const NLKINLIMITS *pkmax); + const Nu32 accVelFullCheck(const NLKINLIMITS *pkmax); + const Nu32 velForwardCheck(const NLKINLIMITS *pkmax); + const Nu32 velBackwardCheck(const NLKINLIMITS *pkmax); +*/ +#ifdef _NEDITOR +void draw(NL2DOCS * p2docs, const NLKIN *pk0); +#endif + + + union + { + struct + { + Nf32 m_s; ///< abscisse curviligne, a la date m_t, mesuree depuis le debut du chemin.( m_t = 0, m_s = 0 ). + Nf32 m_v; ///< Velocite a la date m_t. + Nf32 m_a; ///< Acceleration a la date m_t. + Nf32 m_j; ///< Jerk ( qu'il a fallu appliquer depuis le NLKIN precedent pour obtenir ce KIN.) this = Kin0 "+" this.Jerk ( ici le "+" ne repr�sente pas l'addition ). + Nf32 m_t; ///< temps/date, mesuree depuis le temps t0=0 ( debut du chemin). La duree ecoulee entre deux KIN vaut dt = (kin[n].m_t - kin[n-1].m_t). + }; + + Nf32 m_param[5]; ///< an another way to access kin values with \b KIN_PARAM_ID @see KIN_PARAM_ID + }; +}; diff --git a/src/main/include/lib/NL/NLOdometry.h b/src/main/include/lib/NL/NLOdometry.h new file mode 100644 index 0000000..8bdfdb7 --- /dev/null +++ b/src/main/include/lib/NL/NLOdometry.h @@ -0,0 +1,14 @@ +#pragma once +#include "lib/N/NType.h" + +// https://fr.wikipedia.org/wiki/Odom%C3%A9trie +// https://mouniere.blogspot.com/2007/10/cours-et-mthode-leon-n5-la-conduite-dun.html + +// w = rotation angle / vitesse angulaire +// v = translation / vitesse +// axletrack = dist. entre les points de contact au sol des roues droite et gauche. + +#define NLODOMETRY_DRIVETRAIN_V_FROM_WHEELS(left,right) ( ( (right)+(left) )/2.0f ) +#define NLODOMETRY_DRIVETRAIN_W_FROM_WHEELS(left,right,axletrack) ( ( (right)-(left) )/(axletrack) ) +#define NLODOMETRY_L_WHEEL_FROM_DRIVETRAIN(w,v,axletrack) ( (v) - ( (w) * (axletrack) )/2.0f ) +#define NLODOMETRY_R_WHEEL_FROM_DRIVETRAIN(w,v,axletrack) ( (v) + ( (w) * (axletrack) )/2.0f ) diff --git a/src/main/include/lib/NL/NLPid.h b/src/main/include/lib/NL/NLPid.h new file mode 100644 index 0000000..0c87dc7 --- /dev/null +++ b/src/main/include/lib/NL/NLPid.h @@ -0,0 +1,25 @@ +#pragma once + +#include "lib/N/NType.h" +#include "lib/N/NMemory.h" + +typedef struct NLPID_ERROR NLPID_ERROR; +struct NLPID_ERROR +{ + inline void reset() { Nmem0(this, NLPID_ERROR); } + inline void update(const Nf32 error) { m_previous = m_current; m_current = error; m_derivate = m_current - m_previous; m_integral += error; } + Nf32 m_current; // erreur actuelle + Nf32 m_previous; // erreur pr�c�dente + Nf32 m_derivate; // variation d'erreur + Nf32 m_integral; // somme des erreurs +}; + +typedef struct NLPID NLPID; +struct NLPID +{ + Nf32 m_kP; + Nf32 m_kI; + Nf32 m_kD; + inline Nf32 command(const NLPID_ERROR *perr) { return m_kP * perr->m_current + m_kI * perr->m_integral + m_kD * perr->m_derivate; } +}; + diff --git a/src/main/include/lib/NL/NLTrajectoryStateS.h b/src/main/include/lib/NL/NLTrajectoryStateS.h new file mode 100644 index 0000000..3cfd9e9 --- /dev/null +++ b/src/main/include/lib/NL/NLTrajectoryStateS.h @@ -0,0 +1,18 @@ +#pragma once +#include "lib/N/NType.h" +//#include "lib/N/Maths/NVec2f32.h" +#include "lib/NL/NLKin.h" + +typedef struct NLTRAJECTORY_STATE_S NLTRAJECTORY_STATE_S; +struct NLTRAJECTORY_STATE_S +{ + inline void set(const NLKIN *pkin, const Nf32 curvature) + { + m_localCurvature = curvature; + m_kin = *pkin; + } + inline void null() { Nmem0(this, NLTRAJECTORY_STATE_S); } + + NLKIN m_kin; // kin repr�sentant le robot ( son centre d'inertie ) + Nf32 m_localCurvature; // courbure � l'abscisse curviligne m_kin.m_s +}; diff --git a/src/main/include/lib/NL/NLTrajectoryStateSPack.h b/src/main/include/lib/NL/NLTrajectoryStateSPack.h new file mode 100644 index 0000000..3eebe57 --- /dev/null +++ b/src/main/include/lib/NL/NLTrajectoryStateSPack.h @@ -0,0 +1,29 @@ +#pragma once +#include "../N/NType.h" +#include "../N/Containers/NArray.h" +//#include "NLPathGeometry.h" +#include "NLTrajectoryStateS.h" + +#ifdef _NEDITOR +#include "../NL2DOrthogonalCoordinateSystem.h" +#endif + +class NLTRAJECTORY_STATE_S_PACK +{ +public: + NLTRAJECTORY_STATE_S_PACK(); + ~NLTRAJECTORY_STATE_S_PACK(); + + Nu32 read(FILE *pfile); + Nu32 write(FILE *pfile); + + NLTRAJECTORY_STATE_S* getState(NLTRAJECTORY_STATE_S *pstate, const Nf32 t); + +#ifdef _NEDITOR + void drawTrajectoryStateSArray(NL2DOCS * p2docs); +#endif + + NARRAY m_trajectoryStateSArray; + Nf32 m_dt; // Dur�e totale n�c�ssaire pour parcourir la trajectoire + Nf32 m_ds; // Distance totale couverte par la trajectoire +}; diff --git a/src/main/include/lib/Utils.h b/src/main/include/lib/Utils.h new file mode 100644 index 0000000..a9bc2ef --- /dev/null +++ b/src/main/include/lib/Utils.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +typedef struct VA VA; +struct VA +{ + double m_speed; + double m_acceleration; + double m_jerk; +}; + +class KineticToVoltage +{ + + //k_lut[MoteurIndex][ForwardBackward][Kv, Ka, Kintersept] + double k_lut[4][2][3]; + +public: + void SetMotorCoefficients(uint motorID, uint isBackward, double kv, double ka, double vintersept); + double getVoltage(uint motorID, const VA *pva); +}; \ No newline at end of file diff --git a/src/main/include/lib/newCSVLogFile.h b/src/main/include/lib/newCSVLogFile.h new file mode 100644 index 0000000..cc0d401 --- /dev/null +++ b/src/main/include/lib/newCSVLogFile.h @@ -0,0 +1,15 @@ +#include +#include +#include +#pragma once + +class newCSVLogFile +{ +public: + newCSVLogFile(char *filename, char *head); + ~newCSVLogFile(); + void log(double value[3], int arraySize); + +private: + FILE *m_file; +}; \ No newline at end of file diff --git a/src/test/cpp/main.cpp b/src/test/cpp/main.cpp new file mode 100644 index 0000000..b8b23d2 --- /dev/null +++ b/src/test/cpp/main.cpp @@ -0,0 +1,10 @@ +#include + +#include "gtest/gtest.h" + +int main(int argc, char** argv) { + HAL_Initialize(500, 0); + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + return ret; +} diff --git a/vendordeps/Phoenix5.json b/vendordeps/Phoenix5.json new file mode 100644 index 0000000..88a68dd --- /dev/null +++ b/vendordeps/Phoenix5.json @@ -0,0 +1,151 @@ +{ + "fileName": "Phoenix5.json", + "name": "CTRE-Phoenix (v5)", + "version": "5.33.0", + "frcYear": 2024, + "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix/Phoenix5-frc2024-latest.json", + "requires": [ + { + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "errorMessage": "Phoenix 5 requires low-level libraries from Phoenix 6. Please add the Phoenix 6 vendordep before adding Phoenix 5.", + "offlineFileName": "Phoenix6.json", + "onlineUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2024-latest.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-java", + "version": "5.33.0" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-java", + "version": "5.33.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.33.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.33.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-cpp", + "version": "5.33.0", + "libName": "CTRE_Phoenix_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-cpp", + "version": "5.33.0", + "libName": "CTRE_Phoenix", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.33.0", + "libName": "CTRE_PhoenixCCI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "5.33.0", + "libName": "CTRE_Phoenix_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "api-cpp-sim", + "version": "5.33.0", + "libName": "CTRE_PhoenixSim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix.sim", + "artifactId": "cci-sim", + "version": "5.33.0", + "libName": "CTRE_PhoenixCCISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/vendordeps/Phoenix6.json b/vendordeps/Phoenix6.json new file mode 100644 index 0000000..69a4079 --- /dev/null +++ b/vendordeps/Phoenix6.json @@ -0,0 +1,339 @@ +{ + "fileName": "Phoenix6.json", + "name": "CTRE-Phoenix (v6)", + "version": "24.1.0", + "frcYear": 2024, + "uuid": "e995de00-2c64-4df5-8831-c1441420ff19", + "mavenUrls": [ + "https://maven.ctr-electronics.com/release/" + ], + "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2024-latest.json", + "conflictsWith": [ + { + "uuid": "3fcf3402-e646-4fa6-971e-18afe8173b1a", + "errorMessage": "The combined Phoenix-6-And-5 vendordep is no longer supported. Please remove the vendordep and instead add both the latest Phoenix 6 vendordep and Phoenix 5 vendordep.", + "offlineFileName": "Phoenix6And5.json" + } + ], + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-java", + "version": "24.1.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "24.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "24.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "24.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonFX", + "version": "24.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "24.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "24.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simCANCoder", + "version": "24.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "24.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "24.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "24.1.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix6", + "artifactId": "wpiapi-cpp", + "version": "24.1.0", + "libName": "CTRE_Phoenix6_WPI", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6", + "artifactId": "tools", + "version": "24.1.0", + "libName": "CTRE_PhoenixTools", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "linuxathena" + ], + "simMode": "hwsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "wpiapi-cpp-sim", + "version": "24.1.0", + "libName": "CTRE_Phoenix6_WPISim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "tools-sim", + "version": "24.1.0", + "libName": "CTRE_PhoenixTools_Sim", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonSRX", + "version": "24.1.0", + "libName": "CTRE_SimTalonSRX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simTalonFX", + "version": "24.1.0", + "libName": "CTRE_SimTalonFX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simVictorSPX", + "version": "24.1.0", + "libName": "CTRE_SimVictorSPX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simPigeonIMU", + "version": "24.1.0", + "libName": "CTRE_SimPigeonIMU", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simCANCoder", + "version": "24.1.0", + "libName": "CTRE_SimCANCoder", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProTalonFX", + "version": "24.1.0", + "libName": "CTRE_SimProTalonFX", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProCANcoder", + "version": "24.1.0", + "libName": "CTRE_SimProCANcoder", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + }, + { + "groupId": "com.ctre.phoenix6.sim", + "artifactId": "simProPigeon2", + "version": "24.1.0", + "libName": "CTRE_SimProPigeon2", + "headerClassifier": "headers", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "windowsx86-64", + "linuxx86-64", + "osxuniversal" + ], + "simMode": "swsim" + } + ] +} \ No newline at end of file diff --git a/vendordeps/WPILibNewCommands.json b/vendordeps/WPILibNewCommands.json new file mode 100644 index 0000000..67bf389 --- /dev/null +++ b/vendordeps/WPILibNewCommands.json @@ -0,0 +1,38 @@ +{ + "fileName": "WPILibNewCommands.json", + "name": "WPILib-New-Commands", + "version": "1.0.0", + "uuid": "111e20f7-815e-48f8-9dd6-e675ce75b266", + "frcYear": "2024", + "mavenUrls": [], + "jsonUrl": "", + "javaDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-java", + "version": "wpilib" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "edu.wpi.first.wpilibNewCommands", + "artifactId": "wpilibNewCommands-cpp", + "version": "wpilib", + "libName": "wpilibNewCommands", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": true, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxarm32", + "linuxarm64", + "windowsx86-64", + "windowsx86", + "linuxx86-64", + "osxuniversal" + ] + } + ] +}