mirror of
https://github.com/scottbez1/smartknob.git
synced 2025-09-26 23:09:27 +08:00
Updated config schema, improved demo (#121)
- Breaking proto updates - added position nonce to config, and added ability to specify a sub_position via config as well => more flexibility to control position via config - added version as first field of serial protocol messages, so future breaking proto updates can easily be detected and ignored - Fixed up web-based demo of a mock video editor/timeline jog/playback controller - Fixed config/state flow so that mode changes correctly maintain playback position - Demo: https://www.youtube.com/watch?v=J9192DfZplk
This commit is contained in:
parent
08146e292d
commit
2afc38f7f9
@ -27,6 +27,8 @@ Adafruit_VEML7700 veml = Adafruit_VEML7700();
|
||||
|
||||
static PB_SmartKnobConfig configs[] = {
|
||||
// int32_t position;
|
||||
// float sub_position_unit;
|
||||
// uint8_t position_nonce;
|
||||
// int32_t min_position;
|
||||
// int32_t max_position;
|
||||
// float position_width_radians;
|
||||
@ -39,6 +41,8 @@ static PB_SmartKnobConfig configs[] = {
|
||||
// float snap_point_bias;
|
||||
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
-1, // max position < min position indicates no bounds
|
||||
@ -54,6 +58,8 @@ static PB_SmartKnobConfig configs[] = {
|
||||
{
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
10,
|
||||
10 * PI / 180,
|
||||
0,
|
||||
@ -67,6 +73,8 @@ static PB_SmartKnobConfig configs[] = {
|
||||
{
|
||||
0,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
72,
|
||||
10 * PI / 180,
|
||||
0,
|
||||
@ -80,6 +88,8 @@ static PB_SmartKnobConfig configs[] = {
|
||||
{
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
0,
|
||||
1,
|
||||
60 * PI / 180,
|
||||
1,
|
||||
@ -93,6 +103,8 @@ static PB_SmartKnobConfig configs[] = {
|
||||
{
|
||||
0,
|
||||
0,
|
||||
4,
|
||||
0,
|
||||
0,
|
||||
60 * PI / 180,
|
||||
0.01,
|
||||
@ -106,6 +118,8 @@ static PB_SmartKnobConfig configs[] = {
|
||||
{
|
||||
127,
|
||||
0,
|
||||
5,
|
||||
0,
|
||||
255,
|
||||
1 * PI / 180,
|
||||
0,
|
||||
@ -119,6 +133,8 @@ static PB_SmartKnobConfig configs[] = {
|
||||
{
|
||||
127,
|
||||
0,
|
||||
5,
|
||||
0,
|
||||
255,
|
||||
1 * PI / 180,
|
||||
1,
|
||||
@ -132,6 +148,8 @@ static PB_SmartKnobConfig configs[] = {
|
||||
{
|
||||
0,
|
||||
0,
|
||||
6,
|
||||
0,
|
||||
31,
|
||||
8.225806452 * PI / 180,
|
||||
2,
|
||||
@ -145,6 +163,8 @@ static PB_SmartKnobConfig configs[] = {
|
||||
{
|
||||
0,
|
||||
0,
|
||||
6,
|
||||
0,
|
||||
31,
|
||||
8.225806452 * PI / 180,
|
||||
0.2,
|
||||
@ -158,6 +178,8 @@ static PB_SmartKnobConfig configs[] = {
|
||||
{
|
||||
0,
|
||||
0,
|
||||
7,
|
||||
0,
|
||||
31,
|
||||
7 * PI / 180,
|
||||
2.5,
|
||||
@ -170,6 +192,8 @@ static PB_SmartKnobConfig configs[] = {
|
||||
},
|
||||
{
|
||||
0,
|
||||
0,
|
||||
8,
|
||||
-6,
|
||||
6,
|
||||
60 * PI / 180,
|
||||
|
@ -96,11 +96,15 @@ void MotorTask::run() {
|
||||
float current_detent_center = motor.shaft_angle;
|
||||
PB_SmartKnobConfig config = {
|
||||
.position = 0,
|
||||
.sub_position_unit = 0,
|
||||
.position_nonce = 0,
|
||||
.min_position = 0,
|
||||
.max_position = 1,
|
||||
.position_width_radians = 60 * _PI / 180,
|
||||
.detent_strength_unit = 0,
|
||||
};
|
||||
int32_t current_position = 0;
|
||||
float latest_sub_position_unit = 0;
|
||||
|
||||
float idle_check_velocity_ewma = 0;
|
||||
uint32_t last_idle_start = 0;
|
||||
@ -118,44 +122,60 @@ void MotorTask::run() {
|
||||
break;
|
||||
case CommandType::CONFIG: {
|
||||
// Check new config for validity
|
||||
if (command.data.config.detent_strength_unit < 0) {
|
||||
PB_SmartKnobConfig& new_config = command.data.config;
|
||||
if (new_config.detent_strength_unit < 0) {
|
||||
log("Ignoring invalid config: detent_strength_unit cannot be negative");
|
||||
break;
|
||||
}
|
||||
if (command.data.config.endstop_strength_unit < 0) {
|
||||
if (new_config.endstop_strength_unit < 0) {
|
||||
log("Ignoring invalid config: endstop_strength_unit cannot be negative");
|
||||
break;
|
||||
}
|
||||
if (command.data.config.snap_point < 0.5) {
|
||||
if (new_config.snap_point < 0.5) {
|
||||
log("Ignoring invalid config: snap_point must be >= 0.5 for stability");
|
||||
break;
|
||||
}
|
||||
if (command.data.config.detent_positions_count > COUNT_OF(command.data.config.detent_positions)) {
|
||||
if (new_config.detent_positions_count > COUNT_OF(new_config.detent_positions)) {
|
||||
log("Ignoring invalid config: detent_positions_count is too large");
|
||||
break;
|
||||
}
|
||||
if (command.data.config.snap_point_bias < 0) {
|
||||
if (new_config.snap_point_bias < 0) {
|
||||
log("Ignoring invalid config: snap_point_bias cannot be negative or there is risk of instability");
|
||||
break;
|
||||
}
|
||||
|
||||
// Change haptic input mode
|
||||
PB_SmartKnobConfig newConfig = command.data.config;
|
||||
if (newConfig.position == INT32_MIN) {
|
||||
// INT32_MIN indicates no change to position, so restore from latest_config
|
||||
log("maintaining position");
|
||||
newConfig.position = config.position;
|
||||
bool position_updated = false;
|
||||
if (new_config.position != config.position
|
||||
|| new_config.sub_position_unit != config.sub_position_unit
|
||||
|| new_config.position_nonce != config.position_nonce) {
|
||||
log("applying position change");
|
||||
current_position = new_config.position;
|
||||
position_updated = true;
|
||||
}
|
||||
if (newConfig.position != config.position
|
||||
|| newConfig.position_width_radians != config.position_width_radians) {
|
||||
// Only adjust the detent center if the position or width has changed
|
||||
|
||||
if (new_config.min_position <= new_config.max_position) {
|
||||
// Only check bounds if min/max indicate bounds are active (min >= max)
|
||||
if (current_position < new_config.min_position) {
|
||||
current_position = new_config.min_position;
|
||||
log("adjusting position to min");
|
||||
} else if (current_position > new_config.max_position) {
|
||||
current_position = new_config.max_position;
|
||||
log("adjusting position to max");
|
||||
}
|
||||
}
|
||||
|
||||
if (position_updated || new_config.position_width_radians != config.position_width_radians) {
|
||||
log("adjusting detent center");
|
||||
current_detent_center = motor.shaft_angle;
|
||||
float new_sub_position = position_updated ? new_config.sub_position_unit : latest_sub_position_unit;
|
||||
#if SK_INVERT_ROTATION
|
||||
current_detent_center = -motor.shaft_angle;
|
||||
float shaft_angle = -motor.shaft_angle;
|
||||
#else
|
||||
float shaft_angle = motor.shaft_angle;
|
||||
#endif
|
||||
current_detent_center = shaft_angle + new_sub_position * new_config.position_width_radians;
|
||||
}
|
||||
config = newConfig;
|
||||
config = new_config;
|
||||
log("Got new config");
|
||||
|
||||
// Update derivative factor of torque controller based on detent width.
|
||||
@ -221,26 +241,28 @@ void MotorTask::run() {
|
||||
|
||||
float snap_point_radians = config.position_width_radians * config.snap_point;
|
||||
float bias_radians = config.position_width_radians * config.snap_point_bias;
|
||||
float snap_point_radians_decrease = snap_point_radians + (config.position <= 0 ? bias_radians : -bias_radians);
|
||||
float snap_point_radians_increase = -snap_point_radians + (config.position >= 0 ? -bias_radians : bias_radians);
|
||||
float snap_point_radians_decrease = snap_point_radians + (current_position <= 0 ? bias_radians : -bias_radians);
|
||||
float snap_point_radians_increase = -snap_point_radians + (current_position >= 0 ? -bias_radians : bias_radians);
|
||||
|
||||
int32_t num_positions = config.max_position - config.min_position + 1;
|
||||
if (angle_to_detent_center > snap_point_radians_decrease && (num_positions <= 0 || config.position > config.min_position)) {
|
||||
if (angle_to_detent_center > snap_point_radians_decrease && (num_positions <= 0 || current_position > config.min_position)) {
|
||||
current_detent_center += config.position_width_radians;
|
||||
angle_to_detent_center -= config.position_width_radians;
|
||||
config.position--;
|
||||
} else if (angle_to_detent_center < snap_point_radians_increase && (num_positions <= 0 || config.position < config.max_position)) {
|
||||
current_position--;
|
||||
} else if (angle_to_detent_center < snap_point_radians_increase && (num_positions <= 0 || current_position < config.max_position)) {
|
||||
current_detent_center -= config.position_width_radians;
|
||||
angle_to_detent_center += config.position_width_radians;
|
||||
config.position++;
|
||||
current_position++;
|
||||
}
|
||||
|
||||
latest_sub_position_unit = -angle_to_detent_center / config.position_width_radians;
|
||||
|
||||
float dead_zone_adjustment = CLAMP(
|
||||
angle_to_detent_center,
|
||||
fmaxf(-config.position_width_radians*DEAD_ZONE_DETENT_PERCENT, -DEAD_ZONE_RAD),
|
||||
fminf(config.position_width_radians*DEAD_ZONE_DETENT_PERCENT, DEAD_ZONE_RAD));
|
||||
|
||||
bool out_of_bounds = num_positions > 0 && ((angle_to_detent_center > 0 && config.position == config.min_position) || (angle_to_detent_center < 0 && config.position == config.max_position));
|
||||
bool out_of_bounds = num_positions > 0 && ((angle_to_detent_center > 0 && current_position == config.min_position) || (angle_to_detent_center < 0 && current_position == config.max_position));
|
||||
motor.PID_velocity.limit = 10; //out_of_bounds ? 10 : 3;
|
||||
motor.PID_velocity.P = out_of_bounds ? config.endstop_strength_unit * 4 : config.detent_strength_unit * 4;
|
||||
|
||||
@ -254,7 +276,7 @@ void MotorTask::run() {
|
||||
if (!out_of_bounds && config.detent_positions_count > 0) {
|
||||
bool in_detent = false;
|
||||
for (uint8_t i = 0; i < config.detent_positions_count; i++) {
|
||||
if (config.detent_positions[i] == config.position) {
|
||||
if (config.detent_positions[i] == current_position) {
|
||||
in_detent = true;
|
||||
break;
|
||||
}
|
||||
@ -273,8 +295,8 @@ void MotorTask::run() {
|
||||
// Publish current status to other registered tasks periodically
|
||||
if (millis() - last_publish > 5) {
|
||||
publish({
|
||||
.current_position = config.position,
|
||||
.sub_position_unit = -angle_to_detent_center / config.position_width_radians,
|
||||
.current_position = current_position,
|
||||
.sub_position_unit = latest_sub_position_unit,
|
||||
.has_config = true,
|
||||
.config = config,
|
||||
});
|
||||
|
@ -9,6 +9,9 @@
|
||||
PB_BIND(PB_FromSmartKnob, PB_FromSmartKnob, 2)
|
||||
|
||||
|
||||
PB_BIND(PB_ToSmartknob, PB_ToSmartknob, AUTO)
|
||||
|
||||
|
||||
PB_BIND(PB_Ack, PB_Ack, AUTO)
|
||||
|
||||
|
||||
@ -18,9 +21,6 @@ PB_BIND(PB_Log, PB_Log, 2)
|
||||
PB_BIND(PB_SmartKnobState, PB_SmartKnobState, AUTO)
|
||||
|
||||
|
||||
PB_BIND(PB_ToSmartknob, PB_ToSmartknob, AUTO)
|
||||
|
||||
|
||||
PB_BIND(PB_SmartKnobConfig, PB_SmartKnobConfig, AUTO)
|
||||
|
||||
|
||||
|
@ -20,6 +20,14 @@ typedef struct _PB_Log {
|
||||
|
||||
typedef struct _PB_SmartKnobConfig {
|
||||
int32_t position;
|
||||
float sub_position_unit;
|
||||
/* *
|
||||
Position is normally only applied when it changes, but sometimes it's desirable
|
||||
to reset the position to the same value, so a nonce change can be used to force
|
||||
the position values to be applied as well.
|
||||
|
||||
NOTE: Must be < 256 */
|
||||
uint8_t position_nonce;
|
||||
int32_t min_position;
|
||||
int32_t max_position;
|
||||
float position_width_radians;
|
||||
@ -39,8 +47,9 @@ typedef struct _PB_SmartKnobState {
|
||||
PB_SmartKnobConfig config;
|
||||
} PB_SmartKnobState;
|
||||
|
||||
/* Message FROM the SmartKnob to USB host */
|
||||
/* Message FROM the SmartKnob to the host */
|
||||
typedef struct _PB_FromSmartKnob {
|
||||
uint8_t protocol_version;
|
||||
pb_size_t which_payload;
|
||||
union {
|
||||
PB_Ack ack;
|
||||
@ -53,8 +62,9 @@ typedef struct _PB_RequestState {
|
||||
char dummy_field;
|
||||
} PB_RequestState;
|
||||
|
||||
/* Message TO the Smartknob from the USB host */
|
||||
/* Message TO the Smartknob from the host */
|
||||
typedef struct _PB_ToSmartknob {
|
||||
uint8_t protocol_version;
|
||||
uint32_t nonce;
|
||||
pb_size_t which_payload;
|
||||
union {
|
||||
@ -69,55 +79,70 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define PB_FromSmartKnob_init_default {0, {PB_Ack_init_default}}
|
||||
#define PB_FromSmartKnob_init_default {0, 0, {PB_Ack_init_default}}
|
||||
#define PB_ToSmartknob_init_default {0, 0, 0, {PB_RequestState_init_default}}
|
||||
#define PB_Ack_init_default {0}
|
||||
#define PB_Log_init_default {""}
|
||||
#define PB_SmartKnobState_init_default {0, 0, false, PB_SmartKnobConfig_init_default}
|
||||
#define PB_ToSmartknob_init_default {0, 0, {PB_RequestState_init_default}}
|
||||
#define PB_SmartKnobConfig_init_default {0, 0, 0, 0, 0, 0, 0, "", 0, {0, 0, 0, 0, 0}, 0}
|
||||
#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_FromSmartKnob_init_zero {0, {PB_Ack_init_zero}}
|
||||
#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}
|
||||
#define PB_Log_init_zero {""}
|
||||
#define PB_SmartKnobState_init_zero {0, 0, false, PB_SmartKnobConfig_init_zero}
|
||||
#define PB_ToSmartknob_init_zero {0, 0, {PB_RequestState_init_zero}}
|
||||
#define PB_SmartKnobConfig_init_zero {0, 0, 0, 0, 0, 0, 0, "", 0, {0, 0, 0, 0, 0}, 0}
|
||||
#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}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define PB_Ack_nonce_tag 1
|
||||
#define PB_Log_msg_tag 1
|
||||
#define PB_SmartKnobConfig_position_tag 1
|
||||
#define PB_SmartKnobConfig_min_position_tag 2
|
||||
#define PB_SmartKnobConfig_max_position_tag 3
|
||||
#define PB_SmartKnobConfig_position_width_radians_tag 4
|
||||
#define PB_SmartKnobConfig_detent_strength_unit_tag 5
|
||||
#define PB_SmartKnobConfig_endstop_strength_unit_tag 6
|
||||
#define PB_SmartKnobConfig_snap_point_tag 7
|
||||
#define PB_SmartKnobConfig_text_tag 8
|
||||
#define PB_SmartKnobConfig_detent_positions_tag 9
|
||||
#define PB_SmartKnobConfig_snap_point_bias_tag 10
|
||||
#define PB_SmartKnobConfig_sub_position_unit_tag 2
|
||||
#define PB_SmartKnobConfig_position_nonce_tag 3
|
||||
#define PB_SmartKnobConfig_min_position_tag 4
|
||||
#define PB_SmartKnobConfig_max_position_tag 5
|
||||
#define PB_SmartKnobConfig_position_width_radians_tag 6
|
||||
#define PB_SmartKnobConfig_detent_strength_unit_tag 7
|
||||
#define PB_SmartKnobConfig_endstop_strength_unit_tag 8
|
||||
#define PB_SmartKnobConfig_snap_point_tag 9
|
||||
#define PB_SmartKnobConfig_text_tag 10
|
||||
#define PB_SmartKnobConfig_detent_positions_tag 11
|
||||
#define PB_SmartKnobConfig_snap_point_bias_tag 12
|
||||
#define PB_SmartKnobState_current_position_tag 1
|
||||
#define PB_SmartKnobState_sub_position_unit_tag 2
|
||||
#define PB_SmartKnobState_config_tag 3
|
||||
#define PB_FromSmartKnob_ack_tag 1
|
||||
#define PB_FromSmartKnob_log_tag 2
|
||||
#define PB_FromSmartKnob_smartknob_state_tag 3
|
||||
#define PB_ToSmartknob_nonce_tag 1
|
||||
#define PB_ToSmartknob_request_state_tag 2
|
||||
#define PB_ToSmartknob_smartknob_config_tag 3
|
||||
#define PB_FromSmartKnob_protocol_version_tag 1
|
||||
#define PB_FromSmartKnob_ack_tag 2
|
||||
#define PB_FromSmartKnob_log_tag 3
|
||||
#define PB_FromSmartKnob_smartknob_state_tag 4
|
||||
#define PB_ToSmartknob_protocol_version_tag 1
|
||||
#define PB_ToSmartknob_nonce_tag 2
|
||||
#define PB_ToSmartknob_request_state_tag 3
|
||||
#define PB_ToSmartknob_smartknob_config_tag 4
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define PB_FromSmartKnob_FIELDLIST(X, a) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,ack,payload.ack), 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,log,payload.log), 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,smartknob_state,payload.smartknob_state), 3)
|
||||
X(a, STATIC, SINGULAR, UINT32, protocol_version, 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,ack,payload.ack), 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,log,payload.log), 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,smartknob_state,payload.smartknob_state), 4)
|
||||
#define PB_FromSmartKnob_CALLBACK NULL
|
||||
#define PB_FromSmartKnob_DEFAULT NULL
|
||||
#define PB_FromSmartKnob_payload_ack_MSGTYPE PB_Ack
|
||||
#define PB_FromSmartKnob_payload_log_MSGTYPE PB_Log
|
||||
#define PB_FromSmartKnob_payload_smartknob_state_MSGTYPE PB_SmartKnobState
|
||||
|
||||
#define PB_ToSmartknob_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, protocol_version, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, nonce, 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,request_state,payload.request_state), 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,smartknob_config,payload.smartknob_config), 4)
|
||||
#define PB_ToSmartknob_CALLBACK NULL
|
||||
#define PB_ToSmartknob_DEFAULT NULL
|
||||
#define PB_ToSmartknob_payload_request_state_MSGTYPE PB_RequestState
|
||||
#define PB_ToSmartknob_payload_smartknob_config_MSGTYPE PB_SmartKnobConfig
|
||||
|
||||
#define PB_Ack_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, nonce, 1)
|
||||
#define PB_Ack_CALLBACK NULL
|
||||
@ -136,26 +161,19 @@ X(a, STATIC, OPTIONAL, MESSAGE, config, 3)
|
||||
#define PB_SmartKnobState_DEFAULT NULL
|
||||
#define PB_SmartKnobState_config_MSGTYPE PB_SmartKnobConfig
|
||||
|
||||
#define PB_ToSmartknob_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, nonce, 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,request_state,payload.request_state), 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,smartknob_config,payload.smartknob_config), 3)
|
||||
#define PB_ToSmartknob_CALLBACK NULL
|
||||
#define PB_ToSmartknob_DEFAULT NULL
|
||||
#define PB_ToSmartknob_payload_request_state_MSGTYPE PB_RequestState
|
||||
#define PB_ToSmartknob_payload_smartknob_config_MSGTYPE PB_SmartKnobConfig
|
||||
|
||||
#define PB_SmartKnobConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, INT32, position, 1) \
|
||||
X(a, STATIC, SINGULAR, INT32, min_position, 2) \
|
||||
X(a, STATIC, SINGULAR, INT32, max_position, 3) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, position_width_radians, 4) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, detent_strength_unit, 5) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, endstop_strength_unit, 6) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, snap_point, 7) \
|
||||
X(a, STATIC, SINGULAR, STRING, text, 8) \
|
||||
X(a, STATIC, REPEATED, INT32, detent_positions, 9) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, snap_point_bias, 10)
|
||||
X(a, STATIC, SINGULAR, FLOAT, sub_position_unit, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, position_nonce, 3) \
|
||||
X(a, STATIC, SINGULAR, INT32, min_position, 4) \
|
||||
X(a, STATIC, SINGULAR, INT32, max_position, 5) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, position_width_radians, 6) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, detent_strength_unit, 7) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, endstop_strength_unit, 8) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, snap_point, 9) \
|
||||
X(a, STATIC, SINGULAR, STRING, text, 10) \
|
||||
X(a, STATIC, REPEATED, INT32, detent_positions, 11) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, snap_point_bias, 12)
|
||||
#define PB_SmartKnobConfig_CALLBACK NULL
|
||||
#define PB_SmartKnobConfig_DEFAULT NULL
|
||||
|
||||
@ -165,30 +183,30 @@ X(a, STATIC, SINGULAR, FLOAT, snap_point_bias, 10)
|
||||
#define PB_RequestState_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;
|
||||
extern const pb_msgdesc_t PB_Log_msg;
|
||||
extern const pb_msgdesc_t PB_SmartKnobState_msg;
|
||||
extern const pb_msgdesc_t PB_ToSmartknob_msg;
|
||||
extern const pb_msgdesc_t PB_SmartKnobConfig_msg;
|
||||
extern const pb_msgdesc_t PB_RequestState_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define PB_FromSmartKnob_fields &PB_FromSmartKnob_msg
|
||||
#define PB_ToSmartknob_fields &PB_ToSmartknob_msg
|
||||
#define PB_Ack_fields &PB_Ack_msg
|
||||
#define PB_Log_fields &PB_Log_msg
|
||||
#define PB_SmartKnobState_fields &PB_SmartKnobState_msg
|
||||
#define PB_ToSmartknob_fields &PB_ToSmartknob_msg
|
||||
#define PB_SmartKnobConfig_fields &PB_SmartKnobConfig_msg
|
||||
#define PB_RequestState_fields &PB_RequestState_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define PB_Ack_size 6
|
||||
#define PB_FromSmartKnob_size 261
|
||||
#define PB_FromSmartKnob_size 264
|
||||
#define PB_Log_size 258
|
||||
#define PB_RequestState_size 0
|
||||
#define PB_SmartKnobConfig_size 165
|
||||
#define PB_SmartKnobState_size 184
|
||||
#define PB_ToSmartknob_size 174
|
||||
#define PB_SmartKnobConfig_size 173
|
||||
#define PB_SmartKnobState_size 192
|
||||
#define PB_ToSmartknob_size 185
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -2,14 +2,18 @@
|
||||
|
||||
#include "proto_gen/smartknob.pb.h"
|
||||
|
||||
#define PROTOBUF_PROTOCOL_VERSION (1)
|
||||
|
||||
bool config_eq(PB_SmartKnobConfig& first, PB_SmartKnobConfig& second) {
|
||||
return first.detent_strength_unit == second.detent_strength_unit
|
||||
&& first.endstop_strength_unit == second.endstop_strength_unit
|
||||
&& first.position == second.position
|
||||
&& first.position_nonce == second.position_nonce
|
||||
&& first.min_position == second.min_position
|
||||
&& first.max_position == second.max_position
|
||||
&& first.position_width_radians == second.position_width_radians
|
||||
&& first.snap_point == second.snap_point
|
||||
&& first.sub_position_unit == second.sub_position_unit
|
||||
&& strcmp(first.text, second.text) == 0
|
||||
&& first.detent_positions_count == second.detent_positions_count
|
||||
&& memcmp(first.detent_positions, second.detent_positions, first.detent_positions_count * sizeof(first.detent_positions[0]))
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include "../proto_gen/smartknob.pb.h"
|
||||
|
||||
#include "../proto_helpers.h"
|
||||
#include "proto_helpers.h"
|
||||
|
||||
#include "crc32.h"
|
||||
#include "pb_encode.h"
|
||||
@ -105,6 +105,13 @@ void SerialProtocolProtobuf::handlePacket(const uint8_t* buffer, size_t size) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pb_rx_buffer_.protocol_version != PROTOBUF_PROTOCOL_VERSION) {
|
||||
char buf[200];
|
||||
snprintf(buf, sizeof(buf), "Invalid protocol version. Expected %u, received %u", PROTOBUF_PROTOCOL_VERSION, pb_rx_buffer_.protocol_version);
|
||||
log(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
// Always ACK immediately
|
||||
ack(pb_rx_buffer_.nonce);
|
||||
if (pb_rx_buffer_.nonce == last_nonce_) {
|
||||
@ -133,6 +140,7 @@ void SerialProtocolProtobuf::handlePacket(const uint8_t* buffer, size_t size) {
|
||||
void SerialProtocolProtobuf::sendPbTxBuffer() {
|
||||
// Encode protobuf message to byte buffer
|
||||
pb_ostream_t stream = pb_ostream_from_buffer(tx_buffer_, sizeof(tx_buffer_));
|
||||
pb_tx_buffer_.protocol_version = PROTOBUF_PROTOCOL_VERSION;
|
||||
if (!pb_encode(&stream, PB_FromSmartKnob_fields, &pb_tx_buffer_)) {
|
||||
stream_.println(stream.errmsg);
|
||||
stream_.flush();
|
||||
|
@ -5,13 +5,27 @@ import "nanopb.proto";
|
||||
package PB;
|
||||
|
||||
/*
|
||||
* Message FROM the SmartKnob to USB host
|
||||
* Message FROM the SmartKnob to the host
|
||||
*/
|
||||
message FromSmartKnob {
|
||||
uint32 protocol_version = 1 [(nanopb).int_size = IS_8];
|
||||
oneof payload {
|
||||
Ack ack = 1;
|
||||
Log log = 2;
|
||||
SmartKnobState smartknob_state = 3;
|
||||
Ack ack = 2;
|
||||
Log log = 3;
|
||||
SmartKnobState smartknob_state = 4;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Message TO the Smartknob from the host
|
||||
*/
|
||||
message ToSmartknob {
|
||||
uint32 protocol_version = 1 [(nanopb).int_size = IS_8];
|
||||
uint32 nonce = 2;
|
||||
|
||||
oneof payload {
|
||||
RequestState request_state = 3;
|
||||
SmartKnobConfig smartknob_config = 4;
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,29 +43,29 @@ message SmartKnobState {
|
||||
SmartKnobConfig config = 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Message TO the Smartknob from the USB host
|
||||
*/
|
||||
message ToSmartknob {
|
||||
uint32 nonce = 1;
|
||||
|
||||
oneof payload {
|
||||
RequestState request_state = 2;
|
||||
SmartKnobConfig smartknob_config = 3;
|
||||
}
|
||||
}
|
||||
|
||||
message SmartKnobConfig {
|
||||
int32 position = 1;
|
||||
int32 min_position = 2;
|
||||
int32 max_position = 3;
|
||||
float position_width_radians = 4;
|
||||
float detent_strength_unit = 5;
|
||||
float endstop_strength_unit = 6;
|
||||
float snap_point = 7;
|
||||
string text = 8 [(nanopb).max_length = 50];
|
||||
repeated int32 detent_positions = 9 [(nanopb).max_count = 5];
|
||||
float snap_point_bias = 10;
|
||||
float sub_position_unit = 2;
|
||||
|
||||
/**
|
||||
* Position is normally only applied when it changes, but sometimes it's desirable
|
||||
* to reset the position to the same value, so a nonce change can be used to force
|
||||
* the position values to be applied as well.
|
||||
*
|
||||
* NOTE: Must be < 256
|
||||
*/
|
||||
uint32 position_nonce = 3 [(nanopb).int_size = IS_8];
|
||||
|
||||
int32 min_position = 4;
|
||||
int32 max_position = 5;
|
||||
float position_width_radians = 6;
|
||||
float detent_strength_unit = 7;
|
||||
float endstop_strength_unit = 8;
|
||||
float snap_point = 9;
|
||||
string text = 10 [(nanopb).max_length = 50];
|
||||
repeated int32 detent_positions = 11 [(nanopb).max_count = 5];
|
||||
float snap_point_bias = 12;
|
||||
}
|
||||
|
||||
message RequestState {}
|
||||
|
48
software/js/package-lock.json
generated
48
software/js/package-lock.json
generated
@ -16874,7 +16874,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"serialport": "^9.2.4",
|
||||
"smartknobjs": "^0.1.0",
|
||||
"smartknobjs": "^1.0.0",
|
||||
"socket.io": "^4.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -16908,7 +16908,7 @@
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "^5.0.1",
|
||||
"smartknobjs-proto": "^0.1.1",
|
||||
"smartknobjs-proto": "^1.0.0",
|
||||
"socket.io-client": "^4.5.4",
|
||||
"typescript": "^4.9.3",
|
||||
"web-vitals": "^2.1.4"
|
||||
@ -16927,7 +16927,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"serialport": "^9.2.4",
|
||||
"smartknobjs": "^0.1.0"
|
||||
"smartknobjs": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/serialport": "^8.0.2",
|
||||
@ -16940,13 +16940,13 @@
|
||||
}
|
||||
},
|
||||
"packages/smartknobjs": {
|
||||
"version": "0.1.0",
|
||||
"version": "1.0.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"cobs": "^0.2.1",
|
||||
"crc-32": "^1.2.0",
|
||||
"serialport": "^9.2.4",
|
||||
"smartknobjs-proto": "^0.1.0"
|
||||
"smartknobjs-proto": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/serialport": "^8.0.2",
|
||||
@ -16959,12 +16959,40 @@
|
||||
}
|
||||
},
|
||||
"packages/smartknobjs-proto": {
|
||||
"version": "0.1.1",
|
||||
"version": "1.0.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"protobufjs": "^6.11.2"
|
||||
}
|
||||
},
|
||||
"packages/webserial": {
|
||||
"version": "0.1.0",
|
||||
"extraneous": true,
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.10.5",
|
||||
"@emotion/styled": "^11.10.5",
|
||||
"@fontsource/roboto": "^4.5.8",
|
||||
"@mui/material": "^5.10.16",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/node": "^16.18.4",
|
||||
"@types/react": "^18.0.25",
|
||||
"@types/react-dom": "^18.0.9",
|
||||
"lodash": "^4.17.21",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "^5.0.1",
|
||||
"smartknobjs-proto": "^1.0.0",
|
||||
"socket.io-client": "^4.5.4",
|
||||
"typescript": "^4.9.3",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.14.191"
|
||||
}
|
||||
},
|
||||
"smartknobjs": {
|
||||
"version": "0.1.0",
|
||||
"extraneous": true,
|
||||
@ -21779,7 +21807,7 @@
|
||||
"nodemon": "^2.0.20",
|
||||
"prettier": "^2.4.1",
|
||||
"serialport": "^9.2.4",
|
||||
"smartknobjs": "^0.1.0",
|
||||
"smartknobjs": "^1.0.0",
|
||||
"socket.io": "^4.5.4",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^4.9.3"
|
||||
@ -21804,7 +21832,7 @@
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "^5.0.1",
|
||||
"smartknobjs-proto": "^0.1.1",
|
||||
"smartknobjs-proto": "^1.0.0",
|
||||
"socket.io-client": "^4.5.4",
|
||||
"typescript": "^4.9.3",
|
||||
"web-vitals": "^2.1.4"
|
||||
@ -22793,7 +22821,7 @@
|
||||
"eslint": "^8.25.0",
|
||||
"prettier": "^2.4.1",
|
||||
"serialport": "^9.2.4",
|
||||
"smartknobjs": "^0.1.0",
|
||||
"smartknobjs": "^1.0.0",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^4.8.4"
|
||||
}
|
||||
@ -27375,7 +27403,7 @@
|
||||
"eslint": "^8.25.0",
|
||||
"prettier": "^2.4.1",
|
||||
"serialport": "^9.2.4",
|
||||
"smartknobjs-proto": "^0.1.0",
|
||||
"smartknobjs-proto": "^1.0.0",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^4.8.4"
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"serialport": "^9.2.4",
|
||||
"smartknobjs": "^0.1.0",
|
||||
"smartknobjs": "^1.0.0",
|
||||
"socket.io": "^4.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -13,8 +13,10 @@ const start = async () => {
|
||||
// Implement a check for your device's vendor+product+serial
|
||||
// (this is more robust than the alternative of just hardcoding a "path" like "/dev/ttyUSB0")
|
||||
return (
|
||||
portInfo.vendorId?.toLowerCase() === '1a86'.toLowerCase() &&
|
||||
portInfo.productId?.toLowerCase() === '7523'.toLowerCase()
|
||||
(portInfo.vendorId?.toLowerCase() === '1a86'.toLowerCase() &&
|
||||
portInfo.productId?.toLowerCase() === '7523'.toLowerCase()) ||
|
||||
(portInfo.vendorId?.toLowerCase() === '303a'.toLowerCase() &&
|
||||
portInfo.productId?.toLowerCase() === '1001'.toLowerCase())
|
||||
// && portInfo.serialNumber === 'DEADBEEF'
|
||||
)
|
||||
})
|
||||
|
@ -18,7 +18,7 @@
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "^5.0.1",
|
||||
"smartknobjs-proto": "^0.1.1",
|
||||
"smartknobjs-proto": "^1.0.0",
|
||||
"socket.io-client": "^4.5.4",
|
||||
"typescript": "^4.9.3",
|
||||
"web-vitals": "^2.1.4"
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, {useEffect, useMemo, useRef, useState} from 'react'
|
||||
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'
|
||||
import io from 'socket.io-client'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import Container from '@mui/material/Container'
|
||||
@ -7,7 +7,7 @@ import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'
|
||||
import {PB} from 'smartknobjs-proto'
|
||||
import {VideoInfo} from './types'
|
||||
import {Card, CardContent} from '@mui/material'
|
||||
import {exhaustiveCheck, findNClosest, INT32_MIN, lerp, NoUndefinedField} from './util'
|
||||
import {exhaustiveCheck, findNClosest, lerp, NoUndefinedField} from './util'
|
||||
import {groupBy, parseInt} from 'lodash'
|
||||
|
||||
const socket = io()
|
||||
@ -15,7 +15,7 @@ const socket = io()
|
||||
const MIN_ZOOM = 0.01
|
||||
const MAX_ZOOM = 60
|
||||
|
||||
const PIXELS_PER_POSITION = 10
|
||||
const PIXELS_PER_POSITION = 5
|
||||
|
||||
enum Mode {
|
||||
Scroll = 'Scroll',
|
||||
@ -23,10 +23,16 @@ enum Mode {
|
||||
Speed = 'Speed',
|
||||
}
|
||||
|
||||
type State = {
|
||||
mode: Mode
|
||||
playbackSpeed: number
|
||||
type PlaybackState = {
|
||||
speed: number
|
||||
currentFrame: number
|
||||
}
|
||||
|
||||
type InterfaceState = {
|
||||
zoomTimelinePixelsPerFrame: number
|
||||
}
|
||||
|
||||
type Config = NoUndefinedField<PB.ISmartKnobConfig> & {
|
||||
zoomTimelinePixelsPerFrame: number
|
||||
}
|
||||
|
||||
@ -35,123 +41,129 @@ export type AppProps = {
|
||||
}
|
||||
export const App: React.FC<AppProps> = ({info}) => {
|
||||
const [isConnected, setIsConnected] = useState(socket.connected)
|
||||
const [state, setState] = useState<NoUndefinedField<PB.ISmartKnobState>>(
|
||||
|
||||
const [smartKnobState, setSmartKnobState] = useState<NoUndefinedField<PB.ISmartKnobState>>(
|
||||
PB.SmartKnobState.toObject(PB.SmartKnobState.create({config: PB.SmartKnobConfig.create()}), {
|
||||
defaults: true,
|
||||
}) as NoUndefinedField<PB.ISmartKnobState>,
|
||||
)
|
||||
const [derivedState, setDerivedState] = useState<State>({
|
||||
mode: Mode.Scroll,
|
||||
playbackSpeed: 0,
|
||||
currentFrame: 0,
|
||||
zoomTimelinePixelsPerFrame: 0.1,
|
||||
})
|
||||
|
||||
useMemo(() => {
|
||||
setDerivedState((cur) => {
|
||||
const modeText = state.config.text
|
||||
if (modeText === Mode.Scroll) {
|
||||
const rawFrame = Math.trunc(
|
||||
((state.currentPosition + state.subPositionUnit) * PIXELS_PER_POSITION) /
|
||||
cur.zoomTimelinePixelsPerFrame,
|
||||
)
|
||||
return {
|
||||
mode: Mode.Scroll,
|
||||
playbackSpeed: 0,
|
||||
currentFrame: Math.min(Math.max(rawFrame, 0), info.totalFrames - 1),
|
||||
zoomTimelinePixelsPerFrame: cur.zoomTimelinePixelsPerFrame,
|
||||
}
|
||||
} else if (modeText === Mode.Frames) {
|
||||
return {
|
||||
mode: Mode.Frames,
|
||||
playbackSpeed: 0,
|
||||
currentFrame: state.currentPosition ?? 0,
|
||||
zoomTimelinePixelsPerFrame: cur.zoomTimelinePixelsPerFrame,
|
||||
}
|
||||
} else if (modeText === Mode.Speed) {
|
||||
const normalizedWholeValue = state.currentPosition
|
||||
const normalizedFractional =
|
||||
Math.sign(state.subPositionUnit) *
|
||||
lerp(state.subPositionUnit * Math.sign(state.subPositionUnit), 0.1, 0.9, 0, 1)
|
||||
const normalized = normalizedWholeValue + normalizedFractional
|
||||
const speed = Math.sign(normalized) * Math.pow(2, Math.abs(normalized) - 1)
|
||||
return {
|
||||
mode: Mode.Speed,
|
||||
playbackSpeed: speed,
|
||||
currentFrame: cur.currentFrame,
|
||||
zoomTimelinePixelsPerFrame: cur.zoomTimelinePixelsPerFrame,
|
||||
}
|
||||
}
|
||||
return cur
|
||||
})
|
||||
}, [state.config.text, state.currentPosition, state.subPositionUnit])
|
||||
|
||||
const totalPositions = Math.ceil((info.totalFrames * derivedState.zoomTimelinePixelsPerFrame) / PIXELS_PER_POSITION)
|
||||
const detentPositions = useMemo(() => {
|
||||
// Always include the first and last positions at detents
|
||||
const positionsToFrames = groupBy([0, ...info.boundaryFrames, info.totalFrames - 1], (frame) =>
|
||||
Math.round((frame * derivedState.zoomTimelinePixelsPerFrame) / PIXELS_PER_POSITION),
|
||||
)
|
||||
console.log(JSON.stringify(positionsToFrames))
|
||||
return positionsToFrames
|
||||
}, [info.boundaryFrames, totalPositions, derivedState.zoomTimelinePixelsPerFrame])
|
||||
|
||||
// Continuous config updates for scrolling, to update detent positions
|
||||
useMemo(() => {
|
||||
if (derivedState.mode === Mode.Scroll) {
|
||||
const config = PB.SmartKnobConfig.create({
|
||||
position: INT32_MIN,
|
||||
const [smartKnobConfig, setSmartKnobConfig] = useState<Config>({
|
||||
position: 0,
|
||||
subPositionUnit: 0,
|
||||
positionNonce: Math.floor(Math.random() * 255),
|
||||
minPosition: 0,
|
||||
maxPosition: totalPositions - 1,
|
||||
positionWidthRadians: (8 * Math.PI) / 180,
|
||||
detentStrengthUnit: 2.5,
|
||||
maxPosition: 0,
|
||||
positionWidthRadians: (15 * Math.PI) / 180,
|
||||
detentStrengthUnit: 0,
|
||||
endstopStrengthUnit: 1,
|
||||
snapPoint: 0.7,
|
||||
text: Mode.Scroll,
|
||||
detentPositions: findNClosest(Object.keys(detentPositions).map(parseInt), state.currentPosition, 5),
|
||||
detentPositions: [],
|
||||
snapPointBias: 0,
|
||||
})
|
||||
socket.emit('set_config', config)
|
||||
}
|
||||
}, [derivedState.mode, derivedState.zoomTimelinePixelsPerFrame, detentPositions, state.currentPosition])
|
||||
|
||||
// For one-off config pushes, e.g. mode changes
|
||||
const pushConfig = (state: State) => {
|
||||
let config: PB.SmartKnobConfig
|
||||
if (state.mode === Mode.Scroll) {
|
||||
const position = Math.trunc((state.currentFrame * state.zoomTimelinePixelsPerFrame) / PIXELS_PER_POSITION)
|
||||
config = PB.SmartKnobConfig.create({
|
||||
zoomTimelinePixelsPerFrame: 0.1,
|
||||
})
|
||||
useEffect(() => {
|
||||
console.log('send config', smartKnobConfig)
|
||||
socket.emit('set_config', smartKnobConfig)
|
||||
}, [
|
||||
smartKnobConfig.position,
|
||||
smartKnobConfig.subPositionUnit,
|
||||
smartKnobConfig.positionNonce,
|
||||
smartKnobConfig.minPosition,
|
||||
smartKnobConfig.maxPosition,
|
||||
smartKnobConfig.positionWidthRadians,
|
||||
smartKnobConfig.detentStrengthUnit,
|
||||
smartKnobConfig.endstopStrengthUnit,
|
||||
smartKnobConfig.snapPoint,
|
||||
smartKnobConfig.text,
|
||||
smartKnobConfig.detentPositions,
|
||||
smartKnobConfig.snapPointBias,
|
||||
])
|
||||
const [playbackState, setPlaybackState] = useState<PlaybackState>({
|
||||
speed: 0,
|
||||
currentFrame: 0,
|
||||
})
|
||||
const [interfaceState, setInterfaceState] = useState<InterfaceState>({
|
||||
zoomTimelinePixelsPerFrame: 0.1,
|
||||
})
|
||||
|
||||
const totalPositions = Math.ceil(
|
||||
(info.totalFrames * smartKnobConfig.zoomTimelinePixelsPerFrame) / PIXELS_PER_POSITION,
|
||||
)
|
||||
const detentPositions = useMemo(() => {
|
||||
// Always include the first and last positions at detents
|
||||
const positionsToFrames = groupBy([0, ...info.boundaryFrames, info.totalFrames - 1], (frame) =>
|
||||
Math.round((frame * smartKnobConfig.zoomTimelinePixelsPerFrame) / PIXELS_PER_POSITION),
|
||||
)
|
||||
console.log(JSON.stringify(positionsToFrames))
|
||||
return positionsToFrames
|
||||
}, [info.boundaryFrames, info.totalFrames, totalPositions, smartKnobConfig.zoomTimelinePixelsPerFrame])
|
||||
|
||||
const scrollPositionWholeMemo = useMemo(() => {
|
||||
const position = (playbackState.currentFrame * smartKnobConfig.zoomTimelinePixelsPerFrame) / PIXELS_PER_POSITION
|
||||
return Math.round(position)
|
||||
}, [playbackState.currentFrame, smartKnobConfig.zoomTimelinePixelsPerFrame])
|
||||
const nClosestMemo = useMemo(() => {
|
||||
return findNClosest(Object.keys(detentPositions).map(parseInt), scrollPositionWholeMemo, 5).sort(
|
||||
(a, b) => a - b,
|
||||
)
|
||||
}, [scrollPositionWholeMemo])
|
||||
|
||||
const changeMode = useCallback(
|
||||
(newMode: Mode) => {
|
||||
if (newMode === Mode.Scroll) {
|
||||
setSmartKnobConfig((curConfig) => {
|
||||
const position =
|
||||
(playbackState.currentFrame * curConfig.zoomTimelinePixelsPerFrame) / PIXELS_PER_POSITION
|
||||
const positionWhole = Math.round(position)
|
||||
const subPositionUnit = position - positionWhole
|
||||
return {
|
||||
position,
|
||||
subPositionUnit,
|
||||
positionNonce: (curConfig.positionNonce + 1) % 256,
|
||||
minPosition: 0,
|
||||
maxPosition: Math.trunc(
|
||||
((info.totalFrames - 1) * state.zoomTimelinePixelsPerFrame) / PIXELS_PER_POSITION,
|
||||
((info.totalFrames - 1) * curConfig.zoomTimelinePixelsPerFrame) / PIXELS_PER_POSITION,
|
||||
),
|
||||
positionWidthRadians: (8 * Math.PI) / 180,
|
||||
detentStrengthUnit: 2.5,
|
||||
detentStrengthUnit: 3,
|
||||
endstopStrengthUnit: 1,
|
||||
snapPoint: 0.7,
|
||||
text: Mode.Scroll,
|
||||
detentPositions: findNClosest(Object.keys(detentPositions).map(parseInt), position, 5),
|
||||
snapPointBias: 0,
|
||||
|
||||
zoomTimelinePixelsPerFrame: curConfig.zoomTimelinePixelsPerFrame,
|
||||
}
|
||||
})
|
||||
} else if (state.mode === Mode.Frames) {
|
||||
config = PB.SmartKnobConfig.create({
|
||||
position: state.currentFrame,
|
||||
} else if (newMode === Mode.Frames) {
|
||||
setSmartKnobConfig((curConfig) => {
|
||||
return {
|
||||
position: playbackState.currentFrame,
|
||||
subPositionUnit: 0,
|
||||
positionNonce: (curConfig.positionNonce + 1) % 256,
|
||||
minPosition: 0,
|
||||
maxPosition: info.totalFrames - 1,
|
||||
positionWidthRadians: (1.5 * Math.PI) / 180,
|
||||
positionWidthRadians: (1.8 * Math.PI) / 180,
|
||||
detentStrengthUnit: 1,
|
||||
endstopStrengthUnit: 1,
|
||||
snapPoint: 1.1,
|
||||
text: Mode.Frames,
|
||||
detentPositions: [],
|
||||
snapPointBias: 0,
|
||||
|
||||
zoomTimelinePixelsPerFrame: curConfig.zoomTimelinePixelsPerFrame,
|
||||
}
|
||||
})
|
||||
} else if (state.mode === Mode.Speed) {
|
||||
config = PB.SmartKnobConfig.create({
|
||||
position: state.playbackSpeed === 0 ? 0 : INT32_MIN,
|
||||
minPosition: state.currentFrame === 0 ? 0 : -6,
|
||||
maxPosition: state.currentFrame === info.totalFrames - 1 ? 0 : 6,
|
||||
} else if (newMode === Mode.Speed) {
|
||||
setSmartKnobConfig((curConfig) => {
|
||||
return {
|
||||
position: 0,
|
||||
subPositionUnit: 0,
|
||||
positionNonce: (curConfig.positionNonce + 1) % 256,
|
||||
minPosition: playbackState.currentFrame === 0 ? 0 : -6,
|
||||
maxPosition: playbackState.currentFrame === info.totalFrames - 1 ? 0 : 6,
|
||||
positionWidthRadians: (60 * Math.PI) / 180,
|
||||
detentStrengthUnit: 1,
|
||||
endstopStrengthUnit: 1,
|
||||
@ -159,73 +171,153 @@ export const App: React.FC<AppProps> = ({info}) => {
|
||||
text: Mode.Speed,
|
||||
detentPositions: [],
|
||||
snapPointBias: 0.4,
|
||||
|
||||
zoomTimelinePixelsPerFrame: curConfig.zoomTimelinePixelsPerFrame,
|
||||
}
|
||||
})
|
||||
} else {
|
||||
throw exhaustiveCheck(state.mode)
|
||||
}
|
||||
socket.emit('set_config', config)
|
||||
exhaustiveCheck(newMode)
|
||||
}
|
||||
},
|
||||
[detentPositions, info.totalFrames, playbackState],
|
||||
)
|
||||
|
||||
const setCurrentFrame = (fn: (oldFrame: number) => number) => {
|
||||
setDerivedState((cur) => {
|
||||
const newState = {...cur}
|
||||
if (cur.mode === Mode.Speed) {
|
||||
newState.currentFrame = fn(cur.currentFrame)
|
||||
}
|
||||
return newState
|
||||
})
|
||||
}
|
||||
|
||||
// Timer for speed-based playback
|
||||
useEffect(() => {
|
||||
const refreshInterval = 20
|
||||
const fps = info.frameRate * derivedState.playbackSpeed
|
||||
if (derivedState.mode === Mode.Speed && fps !== 0) {
|
||||
const timer = setInterval(() => {
|
||||
setCurrentFrame((oldFrame) => {
|
||||
const newFrame = oldFrame + (fps * refreshInterval) / 1000
|
||||
|
||||
const oldFrameTrunc = Math.trunc(oldFrame)
|
||||
const newFrameTrunc = Math.trunc(newFrame)
|
||||
|
||||
if (newFrame < 0 || newFrame >= info.totalFrames) {
|
||||
const clampedNewFrame = Math.min(Math.max(newFrame, 0), info.totalFrames - 1)
|
||||
if (oldFrame !== clampedNewFrame) {
|
||||
// If we've hit a boundary, push a config to set the bounds
|
||||
pushConfig({
|
||||
mode: Mode.Speed,
|
||||
playbackSpeed: 0,
|
||||
currentFrame: Math.trunc(clampedNewFrame),
|
||||
zoomTimelinePixelsPerFrame: derivedState.zoomTimelinePixelsPerFrame,
|
||||
})
|
||||
if (smartKnobState.config.text === '') {
|
||||
console.debug('No valid state yet')
|
||||
return
|
||||
}
|
||||
return clampedNewFrame
|
||||
|
||||
const currentMode = smartKnobState.config.text as Mode
|
||||
if (currentMode !== smartKnobConfig.text) {
|
||||
console.debug('Mode mismatch, ignoring state', {configMode: smartKnobConfig.text, stateMode: currentMode})
|
||||
return
|
||||
}
|
||||
|
||||
// Update playbackState
|
||||
if (currentMode === Mode.Scroll) {
|
||||
// TODO: round input based on zoom level to avoid noise
|
||||
const rawFrame = Math.trunc(
|
||||
((smartKnobState.currentPosition + smartKnobState.subPositionUnit) * PIXELS_PER_POSITION) /
|
||||
smartKnobConfig.zoomTimelinePixelsPerFrame,
|
||||
)
|
||||
const frame =
|
||||
detentPositions[smartKnobState.currentPosition]?.[0] ??
|
||||
Math.min(Math.max(rawFrame, 0), info.totalFrames - 1)
|
||||
setPlaybackState({
|
||||
speed: 0,
|
||||
currentFrame: frame,
|
||||
})
|
||||
|
||||
// Update config with N nearest detents
|
||||
setSmartKnobConfig((curConfig) => {
|
||||
let positionInfo: Partial<Config> = {}
|
||||
if (interfaceState.zoomTimelinePixelsPerFrame !== curConfig.zoomTimelinePixelsPerFrame) {
|
||||
const position =
|
||||
(playbackState.currentFrame * interfaceState.zoomTimelinePixelsPerFrame) / PIXELS_PER_POSITION
|
||||
const positionWhole = Math.round(position)
|
||||
const subPositionUnit = position - positionWhole
|
||||
positionInfo = {
|
||||
position,
|
||||
subPositionUnit,
|
||||
positionNonce: (curConfig.positionNonce + 1) % 256,
|
||||
minPosition: 0,
|
||||
maxPosition: Math.trunc(
|
||||
((info.totalFrames - 1) * interfaceState.zoomTimelinePixelsPerFrame) / PIXELS_PER_POSITION,
|
||||
),
|
||||
zoomTimelinePixelsPerFrame: interfaceState.zoomTimelinePixelsPerFrame,
|
||||
}
|
||||
}
|
||||
return {
|
||||
...curConfig,
|
||||
...positionInfo,
|
||||
detentPositions: nClosestMemo,
|
||||
}
|
||||
})
|
||||
} else if (currentMode === Mode.Frames) {
|
||||
setPlaybackState({
|
||||
speed: 0,
|
||||
currentFrame: smartKnobState.currentPosition,
|
||||
})
|
||||
// No config updates needed
|
||||
} else if (currentMode === Mode.Speed) {
|
||||
const normalizedWholeValue = smartKnobState.currentPosition
|
||||
const normalizedFractional =
|
||||
Math.sign(smartKnobState.subPositionUnit) *
|
||||
lerp(smartKnobState.subPositionUnit * Math.sign(smartKnobState.subPositionUnit), 0.1, 0.9, 0, 1)
|
||||
const normalized = normalizedWholeValue + normalizedFractional
|
||||
const speed = Math.sign(normalized) * Math.pow(2, Math.abs(normalized) - 1)
|
||||
const roundedSpeed = Math.trunc(speed * 10) / 10
|
||||
setPlaybackState((cur) => {
|
||||
return {
|
||||
speed: roundedSpeed,
|
||||
currentFrame: cur.currentFrame,
|
||||
}
|
||||
})
|
||||
|
||||
// Update config with bounds depending on current frame
|
||||
setSmartKnobConfig((curConfig) => {
|
||||
return {
|
||||
...curConfig,
|
||||
minPosition: playbackState.currentFrame === 0 ? 0 : -6,
|
||||
maxPosition: playbackState.currentFrame === info.totalFrames - 1 ? 0 : 6,
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if (
|
||||
(oldFrameTrunc === 0 && newFrameTrunc > 0) ||
|
||||
(oldFrameTrunc === info.totalFrames - 1 && newFrameTrunc < info.totalFrames - 1)
|
||||
) {
|
||||
// If we've left a boundary condition, push a config to reset the bounds
|
||||
pushConfig({
|
||||
mode: derivedState.mode,
|
||||
playbackSpeed: 0,
|
||||
currentFrame: newFrameTrunc,
|
||||
zoomTimelinePixelsPerFrame: derivedState.zoomTimelinePixelsPerFrame,
|
||||
})
|
||||
exhaustiveCheck(currentMode)
|
||||
}
|
||||
return newFrame
|
||||
}, [
|
||||
detentPositions,
|
||||
nClosestMemo,
|
||||
info.totalFrames,
|
||||
smartKnobState.config.text,
|
||||
smartKnobState.currentPosition,
|
||||
smartKnobState.subPositionUnit,
|
||||
smartKnobConfig.text,
|
||||
playbackState.currentFrame,
|
||||
playbackState.speed,
|
||||
interfaceState.zoomTimelinePixelsPerFrame,
|
||||
])
|
||||
|
||||
const refreshInterval = 20
|
||||
const updateFrame = useCallback(() => {
|
||||
const fps = info.frameRate * playbackState.speed
|
||||
setPlaybackState((cur) => {
|
||||
const newFrame = cur.currentFrame + (fps * refreshInterval) / 1000
|
||||
const clampedNewFrame = Math.min(Math.max(newFrame, 0), info.totalFrames - 1)
|
||||
return {
|
||||
speed: cur.speed,
|
||||
currentFrame: clampedNewFrame,
|
||||
}
|
||||
})
|
||||
}, [info.frameRate, playbackState.speed])
|
||||
|
||||
// Store the latest callback in a ref so the long-lived interval closure can invoke the latest version.
|
||||
// See https://overreacted.io/making-setinterval-declarative-with-react-hooks/ for more
|
||||
const savedCallback = useRef<() => void | null>()
|
||||
useEffect(() => {
|
||||
savedCallback.current = updateFrame
|
||||
}, [updateFrame])
|
||||
|
||||
const isPlaying = useMemo(() => {
|
||||
return playbackState.speed !== 0
|
||||
}, [playbackState.speed])
|
||||
|
||||
useEffect(() => {
|
||||
if (smartKnobState.config.text === Mode.Speed && isPlaying) {
|
||||
const timer = setInterval(() => {
|
||||
if (savedCallback.current) {
|
||||
savedCallback.current()
|
||||
}
|
||||
}, refreshInterval)
|
||||
return () => clearInterval(timer)
|
||||
}
|
||||
}, [derivedState.mode, derivedState.playbackSpeed, info.totalFrames, info.frameRate])
|
||||
}, [smartKnobState.config.text, isPlaying])
|
||||
|
||||
// Socket.io subscription
|
||||
useEffect(() => {
|
||||
socket.on('connect', () => {
|
||||
setIsConnected(true)
|
||||
pushConfig(derivedState)
|
||||
})
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
@ -237,7 +329,7 @@ export const App: React.FC<AppProps> = ({info}) => {
|
||||
const stateObj = PB.SmartKnobState.toObject(state, {
|
||||
defaults: true,
|
||||
}) as NoUndefinedField<PB.ISmartKnobState>
|
||||
setState(stateObj)
|
||||
setSmartKnobState(stateObj)
|
||||
})
|
||||
return () => {
|
||||
socket.off('connect')
|
||||
@ -260,16 +352,13 @@ export const App: React.FC<AppProps> = ({info}) => {
|
||||
)}
|
||||
<ToggleButtonGroup
|
||||
color="primary"
|
||||
value={derivedState.mode}
|
||||
value={smartKnobConfig.text}
|
||||
exclusive
|
||||
onChange={(e, value: Mode | null) => {
|
||||
if (value === null) {
|
||||
return
|
||||
}
|
||||
pushConfig({
|
||||
...derivedState,
|
||||
mode: value,
|
||||
})
|
||||
changeMode(value)
|
||||
}}
|
||||
aria-label="Mode"
|
||||
>
|
||||
@ -280,18 +369,18 @@ export const App: React.FC<AppProps> = ({info}) => {
|
||||
))}
|
||||
</ToggleButtonGroup>
|
||||
<Typography>
|
||||
Frame {Math.trunc(derivedState.currentFrame)} / {info.totalFrames - 1}
|
||||
Frame {Math.trunc(playbackState.currentFrame)} / {info.totalFrames - 1}
|
||||
<br />
|
||||
Speed {Math.trunc(derivedState.playbackSpeed * 10) / 10}
|
||||
Speed {playbackState.speed}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Timeline
|
||||
info={info}
|
||||
currentFrame={derivedState.currentFrame}
|
||||
zoomTimelinePixelsPerFrame={derivedState.zoomTimelinePixelsPerFrame}
|
||||
currentFrame={playbackState.currentFrame}
|
||||
zoomTimelinePixelsPerFrame={interfaceState.zoomTimelinePixelsPerFrame}
|
||||
adjustZoom={(factor) => {
|
||||
setDerivedState((cur) => {
|
||||
setInterfaceState((cur) => {
|
||||
const newZoom = Math.min(
|
||||
Math.max(cur.zoomTimelinePixelsPerFrame * factor, MIN_ZOOM),
|
||||
MAX_ZOOM,
|
||||
@ -306,7 +395,7 @@ export const App: React.FC<AppProps> = ({info}) => {
|
||||
/>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<div>{JSON.stringify(detentPositions)}</div>
|
||||
<div>{JSON.stringify(smartKnobConfig)}</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Container>
|
||||
|
@ -17,7 +17,7 @@ const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
|
||||
const info: VideoInfo = {
|
||||
totalFrames: 30 * 60 * 5,
|
||||
frameRate: 30,
|
||||
boundaryFrames: [312, 400, 1234, 1290, 3000, 4000],
|
||||
boundaryFrames: [312, 400, 1234, 1290, 3000, 3300, 4000, 8000, 8100],
|
||||
}
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
|
@ -18,8 +18,6 @@ export type NoUndefinedField<T> = {
|
||||
[P in keyof T]-?: NoUndefinedField<NonNullable<T[P]>>
|
||||
}
|
||||
|
||||
export const INT32_MIN = -2147483648
|
||||
|
||||
export function findNClosest(numbers: number[], target: number, n: number): number[] {
|
||||
// First, we sort the numbers in ascending order based on their absolute difference
|
||||
// from the target number. This means that the numbers that are closest to the target
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "example",
|
||||
"version": "0.1.0",
|
||||
"description": "SmartKnob Interface Library",
|
||||
"description": "SmartKnob Interface Example",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
@ -14,7 +14,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"serialport": "^9.2.4",
|
||||
"smartknobjs": "^0.1.0"
|
||||
"smartknobjs": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/serialport": "^8.0.2",
|
||||
|
@ -30,9 +30,11 @@ const main = async () => {
|
||||
if (message.payload === 'log' && message.log) {
|
||||
console.log('LOG', message.log.msg)
|
||||
} else if (message.payload === 'smartknobState' && message.smartknobState) {
|
||||
// Only log if it's a significant change (major position change, or at least 5 degrees)
|
||||
const radianChange = (message.smartknobState.subPositionUnit ?? 0) * (message.smartknobState.config?.positionWidthRadians ?? 0) - (lastLoggedState?.subPositionUnit ?? 0) * (lastLoggedState?.config?.positionWidthRadians ?? 0)
|
||||
if (
|
||||
message.smartknobState.currentPosition !== lastLoggedState?.currentPosition ||
|
||||
Math.abs((message.smartknobState.subPositionUnit ?? 0) - (lastLoggedState?.subPositionUnit ?? 0)) > 1
|
||||
Math.abs(radianChange)*180/Math.PI > 5
|
||||
) {
|
||||
console.log(
|
||||
`State:\n${JSON.stringify(
|
||||
@ -50,6 +52,8 @@ const main = async () => {
|
||||
detentStrengthUnit: 1,
|
||||
endstopStrengthUnit: 1,
|
||||
position: 0,
|
||||
subPositionUnit: 0,
|
||||
positionNonce: Math.floor(Math.random()*255), // Pick a random nonce to force a position reset on start
|
||||
minPosition: 0,
|
||||
maxPosition: 4,
|
||||
positionWidthRadians: (10 * Math.PI) / 180,
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "smartknobjs-proto",
|
||||
"version": "0.1.1",
|
||||
"version": "1.0.0",
|
||||
"description": "SmartKnob Protobuf Generated Code",
|
||||
"main": "dist/smartknob_proto.js",
|
||||
"types": "dist/smartknob_proto.d.ts",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "smartknobjs",
|
||||
"version": "0.1.0",
|
||||
"version": "1.0.0",
|
||||
"description": "SmartKnob Interface Library",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
@ -15,7 +15,7 @@
|
||||
"cobs": "^0.2.1",
|
||||
"crc-32": "^1.2.0",
|
||||
"serialport": "^9.2.4",
|
||||
"smartknobjs-proto": "^0.1.0"
|
||||
"smartknobjs-proto": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/serialport": "^8.0.2",
|
||||
|
@ -1,9 +1,11 @@
|
||||
import SerialPort = require('serialport')
|
||||
import {decode, encode} from 'cobs'
|
||||
import {decode as cobsDecode, encode as cobsEncode} from 'cobs'
|
||||
import * as CRC32 from 'crc-32'
|
||||
|
||||
import {PB} from 'smartknobjs-proto'
|
||||
|
||||
const PROTOBUF_PROTOCOL_VERSION = 1
|
||||
|
||||
export type MessageCallback = (message: PB.FromSmartKnob) => void
|
||||
|
||||
type QueueEntry = {
|
||||
@ -83,7 +85,7 @@ export class SmartKnob {
|
||||
// Iterate 0-delimited packets
|
||||
while ((i = this.buffer.indexOf(0)) != -1) {
|
||||
const raw_buffer = this.buffer.slice(0, i)
|
||||
const packet = decode(raw_buffer) as Buffer
|
||||
const packet = cobsDecode(raw_buffer) as Buffer
|
||||
this.buffer = this.buffer.slice(i + 1)
|
||||
if (packet.length <= 4) {
|
||||
console.debug(`Received short packet ${this.buffer.slice(0, i)}`)
|
||||
@ -109,6 +111,13 @@ export class SmartKnob {
|
||||
return
|
||||
}
|
||||
|
||||
if (message.protocolVersion !== PROTOBUF_PROTOCOL_VERSION) {
|
||||
console.warn(
|
||||
`Invalid protocol version. Expected ${PROTOBUF_PROTOCOL_VERSION}, received ${message.protocolVersion}`,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (message.payload === 'ack') {
|
||||
const nonce = message.ack?.nonce ?? undefined
|
||||
if (nonce === undefined) {
|
||||
@ -126,6 +135,7 @@ export class SmartKnob {
|
||||
if (this.port === null) {
|
||||
return
|
||||
}
|
||||
message.protocolVersion = PROTOBUF_PROTOCOL_VERSION
|
||||
message.nonce = this.lastNonce++
|
||||
|
||||
// Encode before enqueueing to ensure messages don't change once they're queued
|
||||
@ -173,7 +183,7 @@ export class SmartKnob {
|
||||
const crcBuffer = Buffer.from([crc & 0xff, (crc >>> 8) & 0xff, (crc >>> 16) & 0xff, (crc >>> 24) & 0xff])
|
||||
const packet = Buffer.concat([payload, crcBuffer])
|
||||
|
||||
const encodedDelimitedPacket = Buffer.concat([encode(packet), Buffer.from([0])])
|
||||
const encodedDelimitedPacket = Buffer.concat([cobsEncode(packet), Buffer.from([0])])
|
||||
|
||||
this.retryTimeout = setTimeout(() => {
|
||||
this.retryTimeout = null
|
||||
|
@ -1,8 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: nanopb.proto
|
||||
|
||||
import sys
|
||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
||||
from google.protobuf.internal import enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
@ -20,8 +19,9 @@ DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='nanopb.proto',
|
||||
package='',
|
||||
syntax='proto2',
|
||||
serialized_options=_b('\n\030fi.kapsi.koti.jpa.nanopb'),
|
||||
serialized_pb=_b('\n\x0cnanopb.proto\x1a google/protobuf/descriptor.proto\"\xa4\x07\n\rNanoPBOptions\x12\x10\n\x08max_size\x18\x01 \x01(\x05\x12\x12\n\nmax_length\x18\x0e \x01(\x05\x12\x11\n\tmax_count\x18\x02 \x01(\x05\x12&\n\x08int_size\x18\x07 \x01(\x0e\x32\x08.IntSize:\nIS_DEFAULT\x12$\n\x04type\x18\x03 \x01(\x0e\x32\n.FieldType:\nFT_DEFAULT\x12\x18\n\nlong_names\x18\x04 \x01(\x08:\x04true\x12\x1c\n\rpacked_struct\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0bpacked_enum\x18\n \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0cskip_message\x18\x06 \x01(\x08:\x05\x66\x61lse\x12\x18\n\tno_unions\x18\x08 \x01(\x08:\x05\x66\x61lse\x12\r\n\x05msgid\x18\t \x01(\r\x12\x1e\n\x0f\x61nonymous_oneof\x18\x0b \x01(\x08:\x05\x66\x61lse\x12\x15\n\x06proto3\x18\x0c \x01(\x08:\x05\x66\x61lse\x12#\n\x14proto3_singular_msgs\x18\x15 \x01(\x08:\x05\x66\x61lse\x12\x1d\n\x0e\x65num_to_string\x18\r \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0c\x66ixed_length\x18\x0f \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0b\x66ixed_count\x18\x10 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x0fsubmsg_callback\x18\x16 \x01(\x08:\x05\x66\x61lse\x12/\n\x0cmangle_names\x18\x11 \x01(\x0e\x32\x11.TypenameMangling:\x06M_NONE\x12(\n\x11\x63\x61llback_datatype\x18\x12 \x01(\t:\rpb_callback_t\x12\x34\n\x11\x63\x61llback_function\x18\x13 \x01(\t:\x19pb_default_field_callback\x12\x30\n\x0e\x64\x65scriptorsize\x18\x14 \x01(\x0e\x32\x0f.DescriptorSize:\x07\x44S_AUTO\x12\x1a\n\x0b\x64\x65\x66\x61ult_has\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x0f\n\x07include\x18\x18 \x03(\t\x12\x0f\n\x07\x65xclude\x18\x1a \x03(\t\x12\x0f\n\x07package\x18\x19 \x01(\t\x12\x41\n\rtype_override\x18\x1b \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x19\n\x0bsort_by_tag\x18\x1c \x01(\x08:\x04true\x12.\n\rfallback_type\x18\x1d \x01(\x0e\x32\n.FieldType:\x0b\x46T_CALLBACK*i\n\tFieldType\x12\x0e\n\nFT_DEFAULT\x10\x00\x12\x0f\n\x0b\x46T_CALLBACK\x10\x01\x12\x0e\n\nFT_POINTER\x10\x04\x12\r\n\tFT_STATIC\x10\x02\x12\r\n\tFT_IGNORE\x10\x03\x12\r\n\tFT_INLINE\x10\x05*D\n\x07IntSize\x12\x0e\n\nIS_DEFAULT\x10\x00\x12\x08\n\x04IS_8\x10\x08\x12\t\n\x05IS_16\x10\x10\x12\t\n\x05IS_32\x10 \x12\t\n\x05IS_64\x10@*Z\n\x10TypenameMangling\x12\n\n\x06M_NONE\x10\x00\x12\x13\n\x0fM_STRIP_PACKAGE\x10\x01\x12\r\n\tM_FLATTEN\x10\x02\x12\x16\n\x12M_PACKAGE_INITIALS\x10\x03*E\n\x0e\x44\x65scriptorSize\x12\x0b\n\x07\x44S_AUTO\x10\x00\x12\x08\n\x04\x44S_1\x10\x01\x12\x08\n\x04\x44S_2\x10\x02\x12\x08\n\x04\x44S_4\x10\x04\x12\x08\n\x04\x44S_8\x10\x08:E\n\x0enanopb_fileopt\x12\x1c.google.protobuf.FileOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:G\n\rnanopb_msgopt\x12\x1f.google.protobuf.MessageOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:E\n\x0enanopb_enumopt\x12\x1c.google.protobuf.EnumOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:>\n\x06nanopb\x12\x1d.google.protobuf.FieldOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptionsB\x1a\n\x18\x66i.kapsi.koti.jpa.nanopb')
|
||||
serialized_options=b'\n\030fi.kapsi.koti.jpa.nanopb',
|
||||
create_key=_descriptor._internal_create_key,
|
||||
serialized_pb=b'\n\x0cnanopb.proto\x1a google/protobuf/descriptor.proto\"\xa4\x07\n\rNanoPBOptions\x12\x10\n\x08max_size\x18\x01 \x01(\x05\x12\x12\n\nmax_length\x18\x0e \x01(\x05\x12\x11\n\tmax_count\x18\x02 \x01(\x05\x12&\n\x08int_size\x18\x07 \x01(\x0e\x32\x08.IntSize:\nIS_DEFAULT\x12$\n\x04type\x18\x03 \x01(\x0e\x32\n.FieldType:\nFT_DEFAULT\x12\x18\n\nlong_names\x18\x04 \x01(\x08:\x04true\x12\x1c\n\rpacked_struct\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0bpacked_enum\x18\n \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0cskip_message\x18\x06 \x01(\x08:\x05\x66\x61lse\x12\x18\n\tno_unions\x18\x08 \x01(\x08:\x05\x66\x61lse\x12\r\n\x05msgid\x18\t \x01(\r\x12\x1e\n\x0f\x61nonymous_oneof\x18\x0b \x01(\x08:\x05\x66\x61lse\x12\x15\n\x06proto3\x18\x0c \x01(\x08:\x05\x66\x61lse\x12#\n\x14proto3_singular_msgs\x18\x15 \x01(\x08:\x05\x66\x61lse\x12\x1d\n\x0e\x65num_to_string\x18\r \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0c\x66ixed_length\x18\x0f \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0b\x66ixed_count\x18\x10 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x0fsubmsg_callback\x18\x16 \x01(\x08:\x05\x66\x61lse\x12/\n\x0cmangle_names\x18\x11 \x01(\x0e\x32\x11.TypenameMangling:\x06M_NONE\x12(\n\x11\x63\x61llback_datatype\x18\x12 \x01(\t:\rpb_callback_t\x12\x34\n\x11\x63\x61llback_function\x18\x13 \x01(\t:\x19pb_default_field_callback\x12\x30\n\x0e\x64\x65scriptorsize\x18\x14 \x01(\x0e\x32\x0f.DescriptorSize:\x07\x44S_AUTO\x12\x1a\n\x0b\x64\x65\x66\x61ult_has\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x0f\n\x07include\x18\x18 \x03(\t\x12\x0f\n\x07\x65xclude\x18\x1a \x03(\t\x12\x0f\n\x07package\x18\x19 \x01(\t\x12\x41\n\rtype_override\x18\x1b \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x19\n\x0bsort_by_tag\x18\x1c \x01(\x08:\x04true\x12.\n\rfallback_type\x18\x1d \x01(\x0e\x32\n.FieldType:\x0b\x46T_CALLBACK*i\n\tFieldType\x12\x0e\n\nFT_DEFAULT\x10\x00\x12\x0f\n\x0b\x46T_CALLBACK\x10\x01\x12\x0e\n\nFT_POINTER\x10\x04\x12\r\n\tFT_STATIC\x10\x02\x12\r\n\tFT_IGNORE\x10\x03\x12\r\n\tFT_INLINE\x10\x05*D\n\x07IntSize\x12\x0e\n\nIS_DEFAULT\x10\x00\x12\x08\n\x04IS_8\x10\x08\x12\t\n\x05IS_16\x10\x10\x12\t\n\x05IS_32\x10 \x12\t\n\x05IS_64\x10@*Z\n\x10TypenameMangling\x12\n\n\x06M_NONE\x10\x00\x12\x13\n\x0fM_STRIP_PACKAGE\x10\x01\x12\r\n\tM_FLATTEN\x10\x02\x12\x16\n\x12M_PACKAGE_INITIALS\x10\x03*E\n\x0e\x44\x65scriptorSize\x12\x0b\n\x07\x44S_AUTO\x10\x00\x12\x08\n\x04\x44S_1\x10\x01\x12\x08\n\x04\x44S_2\x10\x02\x12\x08\n\x04\x44S_4\x10\x04\x12\x08\n\x04\x44S_8\x10\x08:E\n\x0enanopb_fileopt\x12\x1c.google.protobuf.FileOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:G\n\rnanopb_msgopt\x12\x1f.google.protobuf.MessageOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:E\n\x0enanopb_enumopt\x12\x1c.google.protobuf.EnumOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:>\n\x06nanopb\x12\x1d.google.protobuf.FieldOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptionsB\x1a\n\x18\x66i.kapsi.koti.jpa.nanopb'
|
||||
,
|
||||
dependencies=[google_dot_protobuf_dot_descriptor__pb2.DESCRIPTOR,])
|
||||
|
||||
@ -30,31 +30,38 @@ _FIELDTYPE = _descriptor.EnumDescriptor(
|
||||
full_name='FieldType',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
create_key=_descriptor._internal_create_key,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='FT_DEFAULT', index=0, number=0,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='FT_CALLBACK', index=1, number=1,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='FT_POINTER', index=2, number=4,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='FT_STATIC', index=3, number=2,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='FT_IGNORE', index=4, number=3,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='FT_INLINE', index=5, number=5,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
],
|
||||
containing_type=None,
|
||||
serialized_options=None,
|
||||
@ -69,27 +76,33 @@ _INTSIZE = _descriptor.EnumDescriptor(
|
||||
full_name='IntSize',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
create_key=_descriptor._internal_create_key,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='IS_DEFAULT', index=0, number=0,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='IS_8', index=1, number=8,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='IS_16', index=2, number=16,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='IS_32', index=3, number=32,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='IS_64', index=4, number=64,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
],
|
||||
containing_type=None,
|
||||
serialized_options=None,
|
||||
@ -104,23 +117,28 @@ _TYPENAMEMANGLING = _descriptor.EnumDescriptor(
|
||||
full_name='TypenameMangling',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
create_key=_descriptor._internal_create_key,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='M_NONE', index=0, number=0,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='M_STRIP_PACKAGE', index=1, number=1,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='M_FLATTEN', index=2, number=2,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='M_PACKAGE_INITIALS', index=3, number=3,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
],
|
||||
containing_type=None,
|
||||
serialized_options=None,
|
||||
@ -135,27 +153,33 @@ _DESCRIPTORSIZE = _descriptor.EnumDescriptor(
|
||||
full_name='DescriptorSize',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
create_key=_descriptor._internal_create_key,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='DS_AUTO', index=0, number=0,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='DS_1', index=1, number=1,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='DS_2', index=2, number=2,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='DS_4', index=3, number=4,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='DS_8', index=4, number=8,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
],
|
||||
containing_type=None,
|
||||
serialized_options=None,
|
||||
@ -193,7 +217,7 @@ nanopb_fileopt = _descriptor.FieldDescriptor(
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=True, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR)
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key)
|
||||
NANOPB_MSGOPT_FIELD_NUMBER = 1010
|
||||
nanopb_msgopt = _descriptor.FieldDescriptor(
|
||||
name='nanopb_msgopt', full_name='nanopb_msgopt', index=1,
|
||||
@ -201,7 +225,7 @@ nanopb_msgopt = _descriptor.FieldDescriptor(
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=True, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR)
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key)
|
||||
NANOPB_ENUMOPT_FIELD_NUMBER = 1010
|
||||
nanopb_enumopt = _descriptor.FieldDescriptor(
|
||||
name='nanopb_enumopt', full_name='nanopb_enumopt', index=2,
|
||||
@ -209,7 +233,7 @@ nanopb_enumopt = _descriptor.FieldDescriptor(
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=True, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR)
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key)
|
||||
NANOPB_FIELD_NUMBER = 1010
|
||||
nanopb = _descriptor.FieldDescriptor(
|
||||
name='nanopb', full_name='nanopb', index=3,
|
||||
@ -217,7 +241,7 @@ nanopb = _descriptor.FieldDescriptor(
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=True, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR)
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key)
|
||||
|
||||
|
||||
_NANOPBOPTIONS = _descriptor.Descriptor(
|
||||
@ -226,6 +250,7 @@ _NANOPBOPTIONS = _descriptor.Descriptor(
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
create_key=_descriptor._internal_create_key,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='max_size', full_name='NanoPBOptions.max_size', index=0,
|
||||
@ -233,203 +258,203 @@ _NANOPBOPTIONS = _descriptor.Descriptor(
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='max_length', full_name='NanoPBOptions.max_length', index=1,
|
||||
number=14, type=5, cpp_type=1, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='max_count', full_name='NanoPBOptions.max_count', index=2,
|
||||
number=2, type=5, cpp_type=1, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='int_size', full_name='NanoPBOptions.int_size', index=3,
|
||||
number=7, type=14, cpp_type=8, label=1,
|
||||
has_default_value=True, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='type', full_name='NanoPBOptions.type', index=4,
|
||||
number=3, type=14, cpp_type=8, label=1,
|
||||
has_default_value=True, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='long_names', full_name='NanoPBOptions.long_names', index=5,
|
||||
number=4, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=True,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='packed_struct', full_name='NanoPBOptions.packed_struct', index=6,
|
||||
number=5, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='packed_enum', full_name='NanoPBOptions.packed_enum', index=7,
|
||||
number=10, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='skip_message', full_name='NanoPBOptions.skip_message', index=8,
|
||||
number=6, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='no_unions', full_name='NanoPBOptions.no_unions', index=9,
|
||||
number=8, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='msgid', full_name='NanoPBOptions.msgid', index=10,
|
||||
number=9, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='anonymous_oneof', full_name='NanoPBOptions.anonymous_oneof', index=11,
|
||||
number=11, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='proto3', full_name='NanoPBOptions.proto3', index=12,
|
||||
number=12, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='proto3_singular_msgs', full_name='NanoPBOptions.proto3_singular_msgs', index=13,
|
||||
number=21, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='enum_to_string', full_name='NanoPBOptions.enum_to_string', index=14,
|
||||
number=13, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='fixed_length', full_name='NanoPBOptions.fixed_length', index=15,
|
||||
number=15, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='fixed_count', full_name='NanoPBOptions.fixed_count', index=16,
|
||||
number=16, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='submsg_callback', full_name='NanoPBOptions.submsg_callback', index=17,
|
||||
number=22, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='mangle_names', full_name='NanoPBOptions.mangle_names', index=18,
|
||||
number=17, type=14, cpp_type=8, label=1,
|
||||
has_default_value=True, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='callback_datatype', full_name='NanoPBOptions.callback_datatype', index=19,
|
||||
number=18, type=9, cpp_type=9, label=1,
|
||||
has_default_value=True, default_value=_b("pb_callback_t").decode('utf-8'),
|
||||
has_default_value=True, default_value=b"pb_callback_t".decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='callback_function', full_name='NanoPBOptions.callback_function', index=20,
|
||||
number=19, type=9, cpp_type=9, label=1,
|
||||
has_default_value=True, default_value=_b("pb_default_field_callback").decode('utf-8'),
|
||||
has_default_value=True, default_value=b"pb_default_field_callback".decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='descriptorsize', full_name='NanoPBOptions.descriptorsize', index=21,
|
||||
number=20, type=14, cpp_type=8, label=1,
|
||||
has_default_value=True, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='default_has', full_name='NanoPBOptions.default_has', index=22,
|
||||
number=23, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='include', full_name='NanoPBOptions.include', index=23,
|
||||
number=24, type=9, cpp_type=9, label=3,
|
||||
has_default_value=False, default_value=[],
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='exclude', full_name='NanoPBOptions.exclude', index=24,
|
||||
number=26, type=9, cpp_type=9, label=3,
|
||||
has_default_value=False, default_value=[],
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='package', full_name='NanoPBOptions.package', index=25,
|
||||
number=25, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
has_default_value=False, default_value=b"".decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='type_override', full_name='NanoPBOptions.type_override', index=26,
|
||||
number=27, type=14, cpp_type=8, label=1,
|
||||
has_default_value=False, default_value=1,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='sort_by_tag', full_name='NanoPBOptions.sort_by_tag', index=27,
|
||||
number=28, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=True,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='fallback_type', full_name='NanoPBOptions.fallback_type', index=28,
|
||||
number=29, type=14, cpp_type=8, label=1,
|
||||
has_default_value=True, default_value=1,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
@ -463,11 +488,11 @@ DESCRIPTOR.extensions_by_name['nanopb_enumopt'] = nanopb_enumopt
|
||||
DESCRIPTOR.extensions_by_name['nanopb'] = nanopb
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
NanoPBOptions = _reflection.GeneratedProtocolMessageType('NanoPBOptions', (_message.Message,), dict(
|
||||
DESCRIPTOR = _NANOPBOPTIONS,
|
||||
__module__ = 'nanopb_pb2'
|
||||
NanoPBOptions = _reflection.GeneratedProtocolMessageType('NanoPBOptions', (_message.Message,), {
|
||||
'DESCRIPTOR' : _NANOPBOPTIONS,
|
||||
'__module__' : 'nanopb_pb2'
|
||||
# @@protoc_insertion_point(class_scope:NanoPBOptions)
|
||||
))
|
||||
})
|
||||
_sym_db.RegisterMessage(NanoPBOptions)
|
||||
|
||||
nanopb_fileopt.message_type = _NANOPBOPTIONS
|
||||
|
@ -15,15 +15,15 @@ _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\"y\n\rFromSmartKnob\x12\x16\n\x03\x61\x63k\x18\x01 \x01(\x0b\x32\x07.PB.AckH\x00\x12\x16\n\x03log\x18\x02 \x01(\x0b\x32\x07.PB.LogH\x00\x12-\n\x0fsmartknob_state\x18\x03 \x01(\x0b\x32\x12.PB.SmartKnobStateH\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\"\x83\x01\n\x0bToSmartknob\x12\r\n\x05nonce\x18\x01 \x01(\r\x12)\n\rrequest_state\x18\x02 \x01(\x0b\x32\x10.PB.RequestStateH\x00\x12/\n\x10smartknob_config\x18\x03 \x01(\x0b\x32\x13.PB.SmartKnobConfigH\x00\x42\t\n\x07payload\"\x8f\x02\n\x0fSmartKnobConfig\x12\x10\n\x08position\x18\x01 \x01(\x05\x12\x14\n\x0cmin_position\x18\x02 \x01(\x05\x12\x14\n\x0cmax_position\x18\x03 \x01(\x05\x12\x1e\n\x16position_width_radians\x18\x04 \x01(\x02\x12\x1c\n\x14\x64\x65tent_strength_unit\x18\x05 \x01(\x02\x12\x1d\n\x15\x65ndstop_strength_unit\x18\x06 \x01(\x02\x12\x12\n\nsnap_point\x18\x07 \x01(\x02\x12\x13\n\x04text\x18\x08 \x01(\tB\x05\x92?\x02p2\x12\x1f\n\x10\x64\x65tent_positions\x18\t \x03(\x05\x42\x05\x92?\x02\x10\x05\x12\x17\n\x0fsnap_point_bias\x18\n \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\x0cRequestStateb\x06proto3')
|
||||
|
||||
|
||||
|
||||
_FROMSMARTKNOB = DESCRIPTOR.message_types_by_name['FromSmartKnob']
|
||||
_TOSMARTKNOB = DESCRIPTOR.message_types_by_name['ToSmartknob']
|
||||
_ACK = DESCRIPTOR.message_types_by_name['Ack']
|
||||
_LOG = DESCRIPTOR.message_types_by_name['Log']
|
||||
_SMARTKNOBSTATE = DESCRIPTOR.message_types_by_name['SmartKnobState']
|
||||
_TOSMARTKNOB = DESCRIPTOR.message_types_by_name['ToSmartknob']
|
||||
_SMARTKNOBCONFIG = DESCRIPTOR.message_types_by_name['SmartKnobConfig']
|
||||
_REQUESTSTATE = DESCRIPTOR.message_types_by_name['RequestState']
|
||||
FromSmartKnob = _reflection.GeneratedProtocolMessageType('FromSmartKnob', (_message.Message,), {
|
||||
@ -33,6 +33,13 @@ FromSmartKnob = _reflection.GeneratedProtocolMessageType('FromSmartKnob', (_mess
|
||||
})
|
||||
_sym_db.RegisterMessage(FromSmartKnob)
|
||||
|
||||
ToSmartknob = _reflection.GeneratedProtocolMessageType('ToSmartknob', (_message.Message,), {
|
||||
'DESCRIPTOR' : _TOSMARTKNOB,
|
||||
'__module__' : 'smartknob_pb2'
|
||||
# @@protoc_insertion_point(class_scope:PB.ToSmartknob)
|
||||
})
|
||||
_sym_db.RegisterMessage(ToSmartknob)
|
||||
|
||||
Ack = _reflection.GeneratedProtocolMessageType('Ack', (_message.Message,), {
|
||||
'DESCRIPTOR' : _ACK,
|
||||
'__module__' : 'smartknob_pb2'
|
||||
@ -54,13 +61,6 @@ SmartKnobState = _reflection.GeneratedProtocolMessageType('SmartKnobState', (_me
|
||||
})
|
||||
_sym_db.RegisterMessage(SmartKnobState)
|
||||
|
||||
ToSmartknob = _reflection.GeneratedProtocolMessageType('ToSmartknob', (_message.Message,), {
|
||||
'DESCRIPTOR' : _TOSMARTKNOB,
|
||||
'__module__' : 'smartknob_pb2'
|
||||
# @@protoc_insertion_point(class_scope:PB.ToSmartknob)
|
||||
})
|
||||
_sym_db.RegisterMessage(ToSmartknob)
|
||||
|
||||
SmartKnobConfig = _reflection.GeneratedProtocolMessageType('SmartKnobConfig', (_message.Message,), {
|
||||
'DESCRIPTOR' : _SMARTKNOBCONFIG,
|
||||
'__module__' : 'smartknob_pb2'
|
||||
@ -78,24 +78,30 @@ _sym_db.RegisterMessage(RequestState)
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
_FROMSMARTKNOB.fields_by_name['protocol_version']._options = None
|
||||
_FROMSMARTKNOB.fields_by_name['protocol_version']._serialized_options = b'\222?\0028\010'
|
||||
_TOSMARTKNOB.fields_by_name['protocol_version']._options = None
|
||||
_TOSMARTKNOB.fields_by_name['protocol_version']._serialized_options = b'\222?\0028\010'
|
||||
_LOG.fields_by_name['msg']._options = None
|
||||
_LOG.fields_by_name['msg']._serialized_options = b'\222?\003p\377\001'
|
||||
_SMARTKNOBCONFIG.fields_by_name['position_nonce']._options = None
|
||||
_SMARTKNOBCONFIG.fields_by_name['position_nonce']._serialized_options = b'\222?\0028\010'
|
||||
_SMARTKNOBCONFIG.fields_by_name['text']._options = None
|
||||
_SMARTKNOBCONFIG.fields_by_name['text']._serialized_options = b'\222?\002p2'
|
||||
_SMARTKNOBCONFIG.fields_by_name['detent_positions']._options = None
|
||||
_SMARTKNOBCONFIG.fields_by_name['detent_positions']._serialized_options = b'\222?\002\020\005'
|
||||
_FROMSMARTKNOB._serialized_start=37
|
||||
_FROMSMARTKNOB._serialized_end=158
|
||||
_ACK._serialized_start=160
|
||||
_ACK._serialized_end=180
|
||||
_LOG._serialized_start=182
|
||||
_LOG._serialized_end=208
|
||||
_SMARTKNOBSTATE._serialized_start=210
|
||||
_SMARTKNOBSTATE._serialized_end=316
|
||||
_TOSMARTKNOB._serialized_start=319
|
||||
_TOSMARTKNOB._serialized_end=450
|
||||
_SMARTKNOBCONFIG._serialized_start=453
|
||||
_SMARTKNOBCONFIG._serialized_end=724
|
||||
_REQUESTSTATE._serialized_start=726
|
||||
_REQUESTSTATE._serialized_end=740
|
||||
_FROMSMARTKNOB._serialized_start=38
|
||||
_FROMSMARTKNOB._serialized_end=192
|
||||
_TOSMARTKNOB._serialized_start=195
|
||||
_TOSMARTKNOB._serialized_end=359
|
||||
_ACK._serialized_start=361
|
||||
_ACK._serialized_end=381
|
||||
_LOG._serialized_start=383
|
||||
_LOG._serialized_end=409
|
||||
_SMARTKNOBSTATE._serialized_start=411
|
||||
_SMARTKNOBSTATE._serialized_end=517
|
||||
_SMARTKNOBCONFIG._serialized_start=520
|
||||
_SMARTKNOBCONFIG._serialized_end=849
|
||||
_REQUESTSTATE._serialized_start=851
|
||||
_REQUESTSTATE._serialized_end=865
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
Loading…
Reference in New Issue
Block a user