Skip to content

Commit 012a26e

Browse files
committed
pybricks.pupdevices.TechnicMoveHub: Simplify interface.
Since we won't be striving to make this match the car block, we don't need to separate the commands. We can just make it match the BLE command. This makes the code simpler and performance is slightly better.
1 parent bf72e5c commit 012a26e

1 file changed

Lines changed: 39 additions & 84 deletions

File tree

pybricks/iodevices/pb_type_iodevices_lwp3device.c

Lines changed: 39 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -629,53 +629,6 @@ static void pb_type_technic_move_hub_handle_notification(void *user, const uint8
629629
// Not processing any notifications. We could monitor the hub's internal sensors.
630630
}
631631

632-
/**
633-
* Stored format for the common data field in the lwp3 object.
634-
*/
635-
typedef struct {
636-
uint8_t speed_now;
637-
uint8_t steering_now;
638-
uint8_t speed_last;
639-
uint8_t steering_last;
640-
} pb_type_lwp3device_technic_movehub_data_t;
641-
642-
static pbio_error_t pb_type_technic_move_hub_write_command(mp_obj_t self_in) {
643-
pb_type_lwp3device_obj_t *self = MP_OBJ_TO_PTR(self_in);
644-
645-
// Don't repeat again if already sent idential values this many
646-
// times in this interval.
647-
const uint8_t max_repeat = 2;
648-
const uint32_t max_repeat_timeout = 500;
649-
650-
pb_type_lwp3device_technic_movehub_data_t *data = (void *)self->data;
651-
652-
// Reusing the remote button buffer to store drive state.
653-
bool identical = data->speed_last == data->speed_now && data->steering_last == data->steering_now;
654-
655-
// Count identical messages sent in short time span, using center for counter.
656-
if (!identical || pbio_os_timer_is_expired(&self->timer)) {
657-
self->data[4] = 0;
658-
}
659-
660-
// If we sent the same thing several times within timeout, it probably arrived.
661-
if (self->data[4] == max_repeat) {
662-
return PBIO_SUCCESS;
663-
}
664-
665-
// Send command and keep track of the time.
666-
uint8_t light_mode = 0;
667-
data->speed_last = data->speed_now;
668-
data->steering_last = data->steering_now;
669-
670-
self->data[4] = pbio_int_math_min(self->data[4] + 1, max_repeat);
671-
pbio_os_timer_set(&self->timer, max_repeat_timeout);
672-
673-
const uint8_t cmd[] = {
674-
0x0d, 0x00, 0x81, 0x36, 0x11, 0x51, 0x00, 0x03, 0x00, data->speed_now, data->steering_now, light_mode, 0,
675-
};
676-
return pbdrv_bluetooth_peripheral_write_characteristic(self->peripheral, self->lwp3_char_handle, cmd, sizeof(cmd));
677-
}
678-
679632
static pbio_error_t pb_type_technic_move_hub_post_connect(pbio_os_state_t *state, mp_obj_t parent_obj) {
680633

681634
pbio_os_state_t unused;
@@ -708,46 +661,53 @@ static pbio_error_t pb_type_technic_move_hub_post_connect(pbio_os_state_t *state
708661
return err;
709662
}
710663

711-
// Initialize at 0 speed and 0 steering.
712-
err = pb_type_technic_move_hub_write_command(parent_obj);
713-
if (err != PBIO_SUCCESS) {
714-
return err;
715-
}
716-
PBIO_OS_AWAIT(state, &unused, err = pbdrv_bluetooth_await_peripheral_command(&unused, self->peripheral));
717-
if (err != PBIO_SUCCESS) {
718-
return err;
719-
}
720-
721664
PBIO_OS_ASYNC_END(PBIO_SUCCESS);
722665
}
723666

