You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I wanted to create a connection between Groot and the BehaviorTree.CPP library on ros2-foxy. I'm working in a docker container and installed all relevant packages. Firstly I installed the behaviortree-pkg via apt install and afterwards I tried installation from src. On the first try, the ZMQ publisher and server died. On the second try, only the publisher died. The error msg is shown below.
Dockerfile
## behavior tree
RUN apt-get update && \
apt-get install -y \
libzmq3-dev \
libboost-dev \
ros-$ROS2_DISTRO-behaviortree-cpp-v3
## GROOT
RUN apt-get update && \
apt-get install -y \
qtbase5-dev \
libqt5svg5-dev \
libzmq3-dev \
libdw-dev
Groot installation
git clone https://github.com/BehaviorTree/Groot.git
colcon build
ros2 run groot Groot
// set PublisherZMQ to connect the tree with GROOT
RCLCPP_INFO(this->get_logger(), "set ZMQ Publisher");
unsigned max_msg_per_second = 25;
unsigned publisher_port = 1666;
unsigned server_port = 1667;
PublisherZMQ publisher_zmq(tree,max_msg_per_second, publisher_port, server_port);
// Copyright (c) 2021 Xeni Robotics
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/* **********************************************************************
* Reads a behavior tree xml file and calls various action servers and
* simple services to complete the mission.
* **********************************************************************/
#include <chrono>
#include <functional>
#include <memory>
#include <string>
#include <fstream> // infile
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
#include "sensor_msgs/msg/battery_state.hpp"
#include "flight_control/utility_action.h"
#include "flight_control/drone_move_action.h"
#include "flight_control/drone_takeoff_action.h"
#include "flight_control/drone_land_action.h"
#include "flight_control/drone_target_land_action.h"
#include "flight_control/camera_save_action.h"
#include "flight_control/map_load_action.h"
#include "flight_control/map_save_action.h"
#include "flight_control/photogrammetry_action.h"
#include "flight_control/coverage_action.h"
#include "flight_control/camera_model_action.h"
#include "navigation_interfaces/srv/mission.hpp"
#include <behaviortree_cpp_v3/loggers/bt_zmq_publisher.h>
using Mission = navigation_interfaces::srv::Mission;
using namespace std::chrono_literals;
using namespace BT;
class FlightControlNode : public rclcpp::Node
{
public:
FlightControlNode()
: Node("flight_control_node"), current_battery_voltage_(14.8), clear_to_fly_(false)
{
one_off_timer_ = this->create_wall_timer(
1000ms, std::bind(&FlightControlNode::init, this));
}
private:
void init ()
{
// Only run this once
this->one_off_timer_->cancel();
// Declare and get parameters
behaviour_tree_file_ = this->declare_parameter<std::string>("mission_bt_file", "mission.xml");
minimum_battery_voltage_ = this->declare_parameter<float>("minimum_battery_voltage", 13.6);
clear_to_fly_ = ! this->declare_parameter<bool>("use_ground_control", false);
drone_code_ = this->declare_parameter<int>("drone_code", 42);
/*
// Handle case where no ground control is to be used
if (clear_to_fly_) {
RCLCPP_INFO(this->get_logger(), "starting mission from main");
read_mission_file();
}*/
// Setup the behavior tree
using namespace DroneNodes;
factory.registerSimpleCondition("BatteryOK", std::bind(&FlightControlNode::CheckBattery, this));
factory.registerNodeType<DroneTakeoffAction>("TakeoffDrone");
factory.registerNodeType<DroneLandAction>("LandDrone");
factory.registerNodeType<DroneTargetLandAction>("TargetLandDrone");
factory.registerNodeType<DroneMoveAction>("MoveDrone");
factory.registerNodeType<SaySomething>("SaySomething");
factory.registerNodeType<GenerateFilename>("GenerateFilename");
factory.registerNodeType<CameraSaveAction>("SavePicture");
factory.registerNodeType<MapLoadAction>("LoadMap");
factory.registerNodeType<MapSaveAction>("SaveMap");
factory.registerNodeType<PhotogrammetryAction>("Photogrammetry");
factory.registerNodeType<CoverageAction>("CalculateCoverage");
factory.registerNodeType<CameraModelAction>("CameraModel");
// mission file creates behavior tree
// this must be called after registration of NOdes
// the BT cration is also necessary as timer_callback ticks the Tree
// mission_start service has no function
read_mission_file();
subscription_ = this->create_subscription<sensor_msgs::msg::BatteryState>(
"drone/battery", 5, std::bind(&FlightControlNode::battery_callback, this, std::placeholders::_1));
mission_service_ = this->create_service<Mission>("drone/mission",
std::bind(&FlightControlNode::start_mission, this, std::placeholders::_1, std::placeholders::_2));
timer_ = this->create_wall_timer(
1000ms, std::bind(&FlightControlNode::timer_callback, this));
// set PublisherZMQ to connect the tree with GROOT
RCLCPP_INFO(this->get_logger(), "set ZMQ Publisher");
unsigned max_msg_per_second = 25;
unsigned publisher_port = 1666;
unsigned server_port = 1667;
PublisherZMQ publisher_zmq(tree,max_msg_per_second, publisher_port, server_port);
}
void start_mission(const std::shared_ptr<Mission::Request> request,
std::shared_ptr<Mission::Response> response)
{
if (request->drone_code == drone_code_) {
behaviour_tree_file_ = request->mission_file;
if (!is_file_exist(behaviour_tree_file_.c_str())) {
RCLCPP_ERROR(this->get_logger(), "Mission file : '%s' not found.", behaviour_tree_file_.c_str());
clear_to_fly_ = false;
} else {
clear_to_fly_ = read_mission_file();
}
} else {
clear_to_fly_ = false;
}
response->accepted = clear_to_fly_;
}
bool is_file_exist(const char *fileName)
{
std::ifstream infile(fileName);
return infile.good();
}
bool read_mission_file() {
if (!is_file_exist(behaviour_tree_file_.c_str())) {
RCLCPP_ERROR(this->get_logger(), "Mission file : '%s' not found.", behaviour_tree_file_.c_str());
return false;
}
RCLCPP_INFO(this->get_logger(), "Reading mission file : '%s'", behaviour_tree_file_.c_str());
tree = factory.createTreeFromFile(behaviour_tree_file_);
RCLCPP_INFO(this->get_logger(), "Successfully read mission file : '%s'", behaviour_tree_file_.c_str());
auto node_ptr = shared_from_this();
// Iterate through all the nodes and call init() if it is an Action_B
using namespace DroneNodes;
for( auto& node: tree.nodes )
{
// Not a typo: it is "=", not "=="
if( auto takeoff_action = dynamic_cast<DroneTakeoffAction*>( node.get() )) {
takeoff_action->init( node_ptr );
} else if( auto land_action = dynamic_cast<DroneLandAction*>( node.get() )) {
land_action->init( node_ptr );
} else if( auto target_land_action = dynamic_cast<DroneTargetLandAction*>( node.get() )) {
target_land_action->init( node_ptr );
} else if( auto move_action = dynamic_cast<DroneMoveAction*>( node.get() )) {
move_action->init( node_ptr );
} else if( auto save_picture_action = dynamic_cast<CameraSaveAction*>( node.get() )) {
save_picture_action->init( node_ptr );
} else if( auto load_action = dynamic_cast<MapLoadAction*>( node.get() )) {
load_action->init( node_ptr );
} else if( auto save_action = dynamic_cast<MapSaveAction*>( node.get() )) {
save_action->init( node_ptr );
} else if( auto save_action = dynamic_cast<PhotogrammetryAction*>( node.get() )) {
save_action->init( node_ptr );
} else if( auto save_action = dynamic_cast<CoverageAction*>( node.get() )) {
save_action->init( node_ptr );
} else if( auto mystery_action = dynamic_cast<CameraModelAction*>( node.get() )) {
mystery_action->init( node_ptr );
}
}
return true;
}
BT::NodeStatus CheckBattery()
{
return (current_battery_voltage_ >= minimum_battery_voltage_) ? BT::NodeStatus::SUCCESS : BT::NodeStatus::FAILURE;
}
void battery_callback(const sensor_msgs::msg::BatteryState::SharedPtr msg)
{
current_battery_voltage_ = msg->voltage;
}
rclcpp::Subscription<sensor_msgs::msg::BatteryState>::SharedPtr subscription_;
void timer_callback()
{
using namespace DroneNodes;
if( !clear_to_fly_ ) {
return;
}
clear_to_fly_ = ( tree.tickRoot() == NodeStatus::RUNNING); // Stop flight once the tree is done.
}
BehaviorTreeFactory factory;
Tree tree;
rclcpp::TimerBase::SharedPtr timer_;
rclcpp::TimerBase::SharedPtr one_off_timer_;
float minimum_battery_voltage_;
float current_battery_voltage_;
int drone_code_;
std::string behaviour_tree_file_;
bool clear_to_fly_;
rclcpp::Service<Mission>::SharedPtr mission_service_;
};
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<FlightControlNode>());
rclcpp::shutdown();
return 0;
}
[PublisherZMQ] Server quitting.
[PublisherZMQ] just died. Exception Context was terminated
[PublisherZMQ] Publisher quitting.
[PublisherZMQ] just died. Exception Context was terminated
I wanted to create a connection between Groot and the BehaviorTree.CPP library on ros2-foxy. I'm working in a docker container and installed all relevant packages. Firstly I installed the behaviortree-pkg via apt install and afterwards I tried installation from src. On the first try, the ZMQ publisher and server died. On the second try, only the publisher died. The error msg is shown below.
Dockerfile
Groot installation
ROS2 node
from: https://github.com/slaghuis/flight_control
with the added lines:
1) installing by: apt install ros-foxy-behaviortree-cpp-v3
2) installing behaviortree-cpp-v3 from source
via
and changing the ip from * to 0.0.0.0
brings following error, only the publisher died
The text was updated successfully, but these errors were encountered: