0

I declared the output port as suggested in the previous answer here using lambda: AbstractValue.Make([ExternallyAppliedSpatialForce() for i in range(N_props + N_wings)] and that resolved the previous error related to DeclareAbstractOutputPort.

The new class is below:


    def __init__(self, N_props, N_wings):
        LeafSystem.__init__(self)
        self.DeclareAbstractInputPort("propeller_force",
            AbstractValue.Make([ExternallyAppliedSpatialForce(), ExternallyAppliedSpatialForce(), 
            ExternallyAppliedSpatialForce(), ExternallyAppliedSpatialForce()]) )
        self.DeclareAbstractInputPort("wing_force",
            AbstractValue.Make(ExternallyAppliedSpatialForce()) )
        self.DeclareAbstractOutputPort("spatial_forces", 
            lambda: AbstractValue.Make([ExternallyAppliedSpatialForce() for i in range(N_props + N_wings)]),
            self.OutputForces)

    def OutputForces(self, context, output):
        propeller_force = self.EvalVectorInput(context, 0)[0]
        wing_force = self.EvalVectorInput(context, 1)[0]

        print(propeller_force)
        print(wing_force)
        
        output.set_value([propeller_force, wing_force])
        print(output)

However, now I am getting this error when I attempt to connect the propeller "spatial_forces" output to the force concatinator.

RuntimeError: DiagramBuilder::Connect: Mismatched value types while connecting output port spatial_force of System drake/multibody/Wing@00000000044be370 (type std::vectordrake::multibody::ExternallyAppliedSpatialForce<double,std::allocatordrake::multibody::ExternallyAppliedSpatialForce<double>>) to input port wing_force of System main.SpatialForceConcatinator@0000000004491390 (type drake::multibody::ExternallyAppliedSpatialForce)

I believe this is due to the fact that I have 4 propeller forces coming out of the Propeller system, which has output of type std::vector<drake::multibody::ExternallyAppliedSpatialForce<double> while it looks like the type for the "propeller force" input port of the SpatialForceConcatinator is of type drake::multibody::ExternallyAppliedSpatialForce<double>

I have found another stack overflow post here where someone ran into the same error and they mentioned using the VectorExternallyAppliedSpatialForced() instead of ExternallyAppliedSpatialForce() when declaring the input port.

However when I try to import this class using from pydrake.all import VectorExternallyAppliedSpatialForced the import fails. And I do not see any mention of this class in the Drake documention.

Is this class still implemented in Drake? If not, is there another way to resolve the above error? I tried passing a list of forces to AbstractValue.Make() like so self.DeclareAbstractInputPort("propeller_force", AbstractValue.Make([ExternallyAppliedSpatialForce(), ExternallyAppliedSpatialForce(), ExternallyAppliedSpatialForce(), ExternallyAppliedSpatialForce()]) ) but this did not resolve the issue.

mason
  • 31
  • 2

1 Answers1

0

I believe you need to replace

        self.DeclareAbstractInputPort("wing_force",
            AbstractValue.Make(ExternallyAppliedSpatialForce()) )

with

        self.DeclareAbstractInputPort("wing_force",
            AbstractValue.Make([ExternallyAppliedSpatialForce()]) )

Your line with output.set_value(...) also looks suspicious to me. [list1, list2] creates a list of lists, not one list of forces. Perhaps you want list1+list2, or one of many ways to concatenate lists in python.

Russ Tedrake
  • 4,703
  • 1
  • 7
  • 10