Stelling van Pythagoras?

Moderators: dirkwb, Xilvo

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

ja klopt.... ik moet het allemaal nog na lopen.... eerst had ik alles X1000 gedaan.... dan was ik ook een beetje alle kommas kwijt.... maar ja , er komt steeds meer rekenwerk in, en nu dus de asin, dus ben nu het aan het na lopen, en daar waar het nodig is ben ik ze aan het vervangen....


en ik weet ook niet of die arduino het allemaal aan kan... misschien moet ik wel naar een zwaardere sneller micro processor toe....

Ik ben nog een beetje uit de oude tijd, dat je probeerde zo min mogelijk float getallen te gebruiken, omdat de meeste plc/micro processors het daar altijd zwaarder mee hebben....

moet ook een beetje zeggen dat ik een beetje ingehaald ben door de tijd... (ik programmeerde de z80 in assembly) ik heb geen idee meer hoe die compilers er mee omgaat... en of dat ze trager worden met float getallen, of dat het veel ruime vreet? maar zal haast wel....

maar ik zie al wel nu, dat het beter beweegt... eers had ik bij een lange verplaatsing bijvoorbeeld horizontaal, het frame toch schuin ging hangen.... en dat is nu veel minder.....
ben nu ook iets aan het maken, dat ik het object, precies in de midden kan hangen, want dat is ook wel belangrijk....

wil ook nog iets maken , dat hij de (belangrijke) coordinaaten ergens in het flash geheugen zet.... dat hij, als ik hem aan zet weet waar die is...

kortom...werk zat... :-) maar vind het altijd leuk mezelf een doel te stellen..... dat ik ergens naar toe probeer te werken....

Berichten: 463

Re: Stelling van Pythagoras?

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.

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

Ik ga het weer bekijken.....

maar ik heb nog een paar vragen wat ik even niet snap...

ik gebruik dit om te roteren om de x-as:

Code: Selecteer alles

void matrixRotX (float X, float Y , float Z , float Xrot, int Motnr ) {

  // Vectoren/punten hebben 4 elementen ipv 3: [X Y Z 1]
  //  Origineel[3] := 1.0;

  float Origineel[4]  ;
  float Getransformeerd[4];
  float Matrix[4][4];

  Xrot=Xrot/100;

  //    [ 1,         0,          0, 0]
  //    [ 0, cos(xrot), -sin(xrot), 0]
  //    [ 0, sin(xrot),  cos(xrot), 0]
  //    [ 0,         0,          0, 1]

  Matrix[0][0] = 1.0;
  Matrix[0][1] = 0.0;
  Matrix[0][2] = 0.0;
  Matrix[0][3] = 0.0;

  Matrix[1][0] = 0.0;
  Matrix[1][1] = cos(Xrot);
  Matrix[1][2] = -sin(Xrot);
  Matrix[1][3] = 0.0;

  Matrix[2][0] = 0.0;
  Matrix[2][1] = sin(Xrot);
  Matrix[2][2] = cos(Xrot);
  Matrix[2][3] = 0.0;

  Matrix[3][0] = 0.0;
  Matrix[3][1] = 0.0;
  Matrix[3][2] = 0.0;
  Matrix[3][3] = 1.0;

  Origineel[0] = X;
  Origineel[1] = Y;
  Origineel[2] = Z;
  Origineel[3] = 1.0;

  for (int i = 0; i <= 3; i++)
  {
    Getransformeerd[i]  = (Origineel[0] * Matrix[0][i]) + (Origineel[1] * Matrix[1][i]) + (Origineel[2] * Matrix[2][i]) + (Origineel[3] * Matrix[3][i]);
  }

  Getransformeerd[0] = Getransformeerd[0] / Getransformeerd[3];
  Getransformeerd[1] = Getransformeerd[1] / Getransformeerd[3];
  Getransformeerd[2] = Getransformeerd[2] / Getransformeerd[3];

//  SerialUSB.print(Getransformeerd[0] );
//  SerialUSB.print(" - ");
//  SerialUSB.print(Getransformeerd[1] );
//  SerialUSB.print(" - ");
//  SerialUSB.println(Getransformeerd[2] );

  ObjectCorner[Motnr].X = Getransformeerd[0];
  ObjectCorner[Motnr].Y = Getransformeerd[1];
  ObjectCorner[Motnr].Z = Getransformeerd[2];

};
en dat werkt...

