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 0000000..d64cd49 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ 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 0000000..f7a3e8d Binary files /dev/null and b/src/main/deploy/paths/0_8Great2UJ30A1_5V1.tsp differ 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 0000000..e3e77db Binary files /dev/null and b/src/main/deploy/paths/0_8GreatUJ30A1_5V1.tsp differ diff --git a/src/main/deploy/paths/0_8GreatUJ45A3V2.tsp b/src/main/deploy/paths/0_8GreatUJ45A3V2.tsp new file mode 100644 index 0000000..36d6b51 Binary files /dev/null and b/src/main/deploy/paths/0_8GreatUJ45A3V2.tsp differ 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 0000000..0055b15 Binary files /dev/null and b/src/main/deploy/paths/0_8lineA1A7_J30A1_5V1.tsp differ diff --git a/src/main/deploy/paths/NEWWAVE_bridge.tsp b/src/main/deploy/paths/NEWWAVE_bridge.tsp new file mode 100644 index 0000000..65ab2d1 Binary files /dev/null and b/src/main/deploy/paths/NEWWAVE_bridge.tsp differ diff --git a/src/main/deploy/paths/NEWWAVE_fastloop.tsp b/src/main/deploy/paths/NEWWAVE_fastloop.tsp new file mode 100644 index 0000000..368867f Binary files /dev/null and b/src/main/deploy/paths/NEWWAVE_fastloop.tsp differ diff --git a/src/main/deploy/paths/NEWWAVE_longway.tsp b/src/main/deploy/paths/NEWWAVE_longway.tsp new file mode 100644 index 0000000..9d7c1c0 Binary files /dev/null and b/src/main/deploy/paths/NEWWAVE_longway.tsp differ diff --git a/src/main/deploy/paths/NEWWAVE_openlink.tsp b/src/main/deploy/paths/NEWWAVE_openlink.tsp new file mode 100644 index 0000000..2747d44 Binary files /dev/null and b/src/main/deploy/paths/NEWWAVE_openlink.tsp differ diff --git a/src/main/deploy/paths/NEWWAVE_snake.tsp b/src/main/deploy/paths/NEWWAVE_snake.tsp new file mode 100644 index 0000000..1f17b3e Binary files /dev/null and b/src/main/deploy/paths/NEWWAVE_snake.tsp differ diff --git a/src/main/deploy/paths/NEWWAVE_snake_4wp.tsp b/src/main/deploy/paths/NEWWAVE_snake_4wp.tsp new file mode 100644 index 0000000..1d60f60 Binary files /dev/null and b/src/main/deploy/paths/NEWWAVE_snake_4wp.tsp differ diff --git a/src/main/deploy/paths/NEWWAVE_superS.tsp b/src/main/deploy/paths/NEWWAVE_superS.tsp new file mode 100644 index 0000000..14a33ed Binary files /dev/null and b/src/main/deploy/paths/NEWWAVE_superS.tsp differ 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 0000000..f8147e7 Binary files /dev/null and b/src/main/deploy/paths/New2_U_J30A1_5V1.tsp differ diff --git a/src/main/deploy/paths/New_U_J30A1V0_5.tsp b/src/main/deploy/paths/New_U_J30A1V0_5.tsp new file mode 100644 index 0000000..7d000e5 Binary files /dev/null and b/src/main/deploy/paths/New_U_J30A1V0_5.tsp differ 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 0000000..f2513a7 Binary files /dev/null and b/src/main/deploy/paths/New_U_J30A1_5V1.tsp differ diff --git a/src/main/deploy/paths/New_U_J45A3V2.tsp b/src/main/deploy/paths/New_U_J45A3V2.tsp new file mode 100644 index 0000000..c6012d7 Binary files /dev/null and b/src/main/deploy/paths/New_U_J45A3V2.tsp differ 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 0000000..bbed585 Binary files /dev/null and b/src/main/deploy/paths/New_U_J60A5V3.tsp differ 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 0000000..99afa5a Binary files /dev/null and b/src/main/deploy/paths/S_[3_348mlong]J45A2V1.tsp differ diff --git a/src/main/deploy/paths/S_highspeed.tsp b/src/main/deploy/paths/S_highspeed.tsp new file mode 100644 index 0000000..c4ba300 Binary files /dev/null and b/src/main/deploy/paths/S_highspeed.tsp differ diff --git a/src/main/deploy/paths/SlalomPathJ30A1_5V1 b/src/main/deploy/paths/SlalomPathJ30A1_5V1 new file mode 100644 index 0000000..c84c1df Binary files /dev/null and b/src/main/deploy/paths/SlalomPathJ30A1_5V1 differ 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 0000000..8fd8f86 Binary files /dev/null and b/src/main/deploy/paths/Snake_J30A3V1_75.tsp differ diff --git a/src/main/deploy/paths/Traj.tsp b/src/main/deploy/paths/Traj.tsp new file mode 100644 index 0000000..693bc13 Binary files /dev/null and b/src/main/deploy/paths/Traj.tsp differ diff --git a/src/main/deploy/paths/Traj10.tsp b/src/main/deploy/paths/Traj10.tsp new file mode 100644 index 0000000..bd2c3be Binary files /dev/null and b/src/main/deploy/paths/Traj10.tsp differ diff --git a/src/main/deploy/paths/Traj11.tsp b/src/main/deploy/paths/Traj11.tsp new file mode 100644 index 0000000..e790295 Binary files /dev/null and b/src/main/deploy/paths/Traj11.tsp differ diff --git a/src/main/deploy/paths/Traj2.tsp b/src/main/deploy/paths/Traj2.tsp new file mode 100644 index 0000000..724d850 Binary files /dev/null and b/src/main/deploy/paths/Traj2.tsp differ diff --git a/src/main/deploy/paths/Traj3.tsp b/src/main/deploy/paths/Traj3.tsp new file mode 100644 index 0000000..bb3e028 Binary files /dev/null and b/src/main/deploy/paths/Traj3.tsp differ diff --git a/src/main/deploy/paths/Traj4.tsp b/src/main/deploy/paths/Traj4.tsp new file mode 100644 index 0000000..426b2dc Binary files /dev/null and b/src/main/deploy/paths/Traj4.tsp differ diff --git a/src/main/deploy/paths/Traj5.tsp b/src/main/deploy/paths/Traj5.tsp new file mode 100644 index 0000000..623123d Binary files /dev/null and b/src/main/deploy/paths/Traj5.tsp differ diff --git a/src/main/deploy/paths/Traj6.tsp b/src/main/deploy/paths/Traj6.tsp new file mode 100644 index 0000000..29fc806 Binary files /dev/null and b/src/main/deploy/paths/Traj6.tsp differ diff --git a/src/main/deploy/paths/Traj7.tsp b/src/main/deploy/paths/Traj7.tsp new file mode 100644 index 0000000..cdda260 Binary files /dev/null and b/src/main/deploy/paths/Traj7.tsp differ diff --git a/src/main/deploy/paths/Traj8.tsp b/src/main/deploy/paths/Traj8.tsp new file mode 100644 index 0000000..af5dbc2 Binary files /dev/null and b/src/main/deploy/paths/Traj8.tsp differ diff --git a/src/main/deploy/paths/Traj9.tsp b/src/main/deploy/paths/Traj9.tsp new file mode 100644 index 0000000..bd2c3be Binary files /dev/null and b/src/main/deploy/paths/Traj9.tsp differ diff --git a/src/main/deploy/paths/U_2mx1mJ45A2V1.tsp b/src/main/deploy/paths/U_2mx1mJ45A2V1.tsp new file mode 100644 index 0000000..69e4c99 Binary files /dev/null and b/src/main/deploy/paths/U_2mx1mJ45A2V1.tsp differ 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 0000000..78c121f Binary files /dev/null and b/src/main/deploy/paths/U_grand_J30A3V1_5.tsp differ diff --git a/src/main/deploy/paths/V_J30A2V1.tsp b/src/main/deploy/paths/V_J30A2V1.tsp new file mode 100644 index 0000000..93d11db Binary files /dev/null and b/src/main/deploy/paths/V_J30A2V1.tsp differ 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 0000000..7cc0552 Binary files /dev/null and b/src/main/deploy/paths/infiniti_J30A3V1_5.tsp differ 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 0000000..8ff93f8 Binary files /dev/null and b/src/main/deploy/paths/ligne_1_505mJ45A2V1.tsp differ 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 0000000..4bc1d9c Binary files /dev/null and b/src/main/deploy/paths/ligne_1_metre.tsp differ 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 0000000..e8dc21e Binary files /dev/null and b/src/main/deploy/paths/lineA1A10-J30A1_5V1.tsp differ diff --git a/src/main/deploy/paths/lineA1A10-J45A3V2.tsp b/src/main/deploy/paths/lineA1A10-J45A3V2.tsp new file mode 100644 index 0000000..d5cc299 Binary files /dev/null and b/src/main/deploy/paths/lineA1A10-J45A3V2.tsp differ 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 0000000..5d3e702 Binary files /dev/null and b/src/main/deploy/paths/lineA1A6-J30A1V0_5.tsp differ 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 0000000..1eb555f Binary files /dev/null and b/src/main/deploy/paths/lineA1A6-J30A1_5V1.tsp differ diff --git a/src/main/deploy/paths/lineA1A6-J45A3V2.tsp b/src/main/deploy/paths/lineA1A6-J45A3V2.tsp new file mode 100644 index 0000000..6ed6e57 Binary files /dev/null and b/src/main/deploy/paths/lineA1A6-J45A3V2.tsp differ diff --git a/src/main/deploy/paths/lineA1A6-J60A5V3.tsp b/src/main/deploy/paths/lineA1A6-J60A5V3.tsp new file mode 100644 index 0000000..3fc5bbc Binary files /dev/null and b/src/main/deploy/paths/lineA1A6-J60A5V3.tsp differ diff --git a/src/main/deploy/paths/lineA1A7_J30A1_5V1.tsp b/src/main/deploy/paths/lineA1A7_J30A1_5V1.tsp new file mode 100644 index 0000000..0055b15 Binary files /dev/null and b/src/main/deploy/paths/lineA1A7_J30A1_5V1.tsp differ diff --git a/src/main/deploy/paths/testU.tsp b/src/main/deploy/paths/testU.tsp new file mode 100644 index 0000000..b07c2bb Binary files /dev/null and b/src/main/deploy/paths/testU.tsp differ 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" + ] + } + ] +}