Stelling van Pythagoras?

Moderators: dirkwb, Xilvo

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

Hoi,

ja maar ik moet even zwaar denken hoe ik dat het beste op ga lossen....

want ik had nu iets gemaakt, dat hij die procenten lengtes om de x tijd opnieuw bepaald...
en dat ging best goed, zolang ik hem maar via 0,0,0 stuurt.... stuur ik heb van -30 naar 30 gaat het fout....

maar dat komt omdat als hij op -30 staat, en je stuurt hem naar 30 moet de draadjes (sommige) eerst korter worden, en zodra hij over de 0 gaat weer langer....

dus dat gaat niet werken.... maar ik denk al dat ik iets moet maken... stel hij staat op -30 en ik wil hem naar 30 hebben, dat ik dan niet in 1 keer de lengte uit reken van -30 naar 30... maar dat ik eerst naar -20 ga, dan naar -10 dan naar 0, dan naar 10 enz enz...

want nu heb ik ook een beetje.... zodra hij gaat bewegen , weet ik eigenlijk niet meer waar die is... ehh hoe zeg ik dat....

ik heb zeg maar in het begin, de 8 hoekpunten op geslagen in een array, dmv eigenlijk het hart van het object, in het hart van het frame...
dan kan dmv de stelling van pythagoras de lengte van de touwtjes uit rekenen....

dan geef ik een command Z naar 30.... dan gaat hij dmv een matrix, de 8 hoekpunten 30 omhoog schuiven...
dan reken die nieuwe lengtes uit....

ik weet de actuele lengtes, en ik weet wat ze moeten worden als hij naar 30 moet...

maar op het moment hij begint te bewegen... weet ik alleen de lengtes van de touwtjes...en terug rekenen vanuit de lengte van de touwjes terug naar de hoekpunten weet ik eigenlijk niet of het kan.... en ik weet ook even niet of ik daar iets aan heb... :-)

kortom ik zit een beetje vast.... :-) maar ik denk eerst maar eens iets ga maken, waarbij tussen gewenst en actueel in stappen ga verdelen.....

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

trouwens die serial.print met die komma werkt....
ik had ook al een keer het getal *1000 gedaan voor het printen... om het te checken....

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

RedCat schreef: ma 29 nov 2021, 20:09
Swets schreef: ma 29 nov 2021, 12:17 ... maar ja , er komt steeds meer rekenwerk in, en nu dus de asin ...
Als het je om snelheid gaat, dan kunnen we waarschijnlijk veel winst behalen met een grovere benadering voor asin(), zie bijvoorbeeld
https://seblagarde.wordpress.com/2014/1 ... hitecture/

De asin() functie is in dat artikel een uitbreiding van de acos() functie. Als we onze formule omzetten naar acos() (in plaats van asin()) zijn we hiermee dus nog sneller:
\(\small ∠KML = \pi - ∠KMB - ∠BMP = \pi - acos\left(\frac{MK}{BM}\right) - acos\left(\frac{abs(mz-bz)}{BM}\right) \)

Hier werken we met hoeken van 0 .. pi/2 (= van 0° .. 90°), aangenomen dat de onderkant van het blok nooit boven het middelpunt van de bovenste katrol uit zal komen.
Daarom kunnen we de benaderingsformules van dat artikel nog verder vereenvoudigen:

Code: Selecteer alles

// IN: 0 <= x <= 1  
// UIT: acos(x), maximale fout 0.0061
float acos1(float x)
{
return((-0.155972*x+1.56467)*sqrt(1.0f-x));
}

Code: Selecteer alles

// IN: 0 <= x <= 1  
// UIT: acos(x), maximale fout 0.00061
float acos2(float x)
{
return(((0.0464619*x-0.201877)*x+1.57018)*sqrt(1.0f-x));
}

Code: Selecteer alles

// IN: 0 <= x <= 1  
// UIT: acos(x), maximale fout 0.000071
float acos3(float x)
{
return((((-0.0186166*x+0.0740935)*x-0.212053)*x+1.57073)*sqrt(1.0f-x));
}
acos1() heeft een maximale fout van 0.0061, acos2() van 0.00061 en acos3() van 0.000071.
Omdat we die functie in onze formule 2 keer nodig hebben, en de cirkelstraal van het katrolwiel 12.49 is,
zijn de maximale fouten in de draadlengte bij
- acos1(): 0.0061 * 2 * 12.49 = 0.15
- acos2(): 0.00061 * 2 * 12.49 = 0.015
- acos3(): 0.000071 * 2 * 12.49 = 0.0018
Afhankelijk van de nauwkeurigheid van je motor kan je de optimale acos() kiezen.

Als ik op mijn desktop acos() in een lus 10^9 keer aanroep, dan dit duurt bij:
- acos1() 2.25 sec
- acos2() 2.48 sec
- acos3() 2.76 sec
terwijl de normale acos() (wel met double nauwkeurigheid) hier 52.8 sec over doet.

