<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en" xmlns="http://www.w3.org/2005/Atom"><title>Recent posts to BUG? CoDeSys AXIS_REF 32bit position rollover</title><link href="https://forge.codesys.com/forge/talk/Motion/thread/6b7e15df54/" rel="alternate"/><link href="https://forge.codesys.com/forge/talk/Motion/thread/6b7e15df54/feed.atom" rel="self"/><id>https://forge.codesys.com/forge/talk/Motion/thread/6b7e15df54/</id><updated>2020-02-27T18:37:51.291000Z</updated><subtitle>Recent posts to BUG? CoDeSys AXIS_REF 32bit position rollover</subtitle><entry><title>BUG? CoDeSys AXIS_REF 32bit position rollover</title><link href="https://forge.codesys.com/forge/talk/Motion/thread/6b7e15df54/?limit=25#5fe4" rel="alternate"/><published>2020-02-27T18:37:51.291000Z</published><updated>2020-02-27T18:37:51.291000Z</updated><author><name>Anonymous</name><uri>https://forge.codesys.com/u/*anonymous/</uri></author><id>https://forge.codesys.comeff7d58db8c08cb94b06eed3449aadde35eba6aa</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;&lt;em&gt;Originally created by:&lt;/em&gt; Nicolai_Hanssing&lt;/p&gt;
&lt;p&gt;The lack of precision in previous post, is due to a bug wich I have posted in a new thread.&lt;/p&gt;
&lt;p&gt;I have now found a way(?) to convert an actual 32bit position, and transform it into the TechUnits-domain for a rotary axis (modulo):&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c"&gt;(* Lets try to calculate actual position from dwActpos *)&lt;/span&gt;
&lt;span class="c"&gt;(* OBS: pAx : POINTER TO AXIS_REF *)&lt;/span&gt;
&lt;span class="n"&gt;ActPosition&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;dwActPosition&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;dwPosOffsetForResiduals&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;MOD&lt;/span&gt; &lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;dwOneTurn&lt;/span&gt;&lt;span class="o"&gt;)/&lt;/span&gt;&lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;fScalefactor&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;TmpLReal&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;fOffsetPosition&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;TRUNC&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;fOffsetPosition&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;fPositionPeriod&lt;/span&gt;&lt;span class="o"&gt;)*&lt;/span&gt;&lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;fPositionPeriod&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;ActPosition&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ActPosition&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;TmpLReal&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;WHILE&lt;/span&gt; &lt;span class="n"&gt;ActPosition&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;fPositionPeriod&lt;/span&gt; &lt;span class="n"&gt;DO&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;ActPosition&lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="n"&gt;ActPosition&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;fPositionPeriod&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;END_WHILE&lt;/span&gt;
&lt;span class="n"&gt;WHILE&lt;/span&gt; &lt;span class="n"&gt;ActPosition&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;DO&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;ActPosition&lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="n"&gt;ActPosition&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;fPositionPeriod&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;END_WHILE&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I however dont understand why the value in AXIS_REF.fOffsetPosition is not kept within .fPositionPeriod?&lt;/p&gt;
&lt;p&gt;When perofrming multiple MC_SetPos() calls the value can become extremely large, causing many iterations in the while-loops, wich is inefficient, so I had to add the TRUNC() calculation to keep it O(1) effecient.&lt;/p&gt;
&lt;p&gt;&lt;span style="color: underline;"&gt;It will also lead to loss of precision eventually when the LREAL value gets big enough&lt;/span&gt;!&lt;/p&gt;
&lt;p&gt;I realise that increment-precision is kept until 2^51 for double precision LREAL, but it still seems wrong?&lt;/p&gt;
&lt;p&gt;Is this intended by 3S?&lt;/p&gt;
&lt;p&gt;Regards&lt;/p&gt;
&lt;p&gt;Nicolai&lt;/p&gt;&lt;/div&gt;</summary></entry><entry><title>BUG? CoDeSys AXIS_REF 32bit position rollover</title><link href="https://forge.codesys.com/forge/talk/Motion/thread/6b7e15df54/?limit=25#8ab4" rel="alternate"/><published>2020-02-27T18:37:50.117000Z</published><updated>2020-02-27T18:37:50.117000Z</updated><author><name>Anonymous</name><uri>https://forge.codesys.com/u/*anonymous/</uri></author><id>https://forge.codesys.coma08d10aa3922bb291909ec9870a78578a954a9e7</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;&lt;em&gt;Originally created by:&lt;/em&gt; Nicolai_Hanssing&lt;/p&gt;
&lt;p&gt;Changing the axis to a modolu-axis, causes the discrepency to not appear when position-rollover from drive occurs.&lt;/p&gt;
&lt;p&gt;However if I run the axis with modulo, how can I correctly transform the 32bit DINT feedback-value to an actual positionvalue?&lt;/p&gt;
&lt;p&gt;My investigations so far has led me to the follwoing construct:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c"&gt;(* pAx is a pointer to AXIS_REF. *)&lt;/span&gt;
&lt;span class="c"&gt;(* Lets calculate actual position from dwActpos (modulo axis) *)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;dwOffset&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;LREAL_TO_DWORD&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;fOffsetPosition&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;fScalefactor&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;ActPosition&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; 
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;dwActPosition&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dwOffset&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;MOD&lt;/span&gt; &lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;dwOneTurn&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;pAx&lt;/span&gt;&lt;span class="o"&gt;^.&lt;/span&gt;&lt;span class="n"&gt;fScalefactor&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Firstoff I need to treat the feedback-value as DW instad of DI?&lt;/p&gt;
&lt;p&gt;Then get the current offset and convert to DW by scalefactor (not precise, anyone know where to get the DW-offsetvalue to avoid rounding-errors?).&lt;/p&gt;
&lt;p&gt;Apply axis modulo as found in AXIS_REF.dwOneTurn.&lt;/p&gt;
&lt;p&gt;However this is not precise! &lt;/p&gt;
&lt;p&gt;I think it is due to rounding-errors in the calculation of dwOffset.&lt;/p&gt;
&lt;p&gt;So anyone have a sure, fast and precise way of transforming a 32bit DINT value to a corresponding AXIS_REF.fActPosition-domain?&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Notes on application: We're reading a 32bit capture-positon in the drive, wich is currently not supported by MC_TouchProbe(), and therefor need to do this conversion.&lt;/p&gt;&lt;/div&gt;</summary></entry><entry><title>BUG? CoDeSys AXIS_REF 32bit position rollover</title><link href="https://forge.codesys.com/forge/talk/Motion/thread/6b7e15df54/?limit=25#fc1b" rel="alternate"/><published>2020-02-27T18:37:46.896000Z</published><updated>2020-02-27T18:37:46.896000Z</updated><author><name>Anonymous</name><uri>https://forge.codesys.com/u/*anonymous/</uri></author><id>https://forge.codesys.com23ffeb7d1da69cbddbd0d1043f43468f4130d08b</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;&lt;em&gt;Originally created by:&lt;/em&gt; Nicolai_Hanssing&lt;/p&gt;
&lt;p&gt;System: CoDeSys 2.3.7.5 with Infranor CD1k CanOpen drives&lt;/p&gt;
&lt;p&gt;Target: WinCE Cybelec&lt;/p&gt;
&lt;p&gt;When using an axis with linear configuration I get some wrong behaviour when the feedback-position (DINT) rolls over at 2^31:&lt;/p&gt;
&lt;p&gt;The raw 32bit feedback-position from the drive is available in:&lt;/p&gt;
&lt;p&gt;AXIS_REF.dwActPosition (OBS: this is unsigned version, but it matches the binary transmission from the drive)&lt;/p&gt;
&lt;p&gt;AXIS_REF.fActPosition - Current actual positon, scaled.&lt;/p&gt;
&lt;p&gt;AXIS_REF.fSetPosition - Current setpoint from Position-profiler, scaled.&lt;/p&gt;
&lt;p&gt;Now all these values are fine until the drive roll-over of the 32bit SIGNED position: 16#80000000 (2^31)&lt;/p&gt;
&lt;p&gt;The setpoint for the drive is continous, when the roll-over hapens (ie. no following error), but is this is by luck i dont know....&lt;/p&gt;
&lt;p&gt;'AXIS_REF.fActPosition' changes sign, and follows the dwActPosition, if that is typecasted into a DINT.&lt;/p&gt;
&lt;p&gt;But 'AXIS_REF.fSetPosition' does not, it continous to grow.&lt;/p&gt;
&lt;p&gt;So you get a large difference (2^32) between fActPosition and fSetPosition. This does not make sense, and is a bug....&lt;/p&gt;
&lt;p&gt;Exspected behaviour would be one of the two below:&lt;/p&gt;
&lt;p&gt;a) Act/Set-Position would both change sign.&lt;/p&gt;
&lt;p&gt;b) Act/Set-Position would both be continous.&lt;/p&gt;
&lt;p&gt;So we have this bug, but is it CoDeSys or is there something wrong with the Drive-libs?&lt;/p&gt;
&lt;p&gt;I have some question I hope some will be able to answer:&lt;/p&gt;
&lt;p&gt;What is the largest linear position, for a linear axis in the profiler?&lt;/p&gt;
&lt;p&gt;How is the relation-ship between fSetPos (From profiler) and Actual command defined, when a roll-over has occured on either feedback or command-setpoint?&lt;/p&gt;
&lt;p&gt;Please feel free to only answer part of the questions in seperate posts.&lt;/p&gt;
&lt;p&gt;I'll try to see if I can provoke more strange behavior.&lt;/p&gt;
&lt;p&gt;Regards&lt;/p&gt;
&lt;p&gt;Nicolai Hanssing&lt;/p&gt;&lt;/div&gt;</summary></entry></feed>