Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remote: apply ramp on remote inputs #136

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions Software/src/constants/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,41 @@ namespace Config {

}


/**
Remote Config
*/
namespace Remote {

// Speed lerp of speed for SinglePenetration and StrokeEngine mode
// Time cycle is approximately 100-200ms in fact system load
namespace SpeedLerp {
constexpr float UpPercentPerCycle = 100.0f;
constexpr float DownPercentPerCycle = 100.0f;
}

// Speed lerp of stroke for StrokeEngine mode
// Time cycle is approximately 100-200ms in fact system load
namespace StrokedLerp {
constexpr float UpPercentPerCycle = 100.0f;
constexpr float DownPercentPerCycle = 100.0f;
}

// Speed lerp of depth for StrokeEngine mode
// Time cycle is approximately 100-200ms in fact system load
namespace DepthLerp {
constexpr float UpPercentPerCycle = 100.0f;
constexpr float DownPercentPerCycle = 100.0f;
}

// Speed lerp of sensation for StrokeEngine mode
// Time cycle is approximately 100-200ms in fact system load
namespace SensationLerp {
constexpr float UpPercentPerCycle = 100.0f;
constexpr float DownPercentPerCycle = 100.0f;
}
}

}

// Alias for "_mm" operator
Expand Down
16 changes: 12 additions & 4 deletions Software/src/extensions/u8g2Extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ namespace drawShape {
};

