diff --git a/Firmware/.vscode/c_cpp_properties.json b/Firmware/.vscode/c_cpp_properties.json index 9c1aec97..1d5ab7cf 100644 --- a/Firmware/.vscode/c_cpp_properties.json +++ b/Firmware/.vscode/c_cpp_properties.json @@ -3,7 +3,7 @@ { "name": "Win32", "includePath": [ - "${workspaceRoot}/**" + "${workspaceFolder}/**" ], "defines": [ "STM32F405xx", @@ -24,7 +24,7 @@ { "name": "Linux", "includePath": [ - "${workspaceRoot}/**" + "${workspaceFolder}/**" ], "defines": [ "STM32F405xx", @@ -44,7 +44,7 @@ { "name": "Mac", "includePath": [ - "${workspaceRoot}/**" + "${workspaceFolder}/**" ], "defines": [ "STM32F405xx", diff --git a/Firmware/MotorControl/axis.cpp b/Firmware/MotorControl/axis.cpp index d593e7bc..99339d50 100644 --- a/Firmware/MotorControl/axis.cpp +++ b/Firmware/MotorControl/axis.cpp @@ -118,12 +118,10 @@ bool Axis::wait_for_current_meas() { // step/direction interface void Axis::step_cb() { - if (step_dir_active_) { - GPIO_PinState dir_pin = HAL_GPIO_ReadPin(dir_port_, dir_pin_); - float dir = (dir_pin == GPIO_PIN_SET) ? 1.0f : -1.0f; - controller_.input_pos_ += dir * config_.turns_per_step; - controller_.input_pos_updated(); - } + const bool dir_pin = dir_port_->IDR & dir_pin_; + const int32_t dir = (-1 + 2 * dir_pin) * step_dir_active_; + controller_.input_pos_ += dir * config_.counts_per_step; + controller_.input_pos_updated(); }; void Axis::load_default_step_dir_pin_config( diff --git a/Firmware/MotorControl/controller.cpp b/Firmware/MotorControl/controller.cpp index da8ca254..ef87376a 100644 --- a/Firmware/MotorControl/controller.cpp +++ b/Firmware/MotorControl/controller.cpp @@ -26,9 +26,6 @@ void Controller::set_error(Error error) { // Command Handling //-------------------------------- -void Controller::input_pos_updated() { - input_pos_updated_ = true; -} bool Controller::select_encoder(size_t encoder_num) { if (encoder_num < AXIS_COUNT) { diff --git a/Firmware/MotorControl/controller.hpp b/Firmware/MotorControl/controller.hpp index 795176da..cb27e808 100644 --- a/Firmware/MotorControl/controller.hpp +++ b/Firmware/MotorControl/controller.hpp @@ -53,7 +53,10 @@ public: void reset(); void set_error(Error error); - void input_pos_updated(); + constexpr void input_pos_updated() { + input_pos_updated_ = true; + } + bool select_encoder(size_t encoder_num); // Trajectory-Planned control diff --git a/Firmware/build.sh b/Firmware/build.sh deleted file mode 100755 index 8f3a0730..00000000 --- a/Firmware/build.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -# Builds the firmware with the configuration specified by -# environment variables named CONFIG_... -# If DEPLOY is set, the deliverables are copied to Firmware/deploy/* -# with the suffix $DEPLOY -set -euo pipefail - -THIS_DIR="$(dirname "$0")" -cd "$THIS_DIR" - -# Treat warnings as errors -export CONFIG_STRICT=true - -# Write all environment variables that start with "CONFIG_" to tup.config -rm -rdf build -mkdir -p build -env | grep ^CONFIG > tup.config -tup init -tup generate ./tup_build.sh -bash -xe ./tup_build.sh - -# Deploy -if ! [ -z ${DEPLOY+x} ]; then - mkdir -p deploy - cp build/ODriveFirmware.elf deploy/ODriveFirmware_"$DEPLOY".elf - cp build/ODriveFirmware.hex deploy/ODriveFirmware_"$DEPLOY".hex -fi diff --git a/Firmware/communication/ascii_protocol.cpp b/Firmware/communication/ascii_protocol.cpp index c8cc3299..5efbed46 100644 --- a/Firmware/communication/ascii_protocol.cpp +++ b/Firmware/communication/ascii_protocol.cpp @@ -36,14 +36,16 @@ static Introspectable root_obj = ODriveTypeInfo::make_introspectable(odr // @brief Sends a line on the specified output. template void respond(StreamSink& output, bool include_checksum, const char * fmt, TArgs&& ... args) { - char response[64]; + char response[64]; // Hardcoded max buffer size. We silently truncate the output if it's too long for the buffer. size_t len = snprintf(response, sizeof(response), fmt, std::forward(args)...); + len = std::min(len, sizeof(response)); output.process_bytes((uint8_t*)response, len, nullptr); // TODO: use process_all instead if (include_checksum) { uint8_t checksum = 0; for (size_t i = 0; i < len; ++i) checksum ^= response[i]; len = snprintf(response, sizeof(response), "*%u", checksum); + len = std::min(len, sizeof(response)); output.process_bytes((uint8_t*)response, len, nullptr); } output.process_bytes((const uint8_t*)"\r\n", 2, nullptr); diff --git a/Firmware/communication/interface_usb.cpp b/Firmware/communication/interface_usb.cpp index 83632bcd..bbdabb3d 100644 --- a/Firmware/communication/interface_usb.cpp +++ b/Firmware/communication/interface_usb.cpp @@ -61,7 +61,7 @@ public: // Loop to ensure all bytes get sent while (length) { size_t chunk = length < USB_TX_DATA_SIZE ? length : USB_TX_DATA_SIZE; - if (output_.process_packet(buffer, length) != 0) + if (output_.process_packet(buffer, chunk) != 0) return -1; buffer += chunk; length -= chunk; diff --git a/Firmware/fibre/cpp/include/fibre/introspection.hpp b/Firmware/fibre/cpp/include/fibre/introspection.hpp index f52b73a8..f7e43f68 100644 --- a/Firmware/fibre/cpp/include/fibre/introspection.hpp +++ b/Firmware/fibre/cpp/include/fibre/introspection.hpp @@ -96,7 +96,7 @@ public: private: Introspectable get_direct_child(const char * name, size_t length) const { for (size_t i = 0; i < type_info_->property_table_length_; ++i) { - if (!strncmp(name, type_info_->property_table_[i].name, length)) { + if (!strncmp(name, type_info_->property_table_[i].name, length) && (length == strlen(type_info_->property_table_[i].name))) { Introspectable result; result.storage_ = type_info_->get_child(storage_, i); result.type_info_ = type_info_->property_table_[i].type_info; diff --git a/Firmware/find_programmer.sh b/Firmware/find_programmer.sh index 4b184b6a..cea57038 100755 --- a/Firmware/find_programmer.sh +++ b/Firmware/find_programmer.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash openocd -d3 -f board/stm32f4discovery.cfg -c "hla_serial wrong_serial" 2>&1 | \ xxd -p | \ tr -d '\n' | \ diff --git a/analysis/Simulation/TranslationalMass.py b/analysis/Simulation/TranslationalMass.py new file mode 100644 index 00000000..3cb1a4aa --- /dev/null +++ b/analysis/Simulation/TranslationalMass.py @@ -0,0 +1,35 @@ +import os +import matplotlib.pyplot as plt +from control.matlab import * + +# Input: Current (A) +# Output: Torque (Nm) +# Params: Kt (Nm/A) +def motor(Kt): + return tf(Kt, 1) + +# Mass-Spring-Damper +# Input: Force +# Output: Position +# Params: m (kg) +# b +# k (N/m) +def mass(m, b, k): + A = [[0, 1.], [-k/m, -b/m]] + B = [[0], [1/m]] + C = [[1., 0]] + return ss(A, B, C, 0) + +# Input: Torque (Nm) +# Output: Force (N) +# Params: r (m) +def pulley(r): + return tf(r, 1) + +sys = series(motor(2.5), pulley(0.015), mass(0.10, 0, 0)) +yout, T, xout = step(sys, return_x=True) +print(yout) +# plt.plot(T, yout) +plt.plot(T, xout) +plt.legend(['Displacement', 'Velocity']) +plt.show() \ No newline at end of file diff --git a/tools/odrive/tests/test_runner.py b/tools/odrive/tests/test_runner.py index 8295a1af..9633b92f 100644 --- a/tools/odrive/tests/test_runner.py +++ b/tools/odrive/tests/test_runner.py @@ -794,7 +794,7 @@ if args.setup_host: if not os.path.isfile('/usr/share/arduino/hardware/tools/teensy_post_compile_old'): os.rename('/usr/share/arduino/hardware/tools/teensy_post_compile', '/usr/share/arduino/hardware/tools/teensy_post_compile_old') with open('/usr/share/arduino/hardware/tools/teensy_post_compile', 'w') as scr: - scr.write('#!/bin/bash\n') + scr.write('#!/usr/bin/env bash\n') scr.write('if [ "$ARDUINO_COMPILE_DESTINATION" != "" ]; then\n') scr.write(' cp -r ${2#-path=}/*.ino.hex ${ARDUINO_COMPILE_DESTINATION}\n') scr.write('fi\n')