Skip to content

Commit c326572

Browse files
jmriegojmriegoJose Riego Valenzuela
authored
Default spring (#18)
* default_spring: 1st try * adding dump * get default spring working * add workflow and remove dump debug * modify to use structs for joystick gains * add new setup gains Co-authored-by: jmriego <[email protected]> Co-authored-by: Jose Riego Valenzuela <[email protected]>
1 parent 1e7ba75 commit c326572

File tree

9 files changed

+141
-69
lines changed

9 files changed

+141
-69
lines changed

.github/workflows/arduino.yml

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Arduino
2+
3+
on:
4+
push:
5+
tags: ['v*']
6+
pull_request:
7+
branches: [ master ]
8+
9+
jobs:
10+
build:
11+
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- uses: actions/checkout@v2
16+
17+
- name: Setup Arduino CLI
18+
uses: arduino/[email protected]
19+
20+
- name: Install Arduino Micro platform
21+
run: |
22+
arduino-cli core update-index
23+
arduino-cli core install arduino:avr
24+
25+
- name: Compile Fino Arduino Sketch
26+
run: |
27+
mkdir -p build/arduino.avr.micro
28+
arduino-cli compile --fqbn arduino:avr:micro --verbose --output-dir build/arduino.avr.micro
29+
30+
- name: Upload Arduino sketch artifact
31+
uses: actions/upload-artifact@v2
32+
with:
33+
name: Artifact.Fino
34+
path: build/arduino.avr.micro/Fino.ino.hex
35+
36+

Fino.ino

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define DEBUGNO
22
// the digits mean Mmmmrrr (M=Major,m=minor,r=revision)
3-
#define SKETCH_VERSION 2004000
3+
#define SKETCH_VERSION 3000000
44

55
#include "src/Joystick.h"
66
#include "config.h"

com.ino

+13-3
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,21 @@ void get_messages_from_serial()
5353
write_i32(SKETCH_VERSION);
5454
break;
5555
}
56-
// Unknown order
57-
default:
56+
case CONFIG:
57+
{
58+
float defaultSpringGain = read_i8() / 100.0;
59+
60+
Gains gains[FFB_AXIS_COUNT];
61+
gains[0].defaultSpringGain = defaultSpringGain;
62+
gains[1].defaultSpringGain = defaultSpringGain;
63+
Joystick.setGains(gains);
64+
break;
65+
}
66+
// Unknown order
67+
default:
5868
write_order(ERROR);
5969
write_i16(404);
60-
return;
70+
return;
6171
}
6272
}
6373
write_order(RECEIVED); // Confirm the reception

config.h

-12
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,6 @@
55
// --------------------------
66

77
#define default_gain 1.0
8-
#define totalGain default_gain
9-
#define constantGain default_gain
10-
#define rampGain default_gain
11-
#define squareGain default_gain
12-
#define sineGain default_gain
13-
#define triangleGain default_gain
14-
#define sawtoothdownGain default_gain
15-
#define sawtoothupGain default_gain
16-
#define springGain default_gain
17-
#define inertiaGain default_gain
18-
#define frictionGain 0.25
19-
#define damperGain default_gain
208
#define damperSplineNumPoints 6
219

2210
// comment out this line if you don't want to have a spline configuration for the damper

order.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ enum Order {
1010
POSITION = 4,
1111
ERROR = 5,
1212
LOG = 6,
13-
VERSION = 7
13+
VERSION = 7,
14+
CONFIG = 8
1415
};
1516

1617
typedef enum Order Order;

src/DynamicHID/PIDReportHandler.cpp

+23-20
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
PIDReportHandler::PIDReportHandler()
44
{
55
nextEID = 1;
6-
devicePaused = 0;
6+
deviceState = MDEVICESTATE_SPRING;
77
}
88

