Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
42cdbb8
base work for tire model done (pure slip).... will change for combine…
shayana18 Mar 21, 2026
26f9b13
algo in progress changes
shayana18 Mar 27, 2026
7cd32b8
work in progress, most peices are there
shayana18 Apr 5, 2026
f5ef2f3
logic is there now
shayana18 Apr 8, 2026
9bcb1ba
fahh
Lucien950 Apr 8, 2026
3600b82
small changes
Lucien950 Apr 9, 2026
80aa912
a few more small changes
Lucien950 Apr 9, 2026
1e509fe
kms hours
Lucien950 Apr 9, 2026
8e44ed2
rotations
Lucien950 Apr 10, 2026
13ced94
edwin zheng forgot how to do rotation matrix
Lucien950 Apr 10, 2026
c8a8020
template metaprogramming masturbation
Lucien950 Apr 10, 2026
ffb80cd
W optimizer?
Lucien950 Apr 10, 2026
4940e26
nuclearize
Lucien950 Apr 10, 2026
9471b20
penis
Lucien950 Apr 10, 2026
731d184
name
Lucien950 Apr 10, 2026
479c14e
I didnt even know this was possible
Aditya-Dhiman4 Apr 10, 2026
3741ff9
wow
Lucien950 Apr 12, 2026
a66fb4c
L
Lucien950 Apr 12, 2026
6baefc0
maybe everything is fucked idk man, love matlab
Lucien950 Apr 13, 2026
ba10cbb
clean up matlab interface
Lucien950 Apr 13, 2026
32ceac5
small mistake
Lucien950 Apr 13, 2026
f2d8942
matplotlib and others
Lucien950 Apr 13, 2026
2dd61e9
fixed torque bounds plus multiplied speed request by gear ratio to ma…
Aditya-Dhiman4 Apr 15, 2026
a182398
tweaks for ta
Lucien950 Apr 16, 2026
68b41ff
WORKS?S???????
Lucien950 Apr 16, 2026
6c91f74
working optimizer
Lucien950 Apr 16, 2026
b95da94
torque allocator W
Lucien950 Apr 16, 2026
14cfe3f
working for floats as well now
Lucien950 Apr 16, 2026
ba6f1a5
better ig
Lucien950 Apr 16, 2026
6a3cf82
turning tests
Lucien950 Apr 16, 2026
3b10a21
consistent optimizer
Lucien950 Apr 17, 2026
2945824
Steering Model (#1949)
Aditya-Dhiman4 Apr 20, 2026
da931f5
6.2 implemented
shayana18 Apr 26, 2026
1328739
tire model :)
Lucien950 Apr 27, 2026
79d12c4
Optimizer converges, Fz temporarily removed
Aditya-Dhiman4 Jun 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion firmware/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
include(cmake/dependencies.cmake)
include(../scripts/code_generation/commit_info_gen/commit_info.cmake)
include(cmake/eigenlib.cmake)
include(cmake/eigenlib.cmake)
include(cmake/autodiff.cmake)
include(cmake/matplotlib.cmake)

