EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  <20232024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  <20232024 
<== Date ==> <== Thread ==>

Subject: RE: [EXTERNAL] DeferredMoves without setting moving flag
From: "Pearson, Matthew via Tech-talk" <tech-talk at aps.anl.gov>
To: Laurenz Rettig <rettig at fhi-berlin.mpg.de>, Torsten Bögershausen <torsten.bogershausen at ess.eu>
Cc: "tech-talk at aps.anl.gov" <tech-talk at aps.anl.gov>
Date: Mon, 13 Mar 2023 15:36:17 +0000
Hi,

Sounds like Laurenz may have a solution.

> Here we go, this is my understanding, how things work:
> a) The user set the motorDeferMoves_ flag by writing to a record.
>      Q: Is this global for all motors on the controller, or a bit map (*)
> b) The user sets the .VAL field of the motor(s), one by one, by writing
>       to the motorRecords of the axes involved.
> c) The user sets the motorDeferMoves_ flag to 0
>     Motion should start
>
> Is a good description of the scenario ?

That's about it. It's not a bitmap. Since each axis has an object there are data members used to hold the 'move pending' flag and position. These are then read by the controller object when turning off the main deferred move flag, and the controller object sends the composite move command to the controller. 

I suspect most drivers don't bother implementing this feature, but it can be useful for some systems. For example, it can mean the difference between an XY stage moving in a straight line or a curve to move from point A to point B. 

There are examples:

https://github.com/epics-motor/motorNewport/blob/master/newportApp/src/XPSController.cpp#L430

https://github.com/dls-controls/pmac/blob/dls-master/pmacApp/src/pmacController.cpp#L3893

https://github.com/mp49/parker6k/blob/master/parker6kApp/src/parker6kController.cpp#L1082

https://github.com/motorapp/Galil-3-0/blob/master/3-6/GalilSup/src/GalilController.cpp#L3413

and the simulation driver:

https://github.com/epics-motor/motorMotorSim/blob/master/motorSimApp/src/motorSimDriver.cpp#L151

Cheers,
Matt



