Reputation: 2004
I am trying something like the following (using drake@00cdef03)
Note: This is not proper idiomatic Drake; you should declare a separate subclass when making a novel LeafSystem
. This post just shows a compact, but hacky, form.
from pydrake.all import (
AbstractValue,
DiagramBuilder,
LeafSystem,
SpatialForce,
Value,
)
def fake_calc(context, output):
raise NotImplemented()
producer = LeafSystem()
producer.DeclareAbstractOutputPort("output", alloc=SpatialForce, calc=fake_calc)
consumer = LeafSystem()
consumer.DeclareAbstractInputPort("input", model_value=AbstractValue.Make(SpatialForce()))
builder = DiagramBuilder()
builder.AddSystem(producer)
builder.AddSystem(consumer)
builder.Connect(producer.get_output_port(), consumer.get_input_port())
For some reason, it fails on builder.Connect(...)
with the following error:
Unable to cast Python instance to C++ type (compile in debug mode for details)
If I print the value of the ports, they seem like the match the signature of the function:
>>> producer.get_output_port()
<pydrake.systems.framework.LeafOutputPort_[float] object at 0x7febb5dba930>
>>> consumer.get_input_port()
<pydrake.systems.framework.InputPort_[float] object at 0x7febb5ff0930>
What's going on?
Upvotes: 0
Views: 281
Reputation: 2004
The issue lies in the fact that alloc=SpatialForce
is being used, but it should be should be alloc=Value[SpatialForce]
.
The following shows the difference between good
and bad
:
system = LeafSystem()
# Good!
good = system.DeclareAbstractOutputPort("good", alloc=Value[SpatialForce], calc=fake_calc)
good.Allocate()
# BAD!
bad = system.DeclareAbstractOutputPort("bad", alloc=SpatialForce, calc=fake_calc)
bad.Allocate() # Fails here
This happens because alloc
must produce an instance of AbstractValue
, which is used by OutputPort::Alocate()
(in C++), which uses this std::function<>
type:
drake/.../value_producer.h
It happens during .Connect()
because that will ultimately call Allocate()
:
drake/.../diagram_builder.cc
Because Python returns something not of an AbstractValue
type, it is unable to cast, hence the error message
Upvotes: 1