[IEC 61131] Afronden met integers ipv floats?

Pagina: 1
Acties:

  • Maverick
  • Registratie: Oktober 2001
  • Laatst online: 08:49
Ik heb een (Maxon) motorsturing waarin ik wil rekenen met integers. kan allemaal best, maar nu kwam ik erachter dat als ik 99 deel door 100, dat daar dan 0 uit komt. Niet heel vreemd. Meer talen doen dit. Als ik dit op wil lossen dan zet ik de waarde om naar een float en reken ik het op die manier uit. Echter. Die motorsturing werkt niet met reëele getallen.
Vreemd genoeg schrijft de IEC 61131 standaar wel het gebruik van REAL en LREAL voor. ik kan ze echter niet declareren.

Nu zoek ik eigenlijk een manier om dit toch te kunnen doen. maar wat ik ook voor gekunstel uithaal, ik zal uiteindelijk af moeten ronden....
Kan iemand me helpen aan een manier om zoiets aan te pakken? Of nog beter zelfs, iemand enig idee waarom ik geen reëele variabelen kan declareren.

PSN: DutchTrickle PVoutput


Anoniem: 167624

De standaard manier om a/b met integer deling uit te rekenen en ook af te ronden is door dit te doen: (a+(b/2))/b. Je krijgt dan in jouw voorbeeld (99+50)/100 = 149/100 = 1.

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Meest vookomende reden is dat real/float/double niet beschikbaar zijn op alle hardware (de instructieset mist ondersteuning). Je kan eromheen werken door gewoon integer's te gebruiken. Voor correcte afronding, zie de post hierboven.

En anders heb je nog fixed-point math. Houd dan wel goed rekening met precision en range.

-niks-


  • epic007
  • Registratie: Februari 2004
  • Laatst online: 26-06 16:56
Anoniem: 167624 schreef op donderdag 27 december 2012 @ 15:08:
De standaard manier om a/b met integer deling uit te rekenen en ook af te ronden is door dit te doen: (a+(b/2))/b. Je krijgt dan in jouw voorbeeld (99+50)/100 = 149/100 = 1.
Klopt, dit gaat alleen mis als a negatief is.

  • Maverick
  • Registratie: Oktober 2001
  • Laatst online: 08:49
epic007 schreef op donderdag 27 december 2012 @ 15:21:
[...]

Klopt, dit gaat alleen mis als a negatief is.
Dit.
Hier krijg ik idd mee te maken. Ik zal proberen het probleem wat duidelijker te schetsen.
Ik heb een arm welke beweegt. Hoe hoger de arm, hoe sneller mijn motor moet draaien. Als de arm naar boven gaat dan lees ik die positie uit en als de arm op een bepaalde positie staat dan moet mijn motor versnellen. Als mijn motor de gewenste waarde bereikt heeft (die staat niet altijd vast) dan zal de arm zakken (door de mechanica die aan de arm en motor hangt) totdat hij bij de stand hangt waarbij de analoge waarde nul is. Op dit putn stopt de motor met versnellen en hangt de arm stil. Als door de mechanica weer, de arm door het nulpunt heen zakt, dan zal de motor afremmen om de arm weer naar boven te duwen.

Wat nu het probleem is, als ik mijn waarde door 100 wil delen om de motor langzamer te laten reageren, doet de motor helemaal niets qua sturing zolang de analoge waarde tussen de -100 en 100 zit. Hij schiet hierdoor natuurlijk telkens langs die evenwichtspositie heen en als een gevolg daarvan gaat de arm de hele tijd omhoog en omlaag ipv dat hij zich rond het middelpunt stabiliseert.

Als ik dus (a+b/2)/b gebruik, dan plaats ik het probleemgebied wel op, maar het wordt niets kleiner.

PSN: DutchTrickle PVoutput


  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

In C: "When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded".
Dit is dus afronding richting 0. Om dat te compenseren moet je dus een halve deler van 0 optellen/aftrekken om correcte afronding te krijgen.

-niks-


  • KopjeThee
  • Registratie: Maart 2005
  • Niet online
Ik begrijp dat 99/100=0 niet acceptabel is, omdat het te onnauwkeurig is. Als je meer nauwkeurigheid nodig hebt, kan je bijvoorbeeld die 99 met 10 vermenigvuldigen. Dus 990/100=9. Je weet dan dat er eigenlijk 0.9 staat, omdat je met 10 hebt vermenigvuldigd.

  • Maverick
  • Registratie: Oktober 2001
  • Laatst online: 08:49
