Skip to content

Commit 66e00b8

Browse files
au650680au650680
andauthored
Improves Clustering and Mode tracking (#22)
- Fixes errors in clustering and mode tracking code. Refactors the code into smaller functions. - Adds new examples to showcase new capabilities - Updates config format --------- Co-authored-by: au650680 <au650680@uni.au.dk>
1 parent a57a39b commit 66e00b8

40 files changed

+2511
-1295
lines changed

config/production.json.template

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,53 @@
11
{
22
"MQTT": {
3-
"host": "test.mosquitto.org",
4-
"port": 1883,
3+
"host": "",
4+
"port": ,
55
"userId": "",
66
"password": "",
7-
"ClientID": "ReplaySubscriber",
7+
"ClientID": "NOT_NEEDED",
88
"QoS": 1,
99
"TopicsToSubscribe": [
10-
"cpsens/recorded/1/data",
11-
"cpsens/recorded/1/metadata",
12-
"cpsens/recorded/2/data",
13-
"cpsens/recorded/+/data"
10+
"cpsens/d8-3a-dd-37-d2-7e/3050-A-060_sn_106209/1/acc/raw/data",
11+
"cpsens/d8-3a-dd-37-d2-7e/3050-A-060_sn_106209/1/acc/raw/metadata",
12+
"cpsens/d8-3a-dd-37-d2-7e/3050-A-060_sn_106209/2/acc/raw/data",
13+
"cpsens/d8-3a-dd-37-d2-7e/3050-A-060_sn_106209/3/acc/raw/data",
14+
"cpsens/d8-3a-dd-37-d2-7e/3050-A-060_sn_106209/4/acc/raw/data"
1415
]
1516
},
1617

1718
"sysID": {
1819
"host": "",
19-
"port": 1883,
20+
"port": ,
2021
"userId": "",
2122
"password": "",
22-
"ClientID": "sub.232.sds.213s",
23-
"QoS": 1,
24-
"TopicsToSubscribe": ["cpsens/d8-3a-dd-f5-92-48/cpsns_Simulator/1_2/oma_results"]
23+
"ClientID": "NOT_NEEDED",
24+
"QoS": 2,
25+
"TopicsToSubscribe": ["cpsens/d8-3a-dd-37-d2-7e/3050-A-060_sn_106209/1/acc/sysid/data"]
26+
},
27+
28+
"mode_cluster": {
29+
"host": "",
30+
"port": ,
31+
"userId": "",
32+
"password": "",
33+
"ClientID": "NOT_NEEDED",
34+
"QoS": 2,
35+
"TopicsToSubscribe": ["cpsens/d8-3a-dd-37-d2-7e/3050-A-060_sn_106209/1/acc/mode_cluster/data"]
36+
},
37+
38+
"model_update": {
39+
"host": "",
40+
"port": ,
41+
"userId": "",
42+
"password": "",
43+
"ClientID": "NOT_NEEDED",
44+
"QoS": 2,
45+
"TopicsToSubscribe": ["cpsens/d8-3a-dd-37-d2-7e/3050-A-060_sn_106209/1/acc/model_update/data"]
2546
}
2647
}
2748

2849

2950

51+
52+
53+

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ paho-mqtt = "^2.1.0"
1616
numpy = "^2.2.5"
1717
click ="^8.1.8"
1818
pyOMA-2 = "1.0.0"
19-
yafem = { path = "src/methods/packages/yafem-0.2.6-py3-none-any.whl" }
19+
yafem = "1.0.0"
2020

2121

2222
[tool.poetry.group.dev.dependencies]

src/data/accel/hbk/accelerometer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def process_message(self, msg: mqtt.MQTTMessage) -> None:
8686
if not oldest_deque: # Remove the key/deque from the map if it's empty
8787
del self.data_map[oldest_key]
8888
total_samples = sum(len(dq) for dq in self.data_map.values())
89-
print(f" Channel: {self.topic} Key: {samples_from_daq_start}, Samples: {num_samples}")
89+
#print(f" Channel: {self.topic} Key: {samples_from_daq_start}, Samples: {num_samples}")
9090

9191
except Exception as e:
9292
print(f"Error processing message: {e}")

src/data/accel/hbk/aligner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def _extract_aligned_block(self, group: List[int], batch_size: int,
130130
ch.clear_used_data(group[0], requested_samples)
131131

132132
aligned_array = np.array(aligned_data, dtype=np.float32)
133-
print(f"Aligned shape: {aligned_array.shape}")
133+
print(f"\nAligned shape: {aligned_array.shape}")
134134
return aligned_array, utc_time
135135

136136

src/examples/README.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,18 @@ To run the examples with the default config, use:
6262
```bash
6363
python .\src\examples\example.py accelerometers
6464
python .\src\examples\example.py align-readings
65-
python .\src\examples\example.py oma-and-print
66-
python .\src\examples\example.py oma-and-plot
67-
python .\src\examples\example.py oma-and-publish
68-
python .\src\examples\example.py mode-tracking-with-local-sysid
69-
python .\src\examples\example.py mode-tracking-with-remote-sysid
65+
python .\src\examples\example.py sysid-and-print
66+
python .\src\examples\example.py sysid-and-plot
67+
python .\src\examples\example.py sysid-and-publish
68+
python .\src\examples\example.py live-sysid-publish
69+
python .\src\examples\example.py clustering-with-local-sysid
70+
python .\src\examples\example.py clustering-with-remote-sysid
71+
python .\src\examples\example.py live-clustering-with-remote-sysid
72+
python .\src\examples\example.py mode-tracking-remote-sysid
73+
python .\src\examples\example.py mode_tracking-with-local-sysid
74+
python .\src\examples\example.py live-mode-tracking-remote-sysid
7075
python .\src\examples\example.py model-update-local-sysid
71-
python .\src\examples\example.py model-update-remote-sysid
76+
python .\src\examples\example.py ilve-model-update-remote-sysid
7277

7378
```
7479

src/examples/example.py

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,23 @@
22
import click
33
from examples.acceleration_readings import read_accelerometers
44
from examples.aligning_readings import align_acceleration_readings
5-
from examples.run_pyoma import (
6-
run_oma_and_plot,
7-
run_oma_and_publish,
8-
run_oma_and_print,
5+
from examples.run_sysid import (
6+
run_sysid_and_plot,
7+
run_sysid_and_publish,
8+
run_sysid_and_print,
9+
live_sysid_and_publish
910
)
10-
from examples.mode_tracking import (
11+
from examples.run_mode_clustering import (
12+
run_mode_clustering_with_local_sysid,
13+
run_mode_clustering_with_remote_sysid,
14+
run_live_mode_clustering_with_remote_sysid
15+
)
16+
from examples.run_mode_tracking import (
1117
run_mode_tracking_with_local_sysid,
1218
run_mode_tracking_with_remote_sysid,
19+
run_live_mode_tracking_with_remote_sysid
1320
)
14-
from examples.updating_parameters import (
21+
from examples.run_model_update import (
1522
run_model_update_local_sysid,
1623
run_model_update_remote_sysid
1724
)
@@ -34,22 +41,40 @@ def accelerometers(ctx):
3441
def align_readings(ctx):
3542
align_acceleration_readings(ctx.obj["CONFIG"])
3643

44+
@cli.command()
45+
@click.pass_context
46+
def sysid_and_publish(ctx):
47+
run_sysid_and_publish(ctx.obj["CONFIG"])
3748

3849
@cli.command()
3950
@click.pass_context
40-
def oma_and_publish(ctx):
41-
run_oma_and_publish(ctx.obj["CONFIG"])
51+
def live_sysid_publish(ctx):
52+
live_sysid_and_publish(ctx.obj["CONFIG"])
4253

4354
@cli.command()
4455
@click.pass_context
45-
def oma_and_plot(ctx):
46-
run_oma_and_plot(ctx.obj["CONFIG"])
56+
def sysid_and_plot(ctx):
57+
run_sysid_and_plot(ctx.obj["CONFIG"])
4758

4859
@cli.command()
4960
@click.pass_context
50-
def oma_and_print(ctx):
51-
run_oma_and_print(ctx.obj["CONFIG"])
61+
def sysid_and_print(ctx):
62+
run_sysid_and_print(ctx.obj["CONFIG"])
5263

64+
@cli.command()
65+
@click.pass_context
66+
def clustering_with_local_sysid(ctx):
67+
run_mode_clustering_with_local_sysid(ctx.obj["CONFIG"])
68+
69+
@cli.command()
70+
@click.pass_context
71+
def clustering_with_remote_sysid(ctx):
72+
run_mode_clustering_with_remote_sysid(ctx.obj["CONFIG"])
73+
74+
@cli.command()
75+
@click.pass_context
76+
def live_clustering_with_remote_sysid(ctx):
77+
run_live_mode_clustering_with_remote_sysid(ctx.obj["CONFIG"])
5378

5479
@cli.command()
5580
@click.pass_context
@@ -61,6 +86,10 @@ def mode_tracking_with_local_sysid(ctx):
6186
def mode_tracking_with_remote_sysid(ctx):
6287
run_mode_tracking_with_remote_sysid(ctx.obj["CONFIG"])
6388

89+
@cli.command()
90+
@click.pass_context
91+
def live_mode_tracking_with_remote_sysid(ctx):
92+
run_live_mode_tracking_with_remote_sysid(ctx.obj["CONFIG"])
6493

6594
@cli.command()
6695
@click.pass_context
@@ -69,7 +98,7 @@ def model_update_local_sysid(ctx):
6998

7099
@cli.command()
71100
@click.pass_context
72-
def model_update_remote_sysid(ctx):
101+
def live_model_update_remote_sysid(ctx):
73102
run_model_update_remote_sysid(ctx.obj["CONFIG"])
74103

75104
if __name__ == "__main__":

src/examples/mode_tracking.py

Lines changed: 0 additions & 54 deletions
This file was deleted.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import sys
2+
import time
3+
import matplotlib.pyplot as plt
4+
from data.comm.mqtt import load_config
5+
from data.accel.hbk.aligner import Aligner
6+
from methods import sysid as sysID
7+
from methods import mode_clustering as MC
8+
from methods.constants import PARAMS
9+
from functions.plot_clusters import plot_clusters
10+
11+
# pylint: disable=R0914
12+
def run_mode_clustering_with_local_sysid(config_path):
13+
number_of_minutes = 1
14+
config = load_config(config_path)
15+
mqtt_config = config["MQTT"]
16+
17+
# Setting up the client and extracting Fs
18+
data_client, fs = sysID.setup_client(mqtt_config)
19+
20+
# Setting up the aligner
21+
data_topic_indexes = [0, 2, 3, 4]
22+
selected_topics = [mqtt_config["TopicsToSubscribe"][i] for i in data_topic_indexes]
23+
aligner = Aligner(data_client, topics=selected_topics)
24+
25+
aligner_time = None
26+
t1 = time.time()
27+
while aligner_time is None:
28+
time.sleep(0.1)
29+
t2 = time.time()
30+
t_text = f"Waiting for data for {round(t2-t1,1)} seconds"
31+
print(t_text,end="\r")
32+
sysid_output, aligner_time = sysID.get_sysid_results(number_of_minutes, aligner, fs)
33+
data_client.disconnect()
34+
35+
# Mode Tracks
36+
dictionary_of_clusters, median_frequencies = MC.cluster_sysid(
37+
sysid_output,PARAMS)
38+
39+
# Print frequencies
40+
print("\nMedian frequencies:", median_frequencies)
41+
42+
fig_ax = plot_clusters(dictionary_of_clusters, sysid_output, PARAMS, fig_ax = None)
43+
plt.show(block=True)
44+
sys.stdout.flush()
45+
46+
def run_mode_clustering_with_remote_sysid(config_path):
47+
sysid_output, dictionary_of_clusters, meadian_frequencies = MC.subscribe_and_cluster(config_path,PARAMS)
48+
fig_ax = plot_clusters(dictionary_of_clusters, sysid_output, PARAMS, fig_ax = None)
49+
plt.show(block=True)
50+
sys.stdout.flush()
51+
52+
def run_live_mode_clustering_with_remote_sysid(config_path):
53+
MC.live_mode_clustering(config_path,topic_index=0,plot=[1,1])

src/examples/run_mode_tracking.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import sys
2+
import time
3+
import matplotlib.pyplot as plt
4+
from data.comm.mqtt import load_config
5+
from data.accel.hbk.aligner import Aligner
6+
from methods import sysid as sysID
7+
from methods import mode_clustering as MC
8+
from methods import mode_tracking as MT
9+
from methods.constants import PARAMS
10+
from functions.plot_mode_tracking import plot_tracked_modes
11+
12+
# pylint: disable=R0914
13+
def run_mode_tracking_with_local_sysid(config_path):
14+
number_of_minutes = 1
15+
config = load_config(config_path)
16+
mqtt_config = config["MQTT"]
17+
18+
# Setting up the client and extracting Fs
19+
data_client, fs = sysID.setup_client(mqtt_config)
20+
21+
# Setting up the aligner
22+
data_topic_indexes = [0, 2, 3, 4]
23+
selected_topics = [mqtt_config["TopicsToSubscribe"][i] for i in data_topic_indexes]
24+
aligner = Aligner(data_client, topics=selected_topics)
25+
26+
aligner_time = None
27+
t1 = time.time()
28+
while aligner_time is None:
29+
time.sleep(0.1)
30+
t2 = time.time()
31+
t_text = f"Waiting for data for {round(t2-t1,1)} seconds"
32+
print(t_text,end="\r")
33+
sysid_output, aligner_time = sysID.get_sysid_results(number_of_minutes, aligner, fs)
34+
data_client.disconnect()
35+
36+
# Mode Tracks
37+
dictionary_of_clusters, median_frequencies = MC.cluster_sysid(
38+
sysid_output,PARAMS)
39+
40+
# Print frequencies
41+
print("\nMedian frequencies:", median_frequencies)
42+
43+
tracked_clusters = {}
44+
tracked_clusters = MT.track_clusters(dictionary_of_clusters,tracked_clusters,PARAMS)
45+
46+
fig_ax = plot_tracked_modes(tracked_clusters, PARAMS, fig_ax = None, x_length = None)
47+
plt.show(block=True)
48+
sys.stdout.flush()
49+
50+
def run_mode_tracking_with_remote_sysid(config_path):
51+
sysid_output, clusters, tracked_clusters = MT.subscribe_and_track_clusters(config_path)
52+
fig_ax = plot_tracked_modes(tracked_clusters, PARAMS, fig_ax = None, x_length = None)
53+
plt.show(block=True)
54+
sys.stdout.flush()
55+
56+
def run_live_mode_tracking_with_remote_sysid(config_path):
57+
MT.live_mode_tracking(config_path,plot=[1,1])

0 commit comments

Comments
 (0)