|
1 | 1 | # practable-python |
2 | 2 | a library for connecting to experiments in python |
3 | 3 |
|
4 | | -## Requirements |
5 | 4 |
|
6 | | -book: |
7 | | -``` |
8 | | -expt = practable.book(group, duration, [, type="spin"| name="spin32"]) |
9 | | -``` |
| 5 | +## Example Usage |
10 | 6 |
|
11 | | -experiment: |
| 7 | +```python |
| 8 | +import practable |
| 9 | +import numpy as np |
| 10 | +import matplotlib.pyplot as plt |
12 | 11 |
|
13 | | -``` |
14 | | -expt.streams() |
15 | | -``` |
| 12 | +messages = [] |
| 13 | + |
| 14 | +#modify with actual group code and experiment name |
| 15 | +with practable.Experiment('g-open-xxxxx','Spinner 51', exact=True) as expt: |
| 16 | + |
| 17 | + # Command a step of 2 radians & collect the data |
| 18 | + expt.command('{"set":"mode","to":"stop"}') |
| 19 | + expt.command('{"set":"mode","to":"position"}') |
| 20 | + expt.command('{"set":"parameters","kp":1,"ki":0,"kd":0}') |
16 | 21 |
|
17 | | -list the streams the experiment has |
| 22 | + time.sleep(0.5) |
| 23 | + |
| 24 | + expt.command('{"set":"position","to":2}') |
| 25 | + |
| 26 | + expt.ignore(0.5) |
| 27 | + messages = expt.collect(1.5) |
| 28 | + |
| 29 | + # Process the data |
| 30 | + ts = expt.extract_series(messages, "t") |
| 31 | + ds = expt.extract_series(messages, "d") |
| 32 | + cs = expt.extract_series(messages, "c") |
| 33 | + |
| 34 | + t = np.array(ts) |
| 35 | + t = t - t[0] |
| 36 | + |
| 37 | + # Plot the data |
| 38 | + plt.figure() |
| 39 | + plt.plot(t/1e3,ds,'-b',label="position") |
| 40 | + plt.plot(t/1e3,cs,':r',label="set point") |
| 41 | + plt.xlabel("time(s)") |
| 42 | + plt.ylabel("position(rad)") |
| 43 | + plt.legend() |
| 44 | + plt.savefig('spinner.jpg',dpi=300) |
18 | 45 |
|
19 | 46 | ``` |
20 | | -stream = expt.connect(stream_name) |
21 | | -``` |
22 | | -connect to experiment stream |
23 | 47 |
|
| 48 | +This script produces the following text output |
24 | 49 | ``` |
25 | | -stream.ok() |
| 50 | +Command: {"set":"mode","to":"stop"} |
| 51 | +Command: {"set":"mode","to":"position"} |
| 52 | +Command: {"set":"parameters","kp":1,"ki":0,"kd":0} |
| 53 | +Command: {"set":"position","to":2} |
| 54 | +Ignoring messages for 0.5 seconds |██████████████████████████████████████████████████| 100.0% Complete |
| 55 | +
|
| 56 | +Collecting messages for 1.5 seconds |██████████████████████████████████████████████████| 100.0% Complete |
| 57 | +
|
26 | 58 | ``` |
27 | | -check if stream is connected, within the session time |
| 59 | +An a graph: |
28 | 60 |
|
| 61 | + |
29 | 62 |
|
30 | | -Stream should be a generator (iterator) with ability to send and receive messages |
| 63 | +## Additional information |
| 64 | + |
| 65 | +A user name is obtained and stored locally. |
| 66 | + |
| 67 | +Bookings last only as long as the experiment is needed, because they are cancelled when the `with` environment exits. The default booking duration is 3 min. |
| 68 | + |
| 69 | +You can use an existing booking by specifying `user="cxxxxxxxxxx"` where the username is found on the `user` tab of the booking system that holds the booking. |
| 70 | + |
| 71 | +Other `practable` instances can be accessed by specifying it e.g. `booking-server="https://some.booking.server"` |
| 72 | + |
| 73 | +## Requirements |
| 74 | + |
| 75 | +Recommend python >= 3.8 because we're using websockets 12.0 |
31 | 76 |
|
32 | | -``` |
33 | | -next(stream) |
34 | 77 |
|
35 | | -stream.send(message) |
36 | | -``` |
37 | 78 |
|
38 | 79 |
|
39 | 80 |
|
0 commit comments