Move coordinate scaling from app to controller
- joystick.cpp/hpp: - move method scaleCoordinate from joystick class to public function - modify scaleCoordinate function to accept float values instead of ADC pin, change tolerance parameters to percent instead of absolute number - change method getData to use the public function now - control.cpp: - use scaleCoordinate function in http mode - calculate radius in http mode - config.cpp - adjust tolerance thresholds for joystick to percent - App.js - disable "snap to zero" feature -> just scale joystick output to value of -1 to 1
This commit is contained in:
parent
0165a88f1f
commit
20873b4175
@ -27,7 +27,7 @@ single100a_config_t configDriverRight = {
|
||||
.pwmFreq = 10000
|
||||
};
|
||||
|
||||
//configure motor contol
|
||||
//--- configure motor contol ---
|
||||
motorctl_config_t configMotorControl = {
|
||||
.msFade = 900,
|
||||
.currentMax = 10
|
||||
@ -40,16 +40,17 @@ controlledMotor motorRight(configDriverRight, configMotorControl);
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
//------- joystick configuration -------
|
||||
//--------------------------------------
|
||||
joystick_config_t configJoystick = {
|
||||
.adc_x = ADC1_CHANNEL_3, //GPIO39
|
||||
.adc_y = ADC1_CHANNEL_0, //GPIO36
|
||||
//range around center-threshold of each axis the coordinates stays at 0 (adc value 0-4095)
|
||||
.tolerance_zero = 100,
|
||||
//threshold the coordinate snaps to -1 or 1 before configured "_max" or "_min" threshold (mechanical end) is reached (adc value 0-4095)
|
||||
.tolerance_end = 80,
|
||||
//range around center-threshold of each axis the coordinates stays at 0 (percentage of available range 0-100)
|
||||
.tolerance_zero = 7,
|
||||
//threshold the coordinate snaps to -1 or 1 before configured "_max" or "_min" threshold (mechanical end) is reached (percentage of available range 0-100)
|
||||
.tolerance_end = 5,
|
||||
//threshold the radius jumps to 1 before the stick is at max radius (range 0-1)
|
||||
.tolerance_radius = 0.05,
|
||||
|
||||
@ -63,6 +64,27 @@ joystick_config_t configJoystick = {
|
||||
.y_inverted = true
|
||||
};
|
||||
|
||||
|
||||
|
||||
//----------------------------
|
||||
//--- configure fan contol ---
|
||||
//----------------------------
|
||||
fan_config_t configFanLeft = {
|
||||
.gpio_fan = GPIO_NUM_2,
|
||||
.msRun = 5000,
|
||||
.dutyThreshold = 35
|
||||
};
|
||||
fan_config_t configFanRight = {
|
||||
.gpio_fan = GPIO_NUM_15,
|
||||
.msRun = 5000,
|
||||
.dutyThreshold = 35
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=================================
|
||||
//===== create global objects =====
|
||||
//=================================
|
||||
//create global joystic instance
|
||||
evaluatedJoystick joystick(configJoystick);
|
||||
|
||||
@ -76,15 +98,4 @@ buzzer_t buzzer(GPIO_NUM_12, 100);
|
||||
controlledArmchair control(&buzzer, &motorLeft, &motorRight);
|
||||
|
||||
|
||||
//configure fan contol
|
||||
fan_config_t configFanLeft = {
|
||||
.gpio_fan = GPIO_NUM_2,
|
||||
.msRun = 5000,
|
||||
.dutyThreshold = 35
|
||||
};
|
||||
fan_config_t configFanRight = {
|
||||
.gpio_fan = GPIO_NUM_15,
|
||||
.msRun = 5000,
|
||||
.dutyThreshold = 35
|
||||
};
|
||||
|
||||
|
@ -87,11 +87,21 @@ void controlledArmchair::startHandleLoop() {
|
||||
//reset timestamp lastAction
|
||||
http_timestamp_lastData = esp_log_timestamp();
|
||||
|
||||
ESP_LOGD(TAG, "received data from http queue -> generating commands\n x=%.3f y=%.3f radius=%.3f angle=%.3f",
|
||||
ESP_LOGD(TAG, "received data (from queue): x=%.3f y=%.3f radius=%.3f angle=%.3f",
|
||||
dataRead.x, dataRead.y, dataRead.radius, dataRead.angle);
|
||||
|
||||
//--- scale coordinates ---
|
||||
//note: scaleCoordinate function currently can not handle negative input -> add offset to input
|
||||
// scaleCoordinate(input, min, max, center, tolerance_zero_per, tolerance_end_per)
|
||||
dataRead.x = scaleCoordinate(dataRead.x+1, 0, 2, 1, 5, 2); //TODO: move tolerance to config (virtualJoystick or control_Config_t?)
|
||||
dataRead.y = scaleCoordinate(dataRead.y+1, 0, 2, 1, 5, 2);
|
||||
//--- calculate radius with new coordinates ---
|
||||
dataRead.radius = sqrt(pow(dataRead.x,2) + pow(dataRead.y,2));
|
||||
ESP_LOGD(TAG, "processed/scaled data: x=%.3f y=%.3f radius=%.3f", dataRead.x, dataRead.y, dataRead.radius);
|
||||
|
||||
//--- generate motor commands ---
|
||||
//pass received joystick data from http queue to generatecommands function from joystick.hpp
|
||||
ESP_LOGV(TAG, "generating commands...");
|
||||
commands = joystick_generateCommandsDriving(dataRead);
|
||||
|
||||
//--- apply commands to motors ---
|
||||
@ -103,7 +113,7 @@ void controlledArmchair::startHandleLoop() {
|
||||
//--- timeout ---
|
||||
//turn off motors when motor still on and no new data received for some time
|
||||
if (
|
||||
(esp_log_timestamp() - http_timestamp_lastData > 3000) //no data received for x seconds
|
||||
(esp_log_timestamp() - http_timestamp_lastData > 3000) //no data received for x seconds //TODO: move timeout to config
|
||||
&& (commands.left.state != motorstate_t::IDLE || commands.right.state != motorstate_t::IDLE) //at least one motor is still running
|
||||
){
|
||||
ESP_LOGE(TAG, "TIMEOUT - no data received for 3s -> stopping motors");
|
||||
|
@ -68,50 +68,6 @@ int evaluatedJoystick::readAdc(adc1_channel_t adc_channel, bool inverted) {
|
||||
|
||||
|
||||
|
||||
//----------------------------
|
||||
//------ getCoordinate -------
|
||||
//----------------------------
|
||||
//function to read voltage at a gpio pin and scale it to a value from -1 to 1 using the given thresholds and tolerances
|
||||
float evaluatedJoystick::getCoordinate(adc1_channel_t adc_channel, bool inverted, int min, int max, int center, int tolerance_zero, int tolerance_end) {
|
||||
|
||||
float coordinate = 0;
|
||||
|
||||
//read voltage from adc
|
||||
int input = readAdc(adc_channel, inverted);
|
||||
|
||||
//define coordinate value considering the different tolerances
|
||||
//--- center ---
|
||||
if ((input < center+tolerance_zero) && (input > center-tolerance_zero) ) { //adc value is inside tolerance around center threshold
|
||||
coordinate = 0;
|
||||
}
|
||||
//--- maximum ---
|
||||
else if (input > max-tolerance_end) {
|
||||
coordinate = 1;
|
||||
}
|
||||
//--- minimum ---
|
||||
else if (input < min+tolerance_end) {
|
||||
coordinate = -1;
|
||||
}
|
||||
//--- positive area ---
|
||||
else if (input > center) {
|
||||
float range = max - center - tolerance_zero - tolerance_end;
|
||||
coordinate = (input - center - tolerance_end) / range;
|
||||
}
|
||||
//--- negative area ---
|
||||
else if (input < center) {
|
||||
float range = (center - min - tolerance_zero - tolerance_end);
|
||||
coordinate = -(center-input - tolerance_end) / range;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "coordinate=%.3f, input=%d/4095, isInverted=%d", coordinate, input, inverted);
|
||||
//return coordinate (-1 to 1)
|
||||
return coordinate;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------------------
|
||||
//---------- getData ------------
|
||||
//-------------------------------
|
||||
@ -120,10 +76,11 @@ joystickData_t evaluatedJoystick::getData() {
|
||||
//get coordinates
|
||||
//TODO individual tolerances for each axis? Otherwise some parameters can be removed
|
||||
ESP_LOGD(TAG, "getting X coodrinate...");
|
||||
float x = getCoordinate(config.adc_x, config.x_inverted, config.x_min, config.x_max, x_center, config.tolerance_zero, config.tolerance_end);
|
||||
float x = scaleCoordinate(readAdc(config.adc_x, config.x_inverted), config.x_min, config.x_max, x_center, config.tolerance_zero, config.tolerance_end);
|
||||
data.x = x;
|
||||
|
||||
ESP_LOGD(TAG, "getting Y coodrinate...");
|
||||
float y = getCoordinate(config.adc_y, config.y_inverted, config.y_min, config.y_max, y_center, config.tolerance_zero, config.tolerance_end);
|
||||
float y = scaleCoordinate(readAdc(config.adc_y, config.y_inverted), config.y_min, config.y_max, y_center, config.tolerance_zero, config.tolerance_end);
|
||||
data.y = y;
|
||||
|
||||
//calculate radius
|
||||
@ -159,6 +116,53 @@ void evaluatedJoystick::defineCenter(){
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//==============================
|
||||
//====== scaleCoordinate =======
|
||||
//==============================
|
||||
//function that scales an input value (e.g. from adc pin) to a value from -1 to 1 using the given thresholds and tolerances
|
||||
float scaleCoordinate(float input, float min, float max, float center, float tolerance_zero_per, float tolerance_end_per) {
|
||||
|
||||
float coordinate = 0;
|
||||
|
||||
//convert tolerance percentages to actual values of range
|
||||
double tolerance_zero = (max-min) * tolerance_zero_per / 100;
|
||||
double tolerance_end = (max-min) * tolerance_end_per / 100;
|
||||
|
||||
//define coordinate value considering the different tolerances
|
||||
//--- center ---
|
||||
if ((input < center+tolerance_zero) && (input > center-tolerance_zero) ) { //adc value is inside tolerance around center threshold
|
||||
coordinate = 0;
|
||||
}
|
||||
//--- maximum ---
|
||||
else if (input > max-tolerance_end) {
|
||||
coordinate = 1;
|
||||
}
|
||||
//--- minimum ---
|
||||
else if (input < min+tolerance_end) {
|
||||
coordinate = -1;
|
||||
}
|
||||
//--- positive area ---
|
||||
else if (input > center) {
|
||||
float range = max - center - tolerance_zero - tolerance_end;
|
||||
coordinate = (input - center - tolerance_zero - tolerance_end) / range;
|
||||
}
|
||||
//--- negative area ---
|
||||
else if (input < center) {
|
||||
float range = (center - min - tolerance_zero - tolerance_end);
|
||||
coordinate = -(center-input - tolerance_zero - tolerance_end) / range;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "scaled coordinate from %.3f to %.3f", input, coordinate);
|
||||
//return coordinate (-1 to 1)
|
||||
return coordinate;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//=============================================
|
||||
//========= joystick_evaluatePosition =========
|
||||
//=============================================
|
||||
|
@ -86,8 +86,6 @@ class evaluatedJoystick {
|
||||
void init();
|
||||
//read adc while making multiple samples with option to invert the result
|
||||
int readAdc(adc1_channel_t adc_channel, bool inverted = false);
|
||||
//read input voltage and scale to value from -1 to 1 using the given thresholds and tolerances
|
||||
float getCoordinate(adc1_channel_t adc_channel, bool inverted, int min, int max, int center, int tolerance_zero, int tolerance_end);
|
||||
|
||||
//--- variables ---
|
||||
joystick_config_t config;
|
||||
@ -111,9 +109,15 @@ class evaluatedJoystick {
|
||||
motorCommands_t joystick_generateCommandsDriving(joystickData_t data );
|
||||
|
||||
|
||||
//==============================
|
||||
//====== scaleCoordinate =======
|
||||
//==============================
|
||||
//function that scales an input value (e.g. from adc pin) to a value from -1 to 1 using the giben thresholds and tolerances
|
||||
float scaleCoordinate(float input, float min, float max, float center, float tolerance_zero_per, float tolerance_end_per);
|
||||
|
||||
//============================================
|
||||
//========= joystick_CommandsDriving =========
|
||||
//============================================
|
||||
|
||||
//=============================================
|
||||
//========= joystick_evaluatePosition =========
|
||||
//=============================================
|
||||
//function that defines and returns enum joystickPos from x and y coordinates
|
||||
joystickPos_t joystick_evaluatePosition(float x, float y);
|
||||
|
21
react-app/src/App.js
vendored
21
react-app/src/App.js
vendored
@ -33,7 +33,7 @@ function App() {
|
||||
// - snaps 0 zero for a given tolerance in percent
|
||||
// - rounds value do given decimal places
|
||||
// - TODO: add threshold it snaps to 1 / -1 (100%) toleranceEnd
|
||||
const ScaleCoordinate = (input) => {
|
||||
const ScaleCoordinateTolerance = (input) => {
|
||||
//calc tolerance threshold and available range
|
||||
const tolerance = joystickSize/2 * toleranceSnapToZeroPer/100;
|
||||
const range = joystickSize/2 - tolerance;
|
||||
@ -61,6 +61,15 @@ function App() {
|
||||
|
||||
|
||||
|
||||
//----------------------------------------
|
||||
//----------- Scale coordinate -----------
|
||||
//----------------------------------------
|
||||
//simply scale coordinate from joystick to a value of -1 to 1 without applying any tolerances
|
||||
const ScaleCoordinate = (input) => {
|
||||
return ( input / (joystickSize/2) ).toFixed(decimalPlaces);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------
|
||||
//------- Senda data via POST request -------
|
||||
@ -106,13 +115,19 @@ function App() {
|
||||
//evaluate coordinates and send to esp32
|
||||
const handleMove = (e) => {
|
||||
//console.log("data from joystick-element X:" + e.x + " Y:" + e.y + " distance:" + e.distance);
|
||||
//calculate needed variables
|
||||
|
||||
//--- convert coordinates ---
|
||||
//Note: tolerance (snap to zero) now handled by controller -> send raw coordinates
|
||||
//const x = ScaleCoordinateTolerance(e.x);
|
||||
//const y = ScaleCoordinateTolerance(e.y);
|
||||
const x = ScaleCoordinate(e.x);
|
||||
const y = ScaleCoordinate(e.y);
|
||||
//--- scale radius ---
|
||||
const radius = (e.distance / 100).toFixed(5);
|
||||
//--- calculate angle ---
|
||||
const angle = ( Math.atan( y / x ) * 180 / Math.PI ).toFixed(2);
|
||||
|
||||
//crate object with necessary data
|
||||
//create object with necessary data
|
||||
const joystick_data={
|
||||
x: x,
|
||||
y: y,
|
||||
|
Loading…
x
Reference in New Issue
Block a user