MP now supports assigning a new calibration to a servo

pull/259/head
ZodiusInfuser 2022-03-08 16:54:20 +00:00
rodzic d6811e1173
commit 59014f1e86
7 zmienionych plików z 134 dodań i 42 usunięć

Wyświetl plik

@ -19,6 +19,15 @@ namespace servo {
create_default_calibration(default_type);
}
Calibration::Calibration(const Calibration &other)
: calibration(nullptr), calibration_size(0), limit_lower(other.limit_lower), limit_upper(other.limit_upper) {
uint size = other.size();
create_blank_calibration(size);
for(uint i = 0; i < size; i++) {
calibration[i] = other.calibration[i];
}
}
Calibration::~Calibration() {
if(calibration != nullptr) {
delete[] calibration;
@ -26,6 +35,19 @@ namespace servo {
}
}
Calibration& Calibration::operator=(const Calibration &other) {
uint size = other.size();
create_blank_calibration(size);
for(uint i = 0; i < size; i++) {
calibration[i] = other.calibration[i];
}
limit_lower = other.limit_lower;
limit_upper = other.limit_upper;
return *this;
}
void Calibration::create_blank_calibration(uint size) {
if(calibration != nullptr) {
delete[] calibration;

Wyświetl plik

@ -51,9 +51,17 @@ namespace servo {
public:
Calibration();
Calibration(CalibrationType default_type);
Calibration(const Calibration &other);
virtual ~Calibration();
//--------------------------------------------------
// Operators
//--------------------------------------------------
public:
Calibration& operator=(const Calibration &other);
//--------------------------------------------------
// Methods
//--------------------------------------------------

Wyświetl plik

@ -201,14 +201,14 @@ namespace servo {
apply_pulse(servo, new_pulse, load);
}
Calibration* ServoCluster::calibration(uint servo) {
Calibration& ServoCluster::calibration(uint servo) {
assert(is_assigned(servo));
return &servos[servo].calibration();
return servos[servo].calibration();
}
const Calibration* ServoCluster::calibration(uint servo) const {
const Calibration& ServoCluster::calibration(uint servo) const {
assert(is_assigned(servo));
return &servos[servo].calibration();
return servos[servo].calibration();
}
void ServoCluster::apply_pulse(uint servo, float pulse, bool load) {

Wyświetl plik

@ -65,8 +65,8 @@ namespace servo {
void to_percent(uint servo, float in, float in_min = ServoState::ZERO_PERCENT, float in_max = ServoState::ONEHUNDRED_PERCENT, bool load = true);
void to_percent(uint servo, float in, float in_min, float in_max, float value_min, float value_max, bool load = true);
Calibration* calibration(uint servo);
const Calibration* calibration(uint servo) const;
Calibration& calibration(uint servo);
const Calibration& calibration(uint servo) const;
//--------------------------------------------------
private:

Wyświetl plik

@ -33,7 +33,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(Servo_to_min_obj, Servo_to_min);
MP_DEFINE_CONST_FUN_OBJ_1(Servo_to_mid_obj, Servo_to_mid);
MP_DEFINE_CONST_FUN_OBJ_1(Servo_to_max_obj, Servo_to_max);
MP_DEFINE_CONST_FUN_OBJ_KW(Servo_to_percent_obj, 2, Servo_to_percent);
MP_DEFINE_CONST_FUN_OBJ_1(Servo_calibration_obj, Servo_calibration);
MP_DEFINE_CONST_FUN_OBJ_KW(Servo_calibration_obj, 1, Servo_calibration);
MP_DEFINE_CONST_FUN_OBJ_1(ServoCluster___del___obj, ServoCluster___del__);
MP_DEFINE_CONST_FUN_OBJ_1(ServoCluster_count_obj, ServoCluster_count);

Wyświetl plik

@ -52,9 +52,9 @@ void Calibration_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_
if(size > 0) {
mp_print_str(print, "\n");
}
mp_print_str(print, "}, lower_limit = ");
mp_print_str(print, "}, limit_lower = ");
mp_obj_print_helper(print, calib->has_lower_limit() ? mp_const_true : mp_const_false, PRINT_REPR);
mp_print_str(print, ", upper_limit = ");
mp_print_str(print, ", limit_upper = ");
mp_obj_print_helper(print, calib->has_upper_limit() ? mp_const_true : mp_const_false, PRINT_REPR);
mp_print_str(print, ")");
}
@ -62,7 +62,6 @@ void Calibration_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_
/***** Constructor *****/
mp_obj_t Calibration_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
//NOTE Wonder if I can make it so calibration objects cannot be created in MP?
_Calibtration_obj_t *self = nullptr;
enum { ARG_type };
@ -839,18 +838,55 @@ extern mp_obj_t Servo_to_percent(size_t n_args, const mp_obj_t *pos_args, mp_map
return mp_const_none;
}
extern mp_obj_t Servo_calibration(mp_obj_t self_in) {
_Servo_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Servo_obj_t);
extern mp_obj_t Servo_calibration(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
if(n_args <= 1) {
enum { ARG_self };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
};
// NOTE This seems to work, in that it give MP access to the calibration object
// Could very easily mess up in weird ways once object deletion is considered
_Calibration_obj_t *calib = m_new_obj_with_finaliser(_Calibration_obj_t);
calib->base.type = &Calibration_type;
// Parse args.
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
_Servo_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, _Servo_obj_t);
// NOTE This seems to work, in that it give MP access to the calibration object
// Could very easily mess up in weird ways once object deletion is considered
_Calibration_obj_t *calib = m_new_obj_with_finaliser(_Calibration_obj_t);
calib->base.type = &Calibration_type;
calib->calibration = &self->servo->calibration();
calib->owner = false;
return MP_OBJ_FROM_PTR(calib);
}
else {
enum { ARG_self, ARG_calibration };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_calibration, MP_ARG_REQUIRED | MP_ARG_OBJ },
};
// Parse args.
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
_Servo_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, _Servo_obj_t);
const mp_obj_t object = args[ARG_calibration].u_obj;
if(mp_obj_is_type(object, &Calibration_type)) {
_Calibration_obj_t *calib = MP_OBJ_TO_PTR2(object, _Calibration_obj_t);
self->servo->calibration() = *(calib->calibration);
}
else {
mp_raise_TypeError("cannot convert object to a Calibration class instance");
}
}
return mp_const_none;
calib->calibration = &self->servo->calibration();
calib->owner = false;
return MP_OBJ_FROM_PTR(calib);
}
@ -1553,34 +1589,60 @@ extern mp_obj_t ServoCluster_to_percent(size_t n_args, const mp_obj_t *pos_args,
}
extern mp_obj_t ServoCluster_calibration(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_servo };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_servo, MP_ARG_REQUIRED | MP_ARG_INT },
};
if(n_args <= 2) {
enum { ARG_self, ARG_servo };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_servo, MP_ARG_REQUIRED | MP_ARG_INT },
};
// Parse args.
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
// Parse args.
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
_ServoCluster_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, _ServoCluster_obj_t);
_ServoCluster_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, _ServoCluster_obj_t);
int servo = args[ARG_servo].u_int;
int servo_count = (int)self->cluster->get_count();
if(servo_count == 0)
mp_raise_ValueError("this cluster does not have any servos");
else if(servo < 0 || servo >= servo_count)
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("servo out of range. Expected 0 to %d"), servo_count);
int servo = args[ARG_servo].u_int;
int servo_count = (int)self->cluster->get_count();
if(servo_count == 0)
mp_raise_ValueError("this cluster does not have any servos");
else if(servo < 0 || servo >= servo_count)
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("servo out of range. Expected 0 to %d"), servo_count);
else {
// NOTE This seems to work, in that it give MP access to the calibration object
// Could very easily mess up in weird ways once object deletion is considered
_Calibration_obj_t *calib = m_new_obj_with_finaliser(_Calibration_obj_t);
calib->base.type = &Calibration_type;
calib->calibration = &self->cluster->calibration((uint)servo);
calib->owner = false;
return MP_OBJ_FROM_PTR(calib);
}
}
else {
// NOTE This seems to work, in that it give MP access to the calibration object
// Could very easily mess up in weird ways once object deletion is considered
_Calibration_obj_t *calib = m_new_obj_with_finaliser(_Calibration_obj_t);
calib->base.type = &Calibration_type;
enum { ARG_self, ARG_servo, ARG_calibration };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_servo, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_calibration, MP_ARG_REQUIRED | MP_ARG_OBJ },
};
calib->calibration = self->cluster->calibration((uint)servo);
calib->owner = false;
// Parse args.
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
return MP_OBJ_FROM_PTR(calib);
_ServoCluster_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, _ServoCluster_obj_t);
int servo = args[ARG_servo].u_int;
const mp_obj_t object = args[ARG_calibration].u_obj;
if(mp_obj_is_type(object, &Calibration_type)) {
_Calibration_obj_t *calib = MP_OBJ_TO_PTR2(object, _Calibration_obj_t);
self->cluster->calibration((uint)servo) = *(calib->calibration);
}
else {
mp_raise_TypeError("cannot convert object to a Calibration class instance");
}
}
return mp_const_none;

Wyświetl plik

@ -42,7 +42,7 @@ extern mp_obj_t Servo_to_min(mp_obj_t self_in);
extern mp_obj_t Servo_to_mid(mp_obj_t self_in);
extern mp_obj_t Servo_to_max(mp_obj_t self_in);
extern mp_obj_t Servo_to_percent(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t Servo_calibration(mp_obj_t self_in);
extern mp_obj_t Servo_calibration(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern void ServoCluster_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind);
extern mp_obj_t ServoCluster_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);