bliss_motion_control_basics.md 10.3 KB
Newer Older
Matias Guijarro's avatar
Matias Guijarro committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Motion control

1. What is a BLISS Axis ?
1. What can be done with an Axis ?
1. Special Axis


## What is a BLISS Axis ?

In most cases a BLISS Axis represents a motor driven by a physical motor
controller.

This page presents main caracteristics of a BLISS Axis object and its
basic usages.

Basicaly it's a position you can change.

In details, it's much more complex ;-)


See [Motion Axis](motion_axis.md) for a detailled Axis description.

Fundamental caracteristics of an Axis are:

* position
* velocity
* acceleration

To match mechanical reality, an Axis also deals with:

* tolerance
* backlash
* limits
* steps_per_unit
35
36
* velocity_low_limit
* velocity_high_limit
Matias Guijarro's avatar
Matias Guijarro committed
37
38
39
40
41
42
43
44
45
46
47

And to be usable, another set of notions is present:

* name
* user unit
* sign
* offset
* dial position
* acctime
* state

Valentin Valls's avatar
Typo    
Valentin Valls committed
48
Each of these notions is implemented as a "**setting**" in BLISS Axis.
Matias Guijarro's avatar
Matias Guijarro committed
49

Cyril Guilloud's avatar
Cyril Guilloud committed
50
A setting is a value that can be changed by user or that evolves as the
Matias Guijarro's avatar
Matias Guijarro committed
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Axis moves.

Settings can be defined in the configuration or saved in memory during
the existance of the Axis object. This will be presented in another
section.

## Axis Settings

Settings are implemented as python **attributes**, and not as functions.

This pythonic detail means that they are used without brackets `()`

Example:
```python
DEMO [11]: mot1.velocity          # to READ the velocity
 Out [11]: 1.25

DEMO [12]: mot1.velocity = 3.0    # to SET a new velocity
Matias Guijarro's avatar
Matias Guijarro committed
69
'mot1` velocity changed from 1.25 to 3.0
Matias Guijarro's avatar
Matias Guijarro committed
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
DEMO [13]:

DEMO [14]: mot1.velocity ⏎
 Out [14]: 3.0
```

Following sections will briefly present the meaning of these settings.

### name

* string  -  Read Only  -  from config
* unique, but can have an alias in a session.

### state

Cyril Guilloud's avatar
Cyril Guilloud committed
85
86
* AxisState set  -  Read Only  -  computed

Matias Guijarro's avatar
Matias Guijarro committed
87
```python
Cyril Guilloud's avatar
Cyril Guilloud committed
88
DEMO [7]: mot1.state 
Matias Guijarro's avatar
Matias Guijarro committed
89
90
91
92
93
94
 Out [7]: AxisState: READY (Axis is READY)
```


A standard state has a name and a description.

Cyril Guilloud's avatar
Cyril Guilloud committed
95
There are 8 standard states:
Matias Guijarro's avatar
Matias Guijarro committed
96
97
98
99
100
101
102
103
104
105

* `MOVING`  : 'Axis is moving'
* `READY`   : 'Axis is ready to be moved'
* `FAULT`   : 'Error from controller'
* `LIMPOS`  : 'Hardware high limit active'
* `LIMNEG`  : 'Hardware low limit active'
* `HOME`    : 'Home signal active'
* `OFF`     : 'Axis power is off'
* `DISABLED`: 'Axis cannot move'

Cyril Guilloud's avatar
Cyril Guilloud committed
106
New states, specific to a controller, can also be created.
Matias Guijarro's avatar
Matias Guijarro committed
107

Cyril Guilloud's avatar
Cyril Guilloud committed
108
`state` attribute is a *set* of one or many standard states.
Matias Guijarro's avatar
Matias Guijarro committed
109
110

```python
Cyril Guilloud's avatar
Cyril Guilloud committed
111
DEMO [2]: m1.state  
Matias Guijarro's avatar
Matias Guijarro committed
112
113
114
115
116
117
118
 Out [2]: AxisState: READY (Axis is READY) | LIMPOS (Hardware high limit active)
