Drake: Add sugar for fixing input port value

Created on 14 Feb 2019  路  8Comments  路  Source: RobotLocomotion/drake

(From discussion with @mposa in PR #10685.) For the use case where actuation inputs u are to be provided directly rather than via connected port, the current FixInputPort incantations were confusing. Proposal:

  • Make sure the MBP actuation ports are always present, even when there are zero actuators (#10694).
  • Add a method like InputPort::FixValue(context, value).

This would allow

plant.get_actuator_port().FixValue(&context, u);

To me that seems like a nice follow-on to Jeremy's #10592 that allows

u = plant.get_actuator_port().Eval(context);

Thoughts?

/cc @edrumwri @amcastro-tri @jwnimmer-tri

medium dynamics cleanup feature request

Most helpful comment

My one request is to avoid some of the poor argtype choices of Context::FixInputPort, and instead only offer three options that mirror what InputPort::Eval offers:

class InputPort<T> {
  ...
  FixedInputPortValue& FixValue(Context<T>*, const Eigen::Ref<const VectorX<T>>& vector) const;

  template <typename U>  // + SFINAE that Value<U> is valid; bonus for automatic upcasting
  FixedInputPortValue& FixValue(Context<T>*, const U& value) const {
    FixValue(context, Value<U>(value));
  }

  FixedInputPortValue& FixValue(Context<T>*, const AbstractValue& abstract_value) const;
...
}

Remember that the argument names are important in pydrake to force a sensible overload using kwargs when necessary. (I took my best shot above.)

All 8 comments

/cc @rcory due to your recent battles with FixInputPort.

I like both of these proposals, but would propose separating the issues.

... would propose separating the issues.

Good idea - #10694 for zero-length ports. Will leave this issue for the InputPort API addition.

I think this is a great proposal. My one request is to make sure that the documentation for InputPort::FixValue calls out the "stomping" effect it will have on existing connections (via the underlying call to FixInputPort). Easiest thing would be to copy the comment from Context::FixInputPort (see #10665).

My one request is to avoid some of the poor argtype choices of Context::FixInputPort, and instead only offer three options that mirror what InputPort::Eval offers:

class InputPort<T> {
  ...
  FixedInputPortValue& FixValue(Context<T>*, const Eigen::Ref<const VectorX<T>>& vector) const;

  template <typename U>  // + SFINAE that Value<U> is valid; bonus for automatic upcasting
  FixedInputPortValue& FixValue(Context<T>*, const U& value) const {
    FixValue(context, Value<U>(value));
  }

  FixedInputPortValue& FixValue(Context<T>*, const AbstractValue& abstract_value) const;
...
}

Remember that the argument names are important in pydrake to force a sensible overload using kwargs when necessary. (I took my best shot above.)

Assigning to @sherm1 as default owner.

Status: PRs #10759 and #10838 in review.

@mposa, your idea for simplifying actuator-setting for MultibodyPlant (after much mutation and haggling and three PRs) is now in Drake. Please give it a try and let us know whether you think it simplifies the API enough to be reasonable. You can now write:

plant.get_actuator_port().FixValue(&context, value);

where value is a vector of the right size (and zero is OK). It's not quite as nice as SetActuator() would have been, but this is fully general and works for any kind of port anywhere.

Was this page helpful?
0 / 5 - 0 ratings