armchair_fw/main/control.hpp
jonny_l480 73325e08ce Fix bug in scaling, Fix http cmd gen, Fix overflow
Fix several bugs noticed while testing the preceding commits in dev
branch:

- Fix bug in function scaleCoordinate
  - scaling was wrong resulting in negative/inverted values at start of axis

- Adjust timeout value from 30s to 5min

- Fix http joystick behaivor
  - calculate angle, radius and evaluate position AFTER the coordinates
    have been scaled in control.cpp (bug introduced when switching applying tolerance
    on controller instead of in the app)

- Add independent toleranceZero for X and Y axis -> unnecessary to have
  large tolerance for x axis... makes turning more sensitive

- Fix stack overflow in control task
  - controller crashed repeatedly when logging output was enabled in
    control task
  - -> doubled stack size at task creation in main.cpp

currently works, position hast to be evaluated AFTER coordinate scaling
2022-06-22 09:09:40 +02:00

109 lines
3.9 KiB
C++

#pragma once
#include "motordrivers.hpp"
#include "motorctl.hpp"
#include "buzzer.hpp"
//--------------------------------------------
//---- struct, enum, variable declarations ---
//--------------------------------------------
//enum that decides how the motors get controlled
enum class controlMode_t {IDLE, JOYSTICK, MASSAGE, HTTP, MQTT, BLUETOOTH, AUTO};
//string array representing the mode enum (for printing the state as string)
extern const char* controlModeStr[7];
//struct with config parameters
typedef struct control_config_t {
controlMode_t defaultMode; //default mode after startup and toggling IDLE
//--- timeout ---
uint32_t timeoutMs; //time of inactivity after which the mode gets switched to IDLE
float timeoutTolerancePer; //percentage the duty can vary between timeout checks considered still inactive
//--- http mode ---
float http_toleranceZeroX_Per;//percentage around joystick axis the coordinate snaps to 0
float http_toleranceZeroY_Per;
float http_toleranceEndPer; //percentage before joystick end the coordinate snaps to 1/-1
uint32_t http_timeoutMs; //time no new data was received before the motors get turned off
} control_config_t;
//==================================
//========= control class ==========
//==================================
//controls the mode the armchair operates
//repeatedly generates the motor commands corresponding to current mode and sends those to motorcontrol
class controlledArmchair {
public:
//--- constructor ---
controlledArmchair (
control_config_t config_f,
buzzer_t* buzzer_f,
controlledMotor* motorLeft_f,
controlledMotor* motorRight_f
);
//--- functions ---
//task that repeatedly generates motor commands depending on the current mode
void startHandleLoop();
//function that changes to a specified control mode
void changeMode(controlMode_t modeNew);
//function that toggle between IDLE and previous active mode (or default if not switched to certain mode yet)
void toggleIdle();
//function that toggles between two modes, but prefers first argument if entirely different mode is currently active
void toggleModes(controlMode_t modePrimary, controlMode_t modeSecondary);
//function that restarts timer which initiates the automatic timeout (switch to IDLE) after certain time of inactivity
void resetTimeout();
private:
//--- functions ---
//function that evaluates whether there is no activity/change on the motor duty for a certain time, if so a switch to IDLE is issued. - has to be run repeatedly in a slow interval
void handleTimeout();
//--- objects ---
buzzer_t* buzzer;
controlledMotor* motorLeft;
controlledMotor* motorRight;
//---variables ---
//struct for motor commands returned by generate functions of each mode
motorCommands_t commands;
//struct with config parameters
control_config_t config;
//variables for http mode
uint32_t http_timestamp_lastData = 0;
//definition of mode enum
controlMode_t mode = controlMode_t::IDLE;
//variable to store mode when toggling IDLE mode
controlMode_t modePrevious; //default mode
//command preset for idling motors
const motorCommand_t cmd_motorIdle = {
.state = motorstate_t::IDLE,
.duty = 0
};
const motorCommands_t cmds_bothMotorsIdle = {
.left = cmd_motorIdle,
.right = cmd_motorIdle
};
//variable for slow loop
uint32_t timestamp_SlowLoopLastRun = 0;
//variables for detecting timeout (switch to idle, after inactivity)
float dutyLeft_lastActivity = 0;
float dutyRight_lastActivity = 0;
uint32_t timestamp_lastActivity = 0;
};