Compare commits

..

No commits in common. "f5dfda57b7d306daae63adcb645b364f24dc7a08" and "1d8fbd49d1cc07aa2977892f6d2bb71a1fc88509" have entirely different histories.

5 changed files with 97 additions and 4320 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +0,0 @@
{"unit": "dumpload_sp", "value": 0.0, "time": 1718013928.6948164}
{"unit": "dumpload_sp", "value": 20.0, "time": 1718013959.6977577}
{"unit": "dumpload_sp", "value": 10.0, "time": 1718013989.6989655}
{"unit": "dumpload_sp", "value": 0.0, "time": 1718014018.716735}

1
demo_datalogger.py Executable file → Normal file
View File

@ -1,4 +1,3 @@
#!./venv/bin/python3
import syslab import syslab
from json import dump from json import dump
from time import sleep, time from time import sleep, time

128
demo_plotter.py Executable file → Normal file
View File

@ -1,13 +1,11 @@
#!./venv/bin/python3
import pandas as pd import pandas as pd
import numpy as np
import json import json
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import os import os
from datetime import timedelta from datetime import timedelta
## Read the measurements data file ## ## Read the measurements data file ##
DATA_MEAS_DIR = 'data/measurements' DATA_MEAS_DIR = 'data\measurements'
# Always plot latest datafile - replace [-1] with another index if you want to plot a specific file. # Always plot latest datafile - replace [-1] with another index if you want to plot a specific file.
MEAS_LOG_FILE = sorted(os.listdir(DATA_MEAS_DIR))[-1] MEAS_LOG_FILE = sorted(os.listdir(DATA_MEAS_DIR))[-1]
@ -21,7 +19,7 @@ use_setpoint_log = False
## Read the setpoints data file ## ## Read the setpoints data file ##
if use_setpoint_log: if use_setpoint_log:
DATA_SP_DIR = 'data/setpoints' DATA_SP_DIR = 'data\setpoints'
# Always plot latest datafile # Always plot latest datafile
SP_LOG_FILE = sorted(os.listdir(DATA_SP_DIR))[-1] SP_LOG_FILE = sorted(os.listdir(DATA_SP_DIR))[-1]
@ -35,39 +33,107 @@ if use_setpoint_log:
else: else:
data = meas_data data = meas_data
################################################################################
################## Part 2 ######################################################
################################################################################
def overshoot(df, T1, T2):
yT1, yT2 = df[T1], df[T2]
over = 1 / (yT1 - yT2) * np.max(yT2 - df)
return over
SETPOINT_UNIX = 1718013959.6977577
SETPOINT_TS = pd.to_datetime(SETPOINT_UNIX, unit='s')
WINDOW = pd.to_datetime(SETPOINT_UNIX+25, unit='s')
## The controller is reasonably fast at reacting to changes; the sum of in and
## out is at zero roughly 5-10 seconds after a change.
# Construct a dataframe and pivot it to obtain a dataframe with a column per unit, and a row per timestamp. # Construct a dataframe and pivot it to obtain a dataframe with a column per unit, and a row per timestamp.
df = pd.DataFrame.from_records(data) df = pd.DataFrame.from_records(data)
df['time'] = pd.to_datetime(df['time'], unit='s')
df_pivot = df.pivot_table(values='value', columns='unit', index='time') df_pivot = df.pivot_table(values='value', columns='unit', index='time')
df_resampled = df_pivot.resample('0.1s').mean()
df_resampled.interpolate(method='linear', inplace=True)
df_resampled = pd.DataFrame(df_resampled)
# Plot the data. Note, that the data will mostly not be plotted with lines. # Plot the data. Note, that the data will mostly not be plotted with lines.
plt.ion() # Turn interactive mode on plt.ion() # Turn interactive mode on
plt.figure() plt.figure()
ax1, ax2 = plt.subplot(211), plt.subplot(212) ax1 = plt.subplot(211) # Make two separate figures
df_resampled[[c for c in df_resampled.columns if '_p' in c]].plot(marker='.', ax=ax1, linewidth=3) ax2 = plt.subplot(212)
ax2.plot(df_resampled['pcc_p'][SETPOINT_TS:WINDOW], marker='.', linewidth=3, label='pcc_p') df_pivot[[c for c in df_pivot.columns if "_p" in c]].plot(marker='.', ax=ax1, linewidth=3)
ax2.plot(df_resampled['dumpload_p'][SETPOINT_TS:WINDOW], marker='.', linewidth=3, label='dumpload') df_pivot[[c for c in df_pivot.columns if "_q" in c]].plot(marker='.', ax=ax2, linewidth=3)
plt.legend()
# print(overshoot(df_resampled['pcc_p'][SETPOINT_TS:WINDOW], SETPOINT_TS, WINDOW))
plt.show(block=True) plt.show(block=True)
## TODO Q1: Your code here
## TODO Q2:
# Convert time column (index) of df_pivot to datetime
# TODO Your code here
# Hint1: You can use pandas to_numeric() to prepare the index for pandas to_datetime function
# Hint2: Remember to define the unit within pandas to_datetime function
# Resample the data
# TODO Your code here
# Interpolate the measurements
# TODO Your code here
# Hint: For part two of the exercise ("collecting fresh data") the nan rows after a setpoint
# in the recorded step function should be filled with the value of the setpoint until the row of the next setpoint is reached
# You can use the df.fillna(method="ffill") function for that purpose. However, the measurements should still be interpolated!
# Plot the resampled data
# TODO Your code here
## TODO Q3: Your code here
## TODO Q4: Your code here
## Part two: "Collecting fresh data"
# Hint 1: You can build up on the "read_and_plot_data.py" from day 2
# Hint 2: Yoy may want to store your response metric functions from day 2 in the "util.py" and import all of them with
# "from util import *"
if use_setpoint_log:
# Add a column to df_pivot containing the reference/target signal
# TODO your code here
# Loop over all steps and extract T_1, T_2 and the step size
results = {}
for idx in range(0, len(sp_data)-1):
label = f"Step_{sp_data[idx]['value']}kW"
# Extract T_1 and T_2 from the setpoint JSON
# TODO your code here
# Change timestamp format
T_1 = pd.to_datetime(pd.to_numeric(T_1), unit="s").round("0.1S")
T_2 = pd.to_datetime(pd.to_numeric(T_2), unit="s").round("0.1S")
# To ensure we are not considering values of the next load step
T_2 = T_2 - timedelta(seconds=0.2)
# define measured output y and target setpoint r
# TODO your code here
# Derive step direction from the setpoint data
if ...: # TODO your code here
Positive_step = True
else:
Positive_step = False
# Collect response metrics results
results[label] = {
# TODO your code here
}
pd.DataFrame.from_dict(results).plot(kind='bar')
plt.title("Metrics")
plt.tight_layout()
plt.savefig('data/test_metrics'+MEAS_LOG_FILE[-10:]+'.png')
plt.show(block=True)