// Function to draw a setting bar with label and percentage
static void settingBar(const String &name, float value, int x = 0,
static void settingBar(const String &name, float value, float target, int x = 0,
int y = 0, Alignment alignment = LEFT_ALIGNED,
int textPadding = 0, float minValue = 0,
float maxValue = 100) {
Expand All @@ -213,6 +213,9 @@ namespace drawShape {
float scaledValue =
constrain(value, minValue, maxValue) / maxValue * 100;
int boxHeight = ceil(h * scaledValue / 100);
float scaledTarget =
constrain(target, minValue, maxValue) / maxValue * 100;
int targetHeight = ceil(h * scaledTarget / 100);

// Position calculations based on alignment
int barStartX = (alignment == LEFT_ALIGNED) ? x : x - w;
Expand All @@ -222,7 +225,8 @@ namespace drawShape {
padding - w - textPadding;

// Draw the bar and its frame
display.drawBox(barStartX, h - boxHeight, w, boxHeight);
display.drawBox(barStartX, h - boxHeight, w - 2, boxHeight);
display.drawVLine(barStartX + w - 2, h - targetHeight, targetHeight);
display.drawFrame(barStartX, 0, w, h);

// Set font for label and draw it
Expand Down Expand Up @@ -258,7 +262,7 @@ namespace drawShape {
display.setDrawColor(1);
}

static void settingBarSmall(float value, int x = 0, int y = 0,
static void settingBarSmall(float value, float target, int x = 0, int y = 0,
float minValue = 0, float maxValue = 100) {
int w = 3;
int mid = (w - 1) / 2;
Expand All @@ -268,12 +272,16 @@ namespace drawShape {
float scaledValue =
constrain(value, minValue, maxValue) / maxValue * 100;
int boxHeight = ceil(h * scaledValue / 100);
float scaledTarget =
constrain(target, minValue, maxValue) / maxValue * 100;
int targetHeight = ceil(h * scaledTarget / 100);
// draw a single pixel line
int lineH = boxHeight > 0 ? constrain(64 - boxHeight - 2, 0, 64) : 64;
display.drawVLine(x + mid, y, lineH);
display.drawVLine(x + w - 1, h - targetHeight, targetHeight);

// draw a box 3px wide
display.drawBox(x, 64 - boxHeight, w, boxHeight);
display.drawBox(x, 64 - boxHeight, w - 1, boxHeight);
}

// Function to draw lines between a variadic number of points
Expand Down
114 changes: 74 additions & 40 deletions Software/src/ossm/OSSM.PlayControls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ void OSSM::drawPlayControlsTask(void *pvParameters) {

auto menuString = menuStrings[ossm->menuOption];

SettingPercents next = {0, 0, 0, 0};
SettingPercents next;
next.speed = ossm->setting.speed;
next.stroke = ossm->setting.stroke;
next.depth = ossm->setting.depth;
next.sensation = ossm->setting.sensation;

unsigned long displayLastUpdated = 0;

/**
Expand Down Expand Up @@ -53,52 +58,71 @@ void OSSM::drawPlayControlsTask(void *pvParameters) {
bool isStrokeEngine =
ossm->sm->is("strokeEngine"_s) || ossm->sm->is("strokeEngine.idle"_s);

bool shouldUpdateDisplay = false;

// This small break gives the encoder a minute to settle.
vTaskDelay(100);

while (isInCorrectState(ossm)) {
// Always assume the display should not update.
shouldUpdateDisplay = false;

next.speedKnob =
getAnalogAveragePercent(SampleOnPin{Pins::Remote::speedPotPin, 50});
ossm->setting.speedKnob = next.speedKnob;
encoder = ossm->encoder.readEncoder();

next.speed = next.speedKnob;
bool shouldUpdateDisplay = false;

if (next.speed != ossm->setting.speed) {
shouldUpdateDisplay = true;
ossm->setting.speed = next.speed;
}
/**
* ////////////////////////////////////////////
* /////////// Manage analog ////////////
* ////////////////////////////////////////////
*/
next.speed = round(getAnalogAveragePercent(SampleOnPin{Pins::Remote::speedPotPin, 50}));

/**
* /////////////////////////////////////////////
* /////////// Manage encoder ////////////
* /////////////////////////////////////////////
*/
encoder = ossm->encoder.readEncoder();
switch (ossm->playControl) {
// STROKE used for SinglePenetration and StrokeEngine
case PlayControls::STROKE:
next.stroke = encoder;
shouldUpdateDisplay = shouldUpdateDisplay ||
next.stroke - ossm->setting.stroke >= 1;
ossm->setting.stroke = next.stroke;
break;
// SENSATION used for StrokeEngine
case PlayControls::SENSATION:
next.sensation = encoder;
shouldUpdateDisplay =
shouldUpdateDisplay ||
next.sensation - ossm->setting.sensation >= 1;
ossm->setting.sensation = next.sensation;
break;
// DEPTH used for StrokeEngine
case PlayControls::DEPTH:
next.depth = encoder;
shouldUpdateDisplay = shouldUpdateDisplay ||
next.depth - ossm->setting.depth >= 1;
ossm->setting.depth = next.depth;
break;
}

shouldUpdateDisplay =
shouldUpdateDisplay || millis() - displayLastUpdated > 1000;
/**
* //////////////////////////////////////////////
* /////////// Inputs update display ////////////
* //////////////////////////////////////////////
*/
shouldUpdateDisplay = shouldUpdateDisplay || next.speed != ossm->setting.speed;
shouldUpdateDisplay = shouldUpdateDisplay || next.stroke != ossm->setting.stroke;
shouldUpdateDisplay = shouldUpdateDisplay || next.sensation != ossm->setting.sensation;
shouldUpdateDisplay = shouldUpdateDisplay || next.depth != ossm->setting.depth;

shouldUpdateDisplay = shouldUpdateDisplay || millis() - displayLastUpdated > 1000;

/**
* /////////////////////////////////////////////
* /////////// Apply lerp input ////////////
* /////////////////////////////////////////////
*/
ossm->setting.speed = applyLerp(ossm->setting.speed, next.speed,
Config::Remote::SpeedLerp::UpPercentPerCycle,
Config::Remote::SpeedLerp::DownPercentPerCycle);
ossm->setting.stroke = applyLerp(ossm->setting.stroke, next.stroke,
Config::Remote::StrokedLerp::UpPercentPerCycle,
Config::Remote::StrokedLerp::DownPercentPerCycle);
ossm->setting.sensation = applyLerp(ossm->setting.sensation, next.sensation,
Config::Remote::DepthLerp::UpPercentPerCycle,
Config::Remote::DepthLerp::DownPercentPerCycle);
ossm->setting.depth = applyLerp(ossm->setting.depth, next.depth,
Config::Remote::SensationLerp::UpPercentPerCycle,
Config::Remote::SensationLerp::DownPercentPerCycle);

// Waiting and continue if display not updated
if (!shouldUpdateDisplay) {
vTaskDelay(100);
continue;
Expand All @@ -113,35 +137,35 @@ void OSSM::drawPlayControlsTask(void *pvParameters) {
ossm->display.clearBuffer();
ossm->display.setFont(Config::Font::base);

drawShape::settingBar(UserConfig::language.Speed, next.speedKnob);
drawShape::settingBar(UserConfig::language.Speed, next.speed, ossm->setting.speed);

if (isStrokeEngine) {
drawStr::centered(32, UserConfig::language.StrokeEngineNames[(int)ossm->setting.pattern]);
switch (ossm->playControl) {
case PlayControls::STROKE:
drawShape::settingBarSmall(ossm->setting.sensation, 125);
drawShape::settingBarSmall(ossm->setting.depth, 120);
drawShape::settingBar(strokeString, ossm->setting.stroke,
drawShape::settingBarSmall(next.sensation, ossm->setting.sensation, 125);
drawShape::settingBarSmall(next.depth, ossm->setting.depth, 120);
drawShape::settingBar(strokeString, next.stroke, ossm->setting.stroke,
118, 0, RIGHT_ALIGNED);
break;
case PlayControls::SENSATION:
drawShape::settingBar("Sensation", ossm->setting.sensation,
drawShape::settingBar("Sensation", next.sensation, ossm->setting.sensation,
128, 0, RIGHT_ALIGNED, 10);
drawShape::settingBarSmall(ossm->setting.depth, 113);
drawShape::settingBarSmall(ossm->setting.stroke, 108);
drawShape::settingBarSmall(next.depth, ossm->setting.depth, 113);
drawShape::settingBarSmall(next.stroke, ossm->setting.stroke, 108);

break;
case PlayControls::DEPTH:
drawShape::settingBarSmall(ossm->setting.sensation, 125);
drawShape::settingBar("Depth", ossm->setting.depth, 123, 0,
RIGHT_ALIGNED, 5);
drawShape::settingBarSmall(ossm->setting.stroke, 108);
drawShape::settingBarSmall(next.sensation, ossm->setting.sensation, 125);
drawShape::settingBar("Depth", next.depth, ossm->setting.depth,
123, 0, RIGHT_ALIGNED, 5);
drawShape::settingBarSmall(next.stroke, ossm->setting.stroke, 108);

break;
}
} else {
drawStr::multiLine(15, 32, UserConfig::language.SimplePenetration);
drawShape::settingBar(strokeString, ossm->encoder.readEncoder(),
drawShape::settingBar(strokeString, next.stroke, ossm->setting.stroke,
118, 0, RIGHT_ALIGNED);
}

Expand Down Expand Up @@ -190,3 +214,13 @@ void OSSM::drawPlayControls() {
xTaskCreate(drawPlayControlsTask, "drawPlayControlsTask", stackSize, this,
1, &drawPlayControlsTaskH);
}

// Apply lerp in current value to move to target value
float OSSM::applyLerp(float current, float target,
float increaseValue, float decreaseValue) {
if (target > current)
current = constrain(current + increaseValue, current, target);
else
current = constrain(current - decreaseValue, target, current);
return current;
}
4 changes: 2 additions & 2 deletions Software/src/ossm/OSSM.SimplePenetration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void OSSM::startSimplePenetrationTask(void *pvParameters) {
ossm->setting.speed * ossm->setting.speed /
Config::Advanced::accelerationScaling;

bool isSpeedZero = ossm->setting.speedKnob <
bool isSpeedZero = ossm->setting.speed <
Config::Advanced::commandDeadZonePercentage;
bool isSpeedChanged =
!isSpeedZero && abs(speed - lastSpeed) >
Expand Down Expand Up @@ -102,4 +102,4 @@ void OSSM::startSimplePenetration() {
"startSimplePenetrationTask", stackSize, this,
configMAX_PRIORITIES - 1,
&runSimplePenetrationTaskH, operationTaskCore);
}
}
1 change: 1 addition & 0 deletions Software/src/ossm/OSSM.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ class OSSM {
static void drawMenuTask(void *pvParameters);

static void drawPlayControlsTask(void *pvParameters);
static float applyLerp(float current, float target, float increaseValue, float decreaseValue);
static void drawPatternControlsTask(void *pvParameters);

void drawUpdate();
Expand Down
1 change: 0 additions & 1 deletion Software/src/structs/SettingPercents.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ struct SettingPercents {
float sensation;
float depth;
StrokePatterns pattern;
float speedKnob;
};

#endif // SOFTWARE_SETTINGPERCENTS_H