@botty:
habe mir jetzt die letzten Tage deinen Vorschlag noch ein paar mal genauer angesehen und überdacht, etwas herumprobiert und die bereits in meiner "LegoPi" bestehende Raspi- Motorstuktur durch die PID-Parameter aufgebohrt:
Code:
//*************************************************************
// motor API
//*************************************************************
#define MAXMOTORS 10 // maximum number of motors
#define MAXMOTORSLOCAL 2 // maximum number of local motors
#define MAXPWMRANGE 255 // maximum software-pwm range (0-255)
// motor control structure
typedef struct {
// electrical motor pins
uint8_t pind1, pind2, pinpwm; // dir + pwm L293 H-Bridge type
uint8_t pinQa, pinQb; // rotary enc pins Qa,Qb
// pwm and encoder values
int16_t dirpwm;
int32_t motenc, oldenc; // rotary encoder values
// PID
pthread_t tid;
int16_t motorID;
// PID custom target values
int32_t target; // set target
int16_t tarpwm; // motor target speed
// PID custom regulation parameters
double P; // P: basic propotional to error
double I; // I: integral: avoid perish
double D; // D: derivative: avoid oscillating
double precis; // error precision to target
int16_t regtime; // PID loop time
double damp; // damp the integral memory
int8_t cont; // target: continue or hit once
// PID internal control variables
int16_t runstate; // monitors runstate
int16_t outp; // PID control output value
int16_t maxout; // max output (max motor pwr)
int32_t read; // current sensor reading
double err; // current error
double integr; // integral of errors
double speed; // current speed
} tEncMotor;
tEncMotor motor[MAXMOTORS];
3 Fragen dazu:
1) da ich jetzt alles statisch in einem Array deklariert habe: käme man jetzt überwiegend ohne die Pointerpfeile -> aus ?
2) da jede einzelne Motorstruktur über den Platz im Array definiert ist (motor[0] für motorID=0) : braucht man dann noch die Strukturvariable motorID?
3) kann man eine zusätzliche Variable im pthread-Aufruf übergeben, indem man die Motornummer mit übergibt?
bisher läuft mein pthread Aufruf immer per
pthread_create(&threadID, NULL, threadname, NULL);
wofür man die 2 NULLs braucht, ist mir z.B. auch noch unklar, vlt kann man die ein oder andere verwenden - und würde das die Sache einfacher machen?
- - - Aktualisiert - - -
ps,
der API Aufruf
RotatePID(port, Target, RotatSpeed, false);
würde dann die folgende Funktion aufrufen, die wieder nach Setten der Variablen einen pthread task starten müsste..... (????) :
Code:
void RotatePID(char port, long Target, float RotatSpeed, char cont) {
motor[port].runstate=1; // set runstate: PID active
// custom init PID [port]
motor[port].target =Target; // assign target
motor[port].tarpwm =RotatSpeed; // assign rotation speed
motor[port].cont=cont; // cont vs. hit once
// Reset PID control defaults
motor[port].outp =0; // PID control output value
motor[port].maxout =100; // absolute max possible output (max pwr)
motor[port].read =0; // current reading
motor[port].err =0; // current error
motor[port].integr =0; // integral of errors
motor[port].speed =0; // current speed
// <<<<<<
// nur wie wäre das hier dann richtig zu implementieren ????
// threadname ist ja für jeden Motor immer ein anderer ????
// wäre hierfür eine tEncMotor Hilfsvariable char[12] tEncMotor.thrnamebuf hilfreich ????
// ("PIDthread00"... "PIDthread99", könnte man beim Initialisieren setten ????)
// aber schreiben will ich ja für alle nur 1x ein einziges PID-Funktionstask-Muster ????
// >>>>>>
pthread_create(& motor[port].tid, NULL??, motor[port].thrnamebuf, NULL??);
}
Lesezeichen