KopjeThee schreef op donderdag 27 december 2012 @ 16:06:
Ik begrijp dat 99/100=0 niet acceptabel is, omdat het te onnauwkeurig is. Als je meer nauwkeurigheid nodig hebt, kan je bijvoorbeeld die 99 met 10 vermenigvuldigen. Dus 990/100=9. Je weet dan dat er eigenlijk 0.9 staat, omdat je met 10 hebt vermenigvuldigd.
Dit is natuurlijk waar, het probleem is dat de uitvoer vast staat. Als ik dus jouw warades pak dan moet ik bijvoorbeeld een getal tussen de 0 en 10 uitgeven, zonder decimalen, Dat doe ik dus 0.9*10, wat weer 0 is. Dat is een beetje het probleem, ik zit vast aan een bepaalde waarde voor de uitvoer. Hoevaak ik iets ook vergroot om dit probleem met decimalen te ontwijken, ik moet op het eind die decimalen er weer uitslopen, waardoor ik weer terug bij af ben.

PSN: DutchTrickle PVoutput


  • ThomasG
  • Registratie: Juni 2006
  • Laatst online: 06:40
Maverick schreef op donderdag 27 december 2012 @ 16:35:
[...]


Dit is natuurlijk waar, het probleem is dat de uitvoer vast staat. Als ik dus jouw warades pak dan moet ik bijvoorbeeld een getal tussen de 0 en 10 uitgeven, zonder decimalen, Dat doe ik dus 0.9*10, wat weer 0 is. Dat is een beetje het probleem, ik zit vast aan een bepaalde waarde voor de uitvoer. Hoevaak ik iets ook vergroot om dit probleem met decimalen te ontwijken, ik moet op het eind die decimalen er weer uitslopen, waardoor ik weer terug bij af ben.
Dat kun je dan toch oplossen met een if-statement? Kleiner dan of gelijk aan 5, een 0, anders (6 t/m 10) een 1.

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Het punt is dat je alle berekeningen kan doen met meer precisie, waardoor je uiteindelijke uitkomst beter is. Als je op het laast pas afrond, zit je dichter bij je antwoord dan dat je het te vroeg doet.

Als je uiteindelijk decimalen eraf moet halen, WAAROM wil je dan decimalen weten? Voor welke API/aansturing heb je deze decimalen nodig? En als je ze niet nodig hebt, wat heb je dan WEL nodig? En hoe precies? En wat is het bereik? En welke berekeningen moet je erop doen?

Dat zijn de dingen die je eerst helder moet hebben voordat je gaat programmeren, want dan weet je welke technieken je kan toepassen :) Ik zou zeggen, lees je eens in in integer arithmetic en fixed point, weet wat je wilt doen, en dan moet het wel lukken :)

-niks-


  • Jegorex
  • Registratie: April 2004
  • Laatst online: 16-06 18:03
Heb je wel een modulus?
Als de modulus meer of gelijk aan de helft van de 2e variabele is dan tel je 1 bij het antwoord op.

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 09-07 16:23

Matis

Rubber Rocket

Wij ontwikkelen veel software voor zowel microprocessoren als FPGA's. Omdat FPGA's ontzettend slecht (lees veel resources) zijn in het rekenen met floating waardes, passen we daar Fixed-point arithmetic toe; eigenlijk hetzelde als KopjeThee en MLM voorstellen, maar dan wat verder toegelicht.
Ik weet niet precies hoe breed jouw integer is en wat de maximale (dan wel minimale) waardes zijn van jouw input, maar anders zou je daar in factoren van 2 op kunnen nemen als fractional bits.

Aangezien FPGA's geen woordbreedtes kennen, gebruiken we vaak een 64 fractional bits in onze scalers.

Nu weet ik dat een (micro)processor daar anders mee omgaat, maar je kunt het natuurlijk wel overwegen.

Edit; Eigenlijk val ik in herhaling met bovenstaande heren, maar ik denk toch dat je met fixed point het beste resultaat krijgt op een relatief eenvoudige (software technisch) en voor de processor efficiënte manier.

[ Voor 17% gewijzigd door Matis op 27-12-2012 20:03 ]

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 09-07 17:43
De IEC61131.3 norm is al vrij oud, in die tijd was het zeker niet zo dat de PLC hardware (of software) floating point berekeningen ondersteunde. Sterker nog; in hardware werd dit alleen door het topsegment van de PLC's gedaan, en dan heb ik het over CPU units van 10k gulden en meer waar misschien wel een 486 processor in zat.

Ik meen me ook te kunnen herinneren dat de REAL en LREAL data types niet verplicht waren om te ondersteunen door PLC bouwers.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1