diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cb101fe..7daba39 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,15 +7,26 @@ jobs: runs-on: ubuntu-latest + strategy: + matrix: + build: + - path: '.' + target: esp32s3 + command: | + idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.test_stand" build + - path: '.' + target: esp32s3 + command: | + idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.motorgo" build + steps: - name: Checkout repo uses: actions/checkout@v4 - with: - submodules: 'recursive' - name: Build Examples uses: espressif/esp-idf-ci-action@v1 with: - esp_idf_version: release-v5.2 - target: esp32s3 - path: '.' + esp_idf_version: release-v5.4 + target: ${{ matrix.build.target }} + path: ${{ matrix.build.path }} + command: ${{ matrix.build.command }} diff --git a/.github/workflows/package_main.yml b/.github/workflows/package_main.yml index e0fed79..45164e0 100644 --- a/.github/workflows/package_main.yml +++ b/.github/workflows/package_main.yml @@ -5,6 +5,7 @@ on: branches: [main] release: types: [published] + workflow_dispatch: jobs: build: @@ -12,37 +13,68 @@ jobs: runs-on: ubuntu-latest continue-on-error: false + strategy: + matrix: + build: + - name: 'tinys3_test_stand' + path: '.' + target: esp32s3 + command: | + idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.test_stand" build + - name: 'motorgo' + path: '.' + target: esp32s3 + command: | + idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.motorgo" build + steps: - name: Checkout repo uses: actions/checkout@v4 - with: - submodules: 'recursive' - name: Build Main Code uses: espressif/esp-idf-ci-action@v1 with: - esp_idf_version: release-v5.2 - target: esp32s3 - path: '.' - command: 'idf.py build' + esp_idf_version: release-v5.4 + target: ${{ matrix.build.target }} + path: ${{ matrix.build.path }} + command: ${{ matrix.build.command }} - name: Upload Build Outputs uses: actions/upload-artifact@v4 with: - name: build-artifacts + name: ${{ matrix.build.name }}-build-artifacts path: | + build/*.bin + build/*.elf build/bootloader/bootloader.bin build/partition_table/partition-table.bin - build/bldc_test_stand.bin + build/flasher_args.json build/flash_args + - name: Zip up files for upload to release + if: ${{ github.event.release && github.event.action == 'published' }} + shell: bash + run: | + cd build + zip -r ../${{ matrix.build.name }}.zip *.bin *.elf bootloader/bootloader.bin partition_table/partition-table.bin flasher_args.json flash_args + cd .. + - name: Attach files to release uses: softprops/action-gh-release@v2 if: ${{ github.event.release && github.event.action == 'published' }} with: - files: | - build/bldc_test_stand.bin - build/bootloader/bootloader.bin - build/partition_table/partition-table.bin - build/flash_args + files: ${{ matrix.build.name }}.zip + package: + name: Package the binaries into an executables for Windows, MacOS, and Linux (Ubuntu) + needs: build + strategy: + matrix: + os: [windows-latest, macos-latest, ubuntu-latest] + build: ['tinys3_test_stand', 'motorgo'] + runs-on: ${{ matrix.os }} + steps: + - uses: esp-cpp/esp-packaged-programmer-action@v1.0.5 + with: + zipfile-name: ${{ matrix.build }}-build-artifacts + programmer-name: 'software-defined-haptics-${{ matrix.build }}_programmer' diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index c1c252f..f8dccb8 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -9,8 +9,6 @@ jobs: steps: - name: Checkout repo uses: actions/checkout@v4 - with: - submodules: 'recursive' - name: Run static analysis uses: esp-cpp/StaticAnalysis@master @@ -18,8 +16,8 @@ jobs: # Do not build the project and do not use cmake to generate compile_commands.json use_cmake: false - # Use the 5.2 release version since it's what we build with - esp_idf_version: release/v5.2 + # Use the 5.4 release version since it's what we build with + esp_idf_version: release/v5.4 # (Optional) cppcheck args - cppcheck_args: -i$GITHUB_WORKSPACE/components/espp --force --enable=all --inline-suppr --inconclusive --platform=mips32 --std=c++17 --suppressions-list=$GITHUB_WORKSPACE/suppressions.txt + cppcheck_args: --check-level=exhaustive --force --enable=all --inline-suppr --inconclusive --platform=mips32 --std=c++17 --suppressions-list=$GITHUB_WORKSPACE/suppressions.txt diff --git a/.gitignore b/.gitignore index 6a47bed..441fadb 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ build/ sdkconfig sdkconfig.old +managed_components/ diff --git a/.gitmodules b/.gitmodules index 639bc79..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "components/espp"] - path = components/espp - url = git@github.com:esp-cpp/espp diff --git a/CMakeLists.txt b/CMakeLists.txt index 961cd25..bcfd5db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,12 @@ # The following lines of boilerplate have to be in your project's CMakeLists # in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.20) include($ENV{IDF_PATH}/tools/cmake/project.cmake) # add the component directories that we want to use set(EXTRA_COMPONENT_DIRS "components/" - "components/espp/components/" ) set( diff --git a/components/espp b/components/espp deleted file mode 160000 index f7c5024..0000000 --- a/components/espp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f7c5024065fda3e8720a7b24c7f3676461e002dc diff --git a/components/tinys3_test_stand/CMakeLists.txt b/components/tinys3_test_stand/CMakeLists.txt index 117af30..24e0408 100644 --- a/components/tinys3_test_stand/CMakeLists.txt +++ b/components/tinys3_test_stand/CMakeLists.txt @@ -1,4 +1,5 @@ idf_component_register( INCLUDE_DIRS "include" + SRC_DIRS "src" REQUIRES base_component filters math mt6701 pid bldc_driver bldc_motor i2c ) diff --git a/components/tinys3_test_stand/idf_component.yml b/components/tinys3_test_stand/idf_component.yml new file mode 100644 index 0000000..72ee9ca --- /dev/null +++ b/components/tinys3_test_stand/idf_component.yml @@ -0,0 +1,23 @@ +## IDF Component Manager Manifest File +dependencies: + ## Required IDF version + idf: + version: '>=4.1.0' + # # Put list of dependencies here + # # For components maintained by Espressif: + # component: "~1.0.0" + # # For 3rd party components: + # username/component: ">=1.0.0,<2.0.0" + # username2/component2: + # version: "~1.0.0" + # # For transient dependencies `public` flag can be set. + # # `public` flag doesn't have an effect dependencies of the `main` component. + # # All dependencies of `main` are public by default. + # public: true + espp/filters: '>=1.0' + espp/math: '>=1.0' + espp/mt6701: '>=1.0' + espp/pid: '>=1.0' + espp/bldc_driver: '>=1.0' + espp/bldc_motor: '>=1.0' + espp/i2c: '>=1.0' diff --git a/components/tinys3_test_stand/include/tinys3_test_stand.hpp b/components/tinys3_test_stand/include/tinys3_test_stand.hpp index 8f8997b..23ab39a 100644 --- a/components/tinys3_test_stand/include/tinys3_test_stand.hpp +++ b/components/tinys3_test_stand/include/tinys3_test_stand.hpp @@ -22,28 +22,111 @@ namespace espp { /// - One MT6701 magnetic encoder connected via I2C class TinyS3TestStand : public BaseComponent { public: + /// Alias for the encoder type using Encoder = espp::Mt6701<>; + + /// Alias for the BLDC motor type using BldcMotor = espp::BldcMotor; - /// Constructor - /// \param verbosity The verbosity level for the logger of the MotorGo-Mini - /// and its components - explicit TinyS3TestStand(espp::Logger::Verbosity verbosity = espp::Logger::Verbosity::WARN) - : BaseComponent("TinyS3 Test Stand", verbosity) { - init(); + /// Alias for the velocity filter type + using VelocityFilter = espp::SimpleLowpassFilter; + + /// Alias for the angle filter type + using AngleFilter = espp::SimpleLowpassFilter; + + /// @brief Access the singleton instance of the TinyS3TestStand class + /// @return Reference to the singleton instance of the TinyS3TestStand class + static TinyS3TestStand &get() { + static TinyS3TestStand instance; + return instance; } - /// Get a reference to the encoder - /// \return A reference to the encoder - Encoder &encoder() { return encoder_; } + TinyS3TestStand(const TinyS3TestStand &) = delete; + TinyS3TestStand &operator=(const TinyS3TestStand &) = delete; + TinyS3TestStand(TinyS3TestStand &&) = delete; + TinyS3TestStand &operator=(TinyS3TestStand &&) = delete; + + ///////////////////////////////////////////////////////////////////////////// + // Motors + ///////////////////////////////////////////////////////////////////////////// + + /// Driver Configuration for the MotorGo-Mini Motor Driver(s) + struct DriverConfig { + float power_supply_voltage; ///< The power supply voltage in volts + float limit_voltage; ///< The limit voltage in volts + }; + + /// Default configuration for the TinyS3 Test Stand's BLDC motor + const BldcMotor::Config default_motor_config{ + .num_pole_pairs = 7, + .phase_resistance = 4.0f, + .kv_rating = 320, + .current_limit = 1.0f, + .foc_type = espp::detail::FocType::SPACE_VECTOR_PWM, + .driver = motor_driver_, // NOTE: user cannot override this + .sensor = encoder_, // NOTE: user cannot override this + .velocity_pid_config = + { + .kp = 0.020f, + .ki = 0.700f, + .kd = 0.000f, + .integrator_min = -1.0f, // same scale as output_min (so same scale as current) + .integrator_max = 1.0f, // same scale as output_max (so same scale as current) + .output_min = -1.0, // velocity pid works on current (if we have phase resistance) + .output_max = 1.0, // velocity pid works on current (if we have phase resistance) + }, + .angle_pid_config = + { + .kp = 5.000f, + .ki = 1.000f, + .kd = 0.000f, + .integrator_min = -10.0f, // same scale as output_min (so same scale as velocity) + .integrator_max = 10.0f, // same scale as output_max (so same scale as velocity) + .output_min = -20.0, // angle pid works on velocity (rad/s) + .output_max = 20.0, // angle pid works on velocity (rad/s) + }, + .velocity_filter = [this](float v) { return motor_velocity_filter_(v); }, + .angle_filter = [this](float a) { return motor_angle_filter_(a); }, + }; + + /// Initialize the TinyS3's components for its motor + /// \details This function initializes the encoder, driver, and motor. This + /// consists of initializing encoder, motor_driver, and motor. + /// \param motor_config The motor configuration + /// \param driver_config The driver configuration + void init_motor(const BldcMotor::Config &motor_config, + const DriverConfig &driver_config = {.power_supply_voltage = 5.0f, + .limit_voltage = 5.0f}); /// Get a reference to the motor driver - /// \return A reference to the motor driver - espp::BldcDriver &motor_driver() { return motor_driver_; } + /// \return A shared pointer to the motor driver + std::shared_ptr motor_driver(); /// Get a reference to the motor - /// \return A reference to the motor - BldcMotor &motor() { return motor_; } + /// \return A shared pointer to the motor + std::shared_ptr motor(); + + /// Get a reference to the motor velocity filter + /// \return A reference to the motor velocity filter + VelocityFilter &motor_velocity_filter(); + + /// Get a reference to the motor angle filter + /// \return A reference to the motor angle filter + AngleFilter &motor_angle_filter(); + + ///////////////////////////////////////////////////////////////////////////// + // Encoders + ///////////////////////////////////////////////////////////////////////////// + + /// Get a reference to the encoder + /// \return A shared pointer to the encoder + std::shared_ptr encoder(); + + /// Reset the encoder accumulator + /// \details This function resets the encoder accumulator to 0. + /// This will reset the encoder's position to be within the range + /// of 0 to 2*pi. + void reset_encoder_accumulator(); protected: static constexpr auto I2C_PORT = I2C_NUM_0; @@ -61,21 +144,7 @@ class TinyS3TestStand : public BaseComponent { static constexpr auto MOTOR_ENABLE = GPIO_NUM_34; static constexpr auto MOTOR_FAULT = GPIO_NUM_36; - void init() { - init_encoder(); - init_motor(); - } - - void init_encoder() { - bool run_task = true; - std::error_code ec; - encoder_.initialize(run_task, ec); - if (ec) { - logger_.error("Could not initialize encoder: {}", ec.message()); - } - } - - void init_motor() { motor_.initialize(); } + explicit TinyS3TestStand(); /// I2C bus for external communication I2c i2c_{{ @@ -88,68 +157,42 @@ class TinyS3TestStand : public BaseComponent { }}; // Encoder - Encoder encoder_{ - {.write = std::bind(&espp::I2c::write, &i2c_, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3), - .read = std::bind(&espp::I2c::read, &i2c_, std::placeholders::_1, std::placeholders::_2, + Encoder::Config encoder_config_{ + .write = std::bind(&espp::I2c::write, &i2c_, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - .update_period = std::chrono::duration(core_update_period_us / 1e6f), - .auto_init = false, // we have to initialize the SPI first before we can use the encoder - .log_level = get_log_level()}}; + .read = std::bind(&espp::I2c::read, &i2c_, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3), + .update_period = std::chrono::duration(core_update_period_us / 1e6f), + .log_level = get_log_level()}; + + // NOTE: use explicit type of nullptr to force allocation of control block, so + // that it can be shared even if it's nullptr; + std::shared_ptr encoder_{(Encoder *)(nullptr)}; // Driver - espp::BldcDriver motor_driver_{{.gpio_a_h = MOTOR_A_H, - .gpio_a_l = MOTOR_A_L, - .gpio_b_h = MOTOR_B_H, - .gpio_b_l = MOTOR_B_L, - .gpio_c_h = MOTOR_C_H, - .gpio_c_l = MOTOR_C_L, - .gpio_enable = MOTOR_ENABLE, - .gpio_fault = MOTOR_FAULT, - .power_supply_voltage = 5.0f, - .limit_voltage = 5.0f, - .log_level = get_log_level()}}; + espp::BldcDriver::Config motor_driver_config_{ + .gpio_a_h = MOTOR_A_H, + .gpio_a_l = MOTOR_A_L, + .gpio_b_h = MOTOR_B_H, + .gpio_b_l = MOTOR_B_L, + .gpio_c_h = MOTOR_C_H, + .gpio_c_l = MOTOR_C_L, + .gpio_enable = MOTOR_ENABLE, + .gpio_fault = MOTOR_FAULT, + .power_supply_voltage = 5.0f, // NOTE: can be replaced by user + .limit_voltage = 5.0f, // NOTE: can be replaced by user + .log_level = get_log_level()}; + // NOTE: use explicit type of nullptr to force allocation of control block, so + // that it can be shared even if it's nullptr; + std::shared_ptr motor_driver_{(espp::BldcDriver *)(nullptr)}; // Filters - espp::SimpleLowpassFilter motor_velocity_filter_{{.time_constant = 0.005f}}; - espp::SimpleLowpassFilter motor_angle_filter_{{.time_constant = 0.001f}}; + VelocityFilter motor_velocity_filter_{{.time_constant = 0.005f}}; + AngleFilter motor_angle_filter_{{.time_constant = 0.001f}}; // Motor - BldcMotor motor_{{ - .num_pole_pairs = 7, - .phase_resistance = 5.0f, - .kv_rating = 320, - .current_limit = 1.0f, - .foc_type = espp::detail::FocType::SPACE_VECTOR_PWM, - // create shared_ptr from raw pointer to ensure shared_ptr doesn't delete the object - .driver = - std::shared_ptr(std::shared_ptr{}, &motor_driver_), - // create shared_ptr from raw pointer to ensure shared_ptr doesn't delete the object - .sensor = std::shared_ptr(std::shared_ptr{}, &encoder_), - .velocity_pid_config = - { - .kp = 0.010f, - .ki = 1.000f, - .kd = 0.000f, - .integrator_min = -1.0f, // same scale as output_min (so same scale as current) - .integrator_max = 1.0f, // same scale as output_max (so same scale as current) - .output_min = -1.0, // velocity pid works on current (if we have phase resistance) - .output_max = 1.0, // velocity pid works on current (if we have phase resistance) - }, - .angle_pid_config = - { - .kp = 7.000f, - .ki = 0.300f, - .kd = 0.010f, - .integrator_min = -10.0f, // same scale as output_min (so same scale as velocity) - .integrator_max = 10.0f, // same scale as output_max (so same scale as velocity) - .output_min = -20.0, // angle pid works on velocity (rad/s) - .output_max = 20.0, // angle pid works on velocity (rad/s) - }, - .velocity_filter = [this](auto v) { return motor_velocity_filter_(v); }, - .angle_filter = [this](auto v) { return motor_angle_filter_(v); }, - .auto_init = false, // we have to initialize the SPI first before we can use the encoder - .log_level = get_log_level(), - }}; + // NOTE: use explicit type of nullptr to force allocation of control block, so + // that it can be shared even if it's nullptr; + std::shared_ptr motor_{(BldcMotor *)(nullptr)}; }; } // namespace espp diff --git a/components/tinys3_test_stand/src/tinys3_test_stand.cpp b/components/tinys3_test_stand/src/tinys3_test_stand.cpp new file mode 100644 index 0000000..6cd9c83 --- /dev/null +++ b/components/tinys3_test_stand/src/tinys3_test_stand.cpp @@ -0,0 +1,48 @@ +#include "tinys3_test_stand.hpp" + +using namespace espp; + +TinyS3TestStand::TinyS3TestStand() + : BaseComponent("TinyS3 Test Stand") {} + +void TinyS3TestStand::init_motor(const TinyS3TestStand::BldcMotor::Config &motor_config, + const TinyS3TestStand::DriverConfig &driver_config) { + bool run_task = true; + std::error_code ec; + // make the encoder + encoder_ = std::make_shared(encoder_config_); + // initialize the encoder + encoder_->initialize(run_task, ec); + if (ec) { + logger_.error("Could not initialize encoder: {}", ec.message()); + return; + } + + // copy the config data for the driver + motor_driver_config_.power_supply_voltage = driver_config.power_supply_voltage; + motor_driver_config_.limit_voltage = driver_config.limit_voltage; + // make the driver + motor_driver_ = std::make_shared(motor_driver_config_); + + // now copy the relevant configs into the motor config + auto motor_config_copy = motor_config; + motor_config_copy.driver = motor_driver_; + motor_config_copy.sensor = encoder_; + // now make the motor + motor_ = std::make_shared(motor_config_copy); + motor_->initialize(); +} + +std::shared_ptr TinyS3TestStand::encoder() { return encoder_; } + +void TinyS3TestStand::reset_encoder_accumulator() { encoder_->reset_accumulator(); } + +std::shared_ptr TinyS3TestStand::motor_driver() { return motor_driver_; } + +std::shared_ptr TinyS3TestStand::motor() { return motor_; } + +TinyS3TestStand::VelocityFilter &TinyS3TestStand::motor_velocity_filter() { + return motor_velocity_filter_; +} + +TinyS3TestStand::AngleFilter &TinyS3TestStand::motor_angle_filter() { return motor_angle_filter_; } diff --git a/dependencies.lock b/dependencies.lock new file mode 100644 index 0000000..09500e1 --- /dev/null +++ b/dependencies.lock @@ -0,0 +1,396 @@ +dependencies: + espp/adc: + component_hash: ddc044e9e275a773438d04a268e83e2d2c3ad13610b46815ff8dffec9128db99 + dependencies: + - name: espp/base_component + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/task + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com + type: service + version: 1.0.4 + espp/base_component: + component_hash: a9d22731af1f5ba1a4e964580adf80aa4df396ab1aba84fe86f42e78e09382d0 + dependencies: + - name: espp/logger + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com + type: service + version: 1.0.4 + espp/base_peripheral: + component_hash: 176d533324b5b6751f9d61b395ea15514afa155d0621e97c6ff12841dd5dab16 + dependencies: + - name: espp/base_component + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com + type: service + version: 1.0.4 + espp/bldc_driver: + component_hash: f8463ed4ddb86943bbfdfd23435220a10e1aae23566c6a667208eb38e8506348 + dependencies: + - name: espp/base_component + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.0.4 + espp/bldc_haptics: + component_hash: ef524abc695252b2a788aaf9cbc89418e8c32d5caf1e4b3e207e0677b09c088b + dependencies: + - name: espp/base_component + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/bldc_motor + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/math + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/pid + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/task + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.0.4 + espp/bldc_motor: + component_hash: 6e393066b9eb8b5d3698c570a5db57bf3e80cb64fff129fe677f2d20c726482d + dependencies: + - name: idf + require: private + version: '>=5.0' + - name: espp/base_component + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/math + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/pid + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/task + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.0.4 + espp/cli: + component_hash: b8f300efa46d6a8c2ff9332f94f2fa283605c34f4f7f4da9c5c8dd2b5f669ef5 + dependencies: + - name: espp/logger + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.0.4 + espp/filters: + component_hash: 27b6e084aae69247090ce9e904ea218a2f15afefe186ef0eae60c25dd1950e12 + dependencies: + - name: espp/format + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/math + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espressif/esp-dsp + registry_url: https://components.espressif.com + require: private + version: '>=1.6.4' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.0.4 + espp/format: + component_hash: 3581dbbae616c2641a45037f2f844c31e7d05352339783ac06cadcb0b53d1403 + dependencies: + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com + type: service + version: 1.0.4 + espp/i2c: + component_hash: 235600292e09c9f4a1d313d7e0ae4304d9d6ca2753bac001bb5ff26936609b72 + dependencies: + - name: espp/base_component + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/cli + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/task + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.0.4 + espp/interrupt: + component_hash: 1ef551d0f7de1b6196e6277ca7a3fd8eaf5e513608e7a76cb50acaed5aac02f1 + dependencies: + - name: espp/task + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + - name: espp/base_component + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + source: + registry_url: https://components.espressif.com + type: service + version: 1.0.4 + espp/led: + component_hash: b8856570ddf1cc93f7b96904a0e30169478e9ce9d9cdf6705e85ecd46dba2b96 + dependencies: + - name: espp/base_component + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/task + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com + type: service + version: 1.0.4 + espp/logger: + component_hash: 493f2c761f562e2cb2b601263871dc3b67a492758f085444dbf2736d6ebc1c7f + dependencies: + - name: espp/format + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com + type: service + version: 1.0.4 + espp/math: + component_hash: b4e997b1d080c696bbb83e4c984aca2a0f8e9d3bf63d9577baf60e528ff8686d + dependencies: + - name: espp/format + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.0.4 + espp/motorgo-mini: + component_hash: 70af02ad21b93e8160d759cbd824efdf9022790406f22ae3f2e03bca1772962c + dependencies: + - name: espp/adc + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/base_component + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/bldc_driver + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/bldc_motor + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/filters + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/i2c + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/interrupt + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/led + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/math + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/mt6701 + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/pid + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/task + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.0.4 + espp/mt6701: + component_hash: 62a3cda844e08f7d62e92d5db380b4980182965b6a4f6e3e72a515d5230f1141 + dependencies: + - name: espp/base_peripheral + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: espp/timer + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.0.4 + espp/pid: + component_hash: 6b2f5e3a5f424499ed85b65ea235d544e6963d20dcf3581096e4a9c0ed90cc52 + dependencies: + - name: espp/base_component + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.0.4 + espp/task: + component_hash: 87ee9724c85f353cdfdc8420c63b3c7d03852084adf2bd842f45308ab805e932 + dependencies: + - name: espp/base_component + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com + type: service + version: 1.0.4 + espp/timer: + component_hash: 655bf9f6ec6209c5a62f293246b5e17d9db89787f78e33468a30f3ba941a8cf7 + dependencies: + - name: espp/task + registry_url: https://components.espressif.com + require: private + version: '>=1.0' + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com + type: service + version: 1.0.4 + espressif/esp-dsp: + component_hash: ccfd6c9a7799cf66ee044d0239a0e9304431564495d80b3230083c58291a2a23 + dependencies: + - name: idf + require: private + version: '>=4.2' + source: + registry_url: https://components.espressif.com + type: service + version: 1.6.4 + idf: + source: + type: idf + version: 5.4.1 +direct_dependencies: +- espp/bldc_driver +- espp/bldc_haptics +- espp/bldc_motor +- espp/cli +- espp/filters +- espp/i2c +- espp/math +- espp/motorgo-mini +- espp/mt6701 +- espp/pid +- idf +manifest_hash: 51a441b07c8fcb224feecb225df7992e1db285abf68ad0c5d4be80f54d444ef0 +target: esp32s3 +version: 2.0.0 diff --git a/main/idf_component.yml b/main/idf_component.yml new file mode 100644 index 0000000..7200326 --- /dev/null +++ b/main/idf_component.yml @@ -0,0 +1,20 @@ +## IDF Component Manager Manifest File +dependencies: + ## Required IDF version + idf: + version: '>=4.1.0' + # # Put list of dependencies here + # # For components maintained by Espressif: + # component: "~1.0.0" + # # For 3rd party components: + # username/component: ">=1.0.0,<2.0.0" + # username2/component2: + # version: "~1.0.0" + # # For transient dependencies `public` flag can be set. + # # `public` flag doesn't have an effect dependencies of the `main` component. + # # All dependencies of `main` are public by default. + # public: true + espp/motorgo-mini: '>=1.0' + espp/cli: '>=1.0' + espp/filters: '>=1.0' + espp/bldc_haptics: '>=1.0' diff --git a/main/main.cpp b/main/main.cpp index 8729cbc..0978a84 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -19,24 +19,25 @@ extern "C" void app_main(void) { logger.info("Using MotorGo Mini hardware configuration"); // we don't want to init both motors, so we'll pass in auto_init=false auto &motorgo_mini = espp::MotorGoMini::get(); - motorgo_mini.init_motor_channel_1(); - auto &motor = motorgo_mini.motor1(); + auto motor1_config = motorgo_mini.default_motor1_config; + motorgo_mini.init_motor_channel_1(motor1_config); + auto motor = motorgo_mini.motor1(); using BldcHaptics = espp::BldcHaptics; #elif CONFIG_EXAMPLE_HARDWARE_TEST_STAND #pragma message("Using TinyS3 Test Stand hardware configuration") logger.info("Using TinyS3 Test Stand hardware configuration"); - espp::TinyS3TestStand test_stand(espp::Logger::Verbosity::INFO); - auto &motor = test_stand.motor(); + auto &test_stand = espp::TinyS3TestStand::get(); + auto motor = test_stand.motor(); using BldcHaptics = espp::BldcHaptics; #else #error "No hardware configuration selected" #endif - auto haptic_motor = BldcHaptics({.motor = motor, - .kp_factor = 2, - .kd_factor_min = 0.01, - .kd_factor_max = 0.04, - .log_level = espp::Logger::Verbosity::WARN}); + auto haptic_motor = BldcHaptics(BldcHaptics::Config{.motor = motor, + .kp_factor = 2, + .kd_factor_min = 0.01, + .kd_factor_max = 0.04, + .log_level = espp::Logger::Verbosity::WARN}); // set the default detent config to be unbounded no detents so that if haptic_motor.update_detent_config(espp::detail::UNBOUNDED_NO_DETENTS); @@ -73,13 +74,13 @@ extern "C" void app_main(void) { root_menu->Insert( "shaft_angle", [&](std::ostream &out) { - out << "Current shaft angle: " << motor.get_shaft_angle() << " radians\n"; + out << "Current shaft angle: " << motor->get_shaft_angle() << " radians\n"; }, "Print the current position of the haptic motor"); root_menu->Insert( "electrical_angle", [&](std::ostream &out) { - out << "Current electrical angle: " << motor.get_electrical_angle() << " radians\n"; + out << "Current electrical angle: " << motor->get_electrical_angle() << " radians\n"; }, "Print the current position of the haptic motor"); root_menu->Insert( @@ -147,6 +148,7 @@ extern "C" void app_main(void) { "Set the haptic config to return to center with detents"); root_menu->Insert( "click", + // cppcheck-suppress constParameterReference [&](std::ostream &out, float strength) { strength = std::clamp(strength, 0.0f, 10.0f); espp::detail::HapticConfig config{ diff --git a/sdkconfig.motorgo b/sdkconfig.motorgo new file mode 100644 index 0000000..cb02904 --- /dev/null +++ b/sdkconfig.motorgo @@ -0,0 +1 @@ +CONFIG_EXAMPLE_HARDWARE_MOTORGO_MINI=y diff --git a/sdkconfig.test_stand b/sdkconfig.test_stand new file mode 100644 index 0000000..be08473 --- /dev/null +++ b/sdkconfig.test_stand @@ -0,0 +1 @@ +CONFIG_EXAMPLE_HARDWARE_TEST_STAND=y