-
Notifications
You must be signed in to change notification settings - Fork 15
Soft water stable #19
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
dohunnim
wants to merge
43
commits into
0.2-dev
Choose a base branch
from
soft_water_stable
base: 0.2-dev
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 all commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
2a44e47
Added log barrier cost and old factory
ttchalakov 8bf8213
Added log barrier cost and old factory
ttchalakov f0b2946
Merge remote-tracking branch 'origin/soft_water_robot_devel' into sof…
dohunnim 8994cc4
fix_hyperparameter error fixed
dohunnim 1b932a6
minor bug fix in bounds transformer and controller
dohunnim 8e6cfda
fix_hyperparameter error fix
dohunnim d616734
Changing cost factory to transformer in Controller_Tuning example
dohunnim a796e51
get_traj implemented for RoundedOptimizer
dohunnim dfaf603
Fix string formatting bug
dohunnim 1f6dae0
Fix bug converting namedtuple to dict
dohunnim 9fe51a2
Merge remote-tracking branch 'origin/soft_water_robot_devel' into sof…
dohunnim ab9e925
Minor bug fixes
dohunnim 036fb72
Cost minor syntax error fixed. ThresholdCost goal convention fixed
dohunnim c5cc148
Barrier Cost changed from factory to transformer
dohunnim a7b57e0
Barrier cost transformer added to __init__.py
dohunnim ef2a93b
ILQR stop gap solution
dohunnim a61459c
Barrier Cost lower bound fixed
dohunnim 153861a
Fixed goal setter syntax
dohunnim 50a19d2
Barrier Cost Transformer tunable
dohunnim b4b09ec
Controls weren't clipping when multi-stepping
dohunnim a7b2bcf
REVISIT THIS: Solution to fix hyperparameters in twostage tuning?
dohunnim 6597981
Twostage tuning fixes
dohunnim 7d71418
Changing default metric to ControlPerformanceMetric()
dohunnim 8f4787b
New Barrier Transformer API
dohunnim d1fd354
Costs fixed to work with barriers
dohunnim 9bf63e4
Parallel Control Evaluator
dohunnim 6b2c4ab
BarrierCostTransformer works directly with Configs and not separate dict
dohunnim d89aa64
Added ability to change default_value and log when setting hyper_bounds
dohunnim e339ef2
change hyperparameter log scale setting
dohunnim aabc895
max_iter fixed in stop gap solution
dohunnim c1f8d33
Auto stash before merge of "soft_water_robot_devel" and "origin/soft_…
dohunnim 49301f1
ILQR faster again, saves step duration simulation
dohunnim 5410432
Fix conversion of ControlEvaluationTrial to dict
dohunnim 93595f9
Merge of "soft_water_robot_devel" and "origin/soft_water_robot_devel"
dohunnim 905ef84
Timeout feature added to ILQR
dohunnim 825209c
Merge of "soft_water_robot_devel" and "origin/soft_water_robot_devel"
dohunnim 1149260
Removing debugging stuff
dohunnim 17b4403
Remove unrolling w * since it's not compatible with python <3.8
dohunnim 3977ba5
preparing 0.2-dev pull request
dohunnim a3e2f14
OCP needs to be transformed when being set
dohunnim 40bff3f
Fixing ParallelEvaluator
dohunnim 50850b6
Minor change to Barrier Cost Transformer
dohunnim 9cad9a1
Timeout enabled
dohunnim 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
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 |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| from .quad_cost import QuadCost | ||
| from .thresh_cost import ThresholdCost, BoxThresholdCost | ||
| from .barrier_cost import LogBarrierCost | ||
| from .cost import Cost |
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 |
|---|---|---|
| @@ -0,0 +1,187 @@ | ||
| # Created by Teodor Tchalakov, (ttcha2@illinois.edu) | ||
|
|
||
| import numpy as np | ||
| import numpy.linalg as la | ||
|
|
||
| from .cost import Cost | ||
|
|
||
| class LogBarrierCost(Cost): | ||
| def __init__(self, system, boundedStates): | ||
| """ | ||
| Create barrier cost that approximates an inequality constraint. | ||
| Function does not exist outside the limit. | ||
| where : - b * ln ( a - x ) for upper limit | ||
| - b * ln ( a + x ) for lower limit | ||
| Parameters | ||
| ---------- | ||
| system : System | ||
| Robot system object. | ||
| boundedState : dict | ||
| Dictionary of { "observation/control name" : (limit, scale, upper)} | ||
| observation/control (x) : String | ||
| Observation/control name for which limit is specified. | ||
| limit (a) : double | ||
| limit value a that barrier is placed at. | ||
| scale (b) : double | ||
| Positive scalar to magnify the cost function. | ||
| scale: (0, inf) | ||
| upper : boolean | ||
| True if the limit is an upper limit. | ||
| False if the limit is a lower limit. | ||
| """ | ||
| super().__init__(system) | ||
| self.obsConfiguration = [] | ||
| self.ctrlsConfiguration = [] | ||
|
|
||
| for variable in boundedStates.keys(): | ||
| config = boundedStates[variable] | ||
| # Check that scale is positive | ||
| if(config[1] < 0): | ||
| raise ValueError(f"{variable}'s log barrier must be positive, was {config[1]}") | ||
| elif(variable in system.observations): | ||
| self.obsConfiguration.append([variable, config]) | ||
| elif(variable in system.controls): | ||
| self.ctrlsConfiguration.append([variable, config]) | ||
| else: | ||
| raise ValueError(f"Variable {variable} is not in the given system") | ||
|
|
||
| # Configs | ||
| self._is_quad = False | ||
| self._is_convex = True | ||
| self._is_diff = True | ||
| self._is_twice_diff = True | ||
| self._has_goal = False | ||
|
|
||
| def incremental(self, obs, control): | ||
| return self.eval_obs_cost(obs) + self.eval_ctrl_cost(control) | ||
|
|
||
| def incremental_diff(self, obs, control): | ||
| return self.incremental(obs, control), self.eval_obs_cost_diff(obs), self.eval_ctrl_cost_diff(control) | ||
|
|
||
| def incremental_hess(self, obs, control): # TODO: Tuple unpacking only supported for python>=3.8 | ||
| hess_obs_ctrl = np.zeros((self.system.obs_dim, self.system.ctrl_dim)) | ||
| return self.incremental(obs, control), self.eval_obs_cost_diff(obs), self.eval_ctrl_cost_diff(control), self.eval_obs_cost_hess(obs), hess_obs_ctrl, self.eval_ctrl_cost_hess(control) | ||
|
|
||
| def terminal(self, obs): | ||
| return 0 | ||
|
|
||
| def terminal_diff(self, obs): | ||
| return 0, 0 | ||
|
|
||
| def terminal_hess(self, obs): | ||
| return 0, 0, 0 | ||
|
|
||
| def __add__(self, rhs): | ||
| if isinstance(rhs, LogBarrierCost): | ||
| if (self.goal is None and rhs.goal is None) or np.all(self.goal == rhs.goal): | ||
| return LogBarrierCost(self.system, self.boundedStates+rhs.boundedStates) | ||
| return Cost.__add__(self, rhs) | ||
|
|
||
| def __mul__(self, rhs): | ||
| if not isinstance(rhs, (float, int)): | ||
| raise ValueError("* only supports product with numbers") | ||
| new_cost = LogBarrierCost(self.system, self.boundedStates) | ||
| return new_cost | ||
|
|
||
|
|
||
| #Cost Function: | ||
| # b = scale | ||
| # - b * ln ( a - x ) upper limit x < a | ||
| # - b * ln ( a + x ) lower limit x > a | ||
| def eval_obs_cost(self, obs): | ||
| sum = 0 | ||
| for boundedObs in self.obsConfiguration: | ||
| variable, config = boundedObs | ||
| index = self.system.observations.index(variable) | ||
| lower, upper, scale = config | ||
| if lower > -np.inf: | ||
| if lower >= obs[index]: | ||
| sum += np.inf | ||
| else: | ||
| sum = sum + -scale * np.log(-lower + obs[index]) | ||
| if upper < np.inf: | ||
| if obs[index] >= upper: | ||
| sum += np.inf | ||
| else: | ||
| sum = sum + -scale * np.log(upper - obs[index]) | ||
| return sum | ||
|
|
||
| #Jacobian: | ||
| # b / (a - x) upper limit | ||
| # -b / (-a + x) lower limit | ||
| def eval_obs_cost_diff(self, obs): | ||
| jacobian = np.zeros(self.system.obs_dim) | ||
| for boundedObs in self.obsConfiguration: | ||
| variable, config = boundedObs | ||
| index = self.system.observations.index(variable) | ||
| lower, upper, scale = config | ||
| if lower > -np.inf: | ||
| if lower >= obs[index]: | ||
| jacobian[index] += -np.inf | ||
| else: | ||
| jacobian[index] += -scale / (-lower + obs[index]) | ||
| if upper < np.inf: | ||
| if obs[index] >= upper: | ||
| jacobian[index] += np.inf | ||
| else: | ||
| jacobian[index] += scale / (upper - obs[index]) | ||
|
|
||
| return jacobian | ||
|
|
||
| #Hessian: | ||
| # b / (a - x)^2 upper limit | ||
| # b / (-a + x)^2 lower limit | ||
| def eval_obs_cost_hess(self, obs): | ||
| hessian = np.zeros((self.system.obs_dim, self.system.obs_dim)) | ||
| for boundedObs in self.obsConfiguration: | ||
| variable, config = boundedObs | ||
| index = self.system.observations.index(variable) | ||
| lower, upper, scale = config | ||
| if lower > -np.inf: | ||
| if lower >= obs[index]: | ||
| hessian[index][index] += np.inf | ||
| else: | ||
| hessian[index][index] += scale / ((lower - obs[index])**2) | ||
| if upper < np.inf: | ||
| if obs[index] >= upper: | ||
| hessian[index][index] += np.inf | ||
| else: | ||
| hessian[index][index] += scale / ((upper - obs[index])**2) | ||
|
|
||
| return hessian | ||
|
|
||
| def eval_ctrl_cost(self, ctrl): | ||
| sum = 0 | ||
| for boundedCtrl in self.ctrlsConfiguration: | ||
| variable, config = boundedCtrl | ||
| index = self.system.controls.index(variable) | ||
| lower, upper, scale = config | ||
| if lower > -np.inf: | ||
| sum = sum + -scale * np.log(-lower + ctrl[index]) | ||
| if upper < np.inf: | ||
| sum = sum + -scale * np.log(upper - ctrl[index]) | ||
| return sum | ||
|
|
||
| def eval_ctrl_cost_diff(self, ctrl): | ||
| jacobian = np.zeros(self.system.ctrl_dim) | ||
| for boundedCtrl in self.ctrlsConfiguration: | ||
| variable, config = boundedCtrl | ||
| index = self.system.controls.index(variable) | ||
| lower, upper, scale = config | ||
| if lower > -np.inf: | ||
| jacobian[index] += -scale / (-lower + ctrl[index]) | ||
| if upper < np.inf: | ||
| jacobian[index] += scale / (upper - ctrl[index]) | ||
| return jacobian | ||
|
|
||
| def eval_ctrl_cost_hess(self, ctrl): | ||
| hessian = np.zeros((self.system.ctrl_dim, self.system.ctrl_dim)) | ||
| for boundedCtrl in self.ctrlsConfiguration: | ||
| variable, config = boundedCtrl | ||
| index = self.system.controls.index(variable) | ||
| lower, upper, scale = config | ||
| if lower > -np.inf: | ||
| hessian[index][index] += scale / ((lower - ctrl[index])**2) | ||
| if upper < np.inf: | ||
| hessian[index][index] += scale / ((upper - ctrl[index])**2) | ||
| return hessian |
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 |
|---|---|---|
|
|
@@ -81,7 +81,8 @@ def incremental_hess(self, obs, control): | |
| obst = obs | ||
| QQt = (self._Q + self._Q.T) | ||
| RRt = (self._R + self._R) | ||
| return obst.T @ self._Q @ obst + control.T @ self._R @control, QQt @ obst, RRt @ control, QQt, None, RRt | ||
| hess_obs_ctrl = np.zeros((self.system.obs_dim, self.system.ctrl_dim)) | ||
| return obst.T @ self._Q @ obst + control.T @ self._R @control, QQt @ obst, RRt @ control, QQt, hess_obs_ctrl, RRt | ||
|
Collaborator
Author
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. Returning None will create issues |
||
|
|
||
| def terminal(self, obs): | ||
| try: | ||
|
|
||
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
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.
To use @goal.setter property decorator , the function name must be the same as the attribute's name. To be consistent with the coding style of other files, I kept the original Java-style setter function in lines 195-197