Implement WebAssembly runtime and kinematics coverage
This commit is contained in:
@@ -21,8 +21,11 @@ typedef struct {
|
||||
uint32_t thread;
|
||||
uint32_t calls;
|
||||
uint32_t fail;
|
||||
uint32_t transform_kind;
|
||||
} function_entry;
|
||||
|
||||
enum { SIM_HAL_TRANSFORM_NONE = 0, SIM_HAL_TRANSFORM_COREXY = 1 };
|
||||
|
||||
typedef struct {
|
||||
uint32_t tick;
|
||||
pin_entry pins[SIM_HAL_PIN_CAPACITY];
|
||||
@@ -136,6 +139,73 @@ int32_t sim_hal_register_function(const char *thread, const char *name) {
|
||||
return SIM_HAL_ERR_FULL;
|
||||
}
|
||||
|
||||
static int32_t corexy_pin_names(const char *component, char names[8][SIM_HAL_NAME_CAPACITY]) {
|
||||
static const char *suffixes[8] = {
|
||||
".j0-motor-pos-cmd", ".j1-motor-pos-cmd", ".alpha-cmd", ".beta-cmd",
|
||||
".alpha-fb", ".beta-fb", ".j0-motor-pos-fb", ".j1-motor-pos-fb",
|
||||
};
|
||||
uint32_t index;
|
||||
if (!valid_name(component)) return SIM_HAL_ERR_ARGUMENT;
|
||||
for (index = 0; index < 8; ++index) {
|
||||
size_t prefix = strlen(component);
|
||||
size_t suffix = strlen(suffixes[index]);
|
||||
if (prefix + suffix >= SIM_HAL_NAME_CAPACITY) return SIM_HAL_ERR_RANGE;
|
||||
memcpy(names[index], component, prefix);
|
||||
memcpy(names[index] + prefix, suffixes[index], suffix + 1);
|
||||
}
|
||||
return SIM_HAL_OK;
|
||||
}
|
||||
|
||||
int32_t sim_hal_register_corexy_by_hal(const char *component, const char *thread) {
|
||||
char names[8][SIM_HAL_NAME_CAPACITY];
|
||||
uint32_t index;
|
||||
int32_t result;
|
||||
if (component == NULL || thread == NULL) return SIM_HAL_ERR_ARGUMENT;
|
||||
result = corexy_pin_names(component, names);
|
||||
if (result != SIM_HAL_OK) return result;
|
||||
for (index = 0; index < 8; ++index) {
|
||||
if (find_pin(names[index]) >= 0) return SIM_HAL_ERR_DUPLICATE;
|
||||
}
|
||||
if (find_function(component) >= 0) return SIM_HAL_ERR_DUPLICATE;
|
||||
for (index = 0; index < 8; ++index) {
|
||||
result = sim_hal_register_pin(names[index], SIM_HAL_FLOAT);
|
||||
if (result != SIM_HAL_OK) return result;
|
||||
}
|
||||
result = sim_hal_register_function(thread, component);
|
||||
if (result != SIM_HAL_OK) return result;
|
||||
state.functions[find_function(component)].transform_kind = SIM_HAL_TRANSFORM_COREXY;
|
||||
return SIM_HAL_OK;
|
||||
}
|
||||
|
||||
static int32_t float_pin(const char *name, float *value) {
|
||||
sim_hal_value pin = {0};
|
||||
int32_t result = sim_hal_get_pin(name, &pin);
|
||||
if (result != SIM_HAL_OK) return result;
|
||||
if (pin.type != SIM_HAL_FLOAT) return SIM_HAL_ERR_TYPE;
|
||||
*value = pin.value.real;
|
||||
return SIM_HAL_OK;
|
||||
}
|
||||
|
||||
static int32_t set_float_pin(const char *name, float value) {
|
||||
sim_hal_value pin = {SIM_HAL_FLOAT, {.real = value}};
|
||||
return sim_hal_set_pin(name, pin);
|
||||
}
|
||||
|
||||
int32_t sim_hal_corexy_transform(const char *component) {
|
||||
char names[8][SIM_HAL_NAME_CAPACITY];
|
||||
float j0_cmd, j1_cmd, alpha_fb, beta_fb;
|
||||
int32_t result = corexy_pin_names(component, names);
|
||||
if (result != SIM_HAL_OK) return result;
|
||||
result = float_pin(names[0], &j0_cmd); if (result != SIM_HAL_OK) return result;
|
||||
result = float_pin(names[1], &j1_cmd); if (result != SIM_HAL_OK) return result;
|
||||
result = float_pin(names[4], &alpha_fb); if (result != SIM_HAL_OK) return result;
|
||||
result = float_pin(names[5], &beta_fb); if (result != SIM_HAL_OK) return result;
|
||||
result = set_float_pin(names[2], 0.5f * (j0_cmd + j1_cmd)); if (result != SIM_HAL_OK) return result;
|
||||
result = set_float_pin(names[3], 0.5f * (j0_cmd - j1_cmd)); if (result != SIM_HAL_OK) return result;
|
||||
result = set_float_pin(names[6], alpha_fb + beta_fb); if (result != SIM_HAL_OK) return result;
|
||||
return set_float_pin(names[7], alpha_fb - beta_fb);
|
||||
}
|
||||
|
||||
int32_t sim_hal_set_function_failure(const char *name, uint32_t fail) {
|
||||
int index = find_function(name);
|
||||
if (index < 0) return SIM_HAL_ERR_NOT_FOUND;
|
||||
@@ -152,6 +222,10 @@ int32_t sim_hal_step(uint32_t ticks) {
|
||||
function_entry *function = &state.functions[function_index];
|
||||
if (!function->used || tick % state.threads[function->thread].period != 0U) continue;
|
||||
if (function->fail) return SIM_HAL_ERR_FUNCTION;
|
||||
if (function->transform_kind == SIM_HAL_TRANSFORM_COREXY) {
|
||||
int32_t result = sim_hal_corexy_transform(function->name);
|
||||
if (result != SIM_HAL_OK) return SIM_HAL_ERR_FUNCTION;
|
||||
}
|
||||
function->calls += 1U;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user