>
> If we look into the logic of “motor” (both the record and the model 3 driver),
> things work like this:
>
> When the .VAL (or .DVAL, .RVAL) field is changed, the record figures out what
> to do.
> Distance too short ?
> Either we are on the same step count for a stepper motor, or the diff is inside
> the .SPDB range: Do not ask the motor to move. But “blink” with the .DMOV field.
> Motor already moving ? Look at the .NTM field: Either stop the motor, or let it
> complete the movement, before commanding a new one.
> The motorRecord is written in a way that only one thing at a time is possible,
> once a movement is started, wait for it to complete.
>
> Distance worth to travel ?
> Talk to the model 3 driver, wich results in a call to move().
> After that, the generic part of the driver does a call
>   pAxis->setIntegerParam(motorStatusDone_, 0);
> And that call is important, see below.
>
> After the move() business is finished, the lock on the asynPort
> is released, and the poller may kick in after a few microseconds.
> Now it is important, that the motorStatusDone_ reflects the done status:
> Some controllers need some milliseconds to recognize new commands,
> so be careful not to run into the “ready before even started” problem.
>
> The poller will no poll the axes, and call the motorRecord (each time there
> is a change).
> Once the motorStatusDone_ is 1, the motorRecord assumes that the motion is
> done, and typically .DMOV is set to true. (Unless there are backlash, retries or delays
> configured).
>
> In that sense there is already a kind of interlock: No new movement is commanded
> to the driver/controller, before the old one is finished.
> May be you do not need an own interlock here ?
>
> What does this mean for deferred motions ?
> The same rule applies:
> Make sure that once the move() had been called, the motorStatusDone_ must
> be kept at 0 until the whole movement has completed.
>
> Does this make sense ?
>
> (*) Do we have any example of code to look at ?
> BR
> /Torsten
>
>
>> On 11 Mar 2023, at 00:23, Pearson, Matthew <pearsonmr at ornl.gov> wrote:
>>
>> Hi Laurenz,
>>
>> thank you for your feedback. It makes sense to have this state change for triggering callbacks etc. However, I am wondering if it would not be sufficient to trigger these once the DeferredMoves are actually started by lowering the flag again. This could still happen for all axes independent of whether they actually move.
>>
>> It’s been a while since I looked in detail at the DMOV logic. The motor record likely sets DMOV=0 internally at the beginning of a move, and if the driver doesn’t confirm that a move has started you may see a quick 1->0->1 transition, and then another one once the real move has started.
>>
>> In my particular case, I have interlocks in place that prevent the user from entering new setpoints while a motion is in progress. This, however, for a multimotor deferred move is triggered after the first motor position is set, and then any further setpoints cannot be set. Thus, I want to set the DMOV flag only once a move actually starts.
>>
>> Setting a motor setpoint with deferred moves active would only cause that particular motor to go into DMOV=0 state, so you should still be able to set the other motors that will be part of the deferred move? Or, your interlock prevents setting any motor is any motor is moving? Perhaps the interlock could be modified to also take into account the deferred move flag status, and still allow a new setpoint if deferred moves is active?
>>
>> I suppose I could do this when processing deferred moves, and could write a writeFloat64 function in my class that ommits these lines for move commands if deferredMoves is set, no?
>>
>> Overwriting writeFloat64 is an option, but it would complicate the driver and then you still might find issues with callbacks etc.
>>
>> Cheers,
>>
>> Matt
>>
>> Best, Laurenz
>>
>> Am 10.03.2023 um 18:21 schrieb Pearson, Matthew:
>>
>> Hi Torsten,
>>
>>   
>>
>> The deferred moves logic is really associated with a controller concept rather than an axis, so it can’t be entirely handled by the motor record. For example, a lot of controllers provide the ability to synchronize a multi-axis move start (and sometimes even a start and stop time), and that needs a command sequence something like:
>>
>>   
>>
>> Axis 1: set new position
>>
>> Axis 2: set new position
>>
>> Axis 3: set new position
>>
>> Axes 1,2,3: start moving (in one command)   <- a single motor record can’t do this
>>
>>   
>>
>> It’s possible some of the logic could be handled in the controller and axis base class poll functions. Although most (or all) drivers override those and don’t call the base class function since they currently don’t do anything.
>>
>>   
>>
>> Cheers,
>>
>> Matt
>>
>>   
>>
>>   
>>
>> From: Torsten Bögershausen <Torsten.Bogershausen at ess.eu>
>> Sent: Friday, March 10, 2023 12:04 PM
>> To: Pearson, Matthew <pearsonmr at ornl.gov>; Laurenz Rettig <rettig at fhi-berlin.mpg.de>; tech-talk at aps.anl.gov
>> Subject: Re: [EXTERNAL] DeferredMoves without setting moving flag
>>
>>   
>>
>> Oh, I was to fast with my first response.
>> The line you wrote, Matt, could go into the generic code, right ?
>>
>> /Torsten
>>
>>   
>>
>> From: Tech-talk <tech-talk-bounces at aps.anl.gov> on behalf of "Pearson, Matthew via Tech-talk" <tech-talk at aps.anl.gov>
>> Reply-To: "Pearson, Matthew" <pearsonmr at ornl.gov>
>> Date: Friday, 10 March 2023 at 17:50
>> To: Laurenz Rettig <rettig at fhi-berlin.mpg.de>, "tech-talk at aps.anl.gov" <tech-talk at aps.anl.gov>
>> Subject: RE: [EXTERNAL] DeferredMoves without setting moving flag
>>
>>   
>>
>>   
>>
>> Hi,
>>
>>   
>>
>> Certainly that behavior can be confusing. We enable deferred moves, set the position, and a motor appears to be moving before we say ‘Go’. However, I think it is necessary so that the motor record doesn’t think the move is completed before we have started moving. If you are relying on a callback or forward links or looking for a DMOV 0->1 transition, you’ll be depending on this behavior.
>>
>>   
>>
>> Also that line in asynMotorController.cpp applies to all kinds of moves and not just deferred moves. This is necessary for the same reasons, to prevent the motor record thinking that the move is complete before it’s even started and the polling function has chance to return the correct moving status. It’s likely almost every Asyn motor driver depends on that line in the base class writeFloat64 function.
>>
>>   
>>
>> In the poll() function in your derived class, it’s usually handled by looking at the deferred move flag for an axis. If deferred moves is enabled, then the poller reports motorStatusDone=0, something like:
>>
>>   
>>
>> if (deferred_move) {
>>
>>    moving = true;
>>
>> } else {
>>
>>    //calculate moving flag as normal
>>
>> }
>>
>>   
>>
>> Cheers,
>>
>> Matt
>>
>>   
>>
>>   
>>
>> From: Tech-talk <tech-talk-bounces at aps.anl.gov> On Behalf Of Laurenz Rettig via Tech-talk
>> Sent: Friday, March 10, 2023 11:17 AM
>> To: tech-talk at aps.anl.gov
>> Subject: [EXTERNAL] DeferredMoves without setting moving flag
>>
>>   
>>
>> Hi,
>>
>> I've been working on an asyn motor controller with DeferredMoves. This in principle works, however I noticed that when DeferedMoves is enabled, and I change the setpoint of an axis, the moving flag is raised for a short time (i.e. DMOV=0), even though the axis is not moving yet. I would like to get rid of this behavior.
>>
>> As far as I understand it, this is probably induced by the calls to "pAxis->setIntegerParam(motorStatusDone_, 0);" here:
>>
>> https://github.com/epics-modules/motor/blob/34474ed958838ea5083f598fa4bd9f1ca7e1821c/motorApp/MotorSrc/asynMotorController.cpp#L317
>>
>> and the flag is reset by the next call of the axis poll() function.
>>
>> Is there a simple way to avoid this, or do I have to rewrite the whole writeFloat64 function in my controller driver, and remove these lines?
>>
>> Thanks,
>>
>> Laurenz
>>
>> -- 
>> Dr. Laurenz Rettig                  rettig at fhi-berlin.mpg.de
>> Emmy Noether Research Group Dynamics of Correlated Materials
>> Fritz Haber Institute of the Max Planck Society
>> Department of Physical Chemistry
>> Faradayweg 4-6                         Tel: +49 30 8413 5225
>> 14195 Berlin, Germany                  Fax: +49 30 8413-5387
>> -- 
>> Dr. Laurenz Rettig
>> Fritz Haber Institute of the Max Planck Society
>> Department of Physical Chemistry
>> Dynamics of Correlated Materials
>> Faradayweg 4-6
>> 14195 Berlin, Germany
>>   
>> phone: +49-(0)30-8413 5225
>> email: rettig at fhi-berlin.mpg.de

