Wenn man auf die Aufteilung zwischen Sensor- und Action-Teil in zwei Funktionen verzichtet und beides in eine Funktion packt geht es kompakter.
Das mag bei den knappen ASURO Resourcen sinnvoll sein.
Code:
#include "asuro.h"
#define L_DIR ((PORTD & RWD) ? -1 : 1)
#define R_DIR ((PORTB & RWD) ? -1 : 1)
#define ENCODERSEGMENTS 4
typedef int (*FunctionPointer) (int);
FunctionPointer actionList[];
const int slow=60, fast=80;
char currentTask;
int leftSpeed=0;
int rightSpeed=0;
int wait(int msTime) {
long t1=Gettime()+msTime;
char savedTask=currentTask;
int act, action=0;
do {
for(currentTask=0; currentTask<savedTask; currentTask++) {
act=(*actionList[currentTask])(currentTask);
if(act) {
action|=act;
currentTask=-1;
};
}
} while(t1 > Gettime());
currentTask=savedTask;
return action;
}
void drive(int leftSpeed_, int rightSpeed_) {
leftSpeed=leftSpeed_;
rightSpeed=rightSpeed_;
}
const int delta=100, Kp=20; // entspricht Kp=0.2
int regel(int pwm, int e) {
int y= (Kp * e)/100;
pwm+=y;
return (pwm>127)? 127 : ((pwm<-127) ? -127 : pwm);
}
int motor_Task(int idx) {
static long motorTime=0;
static int lpwm=0;
static int rpwm=0;
int l_ticks, r_ticks;
int Ta=Gettime()-motorTime;
if(Ta<0) return 0;
Ta+=delta;
l_ticks=encoder[LEFT];
r_ticks=encoder[RIGHT];
EncoderSet(0, 0);
motorTime=Gettime()+delta;
lpwm=regel(lpwm, leftSpeed -(4960/ENCODERSEGMENTS)*L_DIR*l_ticks/Ta);
rpwm=regel(rpwm, rightSpeed-(4960/ENCODERSEGMENTS)*R_DIR*r_ticks/Ta);
SetMotorPower(lpwm, rpwm);
return 0x1;
}
int blink_Task(int idx) {
static int led=0;
static int t1=0;
int t0=t1;
t1=(Gettime()/1000)&0x1;
if(t0==t1) return 0;
led=1-led;
StatusLED(led);
return 0x1;
}
int avoid_Task(int idx) {
static unsigned char count=0;
static int old=0;
int sensor=PollSwitch();
count++;
if (old!=sensor) count=0;
old=sensor;
if (count<5 || sensor==0) return 0;
drive(-slow, -slow);
wait(2000);
if(sensor<16) drive(-slow, 0); else drive(0, -slow);
wait(1000);
return 0x2;
}
int cruise_Task(int idx) {
drive(fast, fast);
return 0x1;
}
FunctionPointer actionList[] ={
motor_Task,
blink_Task,
avoid_Task,
//findLight_Task,
cruise_Task,
};
int main(void) {
Init();
EncoderInit();
EncoderStart();
drive(0,0);
mSleep(1000);
currentTask=sizeof(actionList)/sizeof(FunctionPointer);
return wait(0);
}
Lesezeichen