724-
static mp_obj_t pb_type_technic_move_hub_drive_power(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
667+
static mp_obj_t pb_type_technic_move_hub_drive(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
725668
PB_PARSE_ARGS_METHOD(n_args, pos_args, kw_args,
726669
pb_type_lwp3device_obj_t, self,
727-
PB_ARG_REQUIRED(power));
728-
729-
mp_obj_t self_in = MP_OBJ_FROM_PTR(self);
730-
pb_type_lwp3device_technic_movehub_data_t *data = (void *)self->data;
731-
data->speed_now = pbio_int_math_clamp(pb_obj_get_int(power_in), 100);
732-
pb_assert(pb_type_technic_move_hub_write_command(self_in));
733-
return wait_or_await_operation(self_in);
734-
}
735-
static MP_DEFINE_CONST_FUN_OBJ_KW(pb_type_technic_move_hub_drive_power_obj, 1, pb_type_technic_move_hub_drive_power);
736-
737-
static mp_obj_t pb_type_technic_move_hub_steer(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
738-
PB_PARSE_ARGS_METHOD(n_args, pos_args, kw_args,
739-
pb_type_lwp3device_obj_t, self,
740-
PB_ARG_REQUIRED(percentage));
741-
mp_obj_t self_in = MP_OBJ_FROM_PTR(self);
670+
PB_ARG_REQUIRED(speed),
671+
PB_ARG_REQUIRED(steering)
672+
);
742673

743674
// Steering is a percentage of the calibrated angle. Go just under maximum
744675
// to avoid pushing against the mechanical constraint.
745-
pb_type_lwp3device_technic_movehub_data_t *data = (void *)self->data;
746-
data->steering_now = pbio_int_math_clamp(pb_obj_get_int(percentage_in), 97);
747-
pb_assert(pb_type_technic_move_hub_write_command(self_in));
748-
return wait_or_await_operation(self_in);
676+
uint8_t steering_byte = pbio_int_math_clamp(pb_obj_get_int(steering_in), 97);
677+
uint8_t speed_byte = pbio_int_math_clamp(pb_obj_get_int(speed_in), 100);
678+
679+
// Don't repeat again if already sent idential values this many
680+
// times in this interval.
681+
const uint8_t max_repeat = 2;
682+
const uint32_t max_repeat_timeout = 500;
683+
684+
// Reusing the remote button buffer to store drive state.
685+
bool identical = speed_byte == self->data[0] && steering_byte == self->data[1];
686+
687+
// Count identical messages sent in short time span, using center for counter.
688+
if (!identical || pbio_os_timer_is_expired(&self->timer)) {
689+
self->data[2] = 0;
690+
}
691+
692+
// If we sent the same thing several times within timeout, it probably arrived.
693+
if (self->data[2] == max_repeat) {
694+
return wait_or_await_operation(MP_OBJ_FROM_PTR(self));
695+
}
696+
697+
// Send command and keep track of the time.
698+
self->data[0] = speed_byte;
699+
self->data[1] = steering_byte;
700+
self->data[2] = pbio_int_math_min(self->data[2] + 1, max_repeat);
701+
pbio_os_timer_set(&self->timer, max_repeat_timeout);
702+
uint8_t light_mode = 0;
703+
704+
const uint8_t cmd[] = {
705+
0x0d, 0x00, 0x81, 0x36, 0x11, 0x51, 0x00, 0x03, 0x00, speed_byte, steering_byte, light_mode, 0,
706+
};
707+
pb_assert(pbdrv_bluetooth_peripheral_write_characteristic(self->peripheral, self->lwp3_char_handle, cmd, sizeof(cmd)));
708+
return wait_or_await_operation(MP_OBJ_FROM_PTR(self));
749709
}
750-
static MP_DEFINE_CONST_FUN_OBJ_KW(pb_type_technic_move_hub_steer_obj, 1, pb_type_technic_move_hub_steer);
710+
static MP_DEFINE_CONST_FUN_OBJ_KW(pb_type_technic_move_hub_drive_obj, 1, pb_type_technic_move_hub_drive);
751711

752712
static mp_obj_t pb_type_technic_move_hub_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
753713
PB_PARSE_ARGS_CLASS(n_args, n_kw, args,
@@ -757,22 +717,18 @@ static mp_obj_t pb_type_technic_move_hub_make_new(const mp_obj_type_t *type, siz
757717
);
758718

759719
pb_module_tools_assert_blocking();
760-
761720
pb_type_lwp3device_obj_t *self = mp_obj_malloc_with_finaliser(pb_type_lwp3device_obj_t, type);
762721
self->iter = NULL;
763722
self->noti_num = 0;
764-
765723
self->hub_kind = LWP3_HUB_KIND_TECHNIC_MOVE;
766724
self->post_connect_setup_func = pb_type_technic_move_hub_post_connect;
767-
768725
self->scan_config = (pbdrv_bluetooth_peripheral_connect_config_t) {
769726
.match_adv = pb_type_lwp3device_advertisement_matches,
770727
.match_adv_rsp = pb_type_lwp3device_advertisement_response_matches,
771728
.notification_handler = pb_type_technic_move_hub_handle_notification,
772729
.options = PBDRV_BLUETOOTH_PERIPHERAL_OPTIONS_PAIR,
773730
};
774731
pb_type_lwp3device_set_name_filter_and_timeout(self, name_in, timeout_in);
775-
776732
pb_type_lwp3device_intialize_connection(MP_OBJ_FROM_PTR(self), connect_in);
777733
return MP_OBJ_FROM_PTR(self);
778734
}
@@ -781,8 +737,7 @@ static const mp_rom_map_elem_t pb_type_technic_move_hub_locals_dict_table[] = {
781737
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&pb_type_lwp3device_close_obj) },
782738
{ MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&pb_type_lwp3device_connect_obj) },
783739
{ MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&pb_type_lwp3device_disconnect_obj) },
784-
{ MP_ROM_QSTR(MP_QSTR_drive_power), MP_ROM_PTR(&pb_type_technic_move_hub_drive_power_obj) },
785-
{ MP_ROM_QSTR(MP_QSTR_steer), MP_ROM_PTR(&pb_type_technic_move_hub_steer_obj) },
740+
{ MP_ROM_QSTR(MP_QSTR_drive), MP_ROM_PTR(&pb_type_technic_move_hub_drive_obj) },
786741
};
787742
static MP_DEFINE_CONST_DICT(pb_type_technic_move_hub_locals_dict, pb_type_technic_move_hub_locals_dict_table);
788743

0 commit comments

Comments
 (0)