-
Notifications
You must be signed in to change notification settings - Fork 3
42 add datadriven mpc #71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sarahleidolf
wants to merge
31
commits into
main
Choose a base branch
from
42-add-datadriven-mpc_
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 26 commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
33e5296
introduce self.time as casadi symbolic
sarahleidolf cfa6269
add at Example OneRoom_SimpleMPC
sarahleidolf c511e39
adjust parsing and data handling for ml mpc
sarahleidolf 5294934
add example
sarahleidolf 468ff65
Merge branch 'main' into 42-add-datadriven-mpc
sarahleidolf 8240253
change requirements
sarahleidolf 43a6538
change self.time
sarahleidolf b07d8a3
first approach for new objective handling
sarahleidolf be5fcf2
Merge branch
sarahleidolf 1097e96
Revert "first approach for new objective handling"
sarahleidolf 7fd7811
Revert "change self.time"
sarahleidolf cc3004e
Revert "Revert "change self.time""
sarahleidolf ca461e1
add set_actuation
sarahleidolf 1766125
update requirements
sarahleidolf 87f0d25
main into #42
sarahleidolf 69b9be8
update globals
sarahleidolf e9c4d97
minor updates after merge from main branch
sarahleidolf da6e785
allow multiple shooting
sarahleidolf 6d4a1b4
minor import changes
sarahleidolf 39b7fb5
Merge branch 'main' into 42-add-datadriven-mpc
sarahleidolf 16220f6
new numpy version
sarahleidolf 3f8c377
move example
sarahleidolf 099df9f
move example
sarahleidolf 6ea896c
adjust snapshots of ci tests for new time grid formulation
sarahleidolf 6f8f0dc
adjust ci workflow
sarahleidolf 9d92f57
change r_del_u handling
sarahleidolf 758861b
include review
sarahleidolf c259f92
Merge branch 'main' into 42-add-datadriven-mpc_
sarahleidolf 647f780
update examples and tests
sarahleidolf 733c708
Update snapshots after assumption "Set the first value of power_flex…
sarahleidolf bbacf73
Merge remote-tracking branch 'remotes/origin/main' into 42-add-datadr…
sarahleidolf File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -200,7 +200,7 @@ def calculate( | |
| enable_energy_costs_correction: bool, | ||
| calculate_flex_cost: bool, | ||
| integration_method: INTEGRATION_METHOD, | ||
| collocation_time_grid: list = None, | ||
| time_grid_info: dict = None, | ||
| ): | ||
| """Calculate the KPIs based on the power and electricity price input profiles. | ||
|
|
||
|
|
@@ -215,7 +215,8 @@ def calculate( | |
| enable_energy_costs_correction: whether the energy costs should be corrected | ||
| calculate_flex_cost: whether the cost of the flexibility should be calculated | ||
| integration_method: method used for integration of KPISeries e.g. linear, constant | ||
| collocation_time_grid: Time grid of the mpc output with collocation discretization | ||
| time_grid_info: Dictionary with 'type' ('collocation', 'multiple_shooting', 'none') | ||
| and 'grid' (list of time points) keys | ||
|
|
||
|
|
||
| """ | ||
|
|
@@ -227,10 +228,10 @@ def calculate( | |
| integration_method=integration_method, | ||
| ) | ||
| self._calculate_power_flex_stats( | ||
| mpc_time_grid=mpc_time_grid, collocation_time_grid=collocation_time_grid | ||
| mpc_time_grid=mpc_time_grid, time_grid_info=time_grid_info | ||
| ) | ||
| self._calculate_energy_flex( | ||
| mpc_time_grid=mpc_time_grid, collocation_time_grid=collocation_time_grid | ||
| mpc_time_grid=mpc_time_grid, time_grid_info=time_grid_info | ||
| ) | ||
|
|
||
| # Costs KPIs | ||
|
|
@@ -245,7 +246,7 @@ def calculate( | |
| stored_energy_diff=stored_energy_diff, | ||
| integration_method=integration_method, | ||
| mpc_time_grid=mpc_time_grid, | ||
| collocation_time_grid=collocation_time_grid, | ||
| time_grid_info=time_grid_info, | ||
| ) | ||
| self._calculate_costs_rel() | ||
|
|
||
|
|
@@ -303,27 +304,42 @@ def _calculate_power_flex( | |
| self.power_flex_offer.integration_method = integration_method | ||
|
|
||
| def _calculate_power_flex_stats( | ||
| self, mpc_time_grid: np.array, collocation_time_grid: list = None | ||
| self, mpc_time_grid: np.array, time_grid_info: dict = None | ||
| ): | ||
| """Calculate the characteristic values of the power flexibility for the offer.""" | ||
| """Calculate the characteristic values of the power flexibility for the offer. | ||
|
|
||
| Args: | ||
| mpc_time_grid: the MPC time grid over the horizon | ||
| time_grid_info: Dictionary with 'type' and 'grid' keys for discretization info | ||
| """ | ||
| if self.power_flex_offer.value is None: | ||
| raise ValueError("Power flexibility value is empty.") | ||
|
|
||
| # Calculate characteristic values | ||
| # max and min of power flex offer | ||
| power_flex_offer = self.power_flex_offer.value.iloc[:-1].drop( | ||
| collocation_time_grid, errors="ignore" | ||
| ) | ||
| power_flex_offer = self.power_flex_offer.value.iloc[:-1] | ||
|
|
||
| # Only drop collocation points if using collocation method | ||
| if time_grid_info and time_grid_info.get("type") == "collocation": | ||
| power_flex_offer = power_flex_offer.drop( | ||
| time_grid_info["grid"], errors="ignore" | ||
| ) | ||
|
|
||
| power_flex_offer_max = power_flex_offer.max() | ||
| power_flex_offer_min = power_flex_offer.min() | ||
|
|
||
| # Average of the power flex offer | ||
| # Get the series for integration before calculating average | ||
| power_flex_offer_integration = self._get_series_for_integration( | ||
| series=self.power_flex_offer, mpc_time_grid=mpc_time_grid | ||
| ) | ||
| power_flex_offer_integration.value = power_flex_offer_integration.value.drop( | ||
| collocation_time_grid, errors="ignore" | ||
| ) | ||
|
|
||
| # Only drop collocation points if using collocation method | ||
| if time_grid_info and time_grid_info.get("type") == "collocation": | ||
| power_flex_offer_integration.value = power_flex_offer_integration.value.drop( | ||
| time_grid_info["grid"], errors="ignore" | ||
| ) | ||
|
|
||
|
sarahleidolf marked this conversation as resolved.
Outdated
|
||
| # Calculate the average and stores the original value | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why remove that? |
||
| power_flex_offer_avg = power_flex_offer_integration.avg() | ||
|
|
||
|
|
@@ -352,9 +368,14 @@ def _get_series_for_integration( | |
| else: | ||
| return series.__deepcopy__() | ||
|
|
||
| def _calculate_energy_flex(self, mpc_time_grid, collocation_time_grid: list = None): | ||
| def _calculate_energy_flex(self, mpc_time_grid, time_grid_info: dict = None): | ||
| """Calculate the energy flexibility by integrating the power flexibility | ||
| of the offer window.""" | ||
| of the offer window. | ||
|
|
||
| Args: | ||
| mpc_time_grid: the MPC time grid over the horizon | ||
| time_grid_info: Dictionary with 'type' and 'grid' keys for discretization info | ||
| """ | ||
| if self.power_flex_offer.value is None: | ||
| raise ValueError("Power flexibility value of the offer is empty.") | ||
|
|
||
|
|
@@ -363,9 +384,13 @@ def _calculate_energy_flex(self, mpc_time_grid, collocation_time_grid: list = No | |
| power_flex_offer_integration = self._get_series_for_integration( | ||
| series=self.power_flex_offer, mpc_time_grid=mpc_time_grid | ||
| ) | ||
| power_flex_offer_integration.value = power_flex_offer_integration.value.drop( | ||
| collocation_time_grid, errors="ignore" | ||
| ) | ||
|
|
||
| # Only drop collocation points if using collocation method | ||
| if time_grid_info and time_grid_info.get("type") == "collocation": | ||
| power_flex_offer_integration.value = power_flex_offer_integration.value.drop( | ||
| time_grid_info["grid"], errors="ignore" | ||
| ) | ||
|
|
||
| # Calculate the energy flex and stores the original value | ||
| energy_flex = power_flex_offer_integration.integrate(time_unit="hours") | ||
|
|
||
|
|
@@ -378,7 +403,7 @@ def _calculate_costs( | |
| stored_energy_diff: float, | ||
| integration_method: INTEGRATION_METHOD, | ||
| mpc_time_grid: np.ndarray, | ||
| collocation_time_grid: list = None, | ||
| time_grid_info: dict = None, | ||
| ): | ||
| """Calculate the costs of the flexibility event based on the electricity costs profile, | ||
| the power flexibility profile and difference of stored energy. | ||
|
|
@@ -388,7 +413,7 @@ def _calculate_costs( | |
| stored_energy_diff: the difference of the stored energy between baseline and shadow mpc | ||
| integration_method: the integration method used to integrate KPISeries | ||
| mpc_time_grid: the MPC time grid over the horizon | ||
| collocation_time_grid: Time grid of the mpc output with collocation discretization | ||
| time_grid_info: Dictionary with 'type' and 'grid' keys for discretization info | ||
|
|
||
|
|
||
| """ | ||
|
|
@@ -405,9 +430,12 @@ def _calculate_costs( | |
| power_flex_full_integration = self._get_series_for_integration( | ||
| series=self.power_flex_full, mpc_time_grid=mpc_time_grid | ||
| ) | ||
| power_flex_full_integration.value = power_flex_full_integration.value.drop( | ||
| collocation_time_grid, errors="ignore" | ||
| ) | ||
|
|
||
| # Only drop collocation points if using collocation method | ||
| if time_grid_info and time_grid_info.get("type") == "collocation": | ||
| power_flex_full_integration.value = power_flex_full_integration.value.drop( | ||
| time_grid_info["grid"], errors="ignore" | ||
| ) | ||
|
|
||
| # Calculate series | ||
| self.electricity_costs_series.value = ( | ||
|
|
@@ -605,15 +633,16 @@ def calculate( | |
| enable_energy_costs_correction: bool, | ||
| calculate_flex_cost: bool, | ||
| integration_method: INTEGRATION_METHOD, | ||
| collocation_time_grid: list = None, | ||
| time_grid_info: dict = None, | ||
| ): | ||
| """Calculate the KPIs for the positive and negative flexibility. | ||
|
|
||
| Args: | ||
| enable_energy_costs_correction: whether the energy costs should be corrected | ||
| calculate_flex_cost: whether the cost of the flexibility should be calculated | ||
| integration_method: method used for integration of KPISeries e.g. linear, constant | ||
| collocation_time_grid: Time grid of the mpc output with collocation discretization | ||
| time_grid_info: Dictionary with 'type' ('collocation', 'multiple_shooting', 'none') | ||
| and 'grid' (list of time points) keys | ||
|
|
||
| """ | ||
| self.kpis_pos.calculate( | ||
|
|
@@ -627,7 +656,7 @@ def calculate( | |
| enable_energy_costs_correction=enable_energy_costs_correction, | ||
| calculate_flex_cost=calculate_flex_cost, | ||
| integration_method=integration_method, | ||
| collocation_time_grid=collocation_time_grid, | ||
| time_grid_info=time_grid_info, | ||
| ) | ||
| self.kpis_neg.calculate( | ||
| power_profile_base=self.power_profile_base, | ||
|
|
@@ -640,7 +669,7 @@ def calculate( | |
| enable_energy_costs_correction=enable_energy_costs_correction, | ||
| calculate_flex_cost=calculate_flex_cost, | ||
| integration_method=integration_method, | ||
| collocation_time_grid=collocation_time_grid, | ||
| time_grid_info=time_grid_info, | ||
| ) | ||
| self.reset_time_grid() | ||
| return self.kpis_pos, self.kpis_neg | ||
|
|
@@ -657,4 +686,4 @@ def reset_time_grid(self): | |
| Reset the common time grid. | ||
| This should be called between different flexibility calculations. | ||
| """ | ||
| self._common_time_grid = None | ||
| self._common_time_grid = None | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the difference between the mpc_time_grid and timegrid_info["grid"]? Maybe add a short description for that