IF ("${TARGET}" STREQUAL "binary")
option(BOOTLOAD "Build the bootloader" OFF)
Expand Down
56 changes: 32 additions & 24 deletions firmware/cmake/dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,19 @@ IF ("${TARGET}" STREQUAL "binary")
)
# Autodiff library: contains header only apis to automatically compute derrivatives of functions
CPMAddPackage(
NAME AUTO_DIFF
GITHUB_REPOSITORY autodiff/autodiff
GIT_TAG 2e2f3a2b16afcd9c04e76c8a689e9fd23ff78679
GIT_SHALLOW TRUE
DOWNLOAD_ONLY TRUE
NAME AUTO_DIFF
GITHUB_REPOSITORY autodiff/autodiff
GIT_TAG 2e2f3a2b16afcd9c04e76c8a689e9fd23ff78679
GIT_SHALLOW TRUE
DOWNLOAD_ONLY TRUE
)
# Eigen Library: provides support for matrices and matrix algebra
CPMAddPackage(
NAME EIGEN
GIT_REPOSITORY https://gitlab.com/libeigen/eigen
GIT_TAG 3147391d946bb4b6c68edd901f2add6ac1f31f8c
GIT_SHALLOW TRUE
DOWNLOAD_ONLY TRUE
NAME EIGEN
GIT_REPOSITORY https://gitlab.com/libeigen/eigen
GIT_TAG 3147391d946bb4b6c68edd901f2add6ac1f31f8c
GIT_SHALLOW TRUE
DOWNLOAD_ONLY TRUE
)
ELSEIF ("${TARGET}" STREQUAL "test")
# Fetch GoogleTest for unit testing.
Expand All @@ -90,29 +90,37 @@ ELSEIF ("${TARGET}" STREQUAL "test")
)
# Autodiff library: contains header only apis to automatically compute derrivatives of functions
CPMAddPackage(
NAME AUTO_DIFF
GITHUB_REPOSITORY autodiff/autodiff
GIT_TAG 2e2f3a2b16afcd9c04e76c8a689e9fd23ff78679
GIT_SHALLOW TRUE
DOWNLOAD_ONLY TRUE
NAME AUTO_DIFF
GITHUB_REPOSITORY autodiff/autodiff
GIT_TAG 2e2f3a2b16afcd9c04e76c8a689e9fd23ff78679
GIT_SHALLOW TRUE
DOWNLOAD_ONLY TRUE
)
# Eigen Library: provides support for matrices and matrix algebra
CPMAddPackage(
NAME EIGEN
GIT_REPOSITORY https://gitlab.com/libeigen/eigen
GIT_TAG 3147391d946bb4b6c68edd901f2add6ac1f31f8c
GIT_SHALLOW TRUE
DOWNLOAD_ONLY TRUE
NAME EIGEN
GIT_REPOSITORY https://gitlab.com/libeigen/eigen
GIT_TAG 3147391d946bb4b6c68edd901f2add6ac1f31f8c
GIT_SHALLOW TRUE
DOWNLOAD_ONLY TRUE
)

# pybind 11: library for creating python bindings for C++ code
CPMAddPackage(
NAME pybind11
GIT_REPOSITORY https://github.com/pybind/pybind11.git
VERSION 3.0.2
DOWNLOAD_ONLY TRUE
NAME pybind11
GIT_REPOSITORY https://github.com/pybind/pybind11.git
VERSION 3.0.2
DOWNLOAD_ONLY TRUE
)
add_subdirectory(${pybind11_SOURCE_DIR} ${pybind11_BINARY_DIR})

CPMAddPackage(
NAME matplotlibcpp
GITHUB_REPOSITORY lava/matplotlib-cpp
GIT_TAG ef0383f1315d32e0156335e10b82e90b334f6d9f
GIT_SHALLOW TRUE
DOWNLOAD_ONLY TRUE
)
ENDIF ()

# protobufs
Expand Down
20 changes: 20 additions & 0 deletions firmware/cmake/matplotlib.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
message("")
message("Configuring matplotlib-cpp...")

# Library target
find_package(Python3 COMPONENTS Development REQUIRED)
add_library(matplotlib_cpp INTERFACE)
target_include_directories(matplotlib_cpp INTERFACE ${matplotlibcpp_SOURCE_DIR})
target_link_libraries(matplotlib_cpp INTERFACE
Python3::Python
Python3::Module
)
#find_package(Python3 COMPONENTS NumPy)
#if (Python3_NumPy_FOUND)
# target_link_libraries(matplotlib_cpp INTERFACE
# Python3::NumPy
# )
#else ()
message(WARNING "NumPy not found. Matplotlib-cpp will be built without NumPy support.")
target_compile_definitions(matplotlib_cpp INTERFACE WITHOUT_NUMPY)
#endif ()
7 changes: 4 additions & 3 deletions firmware/hexray/FSM/src/io/io_apps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "hw_adcs.hpp"
#include "util_utils.hpp"
#include <cmath>
#include <algorithm>

