From 153a9f0d8347e12d6987b0c38f68dc85e4ae1131 Mon Sep 17 00:00:00 2001 From: Fisch Date: Sun, 8 Apr 2018 18:20:11 +0200 Subject: [PATCH] inital commit, working roller coaster based ony physics --- achterbahn.ino | 161 +++++++++++++++++++++++++++++++++++++++++++++++++ wagon.cpp | 134 ++++++++++++++++++++++++++++++++++++++++ wagon.h | 31 ++++++++++ 3 files changed, 326 insertions(+) create mode 100644 achterbahn.ino create mode 100644 wagon.cpp create mode 100644 wagon.h diff --git a/achterbahn.ino b/achterbahn.ino new file mode 100644 index 0000000..cd18e9c --- /dev/null +++ b/achterbahn.ino @@ -0,0 +1,161 @@ +#include +#ifdef __AVR__ + #include +#endif + +#include +#include "wagon.h" + +#define PIN D2 +#define NUMPIXELS 300 + +Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); + +long lastPixelUpdate=0; +#define PIXELUPDATETIME 10 +long lastRoutineUpdate=0; +#define ROUTINEUPDATETIME 10 + +long loopmillis=0; + +uint8_t height[NUMPIXELS]; + +std::vector wagon_arr; +uint8_t maxid=0; + + +void setup() { + Serial.begin(115200); + + for (int i=0;i::iterator it = wagon_arr.begin(); it != wagon_arr.end(); ++it) //all wagons + { + Wagon & w = *it; + w.updateGraphics(); + } + + strip.show(); + } + + + if (lastRoutineUpdate+ROUTINEUPDATETIME::iterator it = wagon_arr.begin(); it != wagon_arr.end(); ++it) //all wagons + { + Wagon & w = *it; + w.updatePhysics(ROUTINEUPDATETIME); + if (!w.alive()) + { + it = wagon_arr.erase(it); // After erasing, it is now pointing the next element. + --it; + spawnWagon(); //spawn new one + } + } + } + + + +} + +// Input a value 0 to 255 to get a color value. +// The colours are a transition r - g - b - back to r. +uint32_t Wheel(byte WheelPos) { + WheelPos = 255 - WheelPos; + if(WheelPos < 85) { + return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); + } + if(WheelPos < 170) { + WheelPos -= 85; + return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); + } + WheelPos -= 170; + return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); +} diff --git a/wagon.cpp b/wagon.cpp new file mode 100644 index 0000000..bdf2587 --- /dev/null +++ b/wagon.cpp @@ -0,0 +1,134 @@ +#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; +} + diff --git a/wagon.h b/wagon.h new file mode 100644 index 0000000..c5f0f41 --- /dev/null +++ b/wagon.h @@ -0,0 +1,31 @@ +#ifndef WAGON_H +#define WAGON_H +#include +#include + +class Wagon +{ + public: + int _id; + Wagon(int id,int numpixels,Adafruit_NeoPixel *strip,uint8_t *height, float pos, float wagonlength, float startvel,float startacc); + Wagon(); + bool operator==(const Wagon &r) const; + void updatePhysics(float updatedelayms); + void updateGraphics(); + float getHeight(int p); + int pos(); + int id(); + bool alive(); + private: + int _numpixels; + Adafruit_NeoPixel *_strip; + float _pos; + float _vel; + float _acc; + float _wagonlength; + uint8_t *_height; +}; + +#endif + +