De bulk van het werk in de 3 benaderingsformules wordt waarschijnlijk veroorzaakt door de sqrt() berekening erin; de extra vermenigvuldigen, elk met factor 10 nauwkeurigheidswinst, lijken er niet zo toe te doen.
Alle 3 zijn ze wel zo'n 20 keer sneller dan de ingebouwde acos() functie.

Ik heb geen arduino, maar je kan zelf testen wat daarop de snelheidsverschillen zijn.
Ditzelfde kan je doen voor optellen, vermenigvuldigen etc. van float getallen versus long getallen.

Mocht je nog in assembly programmeren: het artikel geeft bovenstaande functies ook in een assembly vorm.
ik wil wel eens kijken wat het uitmaak.... maar ik heb dit al 3 keer door gelezen.... maar nu hoe ik het moet toepasen....
?

Code: Selecteer alles

long Mot1(float X, float Y, float Z)
{
  // z,y,z uit rekenen van uit main x,y,z
  // x,y,z van hoek 1
  long result;

  float XCorner1 = -(LengthFrame / 2.0);
  float yCorner1 = -(WidhtFrame / 2.0);
  float zCorner1 = (HighFrame / 2.0);

  float Mot1LengthX = XCorner1 - X;
  float Mot1lengthY = yCorner1 - Y;
  float Mot1lengthZ = zCorner1 - Z;

  float DB = Pythagoras(Mot1lengthY, Mot1LengthX, Mot1lengthZ);

  float BP = DB - (DiaKatrol / 2.0);
  float MP = zCorner1 - Z;

  float BM = Pythagoras(MP, BP, 0);

  float BK = Pythagoras(BM, (DiaKatrol / 2.0), 0);

  float hoekKLM = phi - asin(BK / BM) - asin(BP / BM);

  float KL = (DiaKatrol / 2.0) * hoekKLM;

  float Mot1Length = BK + KL;

  // Serial.print("Length Motor 1 :");
  // Serial.print(Mot1Length);
  // Serial.print("mm, total Steps :");
  // Serial.println(Mot1Length * StepUnit);

  result = ((Mot1Length * StepUnit) + 0.5);
  return result;
};

ik heb deze code voor elke motor...  daar heb ik 2x asin...
maar ik voer dit stuk best wel vaak uit... en natuurlijk voor alle 8 de motoren....



Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

RedCat schreef: ma 29 nov 2021, 20:09
Swets schreef: ma 29 nov 2021, 12:17 ... maar ja , er komt steeds meer rekenwerk in, en nu dus de asin ...
Als het je om snelheid gaat, dan kunnen we waarschijnlijk veel winst behalen met een grovere benadering voor asin(), zie bijvoorbeeld
https://seblagarde.wordpress.com/2014/1 ... hitecture/

De asin() functie is in dat artikel een uitbreiding van de acos() functie. Als we onze formule omzetten naar acos() (in plaats van asin()) zijn we hiermee dus nog sneller:
\(\small ∠KML = \pi - ∠KMB - ∠BMP = \pi - acos\left(\frac{MK}{BM}\right) - acos\left(\frac{abs(mz-bz)}{BM}\right) \)

Hier werken we met hoeken van 0 .. pi/2 (= van 0° .. 90°), aangenomen dat de onderkant van het blok nooit boven het middelpunt van de bovenste katrol uit zal komen.
Daarom kunnen we de benaderingsformules van dat artikel nog verder vereenvoudigen:

Code: Selecteer alles

// IN: 0 <= x <= 1  
// UIT: acos(x), maximale fout 0.0061
float acos1(float x)
{
return((-0.155972*x+1.56467)*sqrt(1.0f-x));
}

Code: Selecteer alles

// IN: 0 <= x <= 1  
// UIT: acos(x), maximale fout 0.00061
float acos2(float x)
{
return(((0.0464619*x-0.201877)*x+1.57018)*sqrt(1.0f-x));
}

Code: Selecteer alles

// IN: 0 <= x <= 1  
// UIT: acos(x), maximale fout 0.000071
float acos3(float x)
{
return((((-0.0186166*x+0.0740935)*x-0.212053)*x+1.57073)*sqrt(1.0f-x));
}
acos1() heeft een maximale fout van 0.0061, acos2() van 0.00061 en acos3() van 0.000071.
Omdat we die functie in onze formule 2 keer nodig hebben, en de cirkelstraal van het katrolwiel 12.49 is,
zijn de maximale fouten in de draadlengte bij
- acos1(): 0.0061 * 2 * 12.49 = 0.15
- acos2(): 0.00061 * 2 * 12.49 = 0.015
- acos3(): 0.000071 * 2 * 12.49 = 0.0018
Afhankelijk van de nauwkeurigheid van je motor kan je de optimale acos() kiezen.

