Skip to content

Commit

Permalink
Trigo struct tuning and support for pan, tilt, roll caching
Browse files Browse the repository at this point in the history
LedLeds: Trigo
- constructor sets period, default 360
- caching for pan, tilt and roll
- subclasses for different sin/cos methods (no type needed, efficiency up)
- only sinBase and cosBase override
- rotate default period is 360
  • Loading branch information
ewowi committed Mar 25, 2024
1 parent 826a417 commit 49cbd13
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 48 deletions.
6 changes: 3 additions & 3 deletions src/App/LedFixture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ void Fixture::projectAndMap() {
USER_PRINTF("dev pre [%d] indexV too high %d>=%d or %d (m:%d p:%d) p:%d,%d,%d s:%d,%d,%d\n", rowNr, indexV, leds->nrOfLeds, NUM_LEDS_Max, leds->mappingTable.size(), indexP, pixel.x, pixel.y, pixel.z, leds->size.x, leds->size.y, leds->size.z);
}
else {
Trigo trigo(trigoInt8);
Trigo trigo(leds->size.x-1); // 8 bits trigo with period leds->size.x-1 (currentl Float trigo as same performance)
//post processing:
switch(leds->projectionNr) {
case p_DistanceFromPoint:
Expand All @@ -265,8 +265,8 @@ void Fixture::projectAndMap() {
for (forUnsigned16 x=0; x<leds->size.x && minDistance > 0.5f; x++) {
// float xFactor = x * TWO_PI / (float)(leds->size.x-1); //between 0 .. 2PI

float xNew = trigo.sin(leds->size.x, x, leds->size.x-1);
float yNew = trigo.cos(leds->size.y, x, leds->size.x-1);
float xNew = trigo.sin(leds->size.x, x);
float yNew = trigo.cos(leds->size.y, x);

for (forUnsigned16 y=0; y<leds->size.y && minDistance > 0.5f; y++) {

Expand Down
82 changes: 42 additions & 40 deletions src/App/LedLeds.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,70 +43,72 @@ enum Projections
p_count
};

#define trigoInt8 0
#define trigoInt16 1 //default
#define trigoFloat 2
// sin8/cos8 sin16/cos16
//0: 128, 255 0 32645
//64: 255, 128 32645 0
//128: 128, 1 0 -32645
//192: 1, 127 -32645 0

struct Trigo {
float sinValue; uint16_t sinAngle = UINT16_MAX; //caching of sinValue=sin(sinAngle)
float cosValue; uint16_t cosAngle = UINT16_MAX; //caching of cosValue=cos(cosAngle)
uint8_t type = trigoInt16;
Trigo(uint8_t type = trigoInt16) {
this->type = type;
}
int16_t sin(int16_t factor, uint16_t angle, uint16_t period = 360) {
if (sinAngle != angle) {
sinAngle = angle;
sinValue = type==trigoInt16?sin16(65536.0f * angle / period) / 32645.0f:
type==trigoInt8?(sin8(256.0f * angle / period) - 128) / 127.0f:
sinf(DEG_TO_RAD * 360 * angle / period);
} else USER_PRINTF("%d", type); //debug show cache efficiency
return factor * sinValue;
}
int16_t cos(int16_t factor, uint16_t angle, uint16_t period = 360) {
if (cosAngle != angle) {
cosAngle = angle;
cosValue = type==trigoInt16?cos16(65536.0f * angle / period) / 32645.0f:
type==trigoInt8?(cos8(256.0f * angle / period) - 128) / 127.0f:
cosf(DEG_TO_RAD * 360 * angle / period);
} else USER_PRINTF("%d", type); //debug show cache efficiency
return factor * cosValue;
uint16_t period = 360; //default
Trigo(uint16_t period = 360) {
this->period = period;
}
float sinValue[3]; uint16_t sinAngle[3] = {UINT16_MAX,UINT16_MAX,UINT16_MAX}; //caching of sinValue=sin(sinAngle) for pan, tilt and roll
float cosValue[3]; uint16_t cosAngle[3] = {UINT16_MAX,UINT16_MAX,UINT16_MAX}; //caching of cosValue=cos(cosAngle) for pan, tilt and roll
virtual float sinBase(uint16_t angle) {return sinf(M_TWOPI * angle / period);}
virtual float cosBase(uint16_t angle) {return cosf(M_TWOPI * angle / period);}
int16_t sin(int16_t factor, uint16_t angle, uint8_t index = 0) {
if (sinAngle[index] != angle) {sinAngle[index] = angle; sinValue[index] = sinBase(angle);} else USER_PRINTF("s");
return factor * sinValue[index];
};
int16_t cos(int16_t factor, uint16_t angle, uint8_t index = 0) {
if (cosAngle[index] != angle) {cosAngle[index] = angle; cosValue[index] = cosBase(angle);} else USER_PRINTF("c");
return factor * cosValue[index];
};
// https://msl.cs.uiuc.edu/planning/node102.html
Coord3D rotateRoll(Coord3D in, Coord3D middle, uint16_t roll) {
Coord3D pan(Coord3D in, Coord3D middle, uint16_t angle) {
Coord3D inM = in - middle;
Coord3D out;
out.x = cos(inM.x, roll) - sin(inM.y, roll);
out.y = sin(inM.x, roll) + cos(inM.y, roll);
out.z = inM.z;
out.x = cos(inM.x, angle, 0) + sin(inM.z, angle, 0);
out.y = inM.y;
out.z = - sin(inM.x, angle, 0) + cos(inM.z, angle, 0);
return out + middle;
}
Coord3D rotatePan(Coord3D in, Coord3D middle, uint16_t pan) {
Coord3D tilt(Coord3D in, Coord3D middle, uint16_t angle) {
Coord3D inM = in - middle;
Coord3D out;
out.x = cos(inM.x, pan) + sin(inM.z, pan);
out.y = inM.y;
out.z = - sin(inM.x, pan) + cos(inM.z, pan);
out.x = inM.x;
out.y = cos(inM.y, angle, 1) - sin(inM.z, angle, 1);
out.z = sin(inM.y, angle, 1) + cos(inM.z, angle, 1);
return out + middle;
}
Coord3D rotateTilt(Coord3D in, Coord3D middle, uint16_t tilt) {
Coord3D roll(Coord3D in, Coord3D middle, uint16_t angle) {
Coord3D inM = in - middle;
Coord3D out;
out.x = inM.x;
out.y = cos(inM.y, tilt) - sin(inM.z, tilt);
out.z = sin(inM.y, tilt) + cos(inM.z, tilt);
out.x = cos(inM.x, angle, 2) - sin(inM.y, angle, 2);
out.y = sin(inM.x, angle, 2) + cos(inM.y, angle, 2);
out.z = inM.z;
return out + middle;
}
Coord3D rotate(Coord3D in, Coord3D middle, uint16_t pan, uint16_t tilt, uint16_t roll) {
return rotateRoll(rotateTilt(rotatePan(in, middle, pan), middle, tilt), middle, roll);
Coord3D rotate(Coord3D in, Coord3D middle, uint16_t panAngle, uint16_t tiltAngle, uint16_t rollAngle, uint16_t period = 360) {
this->period = period;
for (int i=0; i<3;i++) sinAngle[i] = UINT16_MAX;
return roll(tilt(pan(in, middle, panAngle), middle, tiltAngle), middle, rollAngle);
}
};

struct Trigo16: Trigo { //FastLed sin16 and cos16
using Trigo::Trigo;
float sinBase(uint16_t angle) {return sin16(65536.0f * angle / period) / 32645.0f;}
float cosBase(uint16_t angle) {return cos16(65536.0f * angle / period) / 32645.0f;}
};
struct Trigo8: Trigo { //FastLed sin8 and cos8
using Trigo::Trigo;
float sinBase(uint16_t angle) {return (sin8(256.0f * angle / period) - 128) / 127.0f;}
float cosBase(uint16_t angle) {return (cos8(256.0f * angle / period) - 128) / 127.0f;}
};


class Fixture; //forward

Expand Down
7 changes: 5 additions & 2 deletions src/App/LedModEffects.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,11 @@ class LedModEffects:public SysModule {
return true;
case f_ChangeFun:
//initiate projectAndMap
fixture.projections[rowNr]->doMap = true; //Guru Meditation Error: Core 1 panic'ed (StoreProhibited). Exception was unhandled.
fixture.doMap = true;
USER_PRINTF("proCenter %d %d\n", rowNr, fixture.projections.size());
if (rowNr < fixture.projections.size()) {
fixture.projections[rowNr]->doMap = true; //Guru Meditation Error: Core 1 panic'ed (StoreProhibited). Exception was unhandled.
fixture.doMap = true;
}
// ui->setLabel(var, "Size");
return true;
default: return false;
Expand Down
7 changes: 4 additions & 3 deletions src/App/LedModFixtureGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,12 @@ class GenFix {

for (int i=0; i<ledCount; i++) {
Coord3D pixel;
pixel.x = middle.x + trigo.sin(ringDiam, i, ledCount);
pixel.y = middle.y + trigo.cos(ringDiam, i, ledCount);
trigo.period = ledCount; //rotate uses period 360 so set to ledCount
pixel.x = middle.x + trigo.sin(ringDiam, i);
pixel.y = middle.y + trigo.cos(ringDiam, i);
pixel.z = middle.z;

write3D( trigo.rotate(pixel, middle, pan, tilt, roll));
write3D( trigo.rotate(pixel, middle, pan, tilt, roll, 360));
}
closePin();
}
Expand Down

0 comments on commit 49cbd13

Please sign in to comment.