Skip to content
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

Implicit midpoint #21

Merged
merged 14 commits into from
Mar 11, 2022
Merged

Implicit midpoint #21

merged 14 commits into from
Mar 11, 2022

Conversation

bjack205
Copy link
Member

Closes #19.

Defines discrete_dynamics, discrete_dynamics, and jacobian! for DiscretizedDynamics models that use implicit integrators. Currently only ImplicitMidpoint is defined. These methods use Newton's method and the implicit function theorem to emulate the behavior expected by an explicit integrator.

All methods are allocation-free for both static and in-place vector arguments / function signatures.

Each implicit integrator must store an instance of ImplicitNewtonCache, which provides the cache variables needed to compute the needed matrices / vectors. In order to calculate the Jacobian of a DiscretizedModel using an implicit integrator, the ImplicitFunctionTheorem DiffMethod must be used, which also specifies the diff method to be used to evaluate the
Jacobian of implicit dynamics residual function, e.g. ImplicitFunctionTheorem{ForwardAD}, created as ImplicitFunctionTheorem(ForwardAD())

All methods assume the control at the next time step is the same as the control at the current time step (i.e. zero-order-hold).

An example of using the API:

using RobotDynamics
const RD = RobotDynamics

model = Cartpole()
integrator = RD.ImplicitMidpoint(model)
dmodel = RD.DiscretizedDynamics(model, integrator)
# OR 
dmodel = RD.DiscretizedDynamics{RD.ImplicitMidpoint}(model)

n,m = RD.dims(model)
x1,u1 = rand(model)   # generate some random state and control vectors
dt = 0.01
z1 = KnotPoint{n,m}(x1,u1,0.0,dt)
z1_static = KnotPoint{n,m}(SVector{n}(x1), SVector{m}(u1), 0.0, dt)
x2 = copy(x1)

# Solve for next state using Newton's method
RD.discrete_dynamics!(dmodel, x2, z1)
x2_static = RD.discrete_dynamics(dmodel, z1_static)

# Get the dynamics Jacobians
J = zeros(n, n+m)
diff = RD.default_diffmethod(dmodel)  
# OR 
diff = RD.ImplicitFunctionTheorem(ForwardAD())
RD.jacobian!(RD.InPlace(), diff, dmodel, J, xn, z1)
RD.jacobian!(RD.StaticReturn(), diff, dmodel, J, xn, z1_static)

@bjack205 bjack205 requested a review from zacmanchester March 10, 2022 22:54
@bjack205 bjack205 self-assigned this Mar 11, 2022
@bjack205 bjack205 merged commit cf8f4f7 into master Mar 11, 2022
@bjack205 bjack205 deleted the implicit-midpoint branch March 11, 2022 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement discrete_dynamics! and jacobian! for implicit integrators using Newton and IFT
1 participant