ws2812-achterbahn/wagon.cpp

135 lines
2.9 KiB
C++

#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;
}