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  <20212022  2023  2024  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  <20212022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: [EXTERNAL] Re: Access motor controller target positions of other axes in asynMotorAxis::move
From: "Pearson, Matthew R. via Tech-talk" <tech-talk at aps.anl.gov>
To: Laurenz Rettig <rettig at fhi-berlin.mpg.de>, Mark L Rivers <rivers at cars.uchicago.edu>
Cc: EPICS tech-talk <tech-talk at aps.anl.gov>
Date: Mon, 15 Nov 2021 15:52:30 +0000

 

Hi,

 

I wrote the XPS deferred move logic many years ago in a previous life, so I’ll try to explain how it’s meant to be used. Several other drivers have also implemented it, and those may be easier references than the XPS driver (which is complicated by the fact that it’s dealing the XPS axis groups).

 

Many controllers support simple coordinated moves that either start at the same time or start & finish at the same time. This can be very useful in some situations, like multi-axis jack systems, pairs of slits, etc. You may want the motors to start at the same time to avoid unwanted tilt or varying slit gaps for example. Deferred moves is a simple way of dealing with this without having to use the (sometimes complex) controller based move programs or profile moves.

 

I’m going to give an example using an imaginary controller. A normal move command via the motor record might be decomposed into these controller commands:

 

Axis 1 Enable Drive

Axis 1 Set Velocity

Axis 1 Set Acceleration

Axis 1 Set Distance

Axis 1 Start Moving

 

If you wanted to move two motor record axes at the same time, the commands would be:

 

Axis 1 Enable Drive

Axis 1 Set Velocity

Axis 1 Set Acceleration

Axis 1 Set Distance

Axis 1 Start Moving

 

Axis 2 Enable Drive

Axis 2 Set Velocity

Axis 2 Set Acceleration

Axis 2 Set Distance

Axis 2 Start Moving

 

And they wouldn’t start at the same time. Axis 1 would already be moving when we are still sending the commands to start moving axis 2. What we really want is something like:

 

Axis 1 Enable Drive

Axis 1 Set Velocity

Axis 1 Set Acceleration

 

Axis 2 Enable Drive

Axis 2 Set Velocity

Axis 2 Set Acceleration

 

Axis 1 Set Distance

Axis 2 Set Distance

Axis 1,2 Start Moving

 

The deferred moves logic provides a way to do this.

 

You need to add a record to set the MOTOR_DEFER_MOVES parameter in the controller base class:

 

record(bo, "$(S):Defer")

{

  field(DESC, "Defer Moves")

  field(DTYP, "asynInt32")

  field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))MOTOR_DEFER_MOVES")

  field(SCAN, "Passive")

  field(ZNAM, "GO")

  field(ONAM, "DEFER")

  field(VAL, "0")

}

 

And then reimplement the setDeferredMoves(bool deferMoves) function in your controller class. This function will either set a flag to enabled deferred moves mode, or execute the deferred moves (ie. send the ‘Axis 1,2 Start Moving’ command, along with the positions to move to).

 

In the axis class, the move() function has to check if the driver is in deferred moves mode. If it is, then the move() function only sends these commands to the controller:

 

Axis 1 Enable Drive

Axis 1 Set Velocity

Axis 1 Set Acceleration

 

(and the same for axis 2)

 

And the move function will cache the distance required for each axis, for use by the controller function setDeferredMove(). Then when we turn off deferred moves, the setDeferredMoves() function has to figure out which axes are meant to be moving, then send the command to move them all together.

 

The reason we cache the distance is to make it easy to ‘roll back’ and cancel the deferred moves. Then we don’t have to reset the setpoint position back to what it used to be on the controller hardware.

 

At the record level, using caput, to move axis 1 to 10 and axis 2 to 20, the sequence is:

 

caput $(S):Defer 1

caput $(S):Axis1 10

caput $(S):Axis2 20

caput $(S):Defer 0 (this is when both axes move)

 

