Understanding BoundedConstraint class
See original GitHub issueI’m not sure if this is a bug or i’m using the functionality wrong, so please let me know accordingly.
Here is how I’m trying to use BoundedConstraint, specified in my task_config
yaml
file.
constraints:
- constraint_form: bounded_constraint
lower_bounds: [0, 0, 0] # should match state dim
upper_bounds: [2.6, 0, 0]
constrained_variable: state
active_dims: 0 # only position
When i use BoundedConstraint for constraining state (I have 3 states but want to constraint only 1), I realize I needed to supply lower_bounds
& upper_bounds
with shapes that are equal to the number of states (e.g. 3 if have 3 states), due to self.dim
being defined as such: self.dim = env.state_dim
which is used in self.constraint_filter = np.eye(self.dim)[active_dims]
here, where it is supposed to only extract active_dims
from these bounds for the target state to be constrained.
But when i do so, where lower_bounds
matches shape of env.state_dim
, the assertion here assert A.shape[1] == self.dim, '[ERROR] A has the wrong dimension!'
fails.
This seem to fail because in Constraint
, inside this code chunk, after constraint_filter
is defined, self.dim
is overwritten by len(active_dims)
, so it would have shape of active_dims
which when I use is 1, while A
already has shape (6, 3)
due to self.dim
being set to env.state_dim
which was 3 earlier.
if self.constrained_variable == ConstrainedVariableType.STATE:
self.dim = env.state_dim
elif self.constrained_variable == ConstrainedVariableType.INPUT:
self.dim = env.action_dim
elif self.constrained_variable == ConstrainedVariableType.INPUT_AND_STATE:
self.dim = env.state_dim + env.action_dim
else:
raise NotImplementedError('[ERROR] invalid constrained_variable (use STATE, INPUT or INPUT_AND_STATE).')
# Save the strictness attribute
self.strict = strict
# Only want to select specific dimensions, implemented via a filter matrix.
if active_dims is not None:
if isinstance(active_dims, int):
active_dims = [active_dims]
assert isinstance(active_dims, (list, np.ndarray)), '[ERROR] active_dims is not a list/array.'
assert (len(active_dims) <= self.dim), '[ERROR] more active_dim than constrainable self.dim'
assert all(isinstance(n, int) for n in active_dims), '[ERROR] non-integer active_dim.'
assert all((n < self.dim) for n in active_dims), '[ERROR] active_dim not stricly smaller than self.dim.'
assert (len(active_dims) == len(set(active_dims))), '[ERROR] duplicates in active_dim'
self.constraint_filter = np.eye(self.dim)[active_dims]
self.dim = len(active_dims)
Could you please check if this was the issue?
Another attempt I took was to set lower_bounds
to have shape same as active_dims
, e.g. 1 (only want to constraint 1 state). It doesn’t work, because matmul
would fail here self.sym_func = lambda x: self.A @ self.constraint_filter @ x - self.b
for LinearConstraint
.
Full error: ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 1 is different from 3)
Summary:
What is the right shape for lower_bounds
and upper_bounds
?
- When I set it equal to shape of
env.state_dim
, I get error fromassert A.shape[1] == self.dim, '[ERROR] A has the wrong dimension!'
becauseself.dim = len(active_dims)
. - When I set it equal to
len(active_dims)
, it throws errorValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 1 is different from 3)
because ofself.sym_func = lambda x: self.A @ self.constraint_filter @ x - self.b
.
Would love to know if this is indeed a bug or if I’m using it wrong. I’ll also keep trying again in case maybe I missed anything.
Thank you!
Issue Analytics
- State:
- Created a year ago
- Reactions:1
- Comments:6 (5 by maintainers)
Top GitHub Comments
Some warnings and checks for the dimension of the bounds and the active_dims added as part of PR #88.
@adamhall
If missing, can you then create a patch/PR with the dimension check on
lower_bounds
,upper_bounds
,active_dims
raising and exception and error message?It could also be something to mention in the docstrings of
BoundedConstraint
’s constructor (and any other similar class) https://github.com/utiasDSL/safe-control-gym/blob/c031b74ea3b05d4c91ca13d4f2fd9cb410d23a70/safe_control_gym/envs/constraints.py#L285-L292(I think Nicholas has a different state vector length because wants to work on creating a new environment)