Skip to content

Commit d36b293

Browse files
committed
Improve README
1 parent 6887ea3 commit d36b293

1 file changed

Lines changed: 46 additions & 20 deletions

File tree

README.md

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,25 @@ This module implements a 2D surface that resembles a curved slide, suitable for
1717
To give you a quick idea, the following figure is created with the [`plot.py`](plot.py) script in this repository,
1818
and visualizes the slides [`boxcar_blitz.toml`](boxcar_blitz.toml) and [`brutal_bends.toml`](brutal_bends.toml) included in this repository:
1919

20-
![slides.jpg](slides.jpg)
20+
![slides.jpg](https://raw.githubusercontent.com/molmod/soapboxslide/main/slides.jpg)
2121

2222
Your eyes may need some time to adapt to the correct depth perception: black ridges are high-altitude separations between the colored valleys.
2323

2424
## Concept
2525

26-
The overall idea is that students use the surface implemented in `soapboxslide` to simulate the dynamics of a particle (or a connected set of particles) sliding down.
27-
In addition to correctly implementing the dynamics, an additional challenge is do so as quickly as possible without missing any of the waypoints shown as dotted circles.
26+
The idea is for students to use the surface implemented in `soapboxslide` to simulate the dynamics of a particle (or a connected set of particles) sliding down.
27+
In addition to correctly implementing the dynamics, students must do so as quickly as possible without missing any of the waypoints shown as dotted circles.
2828

2929
Two classes of physical models can be considered:
3030

3131
1. The most convenient is to assume a model of point particles strictly bound to the surface with holonomic constraints.
3232
In this case, equations of motion can be derived using a Lagrangian, possibly with a generalized force to include non-conservative friction forces.
3333

34-
2. A more challenging scenario (not used for Py4Sci, but closer in spirit to soap box races) is to impose inequality constraints, allow particles to detach from the surface.
34+
2. A more challenging scenario (not used for now, but closer in spirit to real soap box races) is to impose inequality constraints, allowing particles to detach from the surface.
3535

3636
## Slide Class Usage
3737

38-
One can load a surface from a TOML file and calculate the altitude at a given point, e.g. x=5 and y=38, as follows:
38+
One can load a surface from a TOML file and calculate slide properties at a given point, e.g. $x=5$ and $y=38$, as follows:
3939

4040
```python
4141
import numpy as np
@@ -100,32 +100,58 @@ This will show three gradients, one for each row of `pos`:
100100
[-2.16704263 -2.9280058 ]]
101101
```
102102

103+
In addition, a `Slide` instance has the following attributes:
104+
105+
- `width`: the width of the slide arena in meter.
106+
- `height`: the height of the slide arena in meter.
107+
- `waypoints`: A 2D NumPy array with three columns (and at least two rows)
108+
defining the shape and altitude of the slide track.
109+
These are also intended as points that must be visited by a particle or a system sliding down,
110+
to ensure that it followed a legitimate trajectory.
111+
- `target_radius`: a required proximity between a particle (or the center of mass of a system of particles) to a waypoint, to mark the waypoint as properly visited.
112+
The distance is only measured in the $xy$-plane.
113+
114+
Note that the above surface plots show dashed circles centered on the waypoints, whose radius is the target radius.
115+
103116
## Storing and Sharing Trajectory Data
104117

105118
The `soapboxslide` module also implements a `Trajectory` class for storing the results of a numerical integration of one or more particles sliding over the surface.
106-
This class performs an initial validation on your trajectory data upon construction features `to_npz` and `from_npz` methods with which trajectories can be saved to and loaded from files.
119+
This class performs an initial validation on your trajectory data upon construction.
120+
It also features `to_file` and `from_file` methods with which trajectories can be saved to and loaded from NPZ files.
107121
This is useful if you want to share your trajectory with someone, e.g. for review, and to implement separate computation and visualization scripts (or notebooks).
108122

109123
To use the `Trajectory` class, create an instance as follows after completing the numerical integration of the equations of motion:
110124

111125
```python
112126
traj = Trajectory(
113-
time=...,
114-
mass=...,
115-
gamma=...,
116-
pos=...,
117-
vel=...,
118-
grad=...,
119-
hess=...,
120-
spring_idx=...,
121-
spring_par=...,
122-
end_state=...,
123-
stop_time=...,
124-
stop_pos=...,
125-
stop_vel=...,
127+
time=..., # NDArray[float], shape = (ntime, )
128+
mass=..., # NDArray[float], shape = (npoint, )
129+
gamma=..., # NDArray[float], shape = (npoint, )
130+
pos=..., # NDArray[float], shape = (ntime, npoint, 3), (x, y and z coordinates)
131+
vel=..., # NDArray[float], shape = (ntime, npoint, 3), (x, y and z coordinates)
132+
grad=..., # NDArray[float], shape = (ntime, npoint, 2), (h_x and h_y derivatives)
133+
hess=..., # NDArray[float], shape = (ntime, npoint, 3), (h_xx, h_xy and h_yy derivatives)
134+
spring_idx=..., # NDArray[int], shape = (nspring, 2), (each row is a pair of point indexes)
135+
spring_par=..., # NDArray[float], shape = (nspring, 3), (force constant, rest length, damping coeff)
136+
end_state=..., # One of the EndState enumeration
137+
stop_time=..., # Optional, time that last target was reached
138+
stop_pos=..., # Optional, NDArray[float], shape = (npoint, 3), positions at stop time
139+
stop_vel=..., # Optional, NDArray[float], shape = (npoint, 3), velocities at stop time
126140
)
127141
traj.to_file("traj.npz")
128142
```
129143

130144
In this Python snippet, you need to replace all triple dots by arrays you defined or computed.
131-
The meaning of and requirements for all attributes can be found in the docstrings in [`soapboxslide.py`](soapboxslide.py).
145+
Some guidelines:
146+
147+
- If there are no springs yet, use arrays with zero rows for the spring definitions.
148+
- If there is just one particle, several arrays will have a size 1 axis, i.e. `npoint=1`.
149+
- You can first store all fields in a dictionary, e.g. `data` and optionally add the `stop_*` fields to the dictionary. The trajectory is then created with `Trajectory(**data)`.
150+
- The EndState enumeration can be specified to indicate when the numerical integration has ended:
151+
- `EndState.STOP`: last target was reached in time
152+
- `EndState.CRASH`: the numerical integration failed (e.g. due to Inf or Nan results)
153+
- `EndState.FAR`: the particle moved more than 5 m out of the arena
154+
- `EndState.TIMEOUT`: the maximum time, e.g. 60 s, was reached
155+
- You will get a `TypeError` or `ValueError` when creating the trajectory if some of the data does not meet some basic requirements.
156+
157+
The meaning of and requirements for all attributes is further elaborated in the docstrings in [`soapboxslide.py`](soapboxslide.py).

0 commit comments

Comments
 (0)