Skip to content

Commit

Permalink
fixed min/max pwm vals
Browse files Browse the repository at this point in the history
  • Loading branch information
AsiiaPine committed Apr 25, 2024
1 parent 488ba05 commit 858fef8
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 58 deletions.
1 change: 1 addition & 0 deletions Src/dronecan_application/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ set(applicationSourceCode
${ROOT_DIR}/Src/dronecan_application/modules/CircuitStatusModule.cpp
${ROOT_DIR}/Src/dronecan_application/modules/PWMModule.cpp
${ROOT_DIR}/Src/dronecan_application/logger.cpp
${ROOT_DIR}/Src/dronecan_application/algorithms.cpp

)
set(applicationHeaders
Expand Down
74 changes: 74 additions & 0 deletions Src/dronecan_application/algorithms.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (C) 2022-2023 Dmitry Ponomarev <[email protected]>
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

#include "algorithms.hpp"


static const RawCommand RAW_COMMAND_MIN = 0;
static const RawCommand RAW_COMMAND_MAX = 8191;


static const ActuatorCommandValue ACT_COMMAND_MIN = -1.0f;
static const ActuatorCommandValue ACT_COMMAND_MAX = 1.0f;

PwmDurationUs mapRawCommandToPwm(RawCommand command,
PwmDurationUs min_pwm,
PwmDurationUs max_pwm,
PwmDurationUs def_pwm) {
PwmDurationUs pwm;
if (command < RAW_COMMAND_MIN || command > RAW_COMMAND_MAX) {
pwm = def_pwm;
} else {
pwm = (PwmDurationUs)mapFloat(command, RAW_COMMAND_MIN, RAW_COMMAND_MAX, min_pwm, max_pwm);
}
return pwm;
}


PwmDurationUs mapActuatorCommandToPwm(ActuatorCommandValue command,
PwmDurationUs min_pwm,
PwmDurationUs max_pwm,
PwmDurationUs def_pwm) {
PwmDurationUs pwm;
if (command < ACT_COMMAND_MIN || command > ACT_COMMAND_MAX) {
pwm = def_pwm;
} else {
pwm = (PwmDurationUs)mapFloat(command, ACT_COMMAND_MIN, ACT_COMMAND_MAX, min_pwm, max_pwm);
}
return pwm;
}

float mapPwmToPct(uint16_t pwm_val, int16_t pwm_min, int16_t pwm_max) {
auto max = pwm_max;
auto min = pwm_min;
if (pwm_min > pwm_max) {
max = pwm_min;
min = pwm_max;
}
auto scaled_val = (pwm_val - min) * 100.0f / (max - min);
auto val = std::clamp(scaled_val, 0.f, 100.f);
return val;
}

float mapFloat(float value, float in_min, float in_max, float out_min, float out_max) {
float output;
if (value <= in_min && in_min <= in_max) {
output = out_min;
} else if (value >= in_max && in_min <= in_max) {
output = out_max;
} else if (out_min == out_max) {
output = out_min;
} else {
output = out_min + (value - in_min) / (in_max - in_min) * (out_max - out_min);
if (out_min <= out_max) {
output = std::clamp(output, out_min, out_max);
} else {
output = std::clamp(output, out_max, out_min);
}
}
return output;
}
59 changes: 59 additions & 0 deletions Src/dronecan_application/algorithms.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (C) 2022-2023 Dmitry Ponomarev <[email protected]>
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

#ifndef DEVICES_SERVOS_COMMON_H_
#define DEVICES_SERVOS_COMMON_H_

#include <stdbool.h>
#include <stdint.h>

#include <algorithm>

#ifdef __cplusplus
extern "C" {
#endif

typedef uint16_t PwmDurationUs;
typedef int16_t RawCommand;
typedef float ActuatorCommandValue;

/**
* @brief Map raw command value (in interval from 0 to 8191)
* to PWM duration in us (in interval from min to max)
* @return pwm_duration if input is correct,
* def_pwm if raw_command value is less than min or higher than max
*/

PwmDurationUs mapRawCommandToPwm(RawCommand rc_value, PwmDurationUs min_pwm,
PwmDurationUs max_pwm, PwmDurationUs def_pwm);

/**
* @brief Map array command value (in interval from -1.0 to 1.0)
* to PWM duration in us (in interval from min to max)
* @return pwm_duration if input is correct,
* def_pwm if raw_command value is less than min or higher than max
*/

PwmDurationUs mapActuatorCommandToPwm(ActuatorCommandValue ac_value,
PwmDurationUs min_pwm, PwmDurationUs max_pwm,
PwmDurationUs def_pwm);

/**
* @brief Map PWM duration in us (in interval from min to max) to pct
* @return pwm_duration in pct
*/

float mapPwmToPct(uint16_t pwm_val, int16_t pwm_min, int16_t pwm_max);

float mapFloat(float value, float in_min, float in_max, float out_min,
float out_max);

#ifdef __cplusplus
}
#endif

#endif // DEVICES_SERVOS_COMMON_H_
71 changes: 32 additions & 39 deletions Src/dronecan_application/modules/PWMModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ ModuleStatus PWMModule::module_status = ModuleStatus::MODULE_OK;

PWMModule PWMModule::instance = PWMModule();

float PWMModule::cmnd_min = 0;
float PWMModule::cmnd_max = 0;

PWMModule::PWMModule() {
update_params();
init();
Expand Down Expand Up @@ -76,7 +73,8 @@ void PWMModule::spin_once() {
status_pub_timeout_ms = 1;
static uint32_t next_pub_ms = status_pub_timeout_ms;

if (module_status == ModuleStatus::MODULE_OK && crnt_time_ms > next_pub_ms) {
if (module_status == ModuleStatus::MODULE_OK &&
crnt_time_ms > next_pub_ms) {
publish_state();
next_pub_ms = crnt_time_ms + status_pub_timeout_ms;
}
Expand Down Expand Up @@ -119,12 +117,12 @@ void PWMModule::update_params() {
auto min = paramsGetIntegerValue(params_names[i].min);
auto max = paramsGetIntegerValue(params_names[i].max);
auto def = paramsGetIntegerValue(params_names[i].def);
if (min <= max && def >= min && def <= max) {
params[i].min = min;
params[i].max = max;
params[i].def = def;
} else {
params[i].def = def;
if (min == max) {
params_error = true;
} else {
params[i].min = max;
params[i].max = min;
}
}

Expand All @@ -151,8 +149,6 @@ void PWMModule::apply_params() {
data_type_signature = UAVCAN_EQUIPMENT_ESC_RAWCOMMAND_SIGNATURE;
data_type_id = UAVCAN_EQUIPMENT_ESC_RAWCOMMAND_ID;
publish_state = publish_esc_status;
cmnd_min = 0.0f;
cmnd_max = 8191.0f;
break;

case 1:
Expand All @@ -161,9 +157,7 @@ void PWMModule::apply_params() {
UAVCAN_EQUIPMENT_ACTUATOR_ARRAY_COMMAND_SIGNATURE;
data_type_id = UAVCAN_EQUIPMENT_ACTUATOR_ARRAY_COMMAND_ID;
publish_state = publish_esc_status;
cmnd_min = -1.0f;
cmnd_max = 1.0f;
// publish_state = publish_actuator_status;
publish_state = publish_actuator_status;
break;

default:
Expand All @@ -179,15 +173,18 @@ void PWMModule::publish_esc_status() {
static uint8_t transfer_id = 0;
EscStatus_t msg{};
auto crnt_time_ms = HAL_GetTick();
static uint32_t next_status_pub_ms[static_cast<uint8_t>(PwmPin::PWM_AMOUNT)];
static uint32_t
next_status_pub_ms[static_cast<uint8_t>(PwmPin::PWM_AMOUNT)];
for (int i = 0; i < static_cast<uint8_t>(PwmPin::PWM_AMOUNT); i++) {
auto pwm = params[i];
if (pwm.channel < 0 || pwm.fb == 0 || next_status_pub_ms[i] > crnt_time_ms) {
if (pwm.channel < 0 || pwm.fb == 0 ||
next_status_pub_ms[i] > crnt_time_ms) {
continue;
}
msg = {};
float scaled_value = get_pwm_scaled_value(pwm.pin, -pwm.min, 100.0f / (pwm.max - pwm.min));
msg.esc_index = pwm.channel;
auto pwm_val = PwmPeriphery::get_duration(pwm.pin);
auto scaled_value = mapPwmToPct(pwm_val, pwm.min, pwm.max);
msg.power_rating_pct = (uint8_t)(scaled_value);
if (dronecan_equipment_esc_status_publish(&msg, &transfer_id) == 0) {
transfer_id++;
Expand All @@ -196,34 +193,30 @@ void PWMModule::publish_esc_status() {
}
}

float PWMModule::get_pwm_scaled_value(PwmPin pin, int16_t offset, float scale) {
float pwm_val = (float)(PwmPeriphery::get_duration(pin));
float scaled_val = (pwm_val + offset) * scale;
auto val = std::clamp(scaled_val, 0.f, 100.f);
return val;
}

// void PWMModule::publish_actuator_status() {
// static uint8_t transfer_id = 0;
// ActuatorStatus_t msg {};

// for (int i =0; i < static_cast<uint8_t>(PwmPin::PWM_AMOUNT); i++) {
// auto pwm = params[i];
// if (pwm.channel < 0) continue;
// auto value = PwmPeriphery::get_duration(pwm.pin);
// float scaled_value = (value - pwm.min) * 100.0f / (pwm.max -
// pwm.min); msg.actuator_id = pwm.channel; msg.power_rating_pct =
// (uint8_t) scaled_value; if
// (dronecan_equipment_actuator_status_publish(
// &msg, &transfer_id) == 0)
// transfer_id++;
// if (pwm.channel < 0) {
// continue;
// }
// msg.actuator_id = pwm.channel;
// auto pwm_val = PwmPeriphery::get_duration(pwm.pin);
// auto scaled_value = mapPwmToPct(pwm_val, pwm.min, pwm.max);
// msg.power_rating_pct = (uint8_t) scaled_value;
// if (dronecan_equipment_actuator_status_publish(&msg, &transfer_id) == 0) {
// transfer_id++;
// }
// }
// }

void PWMModule::raw_command_callback(CanardRxTransfer* transfer) {
if (module_status != ModuleStatus::MODULE_OK) return;
RawCommand_t command;
int8_t ch_num = dronecan_equipment_esc_raw_command_deserialize(transfer, &command);
int8_t ch_num =
dronecan_equipment_esc_raw_command_deserialize(transfer, &command);
if (ch_num <= 0) {
return;
}
Expand All @@ -234,9 +227,8 @@ void PWMModule::raw_command_callback(CanardRxTransfer* transfer) {
}
if (command.raw_cmd[pwm->channel] >= 0) {
pwm->cmd_end_time_ms = HAL_GetTick() + ttl_cmd;
pwm->command_val = pwm->min + (uint16_t)((pwm->max - pwm->min) *
command.raw_cmd[pwm->channel] /
8191.0f);
pwm->command_val = mapRawCommandToPwm(command.raw_cmd[pwm->channel],
pwm->min, pwm->max, pwm->def);
} else {
pwm->command_val = pwm->def;
}
Expand All @@ -246,7 +238,8 @@ void PWMModule::raw_command_callback(CanardRxTransfer* transfer) {
void PWMModule::array_command_callback(CanardRxTransfer* transfer) {
if (module_status != ModuleStatus::MODULE_OK) return;
ArrayCommand_t command;
int8_t ch_num = dronecan_equipment_actuator_arraycommand_deserialize(transfer, &command);
int8_t ch_num = dronecan_equipment_actuator_arraycommand_deserialize(
transfer, &command);
if (ch_num <= 0) {
return;
}
Expand All @@ -255,13 +248,13 @@ void PWMModule::array_command_callback(CanardRxTransfer* transfer) {
if (pwm->channel < 0) {
continue;
}
auto mean = pwm->min + pwm->max/2;
for (uint8_t j = 0; j < ch_num; j++) {
if (command.commads[j].actuator_id != pwm->channel) {
continue;
}
pwm->cmd_end_time_ms = HAL_GetTick() + ttl_cmd;
pwm->command_val = mean + command.commads[j].command_value * (pwm->max - pwm->min) / 2;
pwm->command_val = mapActuatorCommandToPwm(command.commads[j].command_value,
pwm->min, pwm->max, pwm->def);
}
}
}
6 changes: 1 addition & 5 deletions Src/dronecan_application/modules/PWMModule.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define SRC_MODULE_PWMMODULE_HPP_

#include <algorithm>
#include "../algorithms.hpp"
#include "dronecan.h"
#include "params.hpp"

Expand Down Expand Up @@ -61,8 +62,6 @@ class PWMModule {
void update_pwm();
void apply_params();

static float get_pwm_scaled_value(PwmPin pin, int16_t offset, float scale);

static void raw_command_callback(CanardRxTransfer* transfer);
static void array_command_callback(CanardRxTransfer* transfer);

Expand All @@ -74,9 +73,6 @@ class PWMModule {
static uint16_t pwm_freq;
static uint8_t pwm_cmd_type;

static float cmnd_min;
static float cmnd_max;

static uint16_t ttl_cmd;
uint16_t status_pub_timeout_ms;
bool verbose;
Expand Down
Loading

0 comments on commit 858fef8

Please sign in to comment.