voor rotatie om de Y-as gebruik ik:

Code: Selecteer alles

void matrixRotY (float X, float Y , float Z , float Yrot, int Motnr ) {

  // Vectoren/punten hebben 4 elementen ipv 3: [X Y Z 1]
  //  Origineel[3] := 1.0;

  float Origineel[4]  ;
  float Getransformeerd[4];
  float Matrix[4][4];

  Yrot=Yrot/100;

  //    [ cos(yrot), 0, sin(yrot), 0]
  //    [         0, 1,         0, 0]
  //    [-sin(yrot), 0, cos(yrot), 0]
  //    [         0, 0,         0, 1]

  Matrix[0][0] = cos(Yrot);
  Matrix[0][1] = 0.0;
  Matrix[0][2] = sin(Yrot);
  Matrix[0][3] = 0.0;

  Matrix[1][0] = 0.0;
  Matrix[1][1] = 1.0;
  Matrix[1][2] = 0.0;
  Matrix[1][3] = 0.0;

  Matrix[2][0] = -sin(Yrot);
  Matrix[2][1] = 0.0;
  Matrix[2][2] = cos(Yrot);
  Matrix[2][3] = 0.0;

  Matrix[3][0] = 0.0;
  Matrix[3][1] = 0.0;
  Matrix[3][2] = 0.0;
  Matrix[3][3] = 1.0;

  Origineel[0] = X;
  Origineel[1] = Y;
  Origineel[2] = Z;
  Origineel[3] = 1.0;

  for (int i = 0; i <= 3; i++)
  {
    Getransformeerd[i]  = (Origineel[0] * Matrix[0][i]) + (Origineel[1] * Matrix[1][i]) + (Origineel[2] * Matrix[2][i]) + (Origineel[3] * Matrix[3][i]);
  }

  Getransformeerd[0] = Getransformeerd[0] / Getransformeerd[3];
  Getransformeerd[1] = Getransformeerd[1] / Getransformeerd[3];
  Getransformeerd[2] = Getransformeerd[2] / Getransformeerd[3];

//  SerialUSB.print(Getransformeerd[0] );
//  SerialUSB.print(" - ");
//  SerialUSB.print(Getransformeerd[1] );
//  SerialUSB.print(" - ");
//  SerialUSB.println(Getransformeerd[2] );

  ObjectCorner[Motnr].X = Getransformeerd[0];
  ObjectCorner[Motnr].Y = Getransformeerd[1];
  ObjectCorner[Motnr].Z = Getransformeerd[2];
  
};
en ook die werkt....

maar dan roteren om de z-as, heb ik dit:

Code: Selecteer alles

