Skip to content

Commit

Permalink
replace getters/setters by attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
v923z committed Mar 5, 2024
1 parent 70e364a commit 81f564f
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 69 deletions.
138 changes: 75 additions & 63 deletions code/pid/pid.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2023 Zoltán Vörös
* Copyright (c) 2024 Zoltán Vörös
*/


Expand All @@ -29,35 +29,73 @@ static const mp_rom_map_elem_t ulab_pid_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_offset), MP_ROM_PTR(&pid_pid_offset_obj) },
{ MP_ROM_QSTR(MP_QSTR_evaluate), MP_ROM_PTR(&pid_pid_evaluate_obj) },
{ MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&pid_pid_reset_obj) },
// { MP_ROM_QSTR(MP_QSTR_buffer), MP_ROM_PTR(&pid_pid_buffer_obj) },
{ MP_ROM_QSTR(MP_QSTR_series), MP_ROM_PTR(&pid_pid_series_obj) },
{ MP_ROM_QSTR(MP_QSTR_parameters), MP_ROM_PTR(&pid_pid_parameters_obj) },
{ MP_ROM_QSTR(MP_QSTR_float_step), MP_ROM_PTR(&pid_pid_float_step_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_point), MP_ROM_PTR(&pid_pid_set_point_obj) },
{ MP_ROM_QSTR(MP_QSTR_step), MP_ROM_PTR(&pid_pid_step_obj) },
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&pid_pid_value_obj) },
};

static MP_DEFINE_CONST_DICT(ulab_pid_locals_dict, ulab_pid_locals_dict_table);

#if defined(MP_DEFINE_CONST_OBJ_TYPE)
static void pid_properties_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
if (dest[0] == MP_OBJ_NULL) {
switch(attr) {
case MP_QSTR_P:
dest[0] = pid_pid_parameters(self_in, MP_OBJ_NULL, PID_PARAMETER_P);
break;
case MP_QSTR_I:
dest[0] = pid_pid_parameters(self_in, MP_OBJ_NULL, PID_PARAMETER_I);
break;
case MP_QSTR_D:
dest[0] = pid_pid_parameters(self_in, MP_OBJ_NULL, PID_PARAMETER_D);
break;
case MP_QSTR_setpoint:
dest[0] = pid_pid_parameters(self_in, MP_OBJ_NULL, PID_SETPOINT);
break;
case MP_QSTR_value:
dest[0] = pid_pid_parameters(self_in, MP_OBJ_NULL, PID_VALUE);
break;
case MP_QSTR_input:
dest[0] = pid_pid_buffer(self_in, MP_OBJ_NULL);
break;
default:
// forward to locals dict
dest[1] = MP_OBJ_SENTINEL;
break;
}
} else {
if(dest[1]) {
switch(attr) {
case MP_QSTR_P:
pid_pid_parameters(self_in, dest[1], PID_PARAMETER_P);
break;
case MP_QSTR_I:
pid_pid_parameters(self_in, dest[1], PID_PARAMETER_I);
break;
case MP_QSTR_D:
pid_pid_parameters(self_in, dest[1], PID_PARAMETER_D);
break;
case MP_QSTR_setpoint:
pid_pid_parameters(self_in, dest[1], PID_SETPOINT);
break;
default:
return;
break;
}
dest[0] = MP_OBJ_NULL;
}
}
}


MP_DEFINE_CONST_OBJ_TYPE(
ulab_pid_type,
MP_QSTR_PID,
MP_TYPE_FLAG_NONE,
print, pid_pid_print,
make_new, pid_pid_make_new,
locals_dict, &ulab_pid_locals_dict
locals_dict, &ulab_pid_locals_dict,
attr, pid_properties_attr
);
#else
const mp_obj_type_t ulab_pid_type = {
{ &mp_type_type },
.name = MP_QSTR_PID,
.print = pid_pid_print,
.make_new = pid_pid_make_new,
.locals_dict = (mp_obj_dict_t*)&pid_locals_dict
};
#endif

void pid_pid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
(void)kind;
Expand All @@ -77,7 +115,7 @@ mp_obj_t pid_pid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
pid_obj_t *self = m_new_obj(pid_obj_t);
self->base.type = &ulab_pid_type;

self->set_point = MICROPY_FLOAT_CONST(0.0);
self->setpoint = MICROPY_FLOAT_CONST(0.0);