Als ik op mijn desktop acos() in een lus 10^9 keer aanroep, dan dit duurt bij:
- acos1() 2.25 sec
- acos2() 2.48 sec
- acos3() 2.76 sec
terwijl de normale acos() (wel met double nauwkeurigheid) hier 52.8 sec over doet.

De bulk van het werk in de 3 benaderingsformules wordt waarschijnlijk veroorzaakt door de sqrt() berekening erin; de extra vermenigvuldigen, elk met factor 10 nauwkeurigheidswinst, lijken er niet zo toe te doen.
Alle 3 zijn ze wel zo'n 20 keer sneller dan de ingebouwde acos() functie.

Ik heb geen arduino, maar je kan zelf testen wat daarop de snelheidsverschillen zijn.
Ditzelfde kan je doen voor optellen, vermenigvuldigen etc. van float getallen versus long getallen.

Mocht je nog in assembly programmeren: het artikel geeft bovenstaande functies ook in een assembly vorm.
ik wil wel eens kijken wat het uitmaak.... maar ik heb dit al 3 keer door gelezen.... maar nu hoe ik het moet toepasen....
?

Code: Selecteer alles

long Mot1(float X, float Y, float Z)
{
  // z,y,z uit rekenen van uit main x,y,z
  // x,y,z van hoek 1
  long result;

  float XCorner1 = -(LengthFrame / 2.0);
  float yCorner1 = -(WidhtFrame / 2.0);
  float zCorner1 = (HighFrame / 2.0);

  float Mot1LengthX = XCorner1 - X;
  float Mot1lengthY = yCorner1 - Y;
  float Mot1lengthZ = zCorner1 - Z;

  float DB = Pythagoras(Mot1lengthY, Mot1LengthX, Mot1lengthZ);

  float BP = DB - (DiaKatrol / 2.0);
  float MP = zCorner1 - Z;

  float BM = Pythagoras(MP, BP, 0);

  float BK = Pythagoras(BM, (DiaKatrol / 2.0), 0);

  float hoekKLM = phi - asin(BK / BM) - asin(BP / BM);

  float KL = (DiaKatrol / 2.0) * hoekKLM;

  float Mot1Length = BK + KL;

  // Serial.print("Length Motor 1 :");
  // Serial.print(Mot1Length);
  // Serial.print("mm, total Steps :");
  // Serial.println(Mot1Length * StepUnit);

  result = ((Mot1Length * StepUnit) + 0.5);
  return result;
};
ik heb deze code voor elke motor... daar heb ik 2x asin...
maar ik voer dit stuk best wel vaak uit... en natuurlijk voor alle 8 de motoren....
ik heb trouwens dit :

Code: Selecteer alles

  float XCorner1 = -(LengthFrame / 2.0);
  float yCorner1 = -(WidhtFrame / 2.0);
  float zCorner1 = (HighFrame / 2.0);
ook ff ergens aan het begin gezet, by de setup... die hoef natuurlijk niet elke keer uitgerekend te worden.... er varanderd niets aan....

of ik het in assembly doe... pfff vroeger veel in Z80 assembly gewerkt...maar dit is allemaal in c++

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

ik heb er ook ff een Straal bij gemaakt, overal waar ik die diameter gebruik, deel ik hem door 2...
dus dat kunnen we ook beter 1 keer doen....

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

begrijp ik het nu goed?

Code: Selecteer alles

// IN: 0 <= x <= 1  
// UIT: acos(x), maximale fout 0.0061
float acos1(float x)
{
return((-0.155972*x+1.56467)*sqrt(1.0f-x));
}
dit is een soort eigen functie voor acos, die ik dan aanroep ipv de echte acos

en asin?

en in me matrixen gebruik ik voor het draaien ook een cos en een sin
zijn daar ook zoiets voor?

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

Code: Selecteer alles

float acos1(float x)
{
return((-0.155972*x+1.56467)*sqrt(1.0f-x));
}
wat is die f ?

en ik heb nu dit:

Code: Selecteer alles

 float hoekKLM = phi - asin (BK / BM) - asin(BP / BM);
en dat zou moeten worden

Code: Selecteer alles

float hoekKLM= phi - acos(MK/BM)- acos(abs(mz-bz)/BM);
Dat zou al sneller zijn... toch dat begrijp ik er uit....

moet ik nog eens goed kijken waar je die MK vandaan haal, want die variable had ik nog niet... en ook mz-bz?

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

Dus die MK, is het zelfde als de straal van de katrol. en MP=mz-bz dus?

Code: Selecteer alles

float hoekKLM= phi- acos(RadiusPulley/BM) - acos(abs(MP)/BM)
zal ik vannavond eens eerst proberen... hooguit vliegen alle draadjes om me oren... :-)

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

okay, dat werkt dus...

ik heb die asin veranderd in die acos1 en het werkt nog steeds... of het echt sneller is?

bestaat er ook zoiets voor cos en sin? want in die rotatie matrixen gebruik ik die,,,?

Reageer