pntos-api 2.1.0.post0.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pntos/__init__.py +3 -0
- pntos/api/__init__.py +79 -0
- pntos/api/plugins/__init__.py +1 -0
- pntos/api/plugins/common.py +1046 -0
- pntos/api/plugins/controller.py +99 -0
- pntos/api/plugins/fusion.py +572 -0
- pntos/api/plugins/fusion_strategy.py +306 -0
- pntos/api/plugins/inertial.py +414 -0
- pntos/api/plugins/initialization.py +278 -0
- pntos/api/plugins/logging.py +68 -0
- pntos/api/plugins/orchestration.py +253 -0
- pntos/api/plugins/platform_integration.py +81 -0
- pntos/api/plugins/preprocessor.py +88 -0
- pntos/api/plugins/registry.py +46 -0
- pntos/api/plugins/state_modeling.py +581 -0
- pntos/api/plugins/transport.py +50 -0
- pntos/api/plugins/ui.py +43 -0
- pntos/api/plugins/utility.py +17 -0
- pntos/py.typed +0 -0
- pntos_api-2.1.0.post0.dev0.dist-info/METADATA +21 -0
- pntos_api-2.1.0.post0.dev0.dist-info/RECORD +24 -0
- pntos_api-2.1.0.post0.dev0.dist-info/WHEEL +5 -0
- pntos_api-2.1.0.post0.dev0.dist-info/licenses/LICENSE +177 -0
- pntos_api-2.1.0.post0.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
"""Python API of pntOS."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from collections.abc import Callable
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from typing import TYPE_CHECKING, Any, TypeVar
|
|
9
|
+
|
|
10
|
+
from aspn23 import TypeTimestamp
|
|
11
|
+
from numpy import float64
|
|
12
|
+
from numpy.typing import NDArray
|
|
13
|
+
|
|
14
|
+
from .common import CommonPlugin, EstimateWithCovariance, Message
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from .fusion import StandardFusionEngine
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class StandardDynamicsModel:
|
|
22
|
+
"""
|
|
23
|
+
A description of the propagation dynamics for a set of states.
|
|
24
|
+
|
|
25
|
+
This model assumes that the state space :math:`x` can be propagated forward in time by the
|
|
26
|
+
equation:
|
|
27
|
+
|
|
28
|
+
.. math::
|
|
29
|
+
x_k = g(x_{k-1}) + w_k
|
|
30
|
+
|
|
31
|
+
where :math:`x_k` is the set of states at time :math:`k`, :math:`g` is an arbitrary function,
|
|
32
|
+
and :math:`w_k` is additive white Gaussian noise.
|
|
33
|
+
|
|
34
|
+
Attributes:
|
|
35
|
+
g (Callable[[NDArray[float64]], NDArray[float64]]): A function that propagates forward in time a set of
|
|
36
|
+
states.
|
|
37
|
+
Phi (NDArray[float64]): The first-order Taylor series expansion (Jacobian) of the function :math:`g`.
|
|
38
|
+
Qd (NDArray[float64]): The covariance matrix of :math:`w_k`.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
g: Callable[[NDArray[float64]], NDArray[float64]]
|
|
42
|
+
Phi: NDArray[float64]
|
|
43
|
+
Qd: NDArray[float64]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class StandardMeasurementModel:
|
|
48
|
+
"""
|
|
49
|
+
A description of how a measurement relates to a state space.
|
|
50
|
+
|
|
51
|
+
This model assumes that the relationship between the measurement and state vector is well
|
|
52
|
+
modeled by the equation:
|
|
53
|
+
|
|
54
|
+
.. math::
|
|
55
|
+
z=h(x) + v
|
|
56
|
+
|
|
57
|
+
where :math:`z` is the measurement itself, :math:`x` is the set of states being estimated,
|
|
58
|
+
:math:`h` is an arbitrary function, and :math:`v` is additive white Gaussian noise.
|
|
59
|
+
|
|
60
|
+
Attributes:
|
|
61
|
+
z (NDArray[float64]): A column vector containing the measurement itself.
|
|
62
|
+
h (Callable[[NDArray[float64]], NDArray[float64]]): A function that maps the state space to measurement space.
|
|
63
|
+
H (NDArray[float64]): The first-order Taylor series expansion (i.e. Jacobian) of the function h.
|
|
64
|
+
R (NDArray[float64]): The covariance matrix of :math:`v`.
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
z: NDArray[float64]
|
|
68
|
+
h: Callable[[NDArray[float64]], NDArray[float64]]
|
|
69
|
+
H: NDArray[float64]
|
|
70
|
+
R: NDArray[float64]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
GenXandP = Callable[[list[str]], EstimateWithCovariance | None]
|
|
74
|
+
"""
|
|
75
|
+
Returns the estimate and covariance associated with the states of ``block_labels`` within a
|
|
76
|
+
particular measurement processor or state block. This is used to lazily evaluate estimate and
|
|
77
|
+
covariance.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
block_labels (list[str]): Labels for state blocks to generate estimate and
|
|
81
|
+
covariance for.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
Estimate and covariance of the provided block_labels. Returns ``None`` if any label in
|
|
85
|
+
``block_labels`` does not correspond to a valid block.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class StandardStateBlock(ABC):
|
|
90
|
+
"""
|
|
91
|
+
A description of a set of states and their dynamics.
|
|
92
|
+
|
|
93
|
+
Attributes:
|
|
94
|
+
label (str): The unique name for this state block.
|
|
95
|
+
num_states (int): The number of states represented by this state block.
|
|
96
|
+
|
|
97
|
+
Note:
|
|
98
|
+
This class must have an operational ``__deepcopy__`` method. For most classes, the default
|
|
99
|
+
``__deepcopy__`` method provided by Python will be sufficient. However, if the class has a
|
|
100
|
+
field which does not properly implement its own ``__deepcopy__`` (such as a C object wrapped
|
|
101
|
+
to Python), then the class will need to implement a custom ``__deepcopy__`` which properly
|
|
102
|
+
copies all fields.
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
label: str
|
|
106
|
+
"""The unique name for this state block."""
|
|
107
|
+
num_states: int
|
|
108
|
+
"""The number of states represented by this state block."""
|
|
109
|
+
|
|
110
|
+
@abstractmethod
|
|
111
|
+
def receive_aux_data(self, aux: list[Message | None]) -> None:
|
|
112
|
+
"""
|
|
113
|
+
Receive and use an arbitrary collection of aux data.
|
|
114
|
+
|
|
115
|
+
This method will be called by the fusion engine when its
|
|
116
|
+
:meth:`pntos.api.StandardFusionEngine.give_state_block_aux_data` is called with a label
|
|
117
|
+
corresponding to this state block's ``label``.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
aux (list[Message | None])
|
|
121
|
+
"""
|
|
122
|
+
pass
|
|
123
|
+
|
|
124
|
+
@abstractmethod
|
|
125
|
+
def generate_dynamics(
|
|
126
|
+
self,
|
|
127
|
+
gen_x_and_p_func: GenXandP,
|
|
128
|
+
time_from: TypeTimestamp,
|
|
129
|
+
time_to: TypeTimestamp,
|
|
130
|
+
) -> StandardDynamicsModel | None:
|
|
131
|
+
"""
|
|
132
|
+
Generate a :class:`pntos.api.StandardDynamicsModel`.
|
|
133
|
+
|
|
134
|
+
The generated model contains a complete description of how to propagate
|
|
135
|
+
this state block forward in time. For simple models, this can simply
|
|
136
|
+
return a set of static matrices that are pre-defined.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
gen_x_and_p_func (GenXandP): A callback function that the state block can
|
|
140
|
+
use to get the current estimate and covariance.
|
|
141
|
+
time_from (TypeTimestamp): The time to propagate from.
|
|
142
|
+
time_to (TypeTimestamp): The time to propagate to.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
StandardDynamicsModel | None: The description of how to propagate this state block over
|
|
146
|
+
the given time interval, or ``None`` if ``time_from`` is later than ``time_to``.
|
|
147
|
+
Otherwise guaranteed to not return ``None``.
|
|
148
|
+
"""
|
|
149
|
+
pass
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class VirtualStateBlock(ABC):
|
|
153
|
+
"""
|
|
154
|
+
A class used to convert a set of states from one representation to another.
|
|
155
|
+
|
|
156
|
+
States are converted using a mapping function :math:`f` to convert estimates,
|
|
157
|
+
and the Jacobian of :math:`f()` to map covariances (note that this implies that
|
|
158
|
+
the order/units of terms in the estimate vector and covariance matrix are
|
|
159
|
+
the same). Each instance is associated with two labels, ``source`` and
|
|
160
|
+
``target``, where ``source`` is the label attached to the quantity to be
|
|
161
|
+
transformed, and ``target`` is the label attached to the result. Typically used
|
|
162
|
+
with a :class:`pntos.api.StandardFusionEngine` where ``source`` refers to a *real*
|
|
163
|
+
:class:`pntos.api.StandardStateBlock` and ``target`` refers to some representation that is
|
|
164
|
+
advantageous for some other element, such as a :class:`pntos.api.StandardMeasurementProcessor`, to use.
|
|
165
|
+
|
|
166
|
+
Attributes:
|
|
167
|
+
source (str): The label associated with the representation this instance can transform
|
|
168
|
+
*from*.
|
|
169
|
+
target (str): The label associated with the representation this instance can transform *to*.
|
|
170
|
+
|
|
171
|
+
Note:
|
|
172
|
+
This class must have an operational ``__deepcopy__`` method. For most classes, the default
|
|
173
|
+
``__deepcopy__`` method provided by Python will be sufficient. However, if the class has a
|
|
174
|
+
field which does not properly implement its own ``__deepcopy__`` (such as a C object wrapped
|
|
175
|
+
to Python), then the class will need to implement a custom ``__deepcopy__`` which properly
|
|
176
|
+
copies all fields.
|
|
177
|
+
"""
|
|
178
|
+
|
|
179
|
+
source: str
|
|
180
|
+
target: str
|
|
181
|
+
|
|
182
|
+
@abstractmethod
|
|
183
|
+
def receive_aux_data(self, aux: list[Message | None]) -> None:
|
|
184
|
+
"""
|
|
185
|
+
Receive and use an arbitrary collection of aux data.
|
|
186
|
+
|
|
187
|
+
This method will be called by the fusion engine when its
|
|
188
|
+
:meth:`pntos.api.StandardFusionEngine.give_virtual_state_block_aux_data` is called with a
|
|
189
|
+
label corresponding to this :class:`pntos.api.VirtualStateBlock` 's ``target``.
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
aux (list[Message | None])
|
|
193
|
+
"""
|
|
194
|
+
pass
|
|
195
|
+
|
|
196
|
+
@abstractmethod
|
|
197
|
+
def convert(
|
|
198
|
+
self,
|
|
199
|
+
estimate_with_covariance: EstimateWithCovariance,
|
|
200
|
+
time: TypeTimestamp,
|
|
201
|
+
) -> EstimateWithCovariance:
|
|
202
|
+
"""
|
|
203
|
+
Convert a full estimate/covariance pair.
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
estimate_with_covariance (EstimateWithCovariance): Estimate and covariance to convert.
|
|
207
|
+
time (TypeTimestamp): Time that ``estimate_with_covariance`` is valid at.
|
|
208
|
+
|
|
209
|
+
Returns:
|
|
210
|
+
EstimateWithCovariance: The converted value.
|
|
211
|
+
"""
|
|
212
|
+
pass
|
|
213
|
+
|
|
214
|
+
@abstractmethod
|
|
215
|
+
def convert_estimate(
|
|
216
|
+
self, estimate: NDArray[float64], time: TypeTimestamp
|
|
217
|
+
) -> NDArray[float64]:
|
|
218
|
+
"""
|
|
219
|
+
Convert just an estimate vector.
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
estimate (NDArray[float64]): Estimate vector to convert, Nx1.
|
|
223
|
+
time (TypeTimestamp): Time that ``estimate`` is valid at.
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
NDArray[float64]: The converted vector, Mx1.
|
|
227
|
+
"""
|
|
228
|
+
pass
|
|
229
|
+
|
|
230
|
+
@abstractmethod
|
|
231
|
+
def jacobian(
|
|
232
|
+
self, estimate: NDArray[float64], time: TypeTimestamp
|
|
233
|
+
) -> NDArray[float64]:
|
|
234
|
+
"""
|
|
235
|
+
Obtain the Jacobian of the transform performed by this instance.
|
|
236
|
+
|
|
237
|
+
The Jacobian is calculated at an instance in time, given an estimate to
|
|
238
|
+
differentiate with respect to.
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
estimate (NDArray[float64]): Estimate vector associated with the return value of ``source``, Nx1.
|
|
242
|
+
time (TypeTimestamp): Time that ``estimate`` is valid at.
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
NDArray[float64]: An MxN matrix that may be used to pre-multiply ``estimate`` to obtain an M
|
|
246
|
+
length vector in ``target`` representation (to first order).
|
|
247
|
+
"""
|
|
248
|
+
pass
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
class StandardMeasurementProcessor(ABC):
|
|
252
|
+
"""
|
|
253
|
+
A class that processes raw measurements/observations.
|
|
254
|
+
|
|
255
|
+
The measurements are used to calculate estimated states suitable for a linear or linearized
|
|
256
|
+
filter to use. Each type of measurement should correspond to a
|
|
257
|
+
:class:`pntos.api.StandardMeasurementProcessor` that is supplied to the fusion engine. Incoming
|
|
258
|
+
measurements received by the fusion engine will be routed to the corresponding measurement
|
|
259
|
+
processor (by label) and call :meth:`generate_model` to process the measurement. The resulting
|
|
260
|
+
:class:`pntos.api.StandardMeasurementModel` will be used by the fusion engine to call the underlying
|
|
261
|
+
:meth:`pntos.api.StandardFusionStrategy.update` method to update the filter estimate/error covariance.
|
|
262
|
+
|
|
263
|
+
Attributes:
|
|
264
|
+
label (str): A unique name for this measurement processor. This value will be used to
|
|
265
|
+
select a measurement processor to handle new measurements that the strategy
|
|
266
|
+
receives.
|
|
267
|
+
state_block_labels (list[str]): A list of unique state block labels associated with
|
|
268
|
+
measurements received by this processor. The estimate and covariance matrices passed
|
|
269
|
+
into :meth:`generate_model` will be composed of the states associated with these state
|
|
270
|
+
blocks, and the returned StandardMeasurementModel.h and StandardMeasurementModel.H must
|
|
271
|
+
respect these states. Note: ``state_block_labels[i]`` is the identifier for the ``i`` th
|
|
272
|
+
state block this processor relates to.
|
|
273
|
+
|
|
274
|
+
Note:
|
|
275
|
+
This class must have an operational ``__deepcopy__`` method. For most classes, the default
|
|
276
|
+
``__deepcopy__`` method provided by Python will be sufficient. However, if the class has a
|
|
277
|
+
field which does not properly implement its own ``__deepcopy__`` (such as a C object wrapped
|
|
278
|
+
to Python), then the class will need to implement a custom ``__deepcopy__`` which properly
|
|
279
|
+
copies all fields.
|
|
280
|
+
"""
|
|
281
|
+
|
|
282
|
+
label: str
|
|
283
|
+
"""A unique name for this measurement processor. This value will be used to
|
|
284
|
+
select a measurement processor to handle new measurements that the strategy
|
|
285
|
+
receives"""
|
|
286
|
+
state_block_labels: list[str]
|
|
287
|
+
"""A list of unique state block labels associated with
|
|
288
|
+
measurements received by this processor. The estimate and covariance matrices passed
|
|
289
|
+
into :meth:`generate_model` will be composed of the states associated with these state
|
|
290
|
+
blocks, and the returned StandardMeasurementModel.h and StandardMeasurementModel.H must
|
|
291
|
+
respect these states. Note: ``state_block_labels[i]`` is the identifier for the ``i`` th
|
|
292
|
+
state block this processor relates to"""
|
|
293
|
+
|
|
294
|
+
@abstractmethod
|
|
295
|
+
def receive_aux_data(self, aux: list[Message | None]) -> None:
|
|
296
|
+
"""
|
|
297
|
+
Receive and use an arbitrary collection of aux data.
|
|
298
|
+
|
|
299
|
+
This method will be called by the fusion engine when its
|
|
300
|
+
:meth:`pntos.api.StandardFusionEngine.give_measurement_processor_aux_data` is called with
|
|
301
|
+
a label corresponding to this measurement processor's ``label``.
|
|
302
|
+
|
|
303
|
+
Args:
|
|
304
|
+
aux (list[Message | None])
|
|
305
|
+
"""
|
|
306
|
+
pass
|
|
307
|
+
|
|
308
|
+
@abstractmethod
|
|
309
|
+
def generate_model(
|
|
310
|
+
self, message: Message, gen_x_and_p_func: GenXandP
|
|
311
|
+
) -> StandardMeasurementModel | None:
|
|
312
|
+
"""
|
|
313
|
+
Generate a :class:`pntos.api.StandardMeasurementModel`.
|
|
314
|
+
|
|
315
|
+
Args:
|
|
316
|
+
message (Message): The measurement/observation to process.
|
|
317
|
+
gen_x_and_p_func (GenXandP): A callback function that can be used to
|
|
318
|
+
retrieve the current estimate and covariance for the state blocks this
|
|
319
|
+
measurement processor targets.
|
|
320
|
+
|
|
321
|
+
Returns:
|
|
322
|
+
StandardMeasurementModel | None: A generated model containing the
|
|
323
|
+
parameters required for a filter update. Will be ``None`` when a
|
|
324
|
+
measurement cannot be produced from ``message`` (for example, this
|
|
325
|
+
could happen if the measurement type is unsupported by the
|
|
326
|
+
measurement processor or if it is rejected due to residual
|
|
327
|
+
monitoring).
|
|
328
|
+
"""
|
|
329
|
+
pass
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
class StandardStateModelProvider(ABC):
|
|
333
|
+
"""
|
|
334
|
+
A collection of tools for modeling states and measurements.
|
|
335
|
+
|
|
336
|
+
These tools are used to model the propagation and innovation of state
|
|
337
|
+
spaces using pntOS's standard fusion model. Specifically, a
|
|
338
|
+
:class:`pntos.api.StandardStateModelProvider` provides three types of tools:
|
|
339
|
+
|
|
340
|
+
1. State Blocks - Define a set of states and a model for propagating those states.
|
|
341
|
+
2. Virtual State Blocks - Relate two statespaces to each other.
|
|
342
|
+
3. Measurement Processors - Relate measurements to a statespace.
|
|
343
|
+
|
|
344
|
+
A :class:`pntos.api.StandardStateModelProvider` conceptually models a set of zero or more
|
|
345
|
+
:class:`pntos.api.StandardStateBlock` s and a set of zero or more
|
|
346
|
+
:class:`pntos.api.StandardMeasurementProcessor` s which together model the phenomenology of
|
|
347
|
+
sensor data that is being brought into a fusion engine. The first type,
|
|
348
|
+
state blocks, describe how a set of states propagates forward through time.
|
|
349
|
+
The second type, measurement processors, describe how a measurement relates
|
|
350
|
+
to a set of state blocks.
|
|
351
|
+
|
|
352
|
+
Each :class:`pntos.api.StandardStateModelProvider` consists of factory methods which generate
|
|
353
|
+
instances of the state blocks and measurement processors it provides. The
|
|
354
|
+
:meth:`pntos.api.StandardStateModelProvider.new_block` method is a factory method that
|
|
355
|
+
returns a newly created state block on each invocation. Because the
|
|
356
|
+
:class:`pntos.api.StandardStateModelProvider` can provide more than one kind of state block,
|
|
357
|
+
the :meth:`pntos.api.StandardStateModelProvider.new_block` method takes a ``block_index``
|
|
358
|
+
parameter which allows the user to request which kind of state block is
|
|
359
|
+
created by the factory. ``block_identifiers[i]`` gives a description of the
|
|
360
|
+
``i`` th kind of state block returned when ``block_index=i``.
|
|
361
|
+
|
|
362
|
+
Similarly, :meth:`pntos.api.StandardStateModelProvider.new_processor` is a factory method for
|
|
363
|
+
returning new measurement processors and ``processor_identifiers`` is a set
|
|
364
|
+
of identifiers for each available kind of measurement processor that can be
|
|
365
|
+
returned by the factory.
|
|
366
|
+
|
|
367
|
+
Attributes:
|
|
368
|
+
processor_identifiers (list[str] | None): A list of identifying strings for each kind of
|
|
369
|
+
measurement processor that this :class:`pntos.api.StandardStateModelProvider` can create instances
|
|
370
|
+
of. The ``processor_index`` parameter of :meth:`new_processor` is an index into this
|
|
371
|
+
array. This field will be ``None`` when this state model provider does not provide
|
|
372
|
+
any measurement processors.
|
|
373
|
+
block_identifiers (list[str] | None): A list of identifying strings for each kind of state block
|
|
374
|
+
that this :class:`pntos.api.StandardStateModelProvider` can create instances of.
|
|
375
|
+
The ``block_index`` parameter of :meth:`new_block` is an index into this array.
|
|
376
|
+
This field will be ``None`` when this state model provider does not
|
|
377
|
+
provide any state blocks.
|
|
378
|
+
virtual_block_identifiers (list[str] | None): A list of identifying strings for each kind of
|
|
379
|
+
virtual state block that this :class:`pntos.api.StandardStateModelProvider` can create instances
|
|
380
|
+
of. The ``virtual_block_index`` parameter of :meth:`new_virtual_block` is an index into
|
|
381
|
+
this array. This field will be ``None`` when this state model provider does not
|
|
382
|
+
provide any virtual state blocks.
|
|
383
|
+
"""
|
|
384
|
+
|
|
385
|
+
processor_identifiers: list[str] | None
|
|
386
|
+
"""Strings describing the measurement processors the provider can create.
|
|
387
|
+
"""
|
|
388
|
+
block_identifiers: list[str] | None
|
|
389
|
+
"""Strings describing the state blocks the provider can create.
|
|
390
|
+
"""
|
|
391
|
+
virtual_block_identifiers: list[str] | None
|
|
392
|
+
"""Strings describing the virtual state blocks the provider can create.
|
|
393
|
+
"""
|
|
394
|
+
|
|
395
|
+
@abstractmethod
|
|
396
|
+
def new_processor(
|
|
397
|
+
self,
|
|
398
|
+
processor_index: int,
|
|
399
|
+
engine: StandardFusionEngine | None,
|
|
400
|
+
label: str,
|
|
401
|
+
state_block_labels: list[str],
|
|
402
|
+
config_group: str | None,
|
|
403
|
+
) -> StandardMeasurementProcessor | None:
|
|
404
|
+
"""
|
|
405
|
+
Generate a newly created :class:`pntos.api.StandardMeasurementProcessor`.
|
|
406
|
+
|
|
407
|
+
This measurement processor describes the relationship between a
|
|
408
|
+
measurement and a set of state blocks.
|
|
409
|
+
|
|
410
|
+
Args:
|
|
411
|
+
processor_index (int): Since the :class:`pntos.api.StandardStateModelProvider` can create
|
|
412
|
+
different kinds of measurement processors, the ``processor_index``
|
|
413
|
+
parameter is used to select which kind of measurement processor
|
|
414
|
+
to create a new instance of. The :attr:`processor_identifiers` field
|
|
415
|
+
contains identifying strings for the kinds of processors. For
|
|
416
|
+
example, if the model can create 45 different processors, the
|
|
417
|
+
identifier of the last processor that can be created is found in
|
|
418
|
+
``processor_identifiers[44]``. An instance of this processor can be
|
|
419
|
+
created by calling ``new_processor(self, 44, ...)``. Note that ``0
|
|
420
|
+
<= processor_index < len(processor_identifiers)``.
|
|
421
|
+
engine (StandardFusionEngine | None): An optional parameter that may be provided to the
|
|
422
|
+
new processor, such that the processor may interact with the fusion engine it
|
|
423
|
+
is being used in (for example, to add/remove states). Set it to
|
|
424
|
+
``None`` when no engine is available for the processor to use.
|
|
425
|
+
label (str): A string which will be used to populate the ``label`` field of
|
|
426
|
+
the newly created processor. This ``label`` will be the unique name
|
|
427
|
+
for the returned instance of a processor, and used to track the
|
|
428
|
+
processor throughout its lifecycle. Note that it differs from
|
|
429
|
+
:attr:`processor_identifiers` which is the model's mechanism for
|
|
430
|
+
selecting the *kind* of processor to create.
|
|
431
|
+
state_block_labels (list[str]): A list of strings which will be used to
|
|
432
|
+
populate the ``state_block_labels`` field of the newly created
|
|
433
|
+
processor.
|
|
434
|
+
config_group (str | None): Indicates which (if any) parameter group in the
|
|
435
|
+
registry may be used to obtain additional configuration values to
|
|
436
|
+
generate the new processor. If the processor requires no outside
|
|
437
|
+
configuration, ``config_group`` may be ``None``.
|
|
438
|
+
|
|
439
|
+
Returns:
|
|
440
|
+
StandardMeasurementProcessor | None: The newly created
|
|
441
|
+
:class:`pntos.api.StandardMeasurementProcessor` or ``None`` when no measurement processor can be
|
|
442
|
+
produced with the given ``processor_index``, ``engine``, and ``config_group``.
|
|
443
|
+
"""
|
|
444
|
+
pass
|
|
445
|
+
|
|
446
|
+
@abstractmethod
|
|
447
|
+
def new_block(
|
|
448
|
+
self,
|
|
449
|
+
block_index: int,
|
|
450
|
+
engine: StandardFusionEngine | None,
|
|
451
|
+
label: str,
|
|
452
|
+
config_group: str | None,
|
|
453
|
+
) -> StandardStateBlock | None:
|
|
454
|
+
"""
|
|
455
|
+
Generate a newly created :class:`pntos.api.StandardStateBlock`.
|
|
456
|
+
|
|
457
|
+
This state block describes a set of states and how they propagate over
|
|
458
|
+
time.
|
|
459
|
+
|
|
460
|
+
Args:
|
|
461
|
+
block_index (int): Since the :class:`pntos.api.StandardStateModelProvider` can create
|
|
462
|
+
different kinds of state blocks, the ``block_index`` parameter is
|
|
463
|
+
used to select which kind of state block to create a new instance
|
|
464
|
+
of. The :attr:`block_identifiers` field contains identifying strings for
|
|
465
|
+
the kinds of state blocks. For example, if the model can create
|
|
466
|
+
45 different state blocks, the identifier of the last state block
|
|
467
|
+
that can be created is found in ``block_identifiers[44]``. An
|
|
468
|
+
instance of this state block can be created by calling
|
|
469
|
+
``new_block(self, 44, ...)``. Note that ``0 <= block_index <
|
|
470
|
+
len(block_identifiers)``.
|
|
471
|
+
engine (StandardFusionEngine | None): An optional parameter that may be provided to the
|
|
472
|
+
new block, such that the block may interact with the fusion engine it
|
|
473
|
+
is being used in (for example, to add/remove states). Set it to
|
|
474
|
+
``None`` when no engine is available for the block to use.
|
|
475
|
+
label (str): A string which will be used to populate the ``label`` field
|
|
476
|
+
of the newly created state block. This ``label`` will be the unique
|
|
477
|
+
name for the returned instance of a state block, and used to
|
|
478
|
+
track the state block throughout its lifecycle. Note that it
|
|
479
|
+
differs from :attr:`block_identifiers` which is the model's mechanism
|
|
480
|
+
for selecting the *kind* of state block to create.
|
|
481
|
+
config_group (str | None): Indicates which (if any) parameter group in the
|
|
482
|
+
registry may be used to obtain additional configuration values to
|
|
483
|
+
generate the new state block. If the state block requires no
|
|
484
|
+
outside configuration, ``config_group`` may be ``None``.
|
|
485
|
+
|
|
486
|
+
Returns:
|
|
487
|
+
StandardStateBlock | None: The newly created
|
|
488
|
+
:class:`pntos.api.StandardStateBlock` or ``None`` when no state block can be produced
|
|
489
|
+
with the given ``block_index``, ``engine``, and ``config_group``.
|
|
490
|
+
"""
|
|
491
|
+
pass
|
|
492
|
+
|
|
493
|
+
@abstractmethod
|
|
494
|
+
def new_virtual_block(
|
|
495
|
+
self,
|
|
496
|
+
virtual_block_index: int,
|
|
497
|
+
source_label: str,
|
|
498
|
+
target_label: str,
|
|
499
|
+
config_group: str | None,
|
|
500
|
+
) -> VirtualStateBlock | None:
|
|
501
|
+
"""
|
|
502
|
+
Generate a newly created :class:`pntos.api.VirtualStateBlock`.
|
|
503
|
+
|
|
504
|
+
This virtual state block is used to convert a set of states from one
|
|
505
|
+
representation to another.
|
|
506
|
+
|
|
507
|
+
Args:
|
|
508
|
+
virtual_block_index (int): Since the :class:`pntos.api.StandardStateModelProvider` can
|
|
509
|
+
create different kinds of virtual state blocks, the
|
|
510
|
+
``virtual_block_index parameter`` is used to select which kind of
|
|
511
|
+
virtual state block to create a new instance of. The
|
|
512
|
+
:attr:`pntos.api.StandardStateModelProvider.virtual_block_identifiers` field contains identifying strings for
|
|
513
|
+
the kinds of virtual state blocks. For example, if the model can
|
|
514
|
+
create 45 different virtual state blocks, the identifier of the
|
|
515
|
+
last virtual state block that can be created is found in
|
|
516
|
+
``virtual_block_identifiers[44]``. An instance of this virtual
|
|
517
|
+
state block can be created by calling ``new_virtual_block(self,
|
|
518
|
+
44, ...)``. Note that ``0 <= virtual_block_index <
|
|
519
|
+
len(virtual_block_identifiers)``.
|
|
520
|
+
source_label (str): The label of the state block or virtual state block
|
|
521
|
+
whose states this virtual state block transforms.
|
|
522
|
+
target_label (str): A unique identifier for this virtual state block.
|
|
523
|
+
config_group (str | None): Indicates which (if any) parameter group in the
|
|
524
|
+
registry may be used to obtain additional configuration values to
|
|
525
|
+
generate the new virtual state block. If the virtual state block
|
|
526
|
+
requires no outside configuration, ``config_group`` may be ``None``.
|
|
527
|
+
|
|
528
|
+
Returns:
|
|
529
|
+
VirtualStateBlock | None: The newly created :class:`pntos.api.VirtualStateBlock` or ``None`` when
|
|
530
|
+
no virtual state block can be produced with the given ``virtual_block_index`` and
|
|
531
|
+
``config_group``.
|
|
532
|
+
"""
|
|
533
|
+
pass
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
StateModelProviderType = TypeVar(
|
|
537
|
+
'StateModelProviderType', StandardStateModelProvider, Any
|
|
538
|
+
)
|
|
539
|
+
"""
|
|
540
|
+
An enumeration of the types of state model providers a state modeling plugin could provide.
|
|
541
|
+
|
|
542
|
+
"Any" is included for future compatibility.
|
|
543
|
+
"""
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
class StateModelingPlugin(CommonPlugin, ABC):
|
|
547
|
+
"""A :class:`pntos.api.CommonPlugin` subclass that generates state model providers."""
|
|
548
|
+
|
|
549
|
+
@abstractmethod
|
|
550
|
+
def is_fusion_type_supported(
|
|
551
|
+
self, fusion_type: type[StateModelProviderType]
|
|
552
|
+
) -> bool:
|
|
553
|
+
"""
|
|
554
|
+
Check if the plugin supports a given type of fusion. See ``StateModelProviderType``.
|
|
555
|
+
|
|
556
|
+
Args:
|
|
557
|
+
fusion_type (StateModelProviderType)
|
|
558
|
+
|
|
559
|
+
Returns:
|
|
560
|
+
bool
|
|
561
|
+
"""
|
|
562
|
+
pass
|
|
563
|
+
|
|
564
|
+
@abstractmethod
|
|
565
|
+
def new_state_model_provider(
|
|
566
|
+
self, fusion_type: type[StateModelProviderType]
|
|
567
|
+
) -> StateModelProviderType | None:
|
|
568
|
+
"""
|
|
569
|
+
Generate a state model provider.
|
|
570
|
+
|
|
571
|
+
Args:
|
|
572
|
+
fusion_type (StateModelProviderType): Specifies the type of fusion that the returned value will
|
|
573
|
+
support. For example, if the user passes in ``STANDARD_MODEL``, then the returned
|
|
574
|
+
value will be an implementation of :class:`pntos.api.StandardStateModelProvider`.
|
|
575
|
+
|
|
576
|
+
Returns:
|
|
577
|
+
StateModelProviderType | None: A state model provider which implements the specified
|
|
578
|
+
type or None if ``fusion_type`` is not supported (:meth:`is_fusion_type_supported` can be used
|
|
579
|
+
to check ``fusion_type``).
|
|
580
|
+
"""
|
|
581
|
+
pass
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Python API of pntOS."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
from pntos.api import CommonPlugin, Message
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TransportPlugin(CommonPlugin, ABC):
|
|
9
|
+
"""
|
|
10
|
+
Transport plugin.
|
|
11
|
+
|
|
12
|
+
A plugin that abstracts a network transport. listening for sensor data off
|
|
13
|
+
the wire and sending data back to the sensors as needed.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
@abstractmethod
|
|
17
|
+
def start_listening(self) -> None:
|
|
18
|
+
"""
|
|
19
|
+
Start listening.
|
|
20
|
+
|
|
21
|
+
Start listening to the transport that this plugin implements, calling
|
|
22
|
+
the appropriate controller function as data streams in.
|
|
23
|
+
"""
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
@abstractmethod
|
|
27
|
+
def stop_listening(self) -> None:
|
|
28
|
+
"""
|
|
29
|
+
Disable listening.
|
|
30
|
+
|
|
31
|
+
Disable listening to the transport that was previously started in a
|
|
32
|
+
call to :meth:`start_listening`.
|
|
33
|
+
"""
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
@abstractmethod
|
|
37
|
+
def broadcast_message(
|
|
38
|
+
self, message: Message, channel_name: str | None = None
|
|
39
|
+
) -> None:
|
|
40
|
+
"""
|
|
41
|
+
Send a message back out to the sensor from pntOS.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
message (Message): The message to send.
|
|
45
|
+
channel_name (str | None, optional): The desired channel. If ``channel_name`` is
|
|
46
|
+
``None`` the implementation may decide where ``message`` should be routed, if
|
|
47
|
+
anywhere. For example, a serial cable might send all messages to a single
|
|
48
|
+
destination.
|
|
49
|
+
"""
|
|
50
|
+
pass
|
pntos/api/plugins/ui.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Python API of pntOS."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
from pntos.api import CommonPlugin
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class UiPlugin(CommonPlugin, ABC):
|
|
9
|
+
"""
|
|
10
|
+
A plugin for a UI that is integrated directly into pntOS.
|
|
11
|
+
|
|
12
|
+
While it is always possible to write a GUI that listens to pntOS outputs and interacts with it
|
|
13
|
+
externally, this plugin allows users to write a GUI that has direct access to pntOS via the
|
|
14
|
+
plugin API. This allows for low latency and high performance GUI/UIs to be generated. Note that
|
|
15
|
+
this plugin is designed for developer/research style UIs and not production environments. A user
|
|
16
|
+
display in a production environment is better modeled as a :class:`pntos.api.PlatformIntegrationPlugin`,
|
|
17
|
+
as that is designed to represent requests from the system and not simply status updates.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
@abstractmethod
|
|
21
|
+
def requires_main_thread(self) -> bool:
|
|
22
|
+
"""
|
|
23
|
+
Check if this plugin needs to run on the main thread.
|
|
24
|
+
|
|
25
|
+
Some systems require GUI applications to run on the main thread. This method can be used to
|
|
26
|
+
query whether or not this plugin must be run on the main thread. If this method returns
|
|
27
|
+
True, then :meth:`run_main_thread` must be called from the main thread in order to start
|
|
28
|
+
this plugin.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
bool: ``True`` if plugin needs to run on the main thread, ``False`` otherwise.
|
|
32
|
+
"""
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
@abstractmethod
|
|
36
|
+
def run_main_thread(self) -> None:
|
|
37
|
+
"""
|
|
38
|
+
Start plugin on the main thread.
|
|
39
|
+
|
|
40
|
+
This method should only be called if :meth:`requires_main_thread` returns True. This method
|
|
41
|
+
should only be called from the main thread.
|
|
42
|
+
"""
|
|
43
|
+
pass
|