Compare commits

..

10 Commits

Author SHA1 Message Date
DBras f5dfda57b7 question: D3 Part 2 Q2 2024-06-10 15:48:18 +02:00
DBras e6c47bac4e dev: plotting file without fluff 2024-06-10 14:54:10 +02:00
DBras d1e6cc19f6 file: setpoints for load test 2024-06-10 14:37:03 +02:00
DBras bb6ebbc9db question: D3 Part 2 2024-06-10 14:34:57 +02:00
DBras fa6eda5c16 question: D3 Q4 2024-06-10 14:15:17 +02:00
DBras 563be46da6 question: D3 Q3 2024-06-10 14:00:46 +02:00
DBras b10d5f623e question: D3 Q2 2024-06-10 13:49:08 +02:00
DBras 3207c3f51f question: D3 Q1 2024-06-10 11:45:01 +02:00
DBras 2a6fc39dc0 question: prep file for answers 2024-06-10 11:33:35 +02:00
DBras a200ff729a fix: env & paths 2024-06-10 11:01:28 +02:00
5 changed files with 4320 additions and 97 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
{"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 Normal file → Executable file
View File

@ -1,3 +1,4 @@
#!./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 Normal file → Executable file
View File

@ -1,11 +1,13 @@
#!./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]
@ -19,7 +21,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]
@ -33,107 +35,39 @@ 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 = plt.subplot(211) # Make two separate figures ax1, ax2 = plt.subplot(211), plt.subplot(212)
ax2 = plt.subplot(212) df_resampled[[c for c in df_resampled.columns if '_p' in c]].plot(marker='.', ax=ax1, linewidth=3)
df_pivot[[c for c in df_pivot.columns if "_p" in c]].plot(marker='.', ax=ax1, linewidth=3) 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 "_q" in c]].plot(marker='.', ax=ax2, linewidth=3) ax2.plot(df_resampled['dumpload_p'][SETPOINT_TS:WINDOW], marker='.', linewidth=3, label='dumpload')
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)

28
plotter.py Executable file
View File

@ -0,0 +1,28 @@
#!./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)