If you want to cancel moving them, after setting the positions, then the sequence would be:

 

caput $(S):Defer 1

caput $(S):Axis1 10

caput $(S):Axis2 20

caput $(S):Axis1.STOP 1

caput $(S):Axis2.STOP 2

caput $(S):Defer 0

 

The driver has to support this by un-setting the internal deferred move flag when running the stop() function.

 

Cheers,

Matt

 

 

 

From: Tech-talk <tech-talk-bounces at aps.anl.gov> On Behalf Of Laurenz Rettig via Tech-talk
Sent: Monday, November 15, 2021 4:17 AM
To: Mark L Rivers <rivers at cars.uchicago.edu>; tech-talk at aps.anl.gov
Subject: [EXTERNAL] Re: Access motor controller target positions of other axes in asynMotorAxis::move

 

Hi Mark,

thanks for the information. Indeed, I will probably actually not need this feature, however wanted to understand how it was supposed to work.

After some digging I also found something about this functionality in the release notes:

 

Deferred moves for asyn motors

The asyn motor framework now supports a flag to indicate that moves should be deferred. When at zero, moves proceed as normal. When set to one, moves should be deferred and remembered by the controller driver, but not executed immediately. When set back to zero, the controller driver should then start all the moves (or at least moves to the last requested demand positions) that have been deferred, as near to simultaneously as is possible for the particular model of controller. The flag is implemented per-controller, so all axes on a particular controller instance are affected, but axes on other controllers via the same driver are unaffected.

It is the responsibility of the motor controller driver to actually provide such functionality, or to give an error if the parameter is not recognised. Currently the Newport XPS controller driver and the Delta Tau PMAC driver (in the tpmac module available from Diamond) support this.

To use the flag, connect to any asyn port/addr combination on the controller, using the parameter "DEFER". e.g. for a bo record, use DTYP=asynUInt32Digital, OUT=@asynMask(port,1,1)DEFER, ZNAM="Go", _ONAM_="Defer"

 

A basic template function for this is also included in the AsynMotor driver, however the related string seems to be:

 

#define motorDeferMovesString           "MOTOR_DEFER_MOVES"

 

Maybe this could be included in the reference?

 

Best, Laurenz

 

On 12.11.2021 23:56, Mark L Rivers wrote:

Hi Laurenz,

 

1.     This deferred move option, and the saving of the target positions however does not seem to be part of the basic model 3 driver templates (asynMotorController), no?

 

Correct, this capability was not abstracted to the base class, it is implemented only in the XPS driver.

 

2.     Is there any documentation on how to actually use it? I.e. how do I tell the driver that I want to do a deferred move, and how do I initialize the actual move then?

 

As far as I can tell it is not documented.  I do use many XPS units, but I have never used this feature.  I just looked at the source code, and I cannot figure out how in fact it is used.  My reading of the code is the following:

 

1.     The XPS controller class has a bool member variable movesDeferred_.

2.     movedDeferred_ is set in XPSController::setDeferredMoves(bool deferMoves) to the value of deferMoves.

3.     If movesDeferred_ is true then when an XPS axis is told to move it just caches the new position.

4.     When setDeferredMoves() is called with deferMoves=false and movesDeferred_=true (i.e. a true to false transition) then all of the motors are moved to their cached target positions.

 

What I don’t understand is what software calls setDeferredMoves().  It is not called from the iocsh functions in XPSController.cpp, or indeed from any code in motorNewport/newportApp/src.  This code was written at Diamond, so someone there may know.  But I am not sure if they use the XPS anymore.

 

It would be easy to implement in the database and the driver.  You just have a bo record called deferredMoves which writes its value to a parameter in your driver.  The writeInt32 function in your driver just calls setDeferredMoves which implements the logic outlined above.

 

But you need to decide how you want your driver to work.  Do you want it to work so that when any axis is moved it just tells all the other axes to go where they already are?  Or do you want to really cache the moves?  In that case you do the following:

5.     Set deferredMoves to True

6.     Tell each axis where to go, it caches the value

7.     Set deferredMoves to False, which causes all of the motors to move at once.

 

Mark

 

 

 

From: Laurenz Rettig <rettig at fhi-berlin.mpg.de>
Sent: Friday, November 12, 2021 8:43 AM
To: Mark L Rivers <rivers at cars.uchicago.edu>; tech-talk at aps.anl.gov
Subject: Re: Access motor controller target positions of other axes in asynMotorAxis::move

 

Hi Mark,

thanks for your answer, this looks exactly like what I need. This deferred move option, and the saving of the target positions however does not seem to be part of the basic model 3 driver templates (asynMotorController), no?

Is there any documentation on how to actually use it? I.e. how do I tell the driver that I want to do a deferred move, and how do I initialize the actual move then?

Thanks, Laurenz

 

On 12.11.2021 14:37, Mark L Rivers wrote:

Hi Laurenz,

 

1.     In the communication with the controller, I have to provide the target positions of all axes at once, if I want to get it moving correctly. 

 

Your asynMotorController class has access to all of the axes.

 

You can look at the Newport XPS driver for an example of how to do this. 

 

That driver has the option of "deferred moves".  This means that as each axis is told to move the desired position is cached.  When that flag is cleared then all of the axes begin to move at the same time.  Note that this is tied to the concept of motion "groups" in the XPS, so the implementation may need to be different for your driver.

 

asynMotorController and asynMotorAxis also support the concept of ProfileMoves.  For this the motion path for each axis is defined in a waveform record.  The time per motion element is also defined, which produces the velocity for each axis in that element.  Then the controller is told to execute that motion profile, so that all the axes can move on a complex trajectory in N space.

 

Mark

 

 

 


From: Tech-talk <tech-talk-bounces at aps.anl.gov> on behalf of Laurenz Rettig via Tech-talk <tech-talk at aps.anl.gov>
Sent: Friday, November 12, 2021 3:58 AM
To:
tech-talk at aps.anl.gov <tech-talk at aps.anl.gov>
Subject: Access motor controller target positions of other axes in asynMotorAxis::move

 

Hi,

I'm working on a motor driver (Model 3) for a SPECS manipulator
controller. In the communication with the controller, I have to provide
the target positions of all axes at once, if I want to get it moving
correctly. The move function in the asynMotorAxis class only moves one
axis at a time. How can I access the target positions (i.e. the values
of the main motor axes PVs) of the other axes in the
asynMotorAxis::move() function, in order to construct the right command
for the controller? Or is there any better way, like a combined axes
command, or so?

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                  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                  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

Replies:
RE: [EXTERNAL] Re: Access motor controller target positions of other axes in asynMotorAxis::move Mark L Rivers via Tech-talk
References:
Access motor controller target positions of other axes in asynMotorAxis::move Laurenz Rettig via Tech-talk
Re: Access motor controller target positions of other axes in asynMotorAxis::move Mark L Rivers via Tech-talk
Re: Access motor controller target positions of other axes in asynMotorAxis::move Laurenz Rettig via Tech-talk
RE: Access motor controller target positions of other axes in asynMotorAxis::move Mark L Rivers via Tech-talk
Re: Access motor controller target positions of other axes in asynMotorAxis::move Laurenz Rettig via Tech-talk

Navigate by Date:
Prev: Re: Access motor controller target positions of other axes in asynMotorAxis::move Laurenz Rettig via Tech-talk
Next: AppImages for EPICS base Zhang, Tong 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  <20212022  2023  2024 
Navigate by Thread:
Prev: Re: Access motor controller target positions of other axes in asynMotorAxis::move Laurenz Rettig via Tech-talk
Next: RE: [EXTERNAL] Re: Access motor controller target positions of other axes in asynMotorAxis::move Mark L 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  <20212022  2023  2024 
ANJ, 15 Nov 2021 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·