```


An axis must be in `READY` state to be moved.


119
### position / dial / offset / steps_per_unit / sign / velocity_low_limit / velocity_high_limit
Matias Guijarro's avatar
Matias Guijarro committed
120
121

`steps_per_unit` is the conversion factor applied to transform
Cyril Guilloud's avatar
Cyril Guilloud committed
122
position given by a motor controller (typically "motor steps") into
123
`dial` value (typically `mm`, `um` or `degrees`).
Matias Guijarro's avatar
Matias Guijarro committed
124

125
126
127
128
129
130
In short, the **dial position** should correspond to the motor controller
position in user units. The dial position is accessible through the
`.dial` property.

The **user position** derives from the dial, following the formula
defined below:
131

Matias Guijarro's avatar
Matias Guijarro committed
132
133
`velocity_low_limit` and `velocity_high_limit` are optional velocity limit
defined in the configuration.
134

Matias Guijarro's avatar
Matias Guijarro committed
135
136
```user_position = (sign * dial_position) + offset```

137
138
139
140
141
142
143
By default, the sign of user and dial is 1 (no sign change), and offset is 0
(no offset).
It is possible to define a particular user position either by assigning a
new value to `.position` (which creates an *offset*), or by directly assigning
an offset value through the `.offset` property.
The *sign* can be defined directly in the YML configuration file for a motor,
or it can be changed on the fly via the `.sign` property. Possible values are 1 or -1.
Matias Guijarro's avatar
Matias Guijarro committed
144
145

```python
Cyril Guilloud's avatar
Cyril Guilloud committed
146
DEMO [2]: wa() ⏎
Matias Guijarro's avatar
Matias Guijarro committed
147
148
149
150
151
152
153
154
155
Current Positions: user
                   dial

  mot1[parsec]       mm2      mm3      mm4
-------------  --------  -------  -------
      1.92000  14.75000  2.00000  0.00000
      6.92000  14.75000  2.00000  0.00000
```

156
### unit
Matias Guijarro's avatar
Matias Guijarro committed
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

Read-Only  -  string  -  from config

`unit` is a string read from the configuration as an indication for the
user (typically: "mm", "um", "degrees").

It does not enter in consideration for any calculation.


### velocity / acceleration / acctime

Read-Write  -  float  -  from config and persistant in memory

* velocity is set in user unit per second
* acceleration is given in user unit per second per second
* acctime (acceleration time) is given in seconds

These 3 notions are related.

acceleration = velocity / acctime

Thus:

* when velocity is changed, acctime is updated
* when acceleration is changed, acctime is updated
* when acctime is changed, acceleration is updated.

```python
Cyril Guilloud's avatar
Cyril Guilloud committed
185
DEMO [17]: mot1.acceleration  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
186
187
 Out [17]: 10.0

Cyril Guilloud's avatar
Cyril Guilloud committed
188
DEMO [18]: mot1.acctime  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
189
190
 Out [18]: 0.4

Cyril Guilloud's avatar
Cyril Guilloud committed
191
DEMO [19]: mot1.acceleration=20  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
192
193
'mot1` acceleration changed from 10.0 to 20.0

Cyril Guilloud's avatar
Cyril Guilloud committed
194
DEMO [20]: mot1.acctime  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
195
196
 Out [20]: 0.2

Cyril Guilloud's avatar
Cyril Guilloud committed
197
DEMO [21]: mot1.acctime=1  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
198
199
'mot1` acceleration changed from 20.0 to 4.0

Cyril Guilloud's avatar
Cyril Guilloud committed
200
DEMO [22]: mot1.acceleration  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
201
202
203
204
205
206
207
208
209
210
211
 Out [22]: 4.0