View File

@ -1,28 +0,0 @@
#!./venv/bin/python3
import pandas as pd
import json
import matplotlib.pyplot as plt
import os
DATA_MEAS_DIR = 'data/measurements'
SPECIFIC_FILE = ''
MEAS_LOG_FILE = sorted(os.listdir(DATA_MEAS_DIR))[-1] if not SPECIFIC_FILE else SPECIFIC_FILE
with open(os.path.join(DATA_MEAS_DIR, MEAS_LOG_FILE)) as f:
meas_data = [json.loads(line) for line in f]
data = meas_data
df = pd.DataFrame.from_records(data)
df['time'] = pd.to_datetime(df['time'], unit='s')
df_pivot = df.pivot_table(values='value', columns='unit', index='time')
df_resampled = df_pivot.resample('s').mean()
df_resampled.interpolate(method='linear', inplace=True)
df_resampled = pd.DataFrame(df_resampled)
# Plot the data. Note, that the data will mostly not be plotted with lines.
plt.ion() # Turn interactive mode on
plt.figure()
ax1, ax2 = plt.subplot(211), plt.subplot(212)
df_resampled[[c for c in df_resampled.columns if '_p' in c]].plot(marker='.', ax=ax1, linewidth=3)
df_resampled[[c for c in df_resampled.columns if '_q' in c]].plot(marker='.', ax=ax2, linewidth=3)
plt.show(block=True)