From 1d73af17cc24d0cd464f24ee4073363a7b0045f0 Mon Sep 17 00:00:00 2001 From: Scott Bezek Date: Wed, 14 Jun 2023 22:43:20 -0700 Subject: [PATCH] SPIFFS persistent storage for motor calibration (#122) - New Configuration class for managing persistent configuration - New proto messages for serialized configuration, with flexibility for expansion - Load persistent configuration at startup, if available, use for default motor calibration - Save motor calibration to persistent configuration file --- firmware/src/configuration.cpp | 125 +++++++++++++++++++++ firmware/src/configuration.h | 33 ++++++ firmware/src/main.cpp | 11 +- firmware/src/motor_task.cpp | 33 +++--- firmware/src/motor_task.h | 4 +- firmware/src/proto_gen/smartknob.pb.c | 6 + firmware/src/proto_gen/smartknob.pb.h | 44 ++++++++ platformio.ini | 3 +- proto/smartknob.proto | 11 ++ software/python/proto_gen/smartknob_pb2.py | 22 +++- 10 files changed, 272 insertions(+), 20 deletions(-) create mode 100644 firmware/src/configuration.cpp create mode 100644 firmware/src/configuration.h diff --git a/firmware/src/configuration.cpp b/firmware/src/configuration.cpp new file mode 100644 index 0000000..a0adf68 --- /dev/null +++ b/firmware/src/configuration.cpp @@ -0,0 +1,125 @@ +#include + +#include "pb_decode.h" +#include "pb_encode.h" + +#include "proto_gen/smartknob.pb.h" +#include "semaphore_guard.h" + +#include "configuration.h" + +static const char* CONFIG_PATH = "/config.pb"; + +Configuration::Configuration() { + mutex_ = xSemaphoreCreateMutex(); + assert(mutex_ != NULL); +} + +Configuration::~Configuration() { + vSemaphoreDelete(mutex_); +} + +bool Configuration::loadFromDisk() { + SemaphoreGuard lock(mutex_); + if (!SPIFFS.begin(true)) { + log("Failed to mount SPIFFS"); + return false; + } + + File f = SPIFFS.open(CONFIG_PATH); + if (!f) { + log("Failed to read config file"); + return false; + } + + size_t read = f.readBytes((char*)buffer_, sizeof(buffer_)); + f.close(); + + pb_istream_t stream = pb_istream_from_buffer(buffer_, read); + if (!pb_decode(&stream, PB_PersistentConfiguration_fields, &pb_buffer_)) { + char buf[200]; + snprintf(buf, sizeof(buf), "Decoding failed: %s", PB_GET_ERROR(&stream)); + log(buf); + return false; + } + + if (pb_buffer_.version != PERSISTENT_CONFIGURATION_VERSION) { + char buf[200]; + snprintf(buf, sizeof(buf), "Invalid config version. Expected %u, received %u", PERSISTENT_CONFIGURATION_VERSION, pb_buffer_.version); + log(buf); + return false; + } + loaded_ = true; + + char buf[200]; + snprintf( + buf, + sizeof(buf), + "Motor calibration: calib=%u, pole_pairs=%u, zero_offset=%.2f, cw=%u", + pb_buffer_.motor.calibrated, + pb_buffer_.motor.pole_pairs, + pb_buffer_.motor.zero_electrical_offset, + pb_buffer_.motor.direction_cw + ); + log(buf); + return true; +} + +bool Configuration::saveToDisk() { + SemaphoreGuard lock(mutex_); + + pb_ostream_t stream = pb_ostream_from_buffer(buffer_, sizeof(buffer_)); + pb_buffer_.version = PERSISTENT_CONFIGURATION_VERSION; + if (!pb_encode(&stream, PB_PersistentConfiguration_fields, &pb_buffer_)) { + char buf[200]; + snprintf(buf, sizeof(buf), "Encoding failed: %s", PB_GET_ERROR(&stream)); + log(buf); + return false; + } + + File f = SPIFFS.open(CONFIG_PATH, FILE_WRITE); + if (!f) { + log("Failed to read config file"); + return false; + } + size_t written = f.write(buffer_, stream.bytes_written); + f.close(); + + char buf[20]; + snprintf(buf, sizeof(buf), "Wrote %d bytes", written); + log(buf); + + if (written != stream.bytes_written) { + log("Failed to write all bytes to file"); + return false; + } + + return true; +} + +PB_PersistentConfiguration Configuration::get() { + SemaphoreGuard lock(mutex_); + if (!loaded_) { + return PB_PersistentConfiguration(); + } + return pb_buffer_; +} + +bool Configuration::setMotorCalibrationAndSave(PB_MotorCalibration& motor_calibration) { + { + SemaphoreGuard lock(mutex_); + pb_buffer_.motor = motor_calibration; + pb_buffer_.has_motor = true; + } + return saveToDisk(); +} + +void Configuration::setLogger(Logger* logger) { + logger_ = logger; +} + +void Configuration::log(const char* msg) { + if (logger_ != nullptr) { + logger_->log(msg); + } +} diff --git a/firmware/src/configuration.h b/firmware/src/configuration.h new file mode 100644 index 0000000..0835d16 --- /dev/null +++ b/firmware/src/configuration.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +#include "proto_gen/smartknob.pb.h" + +#include "logger.h" + +const uint32_t PERSISTENT_CONFIGURATION_VERSION = 1; + +class Configuration { + public: + Configuration(); + ~Configuration(); + + void setLogger(Logger* logger); + bool loadFromDisk(); + bool saveToDisk(); + PB_PersistentConfiguration get(); + bool setMotorCalibrationAndSave(PB_MotorCalibration& motor_calibration); + + private: + SemaphoreHandle_t mutex_; + + Logger* logger_ = nullptr; + bool loaded_ = false; + PB_PersistentConfiguration pb_buffer_ = {}; + + uint8_t buffer_[PB_PersistentConfiguration_size]; + + void log(const char* msg); +}; diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp index 341868b..fc60540 100644 --- a/firmware/src/main.cpp +++ b/firmware/src/main.cpp @@ -1,16 +1,19 @@ #include +#include "configuration.h" #include "display_task.h" #include "interface_task.h" #include "motor_task.h" +Configuration config; + #if SK_DISPLAY static DisplayTask display_task(0); static DisplayTask* display_task_p = &display_task; #else static DisplayTask* display_task_p = nullptr; #endif -static MotorTask motor_task(1); +static MotorTask motor_task(1, config); InterfaceTask interface_task(0, motor_task, display_task_p); @@ -24,9 +27,13 @@ void setup() { motor_task.addListener(display_task.getKnobStateQueue()); #endif + interface_task.begin(); + + config.setLogger(&interface_task); + config.loadFromDisk(); + motor_task.setLogger(&interface_task); motor_task.begin(); - interface_task.begin(); // Free up the Arduino loop task vTaskDelete(NULL); diff --git a/firmware/src/motor_task.cpp b/firmware/src/motor_task.cpp index ccdb331..5657d1b 100644 --- a/firmware/src/motor_task.cpp +++ b/firmware/src/motor_task.cpp @@ -12,15 +12,6 @@ #include "motors/motor_config.h" #include "util.h" -// #### -// Hardware-specific motor calibration constants. -// Run calibration once at startup, then update these constants with the calibration results. -static const float ZERO_ELECTRICAL_OFFSET = 7.61; -static const Direction FOC_DIRECTION = Direction::CW; -static const int MOTOR_POLE_PAIRS = 7; -// #### - - static const float DEAD_ZONE_DETENT_PERCENT = 0.2; static const float DEAD_ZONE_RAD = 1 * _PI / 180; @@ -31,7 +22,7 @@ static const float IDLE_CORRECTION_MAX_ANGLE_RAD = 5 * PI / 180; static const float IDLE_CORRECTION_RATE_ALPHA = 0.0005; -MotorTask::MotorTask(const uint8_t task_core) : Task("Motor", 2500, 1, task_core) { +MotorTask::MotorTask(const uint8_t task_core, Configuration& configuration) : Task("Motor", 3200, 1, task_core), configuration_(configuration) { queue_ = xQueueCreate(5, sizeof(Command)); assert(queue_ != NULL); } @@ -86,8 +77,9 @@ void MotorTask::run() { encoder.update(); delay(10); - motor.pole_pairs = MOTOR_POLE_PAIRS; - motor.initFOC(ZERO_ELECTRICAL_OFFSET, FOC_DIRECTION); + PB_PersistentConfiguration c = configuration_.get(); + motor.pole_pairs = c.motor.calibrated ? c.motor.pole_pairs : 7; + motor.initFOC(c.motor.zero_electrical_offset, c.motor.direction_cw ? Direction::CW : Direction::CCW); motor.monitor_downsample = 0; // disable monitor at first - optional @@ -524,13 +516,13 @@ void MotorTask::calibrate() { // #### Apply settings - // TODO: save to non-volatile storage motor.pole_pairs = measured_pole_pairs; motor.zero_electric_angle = avg_offset_angle + _3PI_2; motor.voltage_limit = FOC_VOLTAGE_LIMIT; motor.controller = MotionControlType::torque; - log("\n\nRESULTS:\n Update these constants at the top of " __FILE__); + log(""); + log("RESULTS:"); snprintf(buf_, sizeof(buf_), " ZERO_ELECTRICAL_OFFSET: %.2f", motor.zero_electric_angle); log(buf_); if (motor.sensor_direction == Direction::CW) { @@ -540,7 +532,18 @@ void MotorTask::calibrate() { } snprintf(buf_, sizeof(buf_), " MOTOR_POLE_PAIRS: %d", motor.pole_pairs); log(buf_); - delay(2000); + + log(""); + log("Saving to persistent configuration..."); + PB_MotorCalibration calibration = { + .calibrated = true, + .zero_electrical_offset = motor.zero_electric_angle, + .direction_cw = motor.sensor_direction == Direction::CW, + .pole_pairs = motor.pole_pairs, + }; + if (configuration_.setMotorCalibrationAndSave(calibration)) { + log("Success!"); + } } void MotorTask::checkSensorError() { diff --git a/firmware/src/motor_task.h b/firmware/src/motor_task.h index 0801410..9f8e4ec 100644 --- a/firmware/src/motor_task.h +++ b/firmware/src/motor_task.h @@ -4,6 +4,7 @@ #include #include +#include "configuration.h" #include "logger.h" #include "proto_gen/smartknob.pb.h" #include "task.h" @@ -33,7 +34,7 @@ class MotorTask : public Task { friend class Task; // Allow base Task to invoke protected run() public: - MotorTask(const uint8_t task_core); + MotorTask(const uint8_t task_core, Configuration& configuration); ~MotorTask(); void setConfig(const PB_SmartKnobConfig& config); @@ -47,6 +48,7 @@ class MotorTask : public Task { void run(); private: + Configuration& configuration_; QueueHandle_t queue_; Logger* logger_; std::vector listeners_; diff --git a/firmware/src/proto_gen/smartknob.pb.c b/firmware/src/proto_gen/smartknob.pb.c index c67fe58..9d3db19 100644 --- a/firmware/src/proto_gen/smartknob.pb.c +++ b/firmware/src/proto_gen/smartknob.pb.c @@ -27,4 +27,10 @@ PB_BIND(PB_SmartKnobConfig, PB_SmartKnobConfig, AUTO) PB_BIND(PB_RequestState, PB_RequestState, AUTO) +PB_BIND(PB_PersistentConfiguration, PB_PersistentConfiguration, AUTO) + + +PB_BIND(PB_MotorCalibration, PB_MotorCalibration, AUTO) + + diff --git a/firmware/src/proto_gen/smartknob.pb.h b/firmware/src/proto_gen/smartknob.pb.h index 7e4870e..0149ff5 100644 --- a/firmware/src/proto_gen/smartknob.pb.h +++ b/firmware/src/proto_gen/smartknob.pb.h @@ -73,6 +73,19 @@ typedef struct _PB_ToSmartknob { } payload; } PB_ToSmartknob; +typedef struct _PB_MotorCalibration { + bool calibrated; + float zero_electrical_offset; + bool direction_cw; + uint32_t pole_pairs; +} PB_MotorCalibration; + +typedef struct _PB_PersistentConfiguration { + uint32_t version; + bool has_motor; + PB_MotorCalibration motor; +} PB_PersistentConfiguration; + #ifdef __cplusplus extern "C" { @@ -86,6 +99,8 @@ extern "C" { #define PB_SmartKnobState_init_default {0, 0, false, PB_SmartKnobConfig_init_default} #define PB_SmartKnobConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, {0, 0, 0, 0, 0}, 0} #define PB_RequestState_init_default {0} +#define PB_PersistentConfiguration_init_default {0, false, PB_MotorCalibration_init_default} +#define PB_MotorCalibration_init_default {0, 0, 0, 0} #define PB_FromSmartKnob_init_zero {0, 0, {PB_Ack_init_zero}} #define PB_ToSmartknob_init_zero {0, 0, 0, {PB_RequestState_init_zero}} #define PB_Ack_init_zero {0} @@ -93,6 +108,8 @@ extern "C" { #define PB_SmartKnobState_init_zero {0, 0, false, PB_SmartKnobConfig_init_zero} #define PB_SmartKnobConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, {0, 0, 0, 0, 0}, 0} #define PB_RequestState_init_zero {0} +#define PB_PersistentConfiguration_init_zero {0, false, PB_MotorCalibration_init_zero} +#define PB_MotorCalibration_init_zero {0, 0, 0, 0} /* Field tags (for use in manual encoding/decoding) */ #define PB_Ack_nonce_tag 1 @@ -120,6 +137,12 @@ extern "C" { #define PB_ToSmartknob_nonce_tag 2 #define PB_ToSmartknob_request_state_tag 3 #define PB_ToSmartknob_smartknob_config_tag 4 +#define PB_MotorCalibration_calibrated_tag 1 +#define PB_MotorCalibration_zero_electrical_offset_tag 2 +#define PB_MotorCalibration_direction_cw_tag 3 +#define PB_MotorCalibration_pole_pairs_tag 4 +#define PB_PersistentConfiguration_version_tag 1 +#define PB_PersistentConfiguration_motor_tag 2 /* Struct field encoding specification for nanopb */ #define PB_FromSmartKnob_FIELDLIST(X, a) \ @@ -182,6 +205,21 @@ X(a, STATIC, SINGULAR, FLOAT, snap_point_bias, 12) #define PB_RequestState_CALLBACK NULL #define PB_RequestState_DEFAULT NULL +#define PB_PersistentConfiguration_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, version, 1) \ +X(a, STATIC, OPTIONAL, MESSAGE, motor, 2) +#define PB_PersistentConfiguration_CALLBACK NULL +#define PB_PersistentConfiguration_DEFAULT NULL +#define PB_PersistentConfiguration_motor_MSGTYPE PB_MotorCalibration + +#define PB_MotorCalibration_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, BOOL, calibrated, 1) \ +X(a, STATIC, SINGULAR, FLOAT, zero_electrical_offset, 2) \ +X(a, STATIC, SINGULAR, BOOL, direction_cw, 3) \ +X(a, STATIC, SINGULAR, UINT32, pole_pairs, 4) +#define PB_MotorCalibration_CALLBACK NULL +#define PB_MotorCalibration_DEFAULT NULL + extern const pb_msgdesc_t PB_FromSmartKnob_msg; extern const pb_msgdesc_t PB_ToSmartknob_msg; extern const pb_msgdesc_t PB_Ack_msg; @@ -189,6 +227,8 @@ extern const pb_msgdesc_t PB_Log_msg; extern const pb_msgdesc_t PB_SmartKnobState_msg; extern const pb_msgdesc_t PB_SmartKnobConfig_msg; extern const pb_msgdesc_t PB_RequestState_msg; +extern const pb_msgdesc_t PB_PersistentConfiguration_msg; +extern const pb_msgdesc_t PB_MotorCalibration_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define PB_FromSmartKnob_fields &PB_FromSmartKnob_msg @@ -198,11 +238,15 @@ extern const pb_msgdesc_t PB_RequestState_msg; #define PB_SmartKnobState_fields &PB_SmartKnobState_msg #define PB_SmartKnobConfig_fields &PB_SmartKnobConfig_msg #define PB_RequestState_fields &PB_RequestState_msg +#define PB_PersistentConfiguration_fields &PB_PersistentConfiguration_msg +#define PB_MotorCalibration_fields &PB_MotorCalibration_msg /* Maximum encoded size of messages (where known) */ #define PB_Ack_size 6 #define PB_FromSmartKnob_size 264 #define PB_Log_size 258 +#define PB_MotorCalibration_size 15 +#define PB_PersistentConfiguration_size 23 #define PB_RequestState_size 0 #define PB_SmartKnobConfig_size 173 #define PB_SmartKnobState_size 192 diff --git a/platformio.ini b/platformio.ini index ae60f25..2f0fd35 100644 --- a/platformio.ini +++ b/platformio.ini @@ -128,8 +128,9 @@ build_flags = [env:nanofoc] extends = base_config -platform = espressif32 +platform = espressif32@6.3.1 board = adafruit_feather_esp32s3 +board_build.partitions = firmware/partitions-4MB-spiffs.csv lib_deps = ${base_config.lib_deps} askuric/Simple FOC@^2.3.0 diff --git a/proto/smartknob.proto b/proto/smartknob.proto index 7630bc2..543793d 100644 --- a/proto/smartknob.proto +++ b/proto/smartknob.proto @@ -70,3 +70,14 @@ message SmartKnobConfig { message RequestState {} +message PersistentConfiguration { + uint32 version = 1; + MotorCalibration motor = 2; +} + +message MotorCalibration { + bool calibrated = 1; + float zero_electrical_offset = 2; + bool direction_cw = 3; + uint32 pole_pairs = 4; +} diff --git a/software/python/proto_gen/smartknob_pb2.py b/software/python/proto_gen/smartknob_pb2.py index 466b17b..f6cd0ab 100644 --- a/software/python/proto_gen/smartknob_pb2.py +++ b/software/python/proto_gen/smartknob_pb2.py @@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default() import nanopb_pb2 as nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fsmartknob.proto\x12\x02PB\x1a\x0cnanopb.proto\"\x9a\x01\n\rFromSmartKnob\x12\x1f\n\x10protocol_version\x18\x01 \x01(\rB\x05\x92?\x02\x38\x08\x12\x16\n\x03\x61\x63k\x18\x02 \x01(\x0b\x32\x07.PB.AckH\x00\x12\x16\n\x03log\x18\x03 \x01(\x0b\x32\x07.PB.LogH\x00\x12-\n\x0fsmartknob_state\x18\x04 \x01(\x0b\x32\x12.PB.SmartKnobStateH\x00\x42\t\n\x07payload\"\xa4\x01\n\x0bToSmartknob\x12\x1f\n\x10protocol_version\x18\x01 \x01(\rB\x05\x92?\x02\x38\x08\x12\r\n\x05nonce\x18\x02 \x01(\r\x12)\n\rrequest_state\x18\x03 \x01(\x0b\x32\x10.PB.RequestStateH\x00\x12/\n\x10smartknob_config\x18\x04 \x01(\x0b\x32\x13.PB.SmartKnobConfigH\x00\x42\t\n\x07payload\"\x14\n\x03\x41\x63k\x12\r\n\x05nonce\x18\x01 \x01(\r\"\x1a\n\x03Log\x12\x13\n\x03msg\x18\x01 \x01(\tB\x06\x92?\x03p\xff\x01\"j\n\x0eSmartKnobState\x12\x18\n\x10\x63urrent_position\x18\x01 \x01(\x05\x12\x19\n\x11sub_position_unit\x18\x02 \x01(\x02\x12#\n\x06\x63onfig\x18\x03 \x01(\x0b\x32\x13.PB.SmartKnobConfig\"\xc9\x02\n\x0fSmartKnobConfig\x12\x10\n\x08position\x18\x01 \x01(\x05\x12\x19\n\x11sub_position_unit\x18\x02 \x01(\x02\x12\x1d\n\x0eposition_nonce\x18\x03 \x01(\rB\x05\x92?\x02\x38\x08\x12\x14\n\x0cmin_position\x18\x04 \x01(\x05\x12\x14\n\x0cmax_position\x18\x05 \x01(\x05\x12\x1e\n\x16position_width_radians\x18\x06 \x01(\x02\x12\x1c\n\x14\x64\x65tent_strength_unit\x18\x07 \x01(\x02\x12\x1d\n\x15\x65ndstop_strength_unit\x18\x08 \x01(\x02\x12\x12\n\nsnap_point\x18\t \x01(\x02\x12\x13\n\x04text\x18\n \x01(\tB\x05\x92?\x02p2\x12\x1f\n\x10\x64\x65tent_positions\x18\x0b \x03(\x05\x42\x05\x92?\x02\x10\x05\x12\x17\n\x0fsnap_point_bias\x18\x0c \x01(\x02\"\x0e\n\x0cRequestStateb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fsmartknob.proto\x12\x02PB\x1a\x0cnanopb.proto\"\x9a\x01\n\rFromSmartKnob\x12\x1f\n\x10protocol_version\x18\x01 \x01(\rB\x05\x92?\x02\x38\x08\x12\x16\n\x03\x61\x63k\x18\x02 \x01(\x0b\x32\x07.PB.AckH\x00\x12\x16\n\x03log\x18\x03 \x01(\x0b\x32\x07.PB.LogH\x00\x12-\n\x0fsmartknob_state\x18\x04 \x01(\x0b\x32\x12.PB.SmartKnobStateH\x00\x42\t\n\x07payload\"\xa4\x01\n\x0bToSmartknob\x12\x1f\n\x10protocol_version\x18\x01 \x01(\rB\x05\x92?\x02\x38\x08\x12\r\n\x05nonce\x18\x02 \x01(\r\x12)\n\rrequest_state\x18\x03 \x01(\x0b\x32\x10.PB.RequestStateH\x00\x12/\n\x10smartknob_config\x18\x04 \x01(\x0b\x32\x13.PB.SmartKnobConfigH\x00\x42\t\n\x07payload\"\x14\n\x03\x41\x63k\x12\r\n\x05nonce\x18\x01 \x01(\r\"\x1a\n\x03Log\x12\x13\n\x03msg\x18\x01 \x01(\tB\x06\x92?\x03p\xff\x01\"j\n\x0eSmartKnobState\x12\x18\n\x10\x63urrent_position\x18\x01 \x01(\x05\x12\x19\n\x11sub_position_unit\x18\x02 \x01(\x02\x12#\n\x06\x63onfig\x18\x03 \x01(\x0b\x32\x13.PB.SmartKnobConfig\"\xc9\x02\n\x0fSmartKnobConfig\x12\x10\n\x08position\x18\x01 \x01(\x05\x12\x19\n\x11sub_position_unit\x18\x02 \x01(\x02\x12\x1d\n\x0eposition_nonce\x18\x03 \x01(\rB\x05\x92?\x02\x38\x08\x12\x14\n\x0cmin_position\x18\x04 \x01(\x05\x12\x14\n\x0cmax_position\x18\x05 \x01(\x05\x12\x1e\n\x16position_width_radians\x18\x06 \x01(\x02\x12\x1c\n\x14\x64\x65tent_strength_unit\x18\x07 \x01(\x02\x12\x1d\n\x15\x65ndstop_strength_unit\x18\x08 \x01(\x02\x12\x12\n\nsnap_point\x18\t \x01(\x02\x12\x13\n\x04text\x18\n \x01(\tB\x05\x92?\x02p2\x12\x1f\n\x10\x64\x65tent_positions\x18\x0b \x03(\x05\x42\x05\x92?\x02\x10\x05\x12\x17\n\x0fsnap_point_bias\x18\x0c \x01(\x02\"\x0e\n\x0cRequestState\"O\n\x17PersistentConfiguration\x12\x0f\n\x07version\x18\x01 \x01(\r\x12#\n\x05motor\x18\x02 \x01(\x0b\x32\x14.PB.MotorCalibration\"p\n\x10MotorCalibration\x12\x12\n\ncalibrated\x18\x01 \x01(\x08\x12\x1e\n\x16zero_electrical_offset\x18\x02 \x01(\x02\x12\x14\n\x0c\x64irection_cw\x18\x03 \x01(\x08\x12\x12\n\npole_pairs\x18\x04 \x01(\rb\x06proto3') @@ -26,6 +26,8 @@ _LOG = DESCRIPTOR.message_types_by_name['Log'] _SMARTKNOBSTATE = DESCRIPTOR.message_types_by_name['SmartKnobState'] _SMARTKNOBCONFIG = DESCRIPTOR.message_types_by_name['SmartKnobConfig'] _REQUESTSTATE = DESCRIPTOR.message_types_by_name['RequestState'] +_PERSISTENTCONFIGURATION = DESCRIPTOR.message_types_by_name['PersistentConfiguration'] +_MOTORCALIBRATION = DESCRIPTOR.message_types_by_name['MotorCalibration'] FromSmartKnob = _reflection.GeneratedProtocolMessageType('FromSmartKnob', (_message.Message,), { 'DESCRIPTOR' : _FROMSMARTKNOB, '__module__' : 'smartknob_pb2' @@ -75,6 +77,20 @@ RequestState = _reflection.GeneratedProtocolMessageType('RequestState', (_messag }) _sym_db.RegisterMessage(RequestState) +PersistentConfiguration = _reflection.GeneratedProtocolMessageType('PersistentConfiguration', (_message.Message,), { + 'DESCRIPTOR' : _PERSISTENTCONFIGURATION, + '__module__' : 'smartknob_pb2' + # @@protoc_insertion_point(class_scope:PB.PersistentConfiguration) + }) +_sym_db.RegisterMessage(PersistentConfiguration) + +MotorCalibration = _reflection.GeneratedProtocolMessageType('MotorCalibration', (_message.Message,), { + 'DESCRIPTOR' : _MOTORCALIBRATION, + '__module__' : 'smartknob_pb2' + # @@protoc_insertion_point(class_scope:PB.MotorCalibration) + }) +_sym_db.RegisterMessage(MotorCalibration) + if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None @@ -104,4 +120,8 @@ if _descriptor._USE_C_DESCRIPTORS == False: _SMARTKNOBCONFIG._serialized_end=849 _REQUESTSTATE._serialized_start=851 _REQUESTSTATE._serialized_end=865 + _PERSISTENTCONFIGURATION._serialized_start=867 + _PERSISTENTCONFIGURATION._serialized_end=946 + _MOTORCALIBRATION._serialized_start=948 + _MOTORCALIBRATION._serialized_end=1060 # @@protoc_insertion_point(module_scope)