-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathVNWheel.ino
119 lines (106 loc) · 3.71 KB
/
VNWheel.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "FfbWheel.h"
#include "Encoder.h"
#include "DigitalWriteFast.h"
#include "PID_v1.h"
Wheel_ Wheel;
#define BAUD_RATE 115200
#define PULSE 9
#define DIR 10
int32_t total_force = 0;
int32_t last_total_force = 0;
double Setpoint, Input, Output;
//double Kp=2, Ki=5, Kd=1;
double Kp = 0.1 , Ki = 30 , Kd = 0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
bool initialRun = true;
#include "PWM.h"
Pwm pwm;
void setup() {
pinMode (PULSE, OUTPUT);
pinMode (DIR, OUTPUT);
attachInterrupt(digitalPinToInterrupt(interruptA), calculateEncoderPostion, CHANGE);
attachInterrupt(digitalPinToInterrupt(interruptB), calculateEncoderPostion, CHANGE); pwm.begin();
pwm.setPWM(0);
Wheel.begin();
Input = Wheel.encoder.currentPosition;
myPID.SetMode(AUTOMATIC);
myPID.SetSampleTime(0.01);
myPID.SetOutputLimits(-50, 50);
Serial.begin(BAUD_RATE);
}
void loop() {
if (initialRun == true ) {
// position control is not correctly, wheel runs over disired postion serveral times before stop
pwm.setPWM(10);
gotoPosition(Wheel.encoder.minValue);
gotoPosition(Wheel.encoder.maxValue);
gotoPosition( 0);
initialRun = false;
pwm.setPWM(0);
} else
{
// assign for re-test without initialRun
// Serial.print("currentVelocity: ");
// Serial.print(Wheel.encoder.maxVelocity);
// Serial.print(" maxAcceleration: ");
// Serial.println(Wheel.encoder.maxAcceleration);
// Serial.print(" maxPositionChange: ");
// Serial.println(Wheel.encoder.currentPosition);
// Wheel.encoder.maxPositionChange = 1151;
// Wheel.encoder.maxVelocity = 72;
// Wheel.encoder.maxAcceleration = 33;
Wheel.encoder.updatePosition();
if (Wheel.encoder.currentPosition > Wheel.encoder.maxValue) {
Wheel.xAxis(32767);
} else if (Wheel.encoder.currentPosition < Wheel.encoder.minValue) {
Wheel.xAxis(-32767);
} else {
Wheel.xAxis(map(Wheel.encoder.currentPosition, Wheel.encoder.minValue , Wheel.encoder.maxValue, -32768, 32767));
}
Wheel.RecvFfbReport();
Wheel.write();
total_force = Wheel.ffbEngine.ForceCalculator(Wheel.encoder);
total_force = constrain(total_force, -255, 255);
// Serial.println(Wheel.encoder.currentPosition);
// when reach max and min wheel range, max force to prevent wheel goes over.
if (Wheel.encoder.currentPosition >= Wheel.encoder.maxValue) {
total_force = 255;
} else if (Wheel.encoder.currentPosition <= Wheel.encoder.minValue) {
total_force = -255;
}
}
// set total gain = 0.2 need replace by wheelConfig.totalGain.
pwm.setPWM(total_force * 0.2);
}
void gotoPosition(int32_t targetPosition) {
Setpoint = targetPosition;
while (Wheel.encoder.currentPosition != targetPosition) {
Setpoint = targetPosition;
Wheel.encoder.updatePosition();
Input = Wheel.encoder.currentPosition ;
myPID.Compute();
pwm.setPWM(-Output);
CalculateMaxSpeedAndMaxAcceleration();
Serial.print("Encoder Position: ");
Serial.print(Wheel.encoder.currentPosition);
Serial.print(" ");
Serial.print(Setpoint);
Serial.print(" ");
Serial.print("PWM: ");
Serial.println(Output);
}
}
void CalculateMaxSpeedAndMaxAcceleration() {
if (Wheel.encoder.maxVelocity < abs(Wheel.encoder.currentVelocity)) {
Wheel.encoder.maxVelocity = abs(Wheel.encoder.currentVelocity);
}
if (Wheel.encoder.maxAcceleration < abs(Wheel.encoder.currentAcceleration)) {
Wheel.encoder.maxAcceleration = abs(Wheel.encoder.currentAcceleration);
}
if (Wheel.encoder.maxPositionChange < abs(Wheel.encoder.positionChange)) {
Wheel.encoder.maxPositionChange = abs(Wheel.encoder.positionChange);
}
}
void calculateEncoderPostion() {
Wheel.encoder.tick();
}