#include "wagon.h" Wagon::Wagon(int id,int numpixels, Adafruit_NeoPixel *strip,uint8_t *height,float pos, float wagonlength,float startvel,float startacc) { _id = id; _numpixels=numpixels; _pos = pos; _wagonlength = wagonlength; _strip=strip; _height=height; _vel=startvel; _acc=startacc; } bool Wagon::operator==(const Wagon &r) const { return (r._id == _id); } void Wagon::updatePhysics(float updatedelayms) { /* float acceleration=0; for (int cpos=int(_pos);cpos>int(_pos-_wagonlength);cpos--){ acceleration=(_height[(int)cpos]-_height[(int)cpos+1])*0.03; } acceleration/=int(_wagonlength); _vel+= acceleration; //Acceleration from height difference _vel*=1-0.001; //resistance float airresistance=_vel*_vel *0.005;//air resistance if (_vel>=0){ _vel-=airresistance; }else{ _vel+=airresistance; }*/ #define CONST_G 9.81 #define PIXELDISTANCE 1.6666667 // 1/60.0 * 100 #define C_ROLL 0.001 // = Croll * G https://de.wikipedia.org/wiki/Rollwiderstand 0.001 #define AIRRES 0.18 //C_w*A*0.5*rho Air resistance: C_w * A * 0.5 * rho (.... *v^2) //http://www.kfz-tech.de/Biblio/Formelsammlung/Luftwiderstand.htm C_w 0.6 //rho Massendichte luft 1,2041 //A = 1m^2 float m=50/_wagonlength; //mass of part of a wagon _acc=0; int cpos=(int)_pos; for (int cpos=(int)_pos;cpos>(int)(_pos-_wagonlength);cpos--){ //for each wagon float hdiff=getHeight((int) (cpos-0.5)) - getHeight((int)(cpos+0.5)); //Serial.print("hdiff="); //Serial.print(hdiff); float beta=atan2(PIXELDISTANCE, hdiff); //Serial.print(" beta="); //Serial.println(beta); //_acc += CONST_G * cos(beta) - C_ROLLG*sin(beta) - AIRRES/m*_vel*_vel; float aa=CONST_G * cos(beta) *updatedelayms/1000; //Gravity and m/s^2 time correction float bb=C_ROLL*CONST_G*updatedelayms/1000*sin(beta); //roll resistance if (_vel<0){ bb*=-1; } float cc=AIRRES/m*_vel*_vel; //air resistance if (_vel<0){ cc*=-1; } //Serial.print("aa="); Serial.print(aa); //Serial.print(" bb="); Serial.print(bb); //Serial.print(" cc="); Serial.println(cc); _acc += aa - bb - cc; } _acc*=updatedelayms/1000; _vel += _acc; _pos += _vel/PIXELDISTANCE; /*Serial.print(" Vel="); Serial.print(_vel); Serial.print(" Acc="); Serial.println(_acc);*/ } float Wagon::getHeight(int p){ if (p<0){ p=0; }else if(p>=_numpixels){ p=_numpixels-1; } return _height[p]; } void Wagon::updateGraphics() { for(int i=_pos;i>_pos-_wagonlength;i--){ uint32_t c=_strip->Color(0,255,0); if (i==int(_pos)){ c=_strip->Color(0,255,100); } _strip->setPixelColor(i,c); } //_strip->setPixelColor(10,_strip->Color(255,0,0)); } int Wagon::pos() { return _pos; } int Wagon::id() { return _id; } bool Wagon::alive() { if (_pos>_numpixels){ return false; } return true; }