99
PIDReportHandler::~PIDReportHandler()
@@ -137,18 +137,20 @@ void PIDReportHandler::DeviceControl(USB_FFBReport_DeviceControl_Output_Data_t*
137137
else if (control == 0x03)
138138
{ // 3=Stop All Effects
139139
StopAllEffects();
140+
deviceState &= ~(MDEVICESTATE_SPRING);
140141
}
141142
else if (control == 0x04)
142143
{ // 4=Reset
143144
FreeAllEffects();
145+
deviceState |= MDEVICESTATE_SPRING;
144146
}
145147
else if (control == 0x05)
146148
{ // 5=Pause
147-
devicePaused = 1;
149+
deviceState |= MDEVICESTATE_PAUSED;
148150
}
149151
else if (control == 0x06)
150152
{ // 6=Continue
151-
devicePaused = 0;
153+
deviceState &= ~(MDEVICESTATE_PAUSED);
152154
}
153155
else if (control & (0xFF - 0x3F))
154156
{
@@ -193,22 +195,22 @@ void PIDReportHandler::SetEffect(USB_FFBReport_SetEffect_Output_Data_t* data)
193195
uint8_t loopCount = effect->loopCount > 0 ? effect->loopCount : 1;
194196
effect->totalDuration = (data->duration + data->startDelay) * loopCount;
195197
}
196-
//Serial.print("lC: ");
197-
//Serial.println(effect->loopCount);
198-
//Serial.print("d: ");
199-
//Serial.print(effect->duration);
200-
//Serial.print("tD: ");
201-
//Serial.println(effect->totalDuration);
202-
//Serial.print("sD: ");
203-
//Serial.println(effect->startDelay);
204-
//Serial.print("dX: ");
205-
//Serial.print(effect->directionX);
206-
//Serial.print(" dX: ");
207-
//Serial.print(effect->directionY);
208-
//Serial.print(" eT: ");
209-
//Serial.print(effect->effectType);
210-
//Serial.print(" eA: ");
211-
//Serial.println(effect->enableAxis);
198+
// Serial.print("lC: ");
199+
// Serial.print(effect->loopCount);
200+
// Serial.print(" d: ");
201+
// Serial.print(effect->duration);
202+
// Serial.print(" tD: ");
203+
// Serial.print(effect->totalDuration);
204+
// Serial.print(" sD: ");
205+
// Serial.print(effect->startDelay);
206+
// Serial.print(" dX: ");
207+
// Serial.print(effect->direction[0]);
208+
// Serial.print(" dY: ");
209+
// Serial.print(effect->direction[1]);
210+
// Serial.print(" eT: ");
211+
// Serial.print(effect->effectType);
212+
// Serial.print(" eA: ");
213+
// Serial.println(effect->enableAxis);
212214
// effect->triggerRepeatInterval;
213215
// effect->samplePeriod; // 0..32767 ms
214216
// effect->triggerButton;
@@ -282,7 +284,8 @@ void PIDReportHandler::CreateNewEffect(USB_FFBReport_CreateNewEffect_Feature_Dat
282284
void PIDReportHandler::UppackUsbData(uint8_t* data, uint16_t len)
283285
{
284286
//Serial.print("len:");
285-
//Serial.println(len);
287+
//Serial.print(len);
288+
//Serial.print("=");
286289
//for (uint16_t i=0; i<len; ++i) {
287290
// if (data[i] < 0xA0) {
288291
// Serial.print(" ");

src/DynamicHID/PIDReportHandler.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
#ifndef _PIDREPORTHANDLER_H
22
#define _PIDREPORTHANDLER_H
3+
4+
// Bit-masks for effect states
5+
#define MDEVICESTATE_FREE 0x00
6+
#define MDEVICESTATE_PAUSED 0x01
7+
#define MDEVICESTATE_SPRING 0x02
8+
39
#include <Arduino.h>
410
#include "PIDReportType.h"
511

@@ -10,7 +16,7 @@ class PIDReportHandler {
1016
// Effect management
1117
volatile uint8_t nextEID; // FFP effect indexes starts from 1
1218
volatile TEffectState g_EffectStates[MAX_EFFECTS + 1];
13-
volatile uint8_t devicePaused;
19+
volatile uint8_t deviceState;
1420
//variables for storing previous values
1521
volatile int32_t inertiaT = 0;
1622
volatile int16_t oldSpeed = 0;

src/Joystick.cpp

+27-16
Original file line numberDiff line numberDiff line change
@@ -513,28 +513,28 @@ int32_t Joystick_::getEffectForce(volatile TEffectState& effect, EffectParams _e
513513
switch (effect.effectType)
514514
{
515515
case USB_EFFECT_CONSTANT://1
516-
force = ConstantForceCalculator(effect) * constantGain * angle_ratio;
516+
force = ConstantForceCalculator(effect) * m_gains[axis].constantGain * angle_ratio;
517517
break;
518518
case USB_EFFECT_RAMP://2
519-
force = RampForceCalculator(effect) * rampGain * angle_ratio;
519+
force = RampForceCalculator(effect) * m_gains[axis].rampGain * angle_ratio;
520520
break;
521521
case USB_EFFECT_SQUARE://3
522-
force = SquareForceCalculator(effect) * squareGain * angle_ratio;
522+
force = SquareForceCalculator(effect) * m_gains[axis].squareGain * angle_ratio;
523523
break;
524524
case USB_EFFECT_SINE://4
525-
force = SinForceCalculator(effect) * sineGain * angle_ratio;
525+
force = SinForceCalculator(effect) * m_gains[axis].sineGain * angle_ratio;
526526
break;
527527
case USB_EFFECT_TRIANGLE://5
528-
force = TriangleForceCalculator(effect) * triangleGain * angle_ratio;
528+
force = TriangleForceCalculator(effect) * m_gains[axis].triangleGain * angle_ratio;
529529
break;
530530
case USB_EFFECT_SAWTOOTHDOWN://6
531-
force = SawtoothDownForceCalculator(effect) * sawtoothdownGain * angle_ratio;
531+
force = SawtoothDownForceCalculator(effect) * m_gains[axis].sawtoothdownGain * angle_ratio;
532532
break;
533533
case USB_EFFECT_SAWTOOTHUP://7
534-
force = SawtoothUpForceCalculator(effect) * sawtoothupGain * angle_ratio;
534+
force = SawtoothUpForceCalculator(effect) * m_gains[axis].sawtoothupGain * angle_ratio;
535535
break;
536536
case USB_EFFECT_SPRING://8
537-
force = ConditionForceCalculator(effect, NormalizeRange(_effect_params.springPosition, m_effect_params[axis].springMaxPosition), condition) * angle_ratio * springGain;
537+
force = ConditionForceCalculator(effect, NormalizeRange(_effect_params.springPosition, m_effect_params[axis].springMaxPosition), condition) * angle_ratio * m_gains[axis].springGain;
538538
break;
539539
case USB_EFFECT_DAMPER://9
540540
force = ConditionForceCalculator(effect, NormalizeRange(_effect_params.damperVelocity, m_effect_params[axis].damperMaxVelocity), condition) * angle_ratio;
@@ -543,21 +543,21 @@ int32_t Joystick_::getEffectForce(volatile TEffectState& effect, EffectParams _e
543543
Interpolation::CatmullSpline(damperSplinePoints[0], damperSplinePoints[1], damperSplineNumPoints, abs(force))
544544
/10000.0);
545545
#else
546-
force = force * damperGain;
546+
force = force * m_gains[axis].damperGain;
547547
#endif
548548
force = damperFilter[axis].update(force);
549549
break;
550550
case USB_EFFECT_INERTIA://10
551551
if (_effect_params.inertiaAcceleration < 0 && _effect_params.frictionPositionChange < 0) {
552-
force = ConditionForceCalculator(effect, abs(NormalizeRange(_effect_params.inertiaAcceleration, m_effect_params[axis].inertiaMaxAcceleration)), condition) * angle_ratio * inertiaGain;
552+
force = ConditionForceCalculator(effect, abs(NormalizeRange(_effect_params.inertiaAcceleration, m_effect_params[axis].inertiaMaxAcceleration)), condition) * angle_ratio * m_gains[axis].inertiaGain;
553553
}
554554
else if (_effect_params.inertiaAcceleration < 0 && _effect_params.frictionPositionChange > 0) {
555-
force = -1 * ConditionForceCalculator(effect, abs(NormalizeRange(_effect_params.inertiaAcceleration, m_effect_params[axis].inertiaMaxAcceleration)), condition) * angle_ratio * inertiaGain;
555+
force = -1 * ConditionForceCalculator(effect, abs(NormalizeRange(_effect_params.inertiaAcceleration, m_effect_params[axis].inertiaMaxAcceleration)), condition) * angle_ratio * m_gains[axis].inertiaGain;
556556
}
557557
force = inertiaFilter[axis].update(force);
558558
break;
559559
case USB_EFFECT_FRICTION://11
560-
force = ConditionForceCalculator(effect, NormalizeRange(_effect_params.frictionPositionChange, m_effect_params[axis].frictionMaxPositionChange), condition) * angle_ratio * frictionGain;
560+
force = ConditionForceCalculator(effect, NormalizeRange(_effect_params.frictionPositionChange, m_effect_params[axis].frictionMaxPositionChange), condition) * angle_ratio * m_gains[axis].frictionGain;
561561
force = frictionFilter[axis].update(force);
562562
break;
563563
case USB_EFFECT_CUSTOM://12
@@ -567,11 +567,21 @@ int32_t Joystick_::getEffectForce(volatile TEffectState& effect, EffectParams _e
567567
return force;
568568
}
569569

570-
571570
void Joystick_::forceCalculator(int32_t* forces) {
572571
forces[0] = 0;
573572
forces[1] = 0;
574-
int32_t force = 0;
573+
574+
// If the device is in default auto spring effect lets calculate it
575+
if (DynamicHID().pidReportHandler.deviceState == MDEVICESTATE_SPRING)
576+
{
577+
for (int axis = 0; axis < FFB_AXIS_COUNT; ++axis)
578+
{
579+
forces[axis] = (int32_t)(NormalizeRange(m_effect_params[axis].springPosition, m_effect_params[axis].springMaxPosition) * -10000 * m_gains[axis].defaultSpringGain); // TODO
580+
}
581+
}
582+
else
583+
{
584+
575585
for (int id = 0; id < MAX_EFFECTS; id++) {
576586
volatile TEffectState& effect = DynamicHID().pidReportHandler.g_EffectStates[id];
577587

@@ -591,7 +601,7 @@ void Joystick_::forceCalculator(int32_t* forces) {
591601
(effect.elapsedTime >= 0) &&
592602
// dont calculate effects that have already finished
593603
(effect.elapsedTime <= effect.duration) &&
594-
!DynamicHID().pidReportHandler.devicePaused)
604+
!DynamicHID().pidReportHandler.deviceState)
595605
{
596606
// if this is a directional conditional calculate the conditional parameters
597607
// as the length in the direction of its angle. This is the same as the dot product of the vectors
@@ -629,10 +639,11 @@ void Joystick_::forceCalculator(int32_t* forces) {
629639
// Serial.println(effect.totalDuration);
630640
//}
631641
}
642+
}
632643

633644
for (int axis = 0; axis < FFB_AXIS_COUNT; ++axis)
634645
{
635-
forces[axis] = (int32_t)((float)totalGain * forces[axis]); // each effect gain * total effect gain = 10000
646+
forces[axis] = (int32_t)((float)m_gains[axis].totalGain * forces[axis]); // each effect gain * total effect gain = 10000
636647
forces[axis] = constrain(forces[axis], -10000, 10000);
637648
}
638649
}

src/Joystick.h

+32-15
Original file line numberDiff line numberDiff line change
@@ -55,23 +55,24 @@
5555
#define JOYSTICK_TYPE_GAMEPAD 0x05
5656
#define JOYSTICK_TYPE_MULTI_AXIS 0x08
5757

58-
#define FORCE_FEEDBACK_MAXGAIN 100
58+
#define FORCE_FEEDBACK_MAXGAIN 1.0
5959
#define DEG_TO_RAD ((float)((float)3.14159265359 / 180.0))
6060

6161
struct Gains{
62-
uint8_t totalGain = FORCE_FEEDBACK_MAXGAIN;
63-
uint8_t constantGain = FORCE_FEEDBACK_MAXGAIN;
64-
uint8_t rampGain = FORCE_FEEDBACK_MAXGAIN;
65-
uint8_t squareGain = FORCE_FEEDBACK_MAXGAIN;
66-
uint8_t sineGain = FORCE_FEEDBACK_MAXGAIN;
67-
uint8_t triangleGain = FORCE_FEEDBACK_MAXGAIN;
68-
uint8_t sawtoothdownGain = FORCE_FEEDBACK_MAXGAIN;
69-
uint8_t sawtoothupGain = FORCE_FEEDBACK_MAXGAIN;
70-
uint8_t springGain = FORCE_FEEDBACK_MAXGAIN;
71-
uint8_t damperGain = FORCE_FEEDBACK_MAXGAIN;
72-
uint8_t inertiaGain = FORCE_FEEDBACK_MAXGAIN;
73-
uint8_t frictionGain = FORCE_FEEDBACK_MAXGAIN;
74-
uint8_t customGain = FORCE_FEEDBACK_MAXGAIN;
62+
float totalGain = FORCE_FEEDBACK_MAXGAIN;
63+
float constantGain = FORCE_FEEDBACK_MAXGAIN;
64+
float rampGain = FORCE_FEEDBACK_MAXGAIN;
65+
float squareGain = FORCE_FEEDBACK_MAXGAIN;
66+
float sineGain = FORCE_FEEDBACK_MAXGAIN;
67+
float triangleGain = FORCE_FEEDBACK_MAXGAIN;
68+
float sawtoothdownGain = FORCE_FEEDBACK_MAXGAIN;
69+
float sawtoothupGain = FORCE_FEEDBACK_MAXGAIN;
70+
float springGain = FORCE_FEEDBACK_MAXGAIN;
71+
float damperGain = FORCE_FEEDBACK_MAXGAIN;
72+
float inertiaGain = FORCE_FEEDBACK_MAXGAIN;
73+
float frictionGain = FORCE_FEEDBACK_MAXGAIN;
74+
float customGain = FORCE_FEEDBACK_MAXGAIN;
75+
float defaultSpringGain = 0.0;
7576
};
7677

7778
struct EffectParams{
@@ -131,6 +132,9 @@ class Joystick_
131132
uint8_t _hidReportId;
132133
uint8_t _hidReportSize;
133134

135+
//force feedback gain
136+
Gains m_gains[FFB_AXIS_COUNT];
137+
134138
//force feedback effect params
135139
EffectParams* m_effect_params;
136140

@@ -171,7 +175,6 @@ class Joystick_
171175

172176
void begin(bool initAutoSendState = true);
173177
void end();
174-
175178
// Set Range Functions
176179
inline void setXAxisRange(int16_t minimum, int16_t maximum)
177180
{
@@ -235,6 +238,20 @@ class Joystick_
235238

236239
//force feedback Interfaces
237240
void getForce(int32_t* forces);
241+
242+
243+
Gains *getGains() {
244+
return m_gains;
245+
}
246+
247+
int8_t setGains(Gains* _gains){
248+
if(_gains != nullptr){
249+
memcpy(m_gains, _gains, sizeof(m_gains));
250+
return 0;
251+
}
252+
return -1;
253+
};
254+
238255
//set effect params funtions
239256
int8_t setEffectParams(EffectParams* _effect_params){
240257
if(_effect_params != nullptr){

0 commit comments

Comments
 (0)