```

### limits

Read-Write  -  float  -  from config and persistant in memory

Software limits are defined in user unit.

They can be changed simultaneously or one by one:
```python
Cyril Guilloud's avatar
Cyril Guilloud committed
212
DEMO [56]: mot1.limits  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
213
214
 Out [56]: (-111.0, 111.0)

Cyril Guilloud's avatar
Cyril Guilloud committed
215
DEMO [57]: mot1.limits = (-5, 5)  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
216

Cyril Guilloud's avatar
Cyril Guilloud committed
217
218
DEMO [58]: mot1.low_limit = -4  ⏎
DEMO [59]: mot1.high_limit = 4  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
219
220
221
222

```

```python
Cyril Guilloud's avatar
Cyril Guilloud committed
223
DEMO [4]: move(mot1, 1122)  ⏎
224
!!! === ValueError: mot1: move to `1122.000000' (with 0.010000 backlash) would exceed high limit (4.000000) === !!!
Matias Guijarro's avatar
Matias Guijarro committed
225
226
```

227
228
229
230
The `dial_limits` property allows to read/set the limits using the dial frame of
reference.


Matias Guijarro's avatar
Matias Guijarro committed
231
232
233
234
235
236
237
238
239
240
### tolerance

Read-Only  -  float  -  from config

At the begining of a movement, the controller position is compared to
the last known axis dial position. If the difference is larger than
the Axis `tolerance`, an exception is raised with a message like:

`discrepancy between dial (0.123) and controller position (0.100), aborting`

Cyril Guilloud's avatar
Cyril Guilloud committed
241
242
243
244
245
246
247
248
249
This can occur if the axis is moved by another software (*IcepapCMS* for
example)

The axis must be re-synchronized with the BLISS session using:

```python
mot1.sync_hard()
```

Matias Guijarro's avatar
Matias Guijarro committed
250
251
252
253
254

###  backlash

Read-Only  -  float  -  from config

Cyril Guilloud's avatar
Cyril Guilloud committed
255
Backlash attribute defines a small movement performed at the end of a
Matias Guijarro's avatar
Matias Guijarro committed
256
257
258
movement if this movement's direction is opposed to the sign of the
backlash.

Cyril Guilloud's avatar
Cyril Guilloud committed
259
The backlash is defined in the config in user units.
Matias Guijarro's avatar
Matias Guijarro committed
260
261
262
263

## Encoder


264
For configuration and usage of encoder, see: [Encoder](motion_encoder.md)
Matias Guijarro's avatar
Matias Guijarro committed
265

Cyril Guilloud's avatar
Cyril Guilloud committed
266

Matias Guijarro's avatar
Matias Guijarro committed
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292

## In-line information


To help users to find their way in all these settings, Axis have a
built-in 'info' function called by just typing their name.

Example in a BLISS shell:
```python
DEMO [11]: mot1 ⏎
 Out [11]: AXIS:
               name (R): mot1
               unit (R): um
               offset (R): 0.0000
               backlash (R): 0.01000
               sign (R): 1
               steps_per_unit (R): 52500.00
               tolerance (R) (to check pos. before a move): 0.001
               limits (RW):    Low: -111.00000 High: 111.00000
               dial (RW): 7.50
               position (RW): 7.50
               state (R): READY (Axis is READY)
               acceleration (RW):   10.00000  (config:   10.00000)
               acctime (RW):         0.40000  (config:    0.90000)
               velocity (RW):        4.00000  (config:    9.00000)
          ICEPAP CONTROLLER:
293
               controller: iceid421
Matias Guijarro's avatar
Matias Guijarro committed
294
295
               version: 3.17
          ICEPAP:
296
               host: iceid421 (ID: 0008.01A1.49C6) (VER: 3.17)
Matias Guijarro's avatar
Matias Guijarro committed
297
298
299
300
301
               address: 42
               status: POWER: ON    CLOOP: ON    WARNING: NONE    ALARM: NO
               IcepapEncoders(ENCIN='393759', ABSENC='-1687552', INPOS='0',
                              MOTOR='393744', AXIS='393750', SYNC='388568')
          ENCODER:
302
               encoder steps_per_unit: 52.0
Matias Guijarro's avatar
Matias Guijarro committed
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
               tolerance (to check pos at end of move): 0.001
               dial_measured_position:    7.50017
```