// initialise the converter object with default values, i.e, expand around 0, to first order in the Taylor series
pid_data_converter_t in, out;
Expand Down Expand Up @@ -188,48 +226,30 @@ mp_obj_t pid_pid_evaluate(mp_obj_t _self, mp_obj_t io, mp_obj_t x) {

MP_DEFINE_CONST_FUN_OBJ_3(pid_pid_evaluate_obj, pid_pid_evaluate);

mp_obj_t pid_pid_parameters(size_t n_args, const mp_obj_t *args) {
// set/get PID parameters
pid_obj_t *self = MP_OBJ_TO_PTR(args[0]);
GET_STR_DATA_LEN(args[1], which, length);

mp_float_t *param;

if(memcmp(which, "P", 1) == 0) {
param = &(self->P);
} else if(memcmp(which, "I", 1) == 0) {
param = &(self->I);
} else if(memcmp(which, "D", 1) == 0) {
param = &(self->D);
mp_obj_t pid_pid_parameters(mp_obj_t self_in, mp_obj_t value, uint8_t designator) {
pid_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_float_t *parameter;

if(designator == PID_PARAMETER_P) {
parameter = &(self->P);
} else if(designator == PID_PARAMETER_I) {
parameter = &(self->I);
} else if(designator == PID_PARAMETER_D) {
parameter = &(self->D);
} else if(designator == PID_SETPOINT) {
parameter = &(self->setpoint);
} else {
mp_raise_ValueError(MP_ERROR_TEXT("first argument must be 'P', 'I', or 'D'"));
parameter = &(self->value);
}

if(n_args == 2) { // this is a getter
return mp_obj_new_float(*param);
} else { // this is a setter
*param = mp_obj_get_float(args[2]);
}
return mp_const_none;
}

MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pid_pid_parameters_obj, 2, 3, pid_pid_parameters);


mp_obj_t pid_pid_set_point(size_t n_args, const mp_obj_t *args) {
// set/get PID parameters
pid_obj_t *self = MP_OBJ_TO_PTR(args[0]);
if(n_args == 1) { // this is a getter
return mp_obj_new_float(self->set_point);
} else { // this is a setter
self->set_point = mp_obj_get_float(args[1]);
if(value == MP_OBJ_NULL) {
return mp_obj_new_float(*parameter);
} else {
*parameter = mp_obj_get_float(value);
}
return mp_const_none;
}

MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pid_pid_set_point_obj, 1, 2, pid_pid_set_point);


mp_obj_t pid_pid_reset(mp_obj_t _self) {
// resets only the PID values but not the parameters
pid_obj_t *self = MP_OBJ_TO_PTR(_self);
Expand Down Expand Up @@ -313,7 +333,7 @@ void pid_pid_loop(pid_obj_t *self, mp_float_t value, mp_float_t t) {
mp_float_t dt = t - self->last_time;
self->last_time = t;

mp_float_t error = value - self->set_point;
mp_float_t error = value - self->setpoint;

mp_float_t diff = (error - self->error) / dt;
self->integral += error * dt;
Expand All @@ -325,8 +345,8 @@ void pid_pid_loop(pid_obj_t *self, mp_float_t value, mp_float_t t) {
}

mp_obj_t pid_pid_step(mp_obj_t _self) {
// The complete PID loop, converting the value from the buffer,
// and converting the results to the buffer
// The complete PID loop, converting the value from the input buffer,
// using the value in the PID loop, and then converting the results to the output buffer
pid_obj_t *self = MP_OBJ_TO_PTR(_self);

// convert value in input buffer
Expand Down Expand Up @@ -386,14 +406,6 @@ mp_obj_t pid_pid_float_step(size_t n_args, const mp_obj_t *args) {

MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pid_pid_float_step_obj, 2, 3, pid_pid_float_step);


mp_obj_t pid_pid_value(mp_obj_t _self) {
pid_obj_t *self = MP_OBJ_TO_PTR(_self);
return mp_obj_new_float(self->value);
}

MP_DEFINE_CONST_FUN_OBJ_1(pid_pid_value_obj, pid_pid_value);

static const mp_rom_map_elem_t ulab_pid_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_PID) },
{ MP_ROM_QSTR(MP_QSTR_PID), MP_ROM_PTR(&ulab_pid_type) },
Expand Down
18 changes: 12 additions & 6 deletions code/pid/pid.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,16 @@
#include "../ulab.h"

extern const mp_obj_module_t ulab_pid_module;

extern const mp_obj_type_t ulab_pid_type;

enum PID_PARAMETER {
PID_PARAMETER_P,
PID_PARAMETER_I,
PID_PARAMETER_D,
PID_SETPOINT,
PID_VALUE,
};

// structure holding the Taylor series representation of
// the conversion of physical values to unitless numbers
typedef struct _pid_series_t {
Expand All @@ -42,7 +49,7 @@ typedef struct _pid_data_converter_t {

typedef struct _pid_obj_t {
mp_obj_base_t base;
mp_float_t set_point; // set point of the controller loop
mp_float_t setpoint; // set point of the controller loop
pid_data_converter_t in; // data converter of the input buffer
pid_data_converter_t out; // data converter of the output buffer
mp_float_t P; // coefficient of the proportional term
Expand All @@ -53,22 +60,21 @@ typedef struct _pid_obj_t {
mp_float_t value; // the last converted value supplied to the loop
mp_float_t error; // the last calculated error; the difference between value and set_point
mp_float_t last_time; // the last time the loop was advanced
uint64_t steps;
uint64_t steps; // the step method has been called this many times
} pid_obj_t;

mp_obj_t pid_pid_make_new(const mp_obj_type_t *, size_t , size_t , const mp_obj_t *);
void pid_pid_print(const mp_print_t *, mp_obj_t , mp_print_kind_t );
mp_obj_t pid_pid_parameters(mp_obj_t , mp_obj_t , uint8_t );


MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(pid_pid_bitdepth_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(pid_pid_offset_obj);
MP_DECLARE_CONST_FUN_OBJ_3(pid_pid_buffer_obj);
MP_DECLARE_CONST_FUN_OBJ_3(pid_pid_evaluate_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(pid_pid_parameters_obj);
MP_DECLARE_CONST_FUN_OBJ_1(pid_pid_reset_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(pid_pid_series_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(pid_pid_set_point_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(pid_pid_float_step_obj);
MP_DECLARE_CONST_FUN_OBJ_1(pid_pid_step_obj);
MP_DECLARE_CONST_FUN_OBJ_1(pid_pid_value_obj);

#endif

0 comments on commit 81f564f

Please sign in to comment.