Coverage for src/gncpy/dynamics/basic/double_integrator.py: 86%
63 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-13 06:15 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-13 06:15 +0000
1import numpy as np
2import gncpy.control._control as cpp_control
3import gncpy.dynamics._dynamics as cpp_bindings
4from warnings import warn
6from .linear_dynamics_base import LinearDynamicsBase
9class DoubleIntegrator(LinearDynamicsBase):
10 """Implements a double integrator model.
12 Todo
13 ----
14 Implement the control model in c++ for this class
15 """
17 def __init__(self, **kwargs):
18 super().__init__(**kwargs)
19 self.__controlParams = cpp_control.ControlParams()
20 self.__stateTransParams = cpp_bindings.StateTransParams()
21 self.__model = cpp_bindings.DoubleIntegrator(0.1)
22 if "control_model" in kwargs and kwargs["control_model"] is not None:
23 self.__model.set_control_model(kwargs("control_model"))
25 @property
26 def allow_cpp(self):
27 return True
29 @property
30 def control_model(self):
31 warn("viewing the control model is not supported for this class")
32 return None
34 @control_model.setter
35 def control_model(self, model):
36 if isinstance(model, cpp_control.ILinearControlModel):
37 self._control_model = model
38 self.__model.set_control_model(self._control_model)
39 else:
40 raise TypeError("must be ILinearControlModel type")
42 def get_input_mat(self, timestep, *ctrl_args):
43 """Calculates the input matrix from the control model.
45 This calculates the jacobian of the control model. If no control model
46 is specified than it returns a zero matrix.
48 Parameters
49 ----------
50 timestep : float
51 current timestep.
52 state : N x 1 numpy array
53 current state.
54 *ctrl_args : tuple
55 Additional arguments to pass to the control model.
57 Returns
58 -------
59 N x Nu numpy array
60 Control input matrix.
61 """
62 if self._control_model is None:
63 raise RuntimeWarning("Control model is not set.")
64 self.args_to_params((0.1,), ctrl_args)
65 return self._control_model.get_input_mat(timestep, self.__controlParams)
67 # must be provided if allow_cpp is true
68 def args_to_params(self, state_args, control_args):
69 if len(state_args) != 1:
70 raise RuntimeError(
71 "state args must be only (dt,) not {}".format(repr(state_args))
72 )
74 if len(control_args) != 0 and self._control_model is None:
75 warn("Control agruments supplied but no control model specified")
76 elif self._control_model is not None:
77 self.__controlParams = self._control_model.args_to_params(
78 tuple(control_args)
79 )
81 self.__constraintParams = cpp_bindings.ConstraintParams()
83 # hack since state params is empty but things are set in the model
84 self.__model.dt = state_args[0]
85 return self.__stateTransParams, self.__controlParams, self.__constraintParams
87 # must be provided if allow_cpp is true
88 @property
89 def model(self):
90 return self.__model
92 @property
93 def state_names(self):
94 return self.__model.state_names()
96 def propagate_state(self, timestep, state, u=None, state_args=None, ctrl_args=None):
97 if state_args is None:
98 raise RuntimeError("state_args must be (dt,) not None")
99 self.__model.dt = state_args[0]
100 if self._control_model is None:
101 next_state = self.__model.propagate_state(timestep, state).reshape((-1, 1))
102 else:
103 next_state = self.__model.propagate_state(
104 timestep, state, u, *self.args_to_params(state_args, ctrl_args)
105 )
106 if self.state_constraint is not None:
107 next_state = self.state_constraint(timestep, next_state)
108 return next_state.reshape((-1, 1))
110 def get_dis_process_noise_mat(self, dt, proc_cov):
111 """Discrete process noise matrix.
113 Parameters
114 ----------
115 dt : float
116 time difference, unused.
117 proc_cov : N x N numpy array
118 Covariance matrix of the process noise.
120 Returns
121 -------
122 4 x 4 numpy array
123 process noise matrix.
125 """
126 gamma = np.array([0, 0, 1, 1]).reshape((4, 1))
127 return gamma @ proc_cov @ gamma.T
129 def get_state_mat(self, timestep, dt):
130 """Class method for getting the discrete time state matrix.
132 Parameters
133 ----------
134 timestep : float
135 timestep.
136 dt : float
137 time difference
139 Returns
140 -------
141 4 x 4 numpy array
142 state matrix.
144 """
145 self.__model.dt = dt
146 return self.__model.get_state_mat(timestep, self.__stateTransParams)