phyling 7.0.2__tar.gz → 7.0.4__tar.gz
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.
- {phyling-7.0.2 → phyling-7.0.4}/.github/workflows/python-lint.yml +3 -0
- {phyling-7.0.2 → phyling-7.0.4}/.gitignore +2 -0
- {phyling-7.0.2 → phyling-7.0.4}/.pre-commit-config.yaml +1 -1
- phyling-7.0.4/CLAUDE.md +37 -0
- {phyling-7.0.2 → phyling-7.0.4}/PKG-INFO +14 -3
- {phyling-7.0.2 → phyling-7.0.4}/README.md +13 -2
- {phyling-7.0.2 → phyling-7.0.4}/examples/Analyse/decoder.ipynb +78 -48
- {phyling-7.0.2/examples/Nano-Phyling → phyling-7.0.4/examples/NanoPhyling-MiniPhyling}/lab_examples/pendulum.ipynb +0 -2
- phyling-7.0.4/examples/NanoPhyling-MiniPhyling/multi_devices.ipynb +210 -0
- phyling-7.0.4/examples/NanoPhyling-MiniPhyling/single_device.ipynb +203 -0
- phyling-7.0.4/examples/Phyling API/Phyling python lib/api.ipynb +560 -0
- {phyling-7.0.2 → phyling-7.0.4}/examples/Phyling API/RAW API examples/minimal_oauth.py +1 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling/api/api.py +186 -0
- phyling-7.0.4/phyling/ble/__init__.py +4 -0
- phyling-7.0.4/phyling/ble/base_device.py +464 -0
- phyling-7.0.4/phyling/ble/miniphyling.py +97 -0
- phyling-7.0.4/phyling/ble/nanophyling.py +52 -0
- phyling-7.0.4/phyling/ble/phyling_devices.py +212 -0
- phyling-7.0.4/phyling/decoder/calib_texisense.py +165 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling/decoder/calibration_use.py +31 -8
- phyling-7.0.4/phyling/decoder/decoder.py +450 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling/decoder/decoder_utils.c +11723 -8533
- {phyling-7.0.2 → phyling-7.0.4}/phyling/decoder/decoder_utils.pyx +275 -66
- phyling-7.0.4/phyling/phyling_utils.py +29 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling.egg-info/PKG-INFO +14 -3
- {phyling-7.0.2 → phyling-7.0.4}/phyling.egg-info/SOURCES.txt +12 -5
- {phyling-7.0.2 → phyling-7.0.4}/setup.py +7 -1
- phyling-7.0.2/examples/Nano-Phyling/nanophyling.ipynb +0 -117
- phyling-7.0.2/examples/Phyling API/Phyling python lib/api.ipynb +0 -304
- phyling-7.0.2/phyling/ble/nanophyling.py +0 -309
- phyling-7.0.2/phyling/decoder/decoder.py +0 -52
- phyling-7.0.2/phyling/phyling_utils.py +0 -113
- {phyling-7.0.2 → phyling-7.0.4}/.flake8 +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/.github/workflows/python-publish.yml +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/LICENSE.txt +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/MANIFEST.in +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/examples/Analyse/example_data.txt +0 -0
- {phyling-7.0.2/examples/Nano-Phyling → phyling-7.0.4/examples/NanoPhyling-MiniPhyling}/lab_examples/data/pendulum_example.csv +0 -0
- {phyling-7.0.2/examples/Nano-Phyling → phyling-7.0.4/examples/NanoPhyling-MiniPhyling}/lab_examples/data/pendulum_picture.jpg +0 -0
- {phyling-7.0.2/examples/Nano-Phyling → phyling-7.0.4/examples/NanoPhyling-MiniPhyling}/lab_examples/data/pendulum_video.mp4 +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/examples/Phyling API/Phyling python lib/realtime.ipynb +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/examples/Phyling API/RAW API examples/minimal_apikey.html +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/examples/Phyling API/RAW API examples/realtime.html +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/examples/Phyling API/RAW API examples/requirement.txt +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/examples/Phyling API/RAW API examples/single-device.html +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling/__init__.py +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling/api/__init__.py +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling/api/phylingSocket.py +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling/api/realtime.py +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling/api/record.py +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling/api/user.py +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling/api/utils.py +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling/decoder/__init__.py +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling.egg-info/dependency_links.txt +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling.egg-info/requires.txt +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/phyling.egg-info/top_level.txt +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/pyproject.toml +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/requirements.txt +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/setup.cfg +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/tests/__init__.py +0 -0
- {phyling-7.0.2 → phyling-7.0.4}/tests/test_base.py +0 -0
|
@@ -48,7 +48,7 @@ repos:
|
|
|
48
48
|
rev: 0.6.1
|
|
49
49
|
hooks:
|
|
50
50
|
- id: nbstripout
|
|
51
|
-
exclude: ^examples/
|
|
51
|
+
exclude: ^examples/NanoPhyling-MiniPhyling/lab_examples/.*\.ipynb$
|
|
52
52
|
- repo: https://github.com/compilerla/conventional-pre-commit
|
|
53
53
|
rev: v4.2.0
|
|
54
54
|
hooks:
|
phyling-7.0.4/CLAUDE.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this directory.
|
|
4
|
+
|
|
5
|
+
## Présentation
|
|
6
|
+
|
|
7
|
+
`phyling` est le package core Python de la plateforme Phyling. Il contient le code Cython pour la communication BLE avec les devices et les algorithmes d'analyse de base.
|
|
8
|
+
|
|
9
|
+
## Stack
|
|
10
|
+
|
|
11
|
+
- **Langage :** Python 3.10 + Cython
|
|
12
|
+
- **Build :** setuptools avec extensions Cython (`pyproject.toml`)
|
|
13
|
+
- **Dépendances :** numpy, bleak, ujson, urllib3, aiohttp, python-socketio
|
|
14
|
+
- **Installation :** mode éditable `pip install -e .`
|
|
15
|
+
|
|
16
|
+
## Build
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
cd PhylingApp/phyling
|
|
20
|
+
|
|
21
|
+
# Compiler les extensions Cython
|
|
22
|
+
pip install -e .
|
|
23
|
+
|
|
24
|
+
# Restart via Docker après recompilation
|
|
25
|
+
just --justfile ../infra/justfile docker-restart cloud-simu-dev latest "celery managers realtime-manager"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
> ⚠️ Toute modification de fichiers `.pyx` nécessite une recompilation.
|
|
29
|
+
|
|
30
|
+
## Conventions
|
|
31
|
+
|
|
32
|
+
- **Python 3.10**, 4 espaces, limite 120 caractères
|
|
33
|
+
- **Linting :** Flake8
|
|
34
|
+
- **Formatage :** Black
|
|
35
|
+
- **Cython :** fichiers `.pyx` compilés en `.c` puis `.so`
|
|
36
|
+
|
|
37
|
+
Voir `PhylingApp/CLAUDE.md` pour les conventions communes (imports, logs, docstrings).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: phyling
|
|
3
|
-
Version: 7.0.
|
|
3
|
+
Version: 7.0.4
|
|
4
4
|
Summary: Phyling public package
|
|
5
5
|
License: MIT License
|
|
6
6
|
|
|
@@ -49,6 +49,16 @@ Installez depuis les sources :
|
|
|
49
49
|
pip install -e .
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
### Prérequis Windows
|
|
53
|
+
|
|
54
|
+
Le package contient une extension Cython qui nécessite un compilateur C++. Sur Windows, deux outils sont requis avant d'installer :
|
|
55
|
+
|
|
56
|
+
1. **Git pour Windows** : https://git-scm.com/download/win
|
|
57
|
+
2. **Microsoft C++ Build Tools** : https://visualstudio.microsoft.com/visual-cpp-build-tools/
|
|
58
|
+
- Dans l'installateur, cocher **"Développement Desktop en C++"**
|
|
59
|
+
|
|
60
|
+
Relancer ensuite `pip install -e .` dans un nouveau terminal après l'installation.
|
|
61
|
+
|
|
52
62
|
## Exemples
|
|
53
63
|
|
|
54
64
|
Cette partie regroupe plusieurs exemples :
|
|
@@ -59,8 +69,9 @@ Cette partie regroupe plusieurs exemples :
|
|
|
59
69
|
### Décoder un fichier brut Phyling
|
|
60
70
|
- `phyling/examples/Analyse/decoder.ipynb` : notebook qui charge un enregistrement `.txt` brut, décrit les trames disponibles et les convertit en tableaux/pandas exploitables pour vos analyses.
|
|
61
71
|
|
|
62
|
-
### Récupérer les données d'un NanoPhyling
|
|
63
|
-
- `examples/
|
|
72
|
+
### Récupérer les données d'un MiniPhyling ou d'un NanoPhyling
|
|
73
|
+
- `examples/NanoPhyling-MiniPhyling/single_device.ipynb` : notebook qui se connecte à un seul Mini-Phyling ou Nano-Phyling, fait une acquisition puis affiche les données
|
|
74
|
+
- `examples/NanoPhyling-MiniPhyling/multi_devices.ipynb` : notebook qui se connecte à plusieurs devices en parallèle et fusionne les acquisitions
|
|
64
75
|
|
|
65
76
|
### Se connecter à l'API Phyling
|
|
66
77
|
La documentation de l'API Phyling est disponible ici : [docs.phyling.fr/api](https://docs.phyling.fr/api/)
|
|
@@ -12,6 +12,16 @@ Installez depuis les sources :
|
|
|
12
12
|
pip install -e .
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
### Prérequis Windows
|
|
16
|
+
|
|
17
|
+
Le package contient une extension Cython qui nécessite un compilateur C++. Sur Windows, deux outils sont requis avant d'installer :
|
|
18
|
+
|
|
19
|
+
1. **Git pour Windows** : https://git-scm.com/download/win
|
|
20
|
+
2. **Microsoft C++ Build Tools** : https://visualstudio.microsoft.com/visual-cpp-build-tools/
|
|
21
|
+
- Dans l'installateur, cocher **"Développement Desktop en C++"**
|
|
22
|
+
|
|
23
|
+
Relancer ensuite `pip install -e .` dans un nouveau terminal après l'installation.
|
|
24
|
+
|
|
15
25
|
## Exemples
|
|
16
26
|
|
|
17
27
|
Cette partie regroupe plusieurs exemples :
|
|
@@ -22,8 +32,9 @@ Cette partie regroupe plusieurs exemples :
|
|
|
22
32
|
### Décoder un fichier brut Phyling
|
|
23
33
|
- `phyling/examples/Analyse/decoder.ipynb` : notebook qui charge un enregistrement `.txt` brut, décrit les trames disponibles et les convertit en tableaux/pandas exploitables pour vos analyses.
|
|
24
34
|
|
|
25
|
-
### Récupérer les données d'un NanoPhyling
|
|
26
|
-
- `examples/
|
|
35
|
+
### Récupérer les données d'un MiniPhyling ou d'un NanoPhyling
|
|
36
|
+
- `examples/NanoPhyling-MiniPhyling/single_device.ipynb` : notebook qui se connecte à un seul Mini-Phyling ou Nano-Phyling, fait une acquisition puis affiche les données
|
|
37
|
+
- `examples/NanoPhyling-MiniPhyling/multi_devices.ipynb` : notebook qui se connecte à plusieurs devices en parallèle et fusionne les acquisitions
|
|
27
38
|
|
|
28
39
|
### Se connecter à l'API Phyling
|
|
29
40
|
La documentation de l'API Phyling est disponible ici : [docs.phyling.fr/api](https://docs.phyling.fr/api/)
|
|
@@ -7,10 +7,27 @@
|
|
|
7
7
|
"source": [
|
|
8
8
|
"# Example notebook\n",
|
|
9
9
|
"\n",
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
10
|
+
"Ce notebook illustre comment :\n",
|
|
11
|
+
"1. Décoder un fichier brut (format `.txt`) et obtenir les données en mémoire (JSON)\n",
|
|
12
|
+
"2. Processer le fichier brut en JSON et le sauvegarder sur disque\n",
|
|
13
|
+
"3. Générer un DataFrame depuis les données et le sauvegarder sur disque\n"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"cell_type": "code",
|
|
18
|
+
"execution_count": null,
|
|
19
|
+
"id": "9fc37f87",
|
|
20
|
+
"metadata": {},
|
|
21
|
+
"outputs": [],
|
|
22
|
+
"source": [
|
|
23
|
+
"%matplotlib widget\n",
|
|
24
|
+
"import matplotlib.pyplot as plt\n",
|
|
25
|
+
"\n",
|
|
26
|
+
"from phyling.decoder import decoder\n",
|
|
27
|
+
"from phyling import phyling_utils\n",
|
|
28
|
+
"\n",
|
|
29
|
+
"path = \"./\"\n",
|
|
30
|
+
"raw_file = \"example_data.txt\""
|
|
14
31
|
]
|
|
15
32
|
},
|
|
16
33
|
{
|
|
@@ -18,21 +35,42 @@
|
|
|
18
35
|
"id": "ba52e96f-8bd9-401a-b4d6-8f6b0993a7c5",
|
|
19
36
|
"metadata": {},
|
|
20
37
|
"source": [
|
|
21
|
-
"## 1.
|
|
38
|
+
"## 1. Décoder le fichier → JSON en mémoire"
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"cell_type": "markdown",
|
|
43
|
+
"id": "719011ea",
|
|
44
|
+
"metadata": {},
|
|
45
|
+
"source": [
|
|
46
|
+
"### 1.1 (optionnel) Changer ou réinitialiser la calibration du fichier\n",
|
|
47
|
+
"Cette étape va modifier le fichier brut mais en sauvegarder une copie"
|
|
22
48
|
]
|
|
23
49
|
},
|
|
24
50
|
{
|
|
25
51
|
"cell_type": "code",
|
|
26
52
|
"execution_count": null,
|
|
27
|
-
"id": "
|
|
53
|
+
"id": "252c84b2",
|
|
28
54
|
"metadata": {},
|
|
29
55
|
"outputs": [],
|
|
30
56
|
"source": [
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"\n",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
57
|
+
"oldFilename = raw_file[:-3] + \"old.\" + raw_file[-3:]\n",
|
|
58
|
+
"newCalibration = {}\n",
|
|
59
|
+
"print(f\"Rename {raw_file} to {oldFilename} and update the calibration of {raw_file} with {newCalibration}\")\n",
|
|
60
|
+
"decoder.updateCalibration(\n",
|
|
61
|
+
" filename=path + raw_file,\n",
|
|
62
|
+
" oldFilename=path + oldFilename,\n",
|
|
63
|
+
" calibration=newCalibration,\n",
|
|
64
|
+
" use_s3=False,\n",
|
|
65
|
+
")"
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"cell_type": "markdown",
|
|
70
|
+
"id": "0993bffc",
|
|
71
|
+
"metadata": {},
|
|
72
|
+
"source": [
|
|
73
|
+
"### 1.2 Décoder le fichier"
|
|
36
74
|
]
|
|
37
75
|
},
|
|
38
76
|
{
|
|
@@ -42,8 +80,6 @@
|
|
|
42
80
|
"metadata": {},
|
|
43
81
|
"outputs": [],
|
|
44
82
|
"source": [
|
|
45
|
-
"path = \"./\"\n",
|
|
46
|
-
"raw_file = \"example_data.txt\"\n",
|
|
47
83
|
"data = decoder.decode(path + raw_file, verbose=True, use_s3=False)"
|
|
48
84
|
]
|
|
49
85
|
},
|
|
@@ -52,7 +88,7 @@
|
|
|
52
88
|
"id": "9b7f69f8",
|
|
53
89
|
"metadata": {},
|
|
54
90
|
"source": [
|
|
55
|
-
"## 2.
|
|
91
|
+
"## 2. Processer le fichier brut en JSON (et sauvegarder)"
|
|
56
92
|
]
|
|
57
93
|
},
|
|
58
94
|
{
|
|
@@ -62,7 +98,7 @@
|
|
|
62
98
|
"metadata": {},
|
|
63
99
|
"outputs": [],
|
|
64
100
|
"source": [
|
|
65
|
-
"#
|
|
101
|
+
"# Décoder et sauvegarder un fichier\n",
|
|
66
102
|
"decoder.decodeSave(path + raw_file, overwrite=False, verbose=True)"
|
|
67
103
|
]
|
|
68
104
|
},
|
|
@@ -73,83 +109,77 @@
|
|
|
73
109
|
"metadata": {},
|
|
74
110
|
"outputs": [],
|
|
75
111
|
"source": [
|
|
76
|
-
"#
|
|
112
|
+
"# Décoder et sauvegarder tous les fichiers d'un dossier\n",
|
|
77
113
|
"processed_files = decoder.decodeSaveFolder(path, overwrite=False, verbose=True)\n",
|
|
78
114
|
"print(processed_files)"
|
|
79
115
|
]
|
|
80
116
|
},
|
|
117
|
+
{
|
|
118
|
+
"cell_type": "code",
|
|
119
|
+
"execution_count": null,
|
|
120
|
+
"id": "c60d6783",
|
|
121
|
+
"metadata": {},
|
|
122
|
+
"outputs": [],
|
|
123
|
+
"source": [
|
|
124
|
+
"# Charger le fichier JSON sauvegardé\n",
|
|
125
|
+
"json_file = raw_file.replace(\".txt\", \".json\")\n",
|
|
126
|
+
"data = phyling_utils.load_json(path + json_file)"
|
|
127
|
+
]
|
|
128
|
+
},
|
|
81
129
|
{
|
|
82
130
|
"cell_type": "markdown",
|
|
83
131
|
"id": "c1f234ae",
|
|
84
132
|
"metadata": {},
|
|
85
133
|
"source": [
|
|
86
|
-
"## 3.
|
|
134
|
+
"## 3. Générer un DataFrame (et sauvegarder)"
|
|
87
135
|
]
|
|
88
136
|
},
|
|
89
137
|
{
|
|
90
138
|
"cell_type": "code",
|
|
91
139
|
"execution_count": null,
|
|
92
|
-
"id": "
|
|
140
|
+
"id": "f367e153",
|
|
93
141
|
"metadata": {},
|
|
94
142
|
"outputs": [],
|
|
95
143
|
"source": [
|
|
96
|
-
"#
|
|
97
|
-
"
|
|
98
|
-
"data = phyling_utils.load_json(path + json_file)"
|
|
144
|
+
"# Générer le DataFrame depuis les données\n",
|
|
145
|
+
"df = decoder.json2csv(data)"
|
|
99
146
|
]
|
|
100
147
|
},
|
|
101
148
|
{
|
|
102
149
|
"cell_type": "code",
|
|
103
150
|
"execution_count": null,
|
|
104
|
-
"id": "
|
|
151
|
+
"id": "7ed8ef70",
|
|
105
152
|
"metadata": {},
|
|
106
153
|
"outputs": [],
|
|
107
154
|
"source": [
|
|
108
|
-
"
|
|
109
|
-
"\n",
|
|
110
|
-
"modName = \"imu\"\n",
|
|
111
|
-
"mod = data[\"modules\"][modName][\"data\"]\n",
|
|
112
|
-
"\n",
|
|
113
|
-
"plt.figure()\n",
|
|
114
|
-
"plt.plot(mod[\"T\"], mod[\"acc_x\"])\n",
|
|
115
|
-
"plt.xlabel(\"Temps (s)\")\n",
|
|
116
|
-
"plt.ylabel(\"Acc. (m/s$^2$)\")"
|
|
155
|
+
"df.head()"
|
|
117
156
|
]
|
|
118
157
|
},
|
|
119
158
|
{
|
|
120
159
|
"cell_type": "code",
|
|
121
160
|
"execution_count": null,
|
|
122
|
-
"id": "
|
|
161
|
+
"id": "a1b2c3d4",
|
|
123
162
|
"metadata": {},
|
|
124
163
|
"outputs": [],
|
|
125
164
|
"source": [
|
|
126
|
-
"#
|
|
127
|
-
"\n",
|
|
128
|
-
"df
|
|
129
|
-
"print(list(df))\n",
|
|
130
|
-
"df[\"imu\"].head()"
|
|
165
|
+
"# Sauvegarder le DataFrame en CSV\n",
|
|
166
|
+
"csv_file = raw_file.replace(\".txt\", \".csv\")\n",
|
|
167
|
+
"df.to_csv(path + csv_file, index=False)"
|
|
131
168
|
]
|
|
132
169
|
},
|
|
133
170
|
{
|
|
134
171
|
"cell_type": "code",
|
|
135
172
|
"execution_count": null,
|
|
136
|
-
"id": "
|
|
173
|
+
"id": "f3116bf5",
|
|
137
174
|
"metadata": {},
|
|
138
175
|
"outputs": [],
|
|
139
176
|
"source": [
|
|
177
|
+
"# Visualisation\n",
|
|
140
178
|
"plt.figure()\n",
|
|
141
|
-
"plt.plot(df[\"
|
|
179
|
+
"plt.plot(df[\"T\"], df[\"imu.acc_x\"])\n",
|
|
142
180
|
"plt.xlabel(\"Temps (s)\")\n",
|
|
143
181
|
"plt.ylabel(\"Acc. (m/s$^2$)\")"
|
|
144
182
|
]
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
"cell_type": "code",
|
|
148
|
-
"execution_count": null,
|
|
149
|
-
"id": "aa491911",
|
|
150
|
-
"metadata": {},
|
|
151
|
-
"outputs": [],
|
|
152
|
-
"source": []
|
|
153
183
|
}
|
|
154
184
|
],
|
|
155
185
|
"metadata": {
|
|
@@ -168,7 +198,7 @@
|
|
|
168
198
|
"name": "python",
|
|
169
199
|
"nbconvert_exporter": "python",
|
|
170
200
|
"pygments_lexer": "ipython3",
|
|
171
|
-
"version": "3.10.
|
|
201
|
+
"version": "3.10.20"
|
|
172
202
|
}
|
|
173
203
|
},
|
|
174
204
|
"nbformat": 4,
|
|
@@ -22,9 +22,7 @@
|
|
|
22
22
|
"from scipy.optimize import curve_fit\n",
|
|
23
23
|
"from scipy.integrate import cumulative_trapezoid\n",
|
|
24
24
|
"from scipy.interpolate import interp1d\n",
|
|
25
|
-
"from scipy.signal import butter, filtfilt\n",
|
|
26
25
|
"from phyling.ble.nanophyling import NanoPhyling\n",
|
|
27
|
-
"from tabulate import tabulate\n",
|
|
28
26
|
"from IPython.display import Video, display\n",
|
|
29
27
|
"import matplotlib.image as mpimg\n",
|
|
30
28
|
"\n",
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "code",
|
|
5
|
+
"execution_count": null,
|
|
6
|
+
"metadata": {},
|
|
7
|
+
"outputs": [],
|
|
8
|
+
"source": [
|
|
9
|
+
"%matplotlib widget\n",
|
|
10
|
+
"import matplotlib.pyplot as plt\n",
|
|
11
|
+
"import nest_asyncio\n",
|
|
12
|
+
"\n",
|
|
13
|
+
"nest_asyncio.apply() # used in notebook\n",
|
|
14
|
+
"\n",
|
|
15
|
+
"from phyling.ble import NanoPhyling, MiniPhyling, PhylingDevices"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"cell_type": "code",
|
|
20
|
+
"execution_count": null,
|
|
21
|
+
"metadata": {},
|
|
22
|
+
"outputs": [],
|
|
23
|
+
"source": [
|
|
24
|
+
"devices = PhylingDevices(\n",
|
|
25
|
+
" [\n",
|
|
26
|
+
" MiniPhyling(\n",
|
|
27
|
+
" module_name=\"gauche\", # Optionnel, par défaut on utilise le nom Bluetooth\n",
|
|
28
|
+
" ble_name=\"MiniPhyling_42\"\n",
|
|
29
|
+
" ),\n",
|
|
30
|
+
" NanoPhyling(\n",
|
|
31
|
+
" module_name=\"droite\", # Optionnel, par défaut on utilise le nom Bluetooth\n",
|
|
32
|
+
" ble_name=\"NanoPhyling_42\",\n",
|
|
33
|
+
" config={\"rate\": 200, \"data\": [\"acc_x\", \"acc_y\", \"acc_z\", \"gyro_x\", \"gyro_y\", \"gyro_z\", \"mag_x\", \"mag_y\", \"mag_z\"]},\n",
|
|
34
|
+
" ),\n",
|
|
35
|
+
" ],\n",
|
|
36
|
+
" output_fs=200,\n",
|
|
37
|
+
")"
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"cell_type": "markdown",
|
|
42
|
+
"metadata": {},
|
|
43
|
+
"source": [
|
|
44
|
+
"## Calibration\n",
|
|
45
|
+
"\n",
|
|
46
|
+
"`tare()` enregistre 5s de données immobiles par device (en parallèle) et calcule un offset par colonne. \n",
|
|
47
|
+
"La calibration s'applique automatiquement dans `get_df()` : `coef * (val + offset)`. \n",
|
|
48
|
+
"Le df existant de chaque device est **préservé**."
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"cell_type": "code",
|
|
53
|
+
"execution_count": null,
|
|
54
|
+
"metadata": {},
|
|
55
|
+
"outputs": [],
|
|
56
|
+
"source": [
|
|
57
|
+
"# Tare sur plusieurs devices en parallèle\n",
|
|
58
|
+
"devices.tare({\n",
|
|
59
|
+
" \"droite\": [\"gyro_x\", \"gyro_y\", \"gyro_z\"],\n",
|
|
60
|
+
" \"gauche\": [\"gyro_x\", \"gyro_y\", \"gyro_z\"],\n",
|
|
61
|
+
"})"
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"cell_type": "code",
|
|
66
|
+
"execution_count": null,
|
|
67
|
+
"metadata": {},
|
|
68
|
+
"outputs": [],
|
|
69
|
+
"source": [
|
|
70
|
+
"# Voir la calibration de tous les devices\n",
|
|
71
|
+
"devices.get_calib()"
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"cell_type": "code",
|
|
76
|
+
"execution_count": null,
|
|
77
|
+
"metadata": {},
|
|
78
|
+
"outputs": [],
|
|
79
|
+
"source": [
|
|
80
|
+
"# Reset la calibration (vide le dict, pas de calibration)\n",
|
|
81
|
+
"devices.reset_calib()"
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"cell_type": "code",
|
|
86
|
+
"execution_count": null,
|
|
87
|
+
"metadata": {},
|
|
88
|
+
"outputs": [],
|
|
89
|
+
"source": [
|
|
90
|
+
"# Remplacer la calibration d'un device\n",
|
|
91
|
+
"devices.set_calib({\n",
|
|
92
|
+
" \"droite\": {\n",
|
|
93
|
+
" \"mag_z\": {\"coef\": 1, \"offset\": 0},\n",
|
|
94
|
+
" },\n",
|
|
95
|
+
"})"
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"cell_type": "code",
|
|
100
|
+
"execution_count": null,
|
|
101
|
+
"metadata": {},
|
|
102
|
+
"outputs": [],
|
|
103
|
+
"source": [
|
|
104
|
+
"# Merger une calibration partielle\n",
|
|
105
|
+
"devices.update_calib({\n",
|
|
106
|
+
" \"droite\": {\n",
|
|
107
|
+
" \"acc_z\": {\"coef\": 1.02, \"offset\": 0},\n",
|
|
108
|
+
" },\n",
|
|
109
|
+
"})"
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"cell_type": "code",
|
|
114
|
+
"execution_count": null,
|
|
115
|
+
"metadata": {},
|
|
116
|
+
"outputs": [],
|
|
117
|
+
"source": [
|
|
118
|
+
"# On peut aussi calibrer un device directement\n",
|
|
119
|
+
"droite = devices.get_device(\"droite\")\n",
|
|
120
|
+
"droite.tare([\"gyro_z\"])\n",
|
|
121
|
+
"droite.get_calib()"
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"cell_type": "markdown",
|
|
126
|
+
"metadata": {},
|
|
127
|
+
"source": [
|
|
128
|
+
"## Acquisition"
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"cell_type": "code",
|
|
133
|
+
"execution_count": null,
|
|
134
|
+
"metadata": {},
|
|
135
|
+
"outputs": [],
|
|
136
|
+
"source": [
|
|
137
|
+
"# Vous pouvez kill la cell pendant l'exécution pour arrêter l'enregistrement\n",
|
|
138
|
+
"devices.run(duration=30)"
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"cell_type": "code",
|
|
143
|
+
"execution_count": null,
|
|
144
|
+
"metadata": {},
|
|
145
|
+
"outputs": [],
|
|
146
|
+
"source": [
|
|
147
|
+
"# La calibration est appliquée ici pour chaque device\n",
|
|
148
|
+
"df = devices.get_df(drop_nan=False)\n",
|
|
149
|
+
"df.head()"
|
|
150
|
+
]
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"cell_type": "code",
|
|
154
|
+
"execution_count": null,
|
|
155
|
+
"metadata": {},
|
|
156
|
+
"outputs": [],
|
|
157
|
+
"source": [
|
|
158
|
+
"cols = [\"acc_x\", \"acc_y\", \"acc_z\"]\n",
|
|
159
|
+
"\n",
|
|
160
|
+
"fig, axes = plt.subplots(len(cols), 1, sharex=True, figsize=(8, 6))\n",
|
|
161
|
+
"\n",
|
|
162
|
+
"for i, col in enumerate(cols):\n",
|
|
163
|
+
" ax = axes[i]\n",
|
|
164
|
+
"\n",
|
|
165
|
+
" for device in devices.devices:\n",
|
|
166
|
+
" colname = f\"{device.get_name()}.{col}\"\n",
|
|
167
|
+
" if colname in df.columns:\n",
|
|
168
|
+
" ax.plot(df[\"T\"], df[colname], label=colname)\n",
|
|
169
|
+
"\n",
|
|
170
|
+
" ax.set_title(col)\n",
|
|
171
|
+
" ax.grid()\n",
|
|
172
|
+
" ax.legend()\n",
|
|
173
|
+
"\n",
|
|
174
|
+
"axes[-1].set_xlabel(\"Time (s)\")\n",
|
|
175
|
+
"plt.tight_layout()"
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"cell_type": "code",
|
|
180
|
+
"execution_count": null,
|
|
181
|
+
"metadata": {},
|
|
182
|
+
"outputs": [],
|
|
183
|
+
"source": [
|
|
184
|
+
"# Enregistrer les données dans un CSV\n",
|
|
185
|
+
"# df.to_csv(\"example_data.csv\", index=False)"
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
],
|
|
189
|
+
"metadata": {
|
|
190
|
+
"kernelspec": {
|
|
191
|
+
"display_name": "venv",
|
|
192
|
+
"language": "python",
|
|
193
|
+
"name": "python3"
|
|
194
|
+
},
|
|
195
|
+
"language_info": {
|
|
196
|
+
"codemirror_mode": {
|
|
197
|
+
"name": "ipython",
|
|
198
|
+
"version": 3
|
|
199
|
+
},
|
|
200
|
+
"file_extension": ".py",
|
|
201
|
+
"mimetype": "text/x-python",
|
|
202
|
+
"name": "python",
|
|
203
|
+
"nbconvert_exporter": "python",
|
|
204
|
+
"pygments_lexer": "ipython3",
|
|
205
|
+
"version": "3.10.19"
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"nbformat": 4,
|
|
209
|
+
"nbformat_minor": 4
|
|
210
|
+
}
|