I'm trying to load a system and then override its dynamics, such that classes like Simulator use the new dynamics instead. This is straightforward for systems declared in python, but doesn't seem to work for ones that are C++ bindings---for instance, the example below:
from pydrake.all import DirectCollocation, Simulator, VectorSystem
from pydrake.examples.pendulum import PendulumPlant
import numpy as np
class CustomVectorSystem(VectorSystem):
def __init__(self):
VectorSystem.__init__(self, 1, 0)
self.DeclareContinuousState(2)
def DoCalcVectorTimeDerivatives(self, context, u, x, x_dot):
x_dot[0] += u
class OverwrittenVectorSystem(CustomVectorSystem):
def __init__(self):
CustomVectorSystem.__init__(self)
def DoCalcVectorTimeDerivatives(self, context, u, x, x_dot):
x_dot = np.zeros_like(x_dot)
class OverwrittenPendulumPlant(PendulumPlant):
def __init__(self):
PendulumPlant.__init__(self)
def DoCalcTimeDerivatives(self, context, derivatives):
derivatives = np.zeros_like(derivatives)
def run_sim_step(sys, t=0.1):
context = sys.CreateDefaultContext()
simulator = Simulator(sys)
context = simulator.get_mutable_context()
context.SetContinuousState([0, 1])
context.FixInputPort(index=0, data=[1.0])
simulator.AdvanceTo(t)
return context.get_continuous_state_vector().get_value()
vector_sys = CustomVectorSystem()
overwritten_vector_sys = OverwrittenVectorSystem()
print(
"CustomVectorSystem results are {}, and {} for overwrite".format(
run_sim_step(vector_sys), run_sim_step(overwritten_vector_sys)
)
)
pendulum = PendulumPlant()
overwritten_pendulum = OverwrittenPendulumPlant()
print(
"PendulumPlant results are {}, and {} for overwrite".format(
run_sim_step(pendulum), run_sim_step(overwritten_pendulum)
)
)
returns the following:
CustomVectorSystem results are [1.4075 1. ], and [0. 1.] for overwrite
PendulumPlant results are [0.11427129 1.24633296], and [0.11427129 1.24633296] for overwrite
And likewise for discrete systems. Is there any way to get a new method to override the dynamics in this case?