//=====
// Geometry and ADC Constants for Pedal Sensors -> PAPPS = primary apps, SAPPS = secondary apps (same as liam's
Expand Down Expand Up @@ -71,7 +72,7 @@ static float calcAppsAngle(const float cos_law_coefficient, const float pot_len,
// Calculate the cosine law expression: (a^2 + b^2 - c^2) / (2ab)
const float value = cos_law_coefficient - pot_len * pot_len / cos_law_denominator;
const float acos_input =
CLAMP(value, -1.0f, 1.0f); // where c is represented indirectly via the measured length (pot_len)
std::clamp(value, -1.0f, 1.0f); // where c is represented indirectly via the measured length (pot_len)
return acos(acos_input);
}

Expand Down Expand Up @@ -110,7 +111,7 @@ float getPrimary(void)

// Scale the percentage to account for the dead zone.
const float pedal_percentage = (100.0f / (100.0f - DEAD_ZONE_PERCENT)) * (pedal_percentage_raw - DEAD_ZONE_PERCENT);
return CLAMP(pedal_percentage, 0.0f, 100.0f);
return std::clamp(pedal_percentage, 0.0f, 100.0f);
}

bool isPrimaryOCSC(void)
Expand Down Expand Up @@ -139,7 +140,7 @@ float getSecondary(void)

// Scale the percentage to account for the dead zone.
const float pedal_percentage = (100.0f / (100.0f - DEAD_ZONE_PERCENT)) * (pedal_percentage_raw - DEAD_ZONE_PERCENT);
return CLAMP(pedal_percentage, 0.0f, 100.0f);
return std::clamp(pedal_percentage, 0.0f, 100.0f);
}

bool isSecondaryOCSC(void)
Expand Down
38 changes: 34 additions & 4 deletions firmware/hexray/VC/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ set(SYSTEM_INCLUDE_DIRS
)

