BehaviorTree/BehaviorTree.ROS2

Feature request: generic sub nodes and ports

Opened this issue · 3 comments

Currently to use topics in BT I wirte up a simple sub node and expose needed members as ports. This works, however after a while there are a lot of similiar code.

Is it possible to make this generic?

Also it would be nice to have generic port types for topic types. To this, to_yaml functions could be used. For example

    multi_uav_bt_nodes::Pose msg;
    msg.position.x = 10;
    msg.position.y = 10;
    msg.position.z = 10;
    EXPECT_EQ( geometry_msgs::msg::to_yaml(msg,true), "{position: {x: 10.0000, y: 10.0000, z: 10.0000}, orientation: {x: 0.00000, y: 0.00000, z: 0.00000, w: 1.00000}}" );

couldnt find how to parse it but probobly some function rosidl will work.

Also for reference my sub nodes looks like this:

using Pose = geometry_msgs::msg::Pose;

class ListenPoseAction : public BT::RosTopicSubNode<Pose>
{
public:
  ListenPoseAction(
    const std::string & name,
    const BT::NodeConfig & conf,
    const BT::RosNodeParams & params)
  : BT::RosTopicSubNode<Pose>(name, conf, params) {}

  static BT::PortsList providedPorts();

  BT::NodeStatus onTick(const typename Pose::SharedPtr & last_msg) override;

  virtual ~ListenPoseAction();
};
BT::PortsList ListenPoseAction::providedPorts()
{
  return providedBasicPorts(
    {
      BT::OutputPort<double>("X"),
      BT::OutputPort<double>("Y"),
      BT::OutputPort<double>("Z")});
}

BT::NodeStatus ListenPoseAction::onTick(const typename Pose::SharedPtr & last_msg)
{
  if (!last_msg) {
    return BT::NodeStatus::FAILURE;
  }
  setOutput("X", last_msg->position.x);
  setOutput("Y", last_msg->position.y);
  setOutput("Z", last_msg->position.z);
  return BT::NodeStatus::SUCCESS;
}

ListenPoseAction::~ListenPoseAction()
{
}

note that ony the first line of the hpp (which could be a template variable) and code related to ports (which would be the generic port) change for different ros topics

if not for the missing parser function and some small details this could have been a merge request 😿

I wonder how nav2 did it 🤔

I have done this a while ago (with sligthly modified dynmsgs ) However, the code is intermingled with personal stuff, and also there some problematic edge cases so i cant create a merge request.

however I wonder if this can somehow used for a better result: https://github.com/facontidavide/rosx_introspection