-- 
Dr. Laurenz Rettig                  rettig at fhi-berlin.mpg.de
Emmy Noether Research Group Dynamics of Correlated Materials
Fritz Haber Institute of the Max Planck Society
Department of Physical Chemistry
Faradayweg 4-6                         Tel: +49 30 8413 5225
14195 Berlin, Germany                  Fax: +49 30 8413-5387


References:
DeferredMoves without setting moving flag Laurenz Rettig via Tech-talk
RE: [EXTERNAL] DeferredMoves without setting moving flag Pearson, Matthew via Tech-talk
Re: [EXTERNAL] DeferredMoves without setting moving flag Torsten Bögershausen via Tech-talk
RE: [EXTERNAL] DeferredMoves without setting moving flag Pearson, Matthew via Tech-talk
Re: [EXTERNAL] DeferredMoves without setting moving flag Laurenz Rettig via Tech-talk
RE: [EXTERNAL] DeferredMoves without setting moving flag Pearson, Matthew via Tech-talk
Re: [EXTERNAL] DeferredMoves without setting moving flag Torsten Bögershausen via Tech-talk
Re: [EXTERNAL] DeferredMoves without setting moving flag Laurenz Rettig via Tech-talk

Navigate by Date:
Prev: Re: [EXTERNAL] DeferredMoves without setting moving flag Laurenz Rettig via Tech-talk
Next: asyn R4-44 available Mark Rivers via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  <20232024 
Navigate by Thread:
Prev: Re: [EXTERNAL] DeferredMoves without setting moving flag Laurenz Rettig via Tech-talk
Next: Re: DeferredMoves without setting moving flag Torsten Bögershausen via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  <20232024 
ANJ, 13 Mar 2023 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·