void matrixRotZ (float X, float Y , float Z , float Zrot, int Motnr ) {

  // Vectoren/punten hebben 4 elementen ipv 3: [X Y Z 1]
  //  Origineel[3] := 1.0;

  float Origineel[4]  ;
  float Getransformeerd[4];
  float Matrix[4][4];

  Zrot=Zrot/100;

//      [ cos(zrot), -sin(zrot), 0, 0]
//      [ sin(zrot),  cos(zrot), 0, 0]
//      [         0,          0, 1, 0]
//      [         0,          0, 0, 1]

  Matrix[0][0] = cos(Zrot);
  Matrix[0][1] = -sin(Zrot);
  Matrix[0][2] = 0.0;
  Matrix[0][3] = 0.0;

  Matrix[1][0] = sin(Zrot);
  Matrix[1][1] = cos(Zrot);
  Matrix[1][2] = 0.0;
  Matrix[1][3] = 0.0;

  Matrix[2][0] = 0.0;
  Matrix[2][1] = 0.0;
  Matrix[2][2] = 1.0;
  Matrix[2][3] = 0.0;

  Matrix[3][0] = 0.0;
  Matrix[3][1] = 0.0;
  Matrix[3][2] = 0.0;
  Matrix[3][3] = 1.0;

  Origineel[0] = X;
  Origineel[1] = Y;
  Origineel[2] = Z;
  Origineel[3] = 1.0;

  for (int i = 0; i <= 3; i++)
  {
    Getransformeerd[i]  = (Origineel[0] * Matrix[0][i]) + (Origineel[1] * Matrix[1][i]) + (Origineel[2] * Matrix[2][i]) + (Origineel[3] * Matrix[3][i]);
  }

  Getransformeerd[0] = Getransformeerd[0] / Getransformeerd[3];
  Getransformeerd[1] = Getransformeerd[1] / Getransformeerd[3];
  Getransformeerd[2] = Getransformeerd[2] / Getransformeerd[3];

//  SerialUSB.print(Getransformeerd[0] );
//  SerialUSB.print(" - ");
//  SerialUSB.print(Getransformeerd[1] );
//  SerialUSB.print(" - ");
//  SerialUSB.println(Getransformeerd[2] );

  ObjectCorner[Motnr].X = Getransformeerd[0];
  ObjectCorner[Motnr].Y = Getransformeerd[1];
  ObjectCorner[Motnr].Z = Getransformeerd[2];

};
maar die gaat fout.... en ik weet even niet waar dat aan ligt?

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.
nou ik merk nog niet veel van de snelheid... ik heb voorlopig bijna overal float variabelen van gemaakt....
en ik wil eerst alee beweging er goed in hebben.... dan ga ik pas kijken hoe snel ik hem kan krijgen..... maar denk dat die tennisbal , niet gaat lukken.... :-)
(

maar helemaal onder aan, waar ik uitreken hoeveel stappen de stappen motor moet maken, (ik heb 250 pulsjes per mm) daar rond ik de float eerst af dmv +0,5 en dan * 250 , daar maak ik dan pas weer een long van....


wat ik ook nog niet helemaal snap,... in dat filmpje... dat hij automatisch beweegt, stuur ik hem naar x=30 en x=-30, en z=30 en z=-30, y=30 en y=-30... en ook roteren om X en om Y geeft ik beide het zelfde waarde...

maar In de z-richting beweegt hij volgens mij meer, als in de x en de y richting....

en met roteren ook...rond om de y-as lijkt hij veel meer te bewegen, als om de x-as... en dat snap ik ook nog niet helemaal?

Berichten: 463

Re: Stelling van Pythagoras?

Swets schreef: ma 29 nov 2021, 21:39 maar dan roteren om de z-as, heb ik dit:
...
maar die gaat fout....
Rotaties om de z-as zijn ook bijna niet mogelijk.
Hier een bovenaanzicht van het systeem in de ruststand, met
- zwart de bovenkant van het frame (PQRS), met de groene diagonaal
- blauw de onderkant van het blok (ABCD), met de blauwe diagonaal
- rood de kabels van het blok naar het frame

wtf_z-rotaties1.png

Kabels AP en CR kunnen het blok maximaal roteren tot aan het punt dat de diagonalen samenvallen.
De groene diagonaal staat onder een hoek van atan(202.87/324.87) = 31.98°,
de blauwe onder een hoek van atan(48/118) = 22.14°.
Rotaties om de z-as zijn nu dus maar mogelijk tot 31.98° - 22.14° = 9.84°

Hier een plaatje als het blok om de z-as zou kunnen roteren van 0° t/m 20°:
wtf_z-rotaties2.png

En hier de bijbehorende (benaderde) 3D-kabellengtes:

Code: Selecteer alles

hoek:	AP=CR:  	BQ=DS:
0	204.1053	204.1053
1	203.9358	204.2926
2	203.7842	204.4975
3	203.6506	204.7200
4	203.5349	204.9600
5	203.4374	205.2172
6	203.3581	205.4916
7	203.2969	205.7830
8	203.2540	206.0912
9	203.2294	206.4161
10	203.2230	206.7575
11	203.2350	207.1153
12	203.2652	207.4891
13	203.3136	207.8789
14	203.3803	208.2843
15	203.4652	208.7053
16	203.5682	209.1415
17	203.6893	209.5928
18	203.8284	210.0589
19	203.9855	210.5396
20	204.1604	211.0346
Bij rotaties boven de 9.84° worden alle kabellengtes langer, dus als in dat geval het blok iets terugdraait houden alle kabels ruimte over en zal het blok door de zwaartekracht dalen (richting negatieve z-as) totdat een nieuwe evenwichtsstand bereikt worden.
De andere 4 kabels lopen van de bovenkant van het blok naar de onderkant van het frame, dus die kunnen de werking van de zwaartekracht dus ook niet opheffen.

Wat je ook nog ziet is dat de sturing van de rotatie zeer nauwkeurig zal moeten: kabels AP en CR veranderen slechts enkele 0.1 tot enkele 0.01 eenheden per graad (steeds kleiner richting de maximale z-as rotatie).

De beperkte z-as rotatie zie je ook terug in dat filmpje met de Offenbach-muziek: het blok kantelt wel om de x-as en om de y-as, maar nauwelijks om de z-as: het voorvlak (met de tekst erop) blijft bij frontaal framebeeld altijd goed zichtbaar.

Daarentegen zijn rotaties om de x-as en om de y-as veel beter te doen. De kabels lopen daarbij steeds twee-aan-twee gekruist: bovenkant frame naar onderkant blok en onderkant frame naar bovenkant blok.
Hierdoor worden de rotatiemogelijkheden (= de maximale rotatiehoeken) groter en is de rotatie-besturing minder gevoelig,

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

ja, en als ik zo je verhaal lees, snap ik het nog ook, en snap ik ook ff niet waarom ik het zelf niet zag...

want dat gebeurde er ook, hij draaide een stukje de ene kant op... en dan begint het op een gegeven moment te zakken, en schuin te hangen....

maar tis ook, als je zit te kijken gebeurt er zoveel tegelijk, dat je het niet voor kan kijken..... :-)

en een groter buitenframe? zou dat helpen?
of, als ik hem eerst verschuif in X, of Y....
moet ik ff beredeneren...

maar dat matrix verhaal is dus gewoon goed....
tis best wel pittige stof voor mijn LTS wiskunde... die matrixen... nooit les ingehad ... en al die gekke haken... :-)
vind het wel geinig hoe dat allemaal werkt.....

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

net nog even in me solidworks verhaaltje zitten kijken...

en inderdaad.... zou wel gaan als het echt stangen waren, zoals in mijn solidworks animatie (solid works, en draadjes is heel lastig, dus ik had stangen gemaakt....)

maar je kan niet duwen tegen een draadje....
volgens mij wel, hoe breder het objec, hoe meer je kan draaien om de z-as?

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

ik zit nu ook even te kijken naar het bewegen, en snap nu ook bijvoorbeeld, waarom hij bij het draaien om de Y-as de magneetjes soms los trok... ook omdat ik te ver wilde draaien...



ook in dit filmpje, valt me nu op , dat ze maar heel weinig om de z-as draaien..(bij 38 sec)...

Berichten: 463

Re: Stelling van Pythagoras?

Swets schreef: ma 29 nov 2021, 21:52 ... maar helemaal onder aan, waar ik uitreken hoeveel stappen de stappen motor moet maken, (ik heb 250 pulsjes per mm) daar rond ik de float eerst af dmv +0,5 en dan * 250 , daar maak ik dan pas weer een long van ...
Als die float de nauwkeurige waarde is, dan moet dit wellicht de volgorde zijn (?):
- eerst vermenigvuldigen (= * 250)
- dan pas die 0.5 erbij optellen (= + 0,5)
- tenslotte er een long van maken.

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

RedCat schreef: wo 01 dec 2021, 09:43
Swets schreef: ma 29 nov 2021, 21:52 ... maar helemaal onder aan, waar ik uitreken hoeveel stappen de stappen motor moet maken, (ik heb 250 pulsjes per mm) daar rond ik de float eerst af dmv +0,5 en dan * 250 , daar maak ik dan pas weer een long van ...
Als die float de nauwkeurige waarde is, dan moet dit wellicht de volgorde zijn (?):
- eerst vermenigvuldigen (= * 250)
- dan pas die 0.5 erbij optellen (= + 0,5)
- tenslotte er een long van maken.
oja... hmmm dat is beter... ( pas aan het einde afronden.... heb ik 35 jaar geleden op school geleerd... :-) )

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

ik heb hem even wat sneller gemaakt:


maar ik heb nog wel een mee denk vraag.... wat best wel een lastig (althans voor mij :D ) verhaal is

dat is het verdelen van de pulsen naar de motors....

https://www.dropbox.com/s/w0zrqyeuhv3uo ... 1.png?dl=0

als je het bovenstaande screenshot bekijk....

ehh hoe ga ik dat allemaal opschrijven.....

in dit screenshot, zie je een verplaatsing over de z-as....
bovenin, zie je hoelang de nieuwe draden moeten worden.... (op dit moment hangt het object in de midden, en zijn alle draden 256.37 mm , total Steps :64091.35 )
motor 1,2,3 en 4 zijn de bovenste motors, moeten korter worden, en moeten worden 232.10
motor 5,6,7,en, zijn de onderste motoren , moeten langer worden, en moeten 282.61 mm worden...

dan ga ik uitreken, huidige lengte - wanted lengte... van elke motor....

dan heb ik dus 8 verplaatsings lengtes.... die ga ik sorteren , zodat in mijn array, de langste bovenaan heb, en de kortste onderaan...

daarna eeeh... deel ik 100.0 door de langste verplaatsing... ( dat is die 0.02 die je ziet staan , maar ik doe net 100/6562 =0,01523, dus waarom hij daar nu 0,02 van maakt? )


en oja, voor ik naar de onderstaande functie toe sprint, doe ik eerst bij alle motors, de verplaatsing in procenten uit rekenen...

dus de langste was 100/6562 =0,01523 , dus zo korter is 6067x0,01523 = 92,400

dus ik weet hoeveel procent elke motor moet verplaatsen...

en dan dus 8 keer de onderstaande functie....
(de vorige filmpjes , stond die StepSpeed op 1000)

die pulse, is een puls uit de hoofdlus, die elke cyclus door pulse=pulse xor 1 omgekeerd word....

Code: Selecteer alles

void Motor1() {
  pulse1 = 0;
  if (Mot1On == 1)
  {
    if (pulse == 1)
    {
      if (Mot1WantedLength != Mot1ActualLength) {

        if (Mot1PulseCounter >= (StepSpeed / mot1PulseProcent) )
        {
          pulse1 = 1;
          Mot1PulseCounter = 0;

          if (Mot1Direction == 1)
          {
            Mot1ActualLength = Mot1ActualLength + 1;
          }
          else
          {
            Mot1ActualLength = Mot1ActualLength - 1;
          };
        };
      };

      Mot1PulseCounter = Mot1PulseCounter + 1;

      digitalWrite(oDir1, Mot1Direction);
      digitalWrite(oStep1, pulse1);
    };
  };
};

ehhh ja wat is nu de vraag..... ik wil dus eigenlijk dat motors tegelijk klaar zijn... maar ik kan geen halve pulsen geven ....

als ik die StepSpeed op 1000 zet, dan de langste verplaatsing (= 100%) stuurt elke 10de puls naar de motor
de kortere verplaatsing (=92) 1000/92 = 10.86

tis wel zo hoe groter ik die StepSpeed maak, hoe nauwkeuriger het word... maar ook hoe trager....

en ik heb het net op 250 gehad, en als ik hem dan automatisch laat bewegen.. gaat het snel, en goed...

maar ja de vraag.... ja hoe kan ik nu het beste de pulsje verdelen? ook hier weer , misschien doe ik het wel weer helemaal verkeerd?

ik zit er een beetje mee, als ik hem op 1000 zet, krijgt ook de motor met de grootste verplaatsing elke 10 pulsje....

maar zet ik hem op 250, 250/100=2,5 , maar het is een int, dus krijgt hij elke 2de puls... 250/92=2,7

ben er nog niet helemaal uit hoe ik dat nu het beste kan doen.... pfff

Berichten: 463

Re: Stelling van Pythagoras?

wtf_cablesteps.png
wtf_cablesteps.png (7.21 KiB) 1209 keer bekeken
Hier een 2D versie van een tijdsgebonden beweging.
De roosterlijnen hebben een onderlinge afstand van 10cm, het frame is de zwarte rechthoek.
De punten zijn de posities van het blokcentrum, vooralsnog laat ik kantelingen van het blok buiten beschouwing.
Het hoofdprogramma (= main code) ziet er zo uit:

Code: Selecteer alles

// init globale variabelen:
blockx=0;
blocky=0;
blockz=0;
steplength = 3.9;

// beweeg:
lineto(-40,30,10); // lijnrecht naar punt (-40,30), met snelheid 10 cm/sec
circle(-10,0,2*pi/3,30); // cirkelvormig om middelpunt (-10,0) over een hoek van (2/3)*pi (tegen de klok in) met snelheid 30 cm/sec
lineto(80,20,20); // lijnrecht naar punt (80,20) met snelheid 20 cm/sec
circle(40,10,-pi,10); // cirkelvormig om middelpunt (40,10) over een hoek van -pi (=pi met klok mee) met snelheid 10 cm/sec
blokx, bloky en blokz zijn de x-, y- en z-positie van het blokcentrum,
steplength is de maximale inkorting die een individuele kabel kan maken zonder dat de magneet losschiet, hier op 3.9 cm gezet, maar die zal in werkelijkheid veel kleiner zijn. Een grotere staplengte mag niet, dan schiet de kabel los, een kleinere staplengte levert meer rekenwerk en een kortere lustijd (waarin je je hele update moet afhandelen) op.
lineto() en circle() handelen de volledige beweging af in tijd:

Code: Selecteer alles

void lineto(double x, double y, double speed)
{
double DX=x-blockx;
double DY=y-blocky;
double L=sqrt(DX*DX+DY*DY);
double steptime = steplength/speed;
double dx=DX*steplength/L;
double dy=DY*steplength/L;
int nsteps=(int)(L/steplength); // geheel aantal stappen dat nodig is
double rest=L-nsteps*steplength; // het restgedeelte van de beweging (< 1 stap)

// handel eerst alle volledige stappen af:
for(int s=0;s<nsteps;s++){
  blockx+=dx;
  blocky+=dy;
  grid->drawDot(blockx,blocky,5,clRed); // UPDATE HIER DE 8 KABELLENGTES
  Sleep((int)(steptime*1000.0));
  }
// handel tenslotte de rest af:
if(rest>0.0){
  blockx=x;
  blocky=y;
  grid->drawDot(blockx,blocky,5,clRed); // UPDATE HIER DE 8 KABELLENGTES
  Sleep((int)(steptime*1000.0));
  }
}
(in jouw code zal double een float zijn en int een long datatype)

Code: Selecteer alles

void circle(double mx, double my, double angle, double speed)
{
int dir=1;
if(angle<0){
  dir=-1;
  angle=-angle;
  }
double DX=blockx-mx;
double DY=blocky-my;
double R=sqrt(DX*DX+DY*DY);
double theta0;
if(DX>=0.0)
  theta0=asin(DY/R);
else
  theta0=pi-asin(DY/R);
double stepangle = steplength/R;;
double steptime = steplength/speed;
int nsteps=(int)(angle/stepangle);
double rest = angle-nsteps*stepangle;
double theta = theta0;
stepangle=dir*stepangle;

for(int s=0;s<nsteps;s++){
  theta+=stepangle;
  blockx=mx+R*cos(theta);
  blocky=my+R*sin(theta);
  grid->drawDot(blockx,blocky,5,clBlue); // UPDATE HIER DE 8 KABELLENGTES
  Sleep((int)(steptime*1000.0));
  }
if(rest>0.0){
  theta=theta0 + dir*angle;
  blockx=mx+R*cos(theta);
  blocky=my+R*sin(theta);
  grid->drawDot(blockx,blocky,5,clBlue); // UPDATE HIER DE 8 KABELLENGTES
  Sleep((int)(steptime*1000.0));
  }
}
Als je het centrum weet, dan kan je de hoekpunten van het blok berekenen en van daaruit de 8 kabellengtes in floats, die afronden naar aantal staplengtes van de stappenmoter, per motor dit nieuwe aantal staplengtes vergelijken met het huidige aantal staplengtes, en alle motors (zo nodig) updaten.
steptime heb ik hier berekend in seconden, Sleep(t) geeft een delay van t ms.
Daar moet je dan de tijd die je stappenmotors voor de update hebben nog van af trekken.
Die totale tijd mag niet onder nul komen. Je moet je snelheid dus zodanig kiezen (niet te groot) dat dat niet gebeurt.

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

Bedankt.... ga het ff goed door lezen.... moet het allemaal weer even in laten dalen.... :-)

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

ik ga het weer eens bekijken.... nog maar een keer lezen... kijken of ik het snap....

Gebruikersavatar
Berichten: 96

Re: Stelling van Pythagoras?

pff... kwartje wil nog niet helemaal vallen....

snap niet helemaal wat je hier doet?
grid->drawDot(blockx,blocky,5,clBlue); // UPDATE HIER DE 8 KABELLENGTES

wat is dat grid... sorry hoor....

Reageer