BehaviorTree/BehaviorTree.CPP

Subtree port remapping using Groot

Closed this issue · 1 comments

I'm trying to do port remapping using Groot. I was not able to find instructions and documentation for that.
I have a sub-tree that is used in a main tree. The nema of the mapped ports in the sub-tree and main tree are identical.
I followed the BT general port remapping instructions in the documentation but did not help.

Here is my example tree designed by Groot:

<?xml version="1.0"?>
<root main_tree_to_execute="BehaviorTree">
    <!-- ////////// -->
    <BehaviorTree ID="BehaviorTree">
        <Sequence>
            <SubTree ID="ScanSubTree" __shared_blackboard="true" drone_id="drone_1"/>
            <Action ID="ReturnToLaunch" drone_id="drone_1" flight_speed="1.0" obstacle_avoidance_required="false" rtk_fixed_required="false" smooth_path_required="true" use_global_planner="false" use_px4_rtl="false"/>
        </Sequence>
    </BehaviorTree>
    <!-- ////////// -->
    <BehaviorTree ID="ScanSubTree">
        <Sequence>
            <Action ID="Takeoff" drone_id="drone_0" target_altitude="4"/>
            <Action ID="ScanGPSPoints" drone_id="drone_0" flight_env_id="field_1" flight_speed="1.0" mission_id="test.json" obstacle_avoidance_required="false" rtk_fixed_required="false" smooth_path_required="false" use_global_planner="false"/>
        </Sequence>
    </BehaviorTree>
    <!-- ////////// -->
    <TreeNodesModel>
        <Action ID="AbortTakeoffAndLand"/>
        <Action ID="AdjustGimbalAngle"/>
        <Condition ID="AreAllSensorsOperational"/>
        <Condition ID="AreDiagnosticsPassed"/>
        <Condition ID="AreMotorsFunctional"/>
        <Condition ID="AreSensorsFunctional"/>
        <Action ID="ArmDrone"/>
        <Action ID="Ascend"/>
        <Condition ID="AtDestination"/>
        <Action ID="AvoidObstacle"/>
        <Condition ID="CanHover"/>
        <Condition ID="CanPickupCargo"/>
        <Action ID="CaptureImage">
            <input_port default="F" name="camera_id"/>
            <input_port default="drone_0" name="drone_id"/>
            <input_port default="5" name="recording_frequency"/>
            <input_port default="true" name="recording_status"/>
        </Action>
        <Condition ID="CargoDetected"/>
        <Condition ID="CargoDropPointReached"/>
        <Action ID="CheckBattery"/>
        <Condition ID="DataTransmissionFailed"/>
        <Condition ID="DataTransmissionSuccessful"/>
        <Action ID="Descend"/>
        <Action ID="DockAtStation"/>
        <Action ID="FixateOnDrone">
            <input_port default="false" name="activate_follow_target"/>
            <input_port default="drone_0" name="drone_id"/>
            <input_port default="drone_1" name="target_drone_id"/>
        </Action>
        <Condition ID="GimbalInPosition"/>
        <Action ID="Hold"/>
        <Condition ID="IsAMSLAltitudeAvailable"/>
        <Condition ID="IsAltitudeIncreasingSteadily"/>
        <Condition ID="IsAltitudeStagnantOrDecreasing"/>
        <Condition ID="IsAreaClear"/>
        <Condition ID="IsBatteryCritical"/>
        <Condition ID="IsBatteryLow"/>
        <Condition ID="IsBatterySufficient"/>
        <Condition ID="IsCameraFunctional"/>
        <Condition ID="IsCargoSecured"/>
        <Condition ID="IsDockingStationAvailable"/>
        <Condition ID="IsGPSLockAvailable"/>
        <Condition ID="IsGimbalFunctional"/>
        <Condition ID="IsImageCaptured"/>
        <Condition ID="IsInAir"/>
        <Condition ID="IsLanded"/>
        <Condition ID="IsLandingAreaClear"/>
        <Condition ID="IsMovingPlatformDetected"/>
        <Condition ID="IsPointInsideOperationalBoundary"/>
        <Condition ID="IsPointWithinSafeBoundary"/>
        <Condition ID="IsRecording"/>
        <Condition ID="IsSignalStrong"/>
        <Condition ID="IsTakeoffAreaClear"/>
        <Condition ID="IsTargetInSight"/>
        <Condition ID="IsTerrainFollowable"/>
        <Condition ID="IsZoomLimitReached"/>
        <Action ID="Land">
            <input_port default="drone_0" name="drone_id"/>
        </Action>
        <Action ID="LandOnMovingPlatform"/>
        <Action ID="LockGimbal">
            <input_port default="0.0" name="altitude"/>
            <input_port default="drone_0" name="drone_id"/>
            <input_port default="F" name="gimbal_id"/>
            <input_port default="false" name="gimbal_locker_status"/>
            <input_port default="0.0" name="latitude"/>
            <input_port default="0.0" name="longitude"/>
        </Action>
        <Condition ID="LostTarget"/>
        <Action ID="MoveBackward"/>
        <Action ID="MoveForward"/>
        <Action ID="MoveLeft"/>
        <Action ID="MoveRight"/>
        <Action ID="NavigateToPoint"/>
        <Condition ID="ObstacleDetected"/>
        <Condition ID="PathClear"/>
        <Condition ID="PathObstructed"/>
        <Condition ID="ReachedMaxAltitude"/>
        <Condition ID="ReachedMinAltitude"/>
        <Condition ID="ReachedTargetAltitude"/>
        <Condition ID="ReceivedDataFromBase"/>
        <Action ID="RecordBag">
            <input_port default="rosbag" name="bag_name">the name of the recorded rosbag</input_port>
            <input_port default="false" name="bag_recording_status">start or stop recording the roasbag</input_port>
            <input_port default="300" name="duration_s">duration of record</input_port>
            <input_port default="false" name="image_recording_status">includes or excludes image topics</input_port>
        </Action>
        <Action ID="RetreatFromThreat"/>
        <Action ID="ReturnToLaunch">
            <input_port default="drone_0" name="drone_id">drone namespace in ROS</input_port>
            <input_port default="1.0" name="flight_speed">maximum horizontal flight speed.</input_port>
            <input_port default="false" name="obstacle_avoidance_required"/>
            <input_port default="false" name="rtk_fixed_required">Won't execute the RTL Action unless the gps status is rtk_fixed. Signinficant effect on the flight stability.</input_port>
            <input_port default="true" name="smooth_path_required"/>
            <input_port default="false" name="use_global_planner"/>
            <input_port default="false" name="use_px4_rtl">if true, the U-shape PX4 RTL will be used to return the drone to its home position</input_port>
        </Action>
        <Action ID="SIYICaptureImages">
            <input_port default="drone_0" name="drone_id"/>
            <input_port default="10" name="number_of_photos"/>
        </Action>
        <Action ID="SIYIRecordVideo">
            <input_port default="drone_0" name="drone_id"/>
            <input_port default="false" name="recording_status"/>
        </Action>
        <Action ID="ScanComplete"/>
        <Action ID="ScanGPSPoints">
            <input_port default="drone_0" name="drone_id"/>
            <input_port default="warren-field" name="flight_env_id"/>
            <input_port default="1.0" name="flight_speed"/>
            <input_port default="test.json" name="mission_id"/>
            <input_port default="false" name="obstacle_avoidance_required"/>
            <input_port default="false" name="rtk_fixed_required"/>
            <input_port default="false" name="smooth_path_required"/>
            <input_port default="false" name="use_global_planner"/>
        </Action>
        <Action ID="ScanOrbit">
            <input_port default="drone_0" name="drone_id">this drone will perform the orbit scan</input_port>
            <input_port default="1.0" name="flight_speed"/>
            <input_port default="2.0" name="orbit_radius"/>
            <input_port default="false" name="orbit_scan_state">if set to true, OrbitScan will be activated.</input_port>
            <input_port default="0.0" name="target_gps_altitude"/>
            <input_port default="0.0" name="target_gps_latitide"/>
            <input_port default="0.0" name="target_gps_longitude"/>
        </Action>
        <SubTree ID="ScanSubTree">
            <input_port default="true" name="__shared_blackboard">If false (default), the Subtree has an isolated blackboard and needs port remapping</input_port>
            <input_port default="drone_0" name="drone_id">namespace of the drone in ROS</input_port>
        </SubTree>
        <Action ID="SendAlertToGroundControl"/>
        <Action ID="SetGimbalAngles">
            <input_port default="0.0" name="angle_pitch">from -90 to 20</input_port>
            <input_port default="0.0" name="angle_roll"> No active</input_port>
            <input_port default="0.0" name="angle_yaw">from -120 to 120</input_port>
            <input_port default="drone_0" name="drone_id"/>
            <input_port default="AirSim" name="gimbal_id">Real Drone: A8  || Simulation: AirSim</input_port>
        </Action>
        <Action ID="StartRecordingVideo"/>
        <Action ID="StartScanning"/>
        <Action ID="StopRecordingVideo"/>
        <Action ID="StopScanning"/>
        <Action ID="Takeoff">
            <input_port default="drone_0" name="drone_id"/>
            <input_port default="4" name="target_altitude"/>
        </Action>
        <Condition ID="ThreatDetected"/>
        <Action ID="UpdateMap">
            <input_port default="v.0" name="map_version">Changes the OBJ map version</input_port>
        </Action>
        <Action ID="YawLeft"/>
        <Action ID="YawRight"/>
        <Action ID="ZoomInCamera"/>
        <Action ID="ZoomOutCamera"/>
        <Action ID="start_recording_img">
            <input_port default="F" name="camera_id">F: Front, D: Down, B: Back, T: ThermalCam, N: NightCam</input_port>
            <input_port default="drone_0" name="drone_id"/>
            <input_port default="2" name="recording_frequency"/>
        </Action>
        <Action ID="stop_recording_img">
            <input_port default="F" name="camera_id"/>
            <input_port default="drone_0" name="drone_id"/>
            <input_port name="recording_frequency"/>
        </Action>
    </TreeNodesModel>
    <!-- ////////// -->
</root>

drone_id is the port that I want to remap. in the main tree, If I set the drone_id=drone_1, it is not reflected in the sub-tree when executing the tree.

I'm using the latest version of BT.CPP in my docker container.

https://www.behaviortree.dev/docs/tutorial-advanced/tutorial_14_subtree_model

When the names of the entries in the SubTree and the parent tree are the same, you can use the attribute _autoremap.
For instance:

<SubTree ID="MoveRobot" target="{target}"  frame="{frame}" result="{result}" />

Can be replaced by:

<SubTree ID="MoveRobot" _autoremap="true" />