## basic commands

* `on()` / `off()`: dependent on controller. For example for icepap,
  these commads switch the power on/off.
* to know where is your axis and how it feels:
    - `wa()`, `wm(mot1, ..., motN)`: print the dial and user position of all or a list of Axis
    - `sta()`, `stm(mot1, ..., motN)`: print the status of all or a list of Axis
* to move it move it:
    - `mv(mot1, 2.41)`: move motor `mot1` to user position 2.41
    - `umv(mot1, 2.41)`: idem and display intermediate positions to follow the move
    - `mvr(mot1, 0.1)`: move motor `mot1` by 0.1 from current position
    - `umvr(mot1, 0.1)`: idem and display intermediate positions to follow the move



Examples:
```python
Cyril Guilloud's avatar
Cyril Guilloud committed
325
DEMO [60]: sta()  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
326
327
328
329
330
331
332
333
334
Axis    Status
------  ---------------------
mot1     READY (Axis is READY)
mot2     READY (Axis is READY)
mot3     READY (Axis is READY)
mot4     READY (Axis is READY)
psf     READY (Axis is READY)
psb     READY (Axis is READY)

Cyril Guilloud's avatar
Cyril Guilloud committed
335
DEMO [61]: stm()  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
336
337
338
Axis    Status
------  --------

Cyril Guilloud's avatar
Cyril Guilloud committed
339
DEMO [62]: stm(mot1)  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
340
341
342
343
344
345
346
347
Axis    Status
------  ---------------------
mot1     READY (Axis is READY)




```python
Cyril Guilloud's avatar
Cyril Guilloud committed
348
DEMO [1]: wa()  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
349
350
351
352
353
354
355
356
357
Current Positions: user
                   dial

  mot1[parsec]    mot2     mot3     mot4     mot5      psf      psb
-------------  -------  -------  -------  -------  -------  -------
      0.00000  4.00000  0.00000  0.00000  0.00000  4.00000  1.00000
      5.00000  4.00000  0.00000  0.00000  0.00000  4.00000  1.00000


Cyril Guilloud's avatar
Cyril Guilloud committed
358
DEMO [4]: wm(mot1)  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373

            mot1[parsec]
--------  -------------
User
 High         111.00000
 Current        0.00000
 Low         -111.00000
Offset         -5.00000

Dial
 High         116.00000
 Current        5.00000
 Low         -106.00000


Cyril Guilloud's avatar
Cyril Guilloud committed
374
DEMO [9]: umv(mot1, 1, mot3, 2)  ⏎
Matias Guijarro's avatar
Matias Guijarro committed
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
Moving mot1 from 2 to 1
Moving mot3 from 4 to 2

  mot1       mot3
   1.000     2.000
```



## Axis-Related features

* Scans will pe presented later.

* See [Motion Axis](motion_axis.md) for a detailled Axis description.
    - [Icepap Configuration](config_icepap.md)

* Standard scans are introduced here: [Default Scans](bliss_standard_scans.md).

* Trajectories

* CalcMotors
    - Calc motor example (slits, tables)
    - calc of calc
    - traj on calcs

* events on change of state, position

* special moves
Cyril Guilloud's avatar
Cyril Guilloud committed
403
404
405
    - group moves: to move multiple motors in same time
    - jog: to move in velocity rather than in position
    - home / limit search: to recover reference positions
Matias Guijarro's avatar
Matias Guijarro committed
406
407

* special motor controller
Cyril Guilloud's avatar
Cyril Guilloud committed
408
409
410
    - NoSettingsAxis: to avoid caching of settings
    - ModuloAxis: for rotary actuators
    - shutters: for 2-positions actuators
Matias Guijarro's avatar
Matias Guijarro committed
411