diff --git a/bindings/pydrake/systems/framework_py.cc b/bindings/pydrake/systems/framework_py.cc index efe1e8ac6626..d6f50b16d85f 100644 --- a/bindings/pydrake/systems/framework_py.cc +++ b/bindings/pydrake/systems/framework_py.cc @@ -281,6 +281,13 @@ PYBIND11_MODULE(framework, m) { [](const System* self, const Context& arg1, int arg2) { return self->EvalVectorInput(arg1, arg2); }, py_reference_internal) + .def( + "EvalAbstractInput", + [](const System* self, const Context& arg1, int arg2) { + return self->EvalAbstractInput(arg1, arg2); + }, py_reference, + // Keep alive, ownership: `return` keeps `Context` alive. + py::keep_alive<0, 2>()) .def("CalcOutput", &System::CalcOutput) // Sugar. .def( @@ -349,9 +356,16 @@ PYBIND11_MODULE(framework, m) { .def("get_num_input_ports", &Context::get_num_input_ports) .def("FixInputPort", py::overload_cast>>( - &Context::FixInputPort), py_reference_internal, + &Context::FixInputPort), + py_reference_internal, // Keep alive, ownership: `BasicVector` keeps `self` alive. py::keep_alive<3, 1>()) + .def("FixInputPort", + py::overload_cast>( + &Context::FixInputPort), + py_reference_internal, + // Keep alive, ownership: `AbstractValue` keeps `self` alive. + py::keep_alive<3, 1>()) .def("get_time", &Context::get_time) .def("Clone", &Context::Clone) .def("__copy__", &Context::Clone) @@ -432,8 +446,12 @@ PYBIND11_MODULE(framework, m) { py::class_>(m, "OutputPort"); - py::class_>(m, "SystemOutput") + py::class_> system_output(m, "SystemOutput"); + DefClone(&system_output); + system_output .def("get_num_ports", &SystemOutput::get_num_ports) + .def("get_data", &SystemOutput::get_data, + py_reference_internal) .def("get_vector_data", &SystemOutput::get_vector_data, py_reference_internal); diff --git a/bindings/pydrake/systems/primitives_py.cc b/bindings/pydrake/systems/primitives_py.cc index 634b6c602465..52e95411782f 100644 --- a/bindings/pydrake/systems/primitives_py.cc +++ b/bindings/pydrake/systems/primitives_py.cc @@ -6,6 +6,7 @@ #include "drake/systems/primitives/constant_value_source.h" #include "drake/systems/primitives/constant_vector_source.h" #include "drake/systems/primitives/integrator.h" +#include "drake/systems/primitives/pass_through.h" #include "drake/systems/primitives/signal_logger.h" #include "drake/systems/primitives/zero_order_hold.h" @@ -31,6 +32,10 @@ PYBIND11_MODULE(primitives, m) { py::class_, LeafSystem>(m, "Integrator") .def(py::init()); + py::class_, LeafSystem>(m, "PassThrough") + .def(py::init()) + .def(py::init()); + py::class_, LeafSystem>(m, "ZeroOrderHold") .def(py::init()); diff --git a/bindings/pydrake/systems/test/general_test.py b/bindings/pydrake/systems/test/general_test.py index 7656d1fe92d1..74be1311762a 100644 --- a/bindings/pydrake/systems/test/general_test.py +++ b/bindings/pydrake/systems/test/general_test.py @@ -12,6 +12,7 @@ Simulator, ) from pydrake.systems.framework import ( + AbstractValue, BasicVector, Diagram, DiagramBuilder, @@ -20,6 +21,7 @@ Adder, ConstantVectorSource, Integrator, + PassThrough, SignalLogger, ) @@ -165,6 +167,19 @@ def test_signal_logger(self): self.assertTrue(t.shape[0] == x.shape[1]) self.assertAlmostEqual(x[0, -1], t[-1]*kValue, places=2) + def test_abstract_pass_through(self): + model_value = AbstractValue.Make("Hello world") + input_value = model_value.Clone() + system = PassThrough(model_value) + context = system.CreateDefaultContext() + context.FixInputPort(0, input_value) + output = system.AllocateOutput(context) + input_eval = system.EvalAbstractInput(context, 0) + self.assertEquals(input_eval.get_value(), input_value.get_value()) + system.CalcOutput(context, output) + output_value = output.get_data(0) + self.assertEquals(output_value.get_value(), input_value.get_value()) + if __name__ == '__main__': unittest.main()