file(GLOB_RECURSE APP_SRCS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/app/*.cpp")
list(APPEND APP_SRCS)
list(APPEND APP_SRCS
"${SHARED_APP_INCLUDE_DIR_CPP}/app_pid.cpp"
)
set(APP_INCLUDE_DIRS
"${SHARED_APP_INCLUDE_DIR}" "${SHARED_APP_INCLUDE_DIR_CPP}" "${CMAKE_CURRENT_SOURCE_DIR}/src/app/"
)
Expand Down Expand Up @@ -128,7 +130,7 @@ if ("${TARGET}" STREQUAL "binary")
"${CMAKE_CURRENT_BINARY_DIR}/app"
)

target_link_libraries("hexray_VC_app.elf" PRIVATE "hexray_VC_stm32" "hexray_VC_commit_info" "hexray_VC_jsoncan" "m" "sbg_ecom_${ARM_CORE}")
target_link_libraries("hexray_VC_app.elf" PRIVATE "hexray_VC_stm32" "hexray_VC_commit_info" "hexray_VC_jsoncan" "m" "autodiff_interface" "sbg_ecom_${ARM_CORE}")
target_compile_definitions("hexray_VC_app.elf" PRIVATE VC)

add_chimera_stm32h7("hexray_VC_chimera" "${CHIMERA_SRCS}" "${CHIMERA_INCLUDE_DIRS}" "hexray_chimera_v2_proto_cm7")
Expand All @@ -143,7 +145,8 @@ elseif ("${TARGET}" STREQUAL "test")
)
set(INCLUDE_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}/test"
${APP_INCLUDE_DIRS} ${SHARED_FAKES_DIR_CPP} ${IO_INCLUDE_DIRS} ${TEST_INCLUDE_DIRS} ${SYSTEM_INCLUDE_DIRS} ${SHARED_UTIL_INCLUDE_DIR_CPP}
${APP_INCLUDE_DIRS} ${SHARED_FAKES_DIR_CPP} ${IO_INCLUDE_DIRS} ${TEST_INCLUDE_DIRS}
${SYSTEM_INCLUDE_DIRS} ${SHARED_UTIL_INCLUDE_DIR_CPP}
)
compile_gtest_executable(
"hexray_VC_test"
Expand All @@ -163,6 +166,33 @@ elseif ("${TARGET}" STREQUAL "test")
"${CMAKE_CURRENT_BINARY_DIR}/app"
)

target_link_libraries("hexray_VC_test" PRIVATE "hexray_VC_commit_info" "hexray_VC_jsoncan")
target_link_libraries("hexray_VC_test" PRIVATE "hexray_VC_commit_info" "hexray_VC_jsoncan" "autodiff_interface")
target_compile_definitions("hexray_VC_test" PRIVATE STM32H733xx)


# MATLAB STATIC LIBRARY
file(GLOB_RECURSE TV_SRCS CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/src/app/torque_vectoring/*.cpp"
"${SHARED_APP_INCLUDE_DIR_CPP}/app_pid.cpp"
)
add_library("hexray_VC_torque_vectoring" STATIC ${TV_SRCS})
target_include_directories("hexray_VC_torque_vectoring" PUBLIC "${INCLUDE_DIRS}")
target_link_libraries("hexray_VC_torque_vectoring" PUBLIC "autodiff_interface" "eigen_interface" "m")
target_compile_options("hexray_VC_torque_vectoring" PRIVATE /MT /bigobj)


# MATPLOTLIB TESTING
add_executable(test_controls)
target_sources(test_controls PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/plot_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/app/torque_vectoring/estimation/tire_model.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/app/torque_vectoring/controllers/torque_allocator.cpp"
)
target_include_directories(test_controls PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/src/app"
${SHARED_UTIL_INCLUDE_DIR_CPP}
)
target_link_libraries(test_controls PRIVATE "matplotlib_cpp" "autodiff_interface")
target_compile_options(test_controls PRIVATE /Zi)
target_link_options(test_controls PRIVATE /DEBUG /INCREMENTAL:NO)
endif ()
102 changes: 102 additions & 0 deletions firmware/hexray/VC/plot_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// ReSharper disable CppTooWideScope
#include "matplotlibcpp.h"
#include "torque_vectoring/estimation/tire_model.hpp"
#include "torque_vectoring/controllers/torque_allocator.hpp"

#include <vector>
#include <string>
#include <iomanip>

namespace plt = matplotlibcpp;

static void plot_combined_fx()
{
constexpr int n_points = 301; // includes endpoints
constexpr float fz_N = 700.0f;

std::vector<double> kappas;
kappas.reserve(n_points);
for (int i = 0; i < n_points; ++i)
{
constexpr double kappa_max = 0.6f;
constexpr double kappa_min = -0.6f;
const double t = static_cast<float>(i) / static_cast<float>(n_points - 1);
const double kappa = kappa_min + t * (kappa_max - kappa_min);
kappas.push_back(kappa);
}

for (const float alpha_rad : { 0.15f, 0.125f, 0.1f, 0.075f, 0.05f, 0.025f, 0.0f })
{
std::vector<double> fxs;
fxs.reserve(kappas.size());
for (const double kappa : kappas)
{
fxs.push_back(app::tv::estimation::tire_model.computeCombinedFx_N<double>(fz_N, alpha_rad, kappa));
}
std::stringstream ss;
ss << "\\alpha = " << std::setprecision(2) << alpha_rad;
plt::named_plot(ss.str(), kappas, fxs);
}

plt::title("F_x as a function of \\kappa and \\alpha");
plt::xlabel("\\kappa");
plt::ylabel("F_x (N)");
plt::grid(true);
plt::legend();
plt::show();
}

static void plot_combined_fy()
{
constexpr int n_points = 301; // includes endpoints
constexpr float fz_N = 700.0f;

std::vector<float> alphas;
alphas.reserve(n_points);
for (int i = 0; i < n_points; ++i)
{
constexpr float alpha_max = 0.6f;
constexpr float alpha_min = -0.6f;
const float t = static_cast<float>(i) / static_cast<float>(n_points - 1);
const float alpha = alpha_min + t * (alpha_max - alpha_min);
alphas.push_back(alpha);
}

for (const double kappa : { 0.3, 0.25, 0.2, 0.15, 0.1, 0.05, 0.0 })
{
std::vector<double> fys;
fys.reserve(alphas.size());
for (const float alpha : alphas)
{
fys.push_back(app::tv::estimation::tire_model.computeCombinedFy_N<double>(fz_N, alpha, kappa));
}
std::stringstream ss;
ss << "\\kappa = " << std::setprecision(2) << kappa;
plt::named_plot(ss.str(), alphas, fys);
}

plt::title("F_y as a function of \\alpha and \\kappa");
plt::xlabel("\\alpha");
plt::ylabel("F_y (N)");
plt::grid(true);
plt::legend();
plt::show();
}

int main()
{
// constexpr app::tv::shared_datatypes::VehicleState<double> state{
// .v_x_mps = 10,
// .v_y_mps = 0,
// .yaw_rate_radps = 0,
// .a_x_mps2 = 1,
// .a_y_mps2 = 0,
// .apps = 0.2,
// .delta = 0,
// };
// const auto [fl, fr, rl, rr] = app::tv::controllers::allocator::optimize(state, 10.0, 5.0);
// std::cout << "Optimal slip found: " << fl << " " << fr << " " << rl << " " << rr << std::endl;

// plot_combined_fx();
plot_combined_fy();
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#pragma once
#include "app_pid.hpp"

namespace app::tv::controllers::dyrc
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "controllers_dyrc.hpp"
#include "torque_vectoring/controllers/controllers_config.hpp"
#include "torque_vectoring/shared_datatypes/constants.hpp"

using namespace app::tv::shared_datatypes::vd_constants;

namespace app::tv::controllers::dyrc
{

// Configuration
static float ku = DYRC_ku; // understeer gradient

// Control Scheme
static PID pid(PID_DYRC_config);

// purely for debugging purposes
static float yaw_moment_Nm = 0.0f;
static float r_ref_rad = 0.0f;

[[nodiscard]] float computeRefYawRate(const float steer_ang_rad, const float body_velx_mps)
{
return (body_velx_mps * steer_ang_rad) / (WHEELBASE_m * (1.0f + ku * body_velx_mps * body_velx_mps));
}

[[nodiscard]] float computeYawMoment(const float r_actual_rad, const float steer_ang_rad, const float body_velx_mps)
{
r_ref_rad = computeRefYawRate(steer_ang_rad, body_velx_mps);
return yaw_moment_Nm = pid.compute(r_ref_rad, r_actual_rad, 0.0f);
}

[[nodiscard]] float getYawMoment()
{
return yaw_moment_Nm;
}

[[nodiscard]] float getRefYawRate()
{
return r_ref_rad;
}
} // namespace app::tv::controllers::dyrc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace app::tv::controllers::dyrc
*
* @return The reference yaw rate to target in rad/s
*/
[[nodiscard]] inline float computeRefYawRate(const float steer_ang_rad, const float body_velx_mps);
[[nodiscard]] float computeRefYawRate(const float steer_ang_rad, const float body_velx_mps);

/**
* @brief Computes the corrective yaw moment to apply on the vehicle to target a reference yaw rate
Expand All @@ -34,8 +34,7 @@ namespace app::tv::controllers::dyrc
*
* @return The corrective yaw moment in Nm to apply on the vehicle
*/
[[nodiscard]] inline float
computeYawMoment(const float r_actual_rad, const float steer_ang_rad, const float body_velx_mps);
[[nodiscard]] float computeYawMoment(const float r_actual_rad, const float steer_ang_rad, const float body_velx_mps);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lowkey can we calculate yawacceleration

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

??


// The functions below are getters for CAN debugging

Expand All @@ -52,4 +51,4 @@ namespace app::tv::controllers::dyrc
* @return The desired yaw rate to achieve in radians per second
*/
[[nodiscard]] float getRefYawRate();
} // namespace app::tv::controllers::dyrc
} // namespace app::tv::controllers::dyrc
Empty file.
Empty file.
Loading