add landing functionality with height meter
This commit is contained in:
@@ -9,6 +9,7 @@ from drone_services.srv import EnableFailsafe
|
|||||||
from drone_services.srv import ArmDrone
|
from drone_services.srv import ArmDrone
|
||||||
from drone_services.srv import DisarmDrone
|
from drone_services.srv import DisarmDrone
|
||||||
from drone_services.srv import ReadyDrone
|
from drone_services.srv import ReadyDrone
|
||||||
|
from drone_services.srv import Land
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import websockets.server
|
import websockets.server
|
||||||
@@ -100,6 +101,10 @@ class ApiListener(Node):
|
|||||||
self.wait_for_service(self.ready_drone_client, "Ready drone")
|
self.wait_for_service(self.ready_drone_client, "Ready drone")
|
||||||
self.ready_drone_request = ReadyDrone.Request()
|
self.ready_drone_request = ReadyDrone.Request()
|
||||||
|
|
||||||
|
self.land_client = self.create_client(Land, "/drone/land")
|
||||||
|
self.wait_for_service(self.land_client, "Land drone")
|
||||||
|
self.land_request = Land.Request()
|
||||||
|
|
||||||
self.status_data = {}
|
self.status_data = {}
|
||||||
self.status_data_received = False
|
self.status_data_received = False
|
||||||
self.last_message = ""
|
self.last_message = ""
|
||||||
@@ -362,6 +367,8 @@ class ApiListener(Node):
|
|||||||
self.move_position_request.front_back = 0.0
|
self.move_position_request.front_back = 0.0
|
||||||
self.move_position_request.angle = 0.0
|
self.move_position_request.angle = 0.0
|
||||||
self.send_move_position_request()
|
self.send_move_position_request()
|
||||||
|
future = self.land_drone_client.call_async(self.land_drone_request)
|
||||||
|
future.add_done_callback(partial(self.land_service_callback))
|
||||||
|
|
||||||
def arm_disarm(self):
|
def arm_disarm(self):
|
||||||
"""Sends an arm or disarm request to the PX4Controller"""
|
"""Sends an arm or disarm request to the PX4Controller"""
|
||||||
@@ -411,6 +418,16 @@ class ApiListener(Node):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.get_logger().error(
|
self.get_logger().error(
|
||||||
'Something went wrong while calling the disarm service!\n' + str(e))
|
'Something went wrong while calling the disarm service!\n' + str(e))
|
||||||
|
def land_service_callback(self, future):
|
||||||
|
try:
|
||||||
|
result = future.result()
|
||||||
|
if result.is_landing:
|
||||||
|
self.get_logger().info('Land service call success')
|
||||||
|
else:
|
||||||
|
self.get_logger().error('Land service call failed')
|
||||||
|
except Exception as e:
|
||||||
|
self.get_logger().error(
|
||||||
|
'Something went wrong while calling the land service!\n' + str(e))
|
||||||
|
|
||||||
def consume_message(self, message):
|
def consume_message(self, message):
|
||||||
"""Consumes a message from the client"""
|
"""Consumes a message from the client"""
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <drone_services/srv/move_position.hpp>
|
#include <drone_services/srv/move_position.hpp>
|
||||||
#include <drone_services/srv/ready_drone.hpp>
|
#include <drone_services/srv/ready_drone.hpp>
|
||||||
#include <drone_services/srv/arm_drone.hpp>
|
#include <drone_services/srv/arm_drone.hpp>
|
||||||
|
#include <drone_services/srv/land.hpp>
|
||||||
|
|
||||||
#include <drone_services/srv/enable_failsafe.hpp>
|
#include <drone_services/srv/enable_failsafe.hpp>
|
||||||
#include <drone_services/msg/failsafe_msg.hpp>
|
#include <drone_services/msg/failsafe_msg.hpp>
|
||||||
@@ -33,6 +34,8 @@
|
|||||||
// converts bitmask control mode to control mode used by PX4Controller
|
// converts bitmask control mode to control mode used by PX4Controller
|
||||||
#define PX4_CONTROLLER_CONTROL_MODE(x) ((x) == 4 ? 1 : ((x) == 16 ? 2 : ((x) == 32 ? 3 : -1)))
|
#define PX4_CONTROLLER_CONTROL_MODE(x) ((x) == 4 ? 1 : ((x) == 16 ? 2 : ((x) == 32 ? 3 : -1)))
|
||||||
|
|
||||||
|
#define HEIGHT_DELTA 0.1
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
struct Quaternion
|
struct Quaternion
|
||||||
@@ -54,7 +57,8 @@ public:
|
|||||||
this->odometry_subscription = this->create_subscription<px4_msgs::msg::VehicleOdometry>("/fmu/out/vehicle_odometry", qos, std::bind(&PositionChanger::handle_odometry_message, this, std::placeholders::_1));
|
this->odometry_subscription = this->create_subscription<px4_msgs::msg::VehicleOdometry>("/fmu/out/vehicle_odometry", qos, std::bind(&PositionChanger::handle_odometry_message, this, std::placeholders::_1));
|
||||||
this->move_position_service = this->create_service<drone_services::srv::MovePosition>("/drone/move_position", std::bind(&PositionChanger::handle_move_position_request, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
this->move_position_service = this->create_service<drone_services::srv::MovePosition>("/drone/move_position", std::bind(&PositionChanger::handle_move_position_request, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||||
this->ready_drone_service = this->create_service<drone_services::srv::ReadyDrone>("/drone/ready", std::bind(&PositionChanger::handle_ready_drone_request, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
this->ready_drone_service = this->create_service<drone_services::srv::ReadyDrone>("/drone/ready", std::bind(&PositionChanger::handle_ready_drone_request, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||||
|
this->land_service = this->create_service<drone_services::srv::Land>("/drone/land", std::bind(&PositionChanger::handle_land_request, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||||
|
|
||||||
this->failsafe_publisher = this->create_publisher<drone_services::msg::FailsafeMsg>("/drone/failsafe", 10);
|
this->failsafe_publisher = this->create_publisher<drone_services::msg::FailsafeMsg>("/drone/failsafe", 10);
|
||||||
|
|
||||||
this->trajectory_client = this->create_client<drone_services::srv::SetTrajectory>("/drone/set_trajectory");
|
this->trajectory_client = this->create_client<drone_services::srv::SetTrajectory>("/drone/set_trajectory");
|
||||||
@@ -271,9 +275,60 @@ public:
|
|||||||
apply_collision_weights();
|
apply_collision_weights();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void attitude_land_callback(rclcpp::Client<drone_services::srv::SetAttitude>::SharedFuture future)
|
||||||
|
{
|
||||||
|
auto status = future.wait_for(1s);
|
||||||
|
if (status == std::future_status::ready)
|
||||||
|
{
|
||||||
|
if (future.get()->success)
|
||||||
|
{
|
||||||
|
this->get_logger()->info("Attitude set to 0 for landing, landing done");
|
||||||
|
this->has_landed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RCLCPP_INFO(this->get_logger(), "Service In-Progress...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vehicle_control_land_request_callback(rclcpp::Client<drone_services::srv::SetVehicleControl>::SharedFuture future)
|
||||||
|
{
|
||||||
|
auto status = future.wait_for(1s);
|
||||||
|
if (status == std::future_status::ready)
|
||||||
|
{
|
||||||
|
if (future.get()->success)
|
||||||
|
{
|
||||||
|
this->get_logger()->info("Vehicle Control mode set to attitude for landing");
|
||||||
|
this->attitude_request->pitch = 0;
|
||||||
|
this->attitude_request->roll = 0;
|
||||||
|
this->attitude_request->yaw = 0;
|
||||||
|
this->attitude_request->thrust = 0;
|
||||||
|
auto attitude_response = this->attitude_client->async_send_request(this->attitude_request, std::bind(&PositionChanger::attitude_land_callback, this, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RCLCPP_INFO(this->get_logger(), "Service In-Progress...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void handle_height_message(const drone_services::msg::HeightData::SharedPtr message)
|
void handle_height_message(const drone_services::msg::HeightData::SharedPtr message)
|
||||||
{
|
{
|
||||||
this->current_height = message->height;
|
this->current_height = message->height;
|
||||||
|
if (!this->got_ready_drone_request)
|
||||||
|
{
|
||||||
|
this->start_height = message->height;
|
||||||
|
}
|
||||||
|
if (this->is_landing)
|
||||||
|
{
|
||||||
|
if (this->current_height <= this->start_height + HEIGHT_DELTA)
|
||||||
|
{
|
||||||
|
this->vehicle_control_request->control = 4;
|
||||||
|
auto control_mode_response = this->vehicle_control_client->async_send_request(this->vehicle_control_request,
|
||||||
|
std::bind(&PositionChanger::vehicle_control_land_request_callback, this, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -386,6 +441,15 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_land_request(
|
||||||
|
const std::shared_ptr<rmw_request_id_t> request_header,
|
||||||
|
const std::shared_ptr<drone_services::srv::Land::Request> request,
|
||||||
|
const std::shared_ptr<drone_services::srv::Land::Response> response)
|
||||||
|
{
|
||||||
|
this->is_landing = true;
|
||||||
|
response->is_landing = this->is_landing;
|
||||||
|
}
|
||||||
|
|
||||||
void handle_ready_drone_request(
|
void handle_ready_drone_request(
|
||||||
const std::shared_ptr<rmw_request_id_t> request_header,
|
const std::shared_ptr<rmw_request_id_t> request_header,
|
||||||
const std::shared_ptr<drone_services::srv::ReadyDrone::Request> request,
|
const std::shared_ptr<drone_services::srv::ReadyDrone::Request> request,
|
||||||
@@ -453,7 +517,7 @@ private:
|
|||||||
|
|
||||||
rclcpp::Service<drone_services::srv::MovePosition>::SharedPtr move_position_service;
|
rclcpp::Service<drone_services::srv::MovePosition>::SharedPtr move_position_service;
|
||||||
rclcpp::Service<drone_services::srv::ReadyDrone>::SharedPtr ready_drone_service;
|
rclcpp::Service<drone_services::srv::ReadyDrone>::SharedPtr ready_drone_service;
|
||||||
|
rclcpp::Service<drone_services::srv::Land>::SharedPtr land_service;
|
||||||
rclcpp::TimerBase::SharedPtr lidar_health_timer;
|
rclcpp::TimerBase::SharedPtr lidar_health_timer;
|
||||||
|
|
||||||
drone_services::srv::SetTrajectory::Request::SharedPtr trajectory_request;
|
drone_services::srv::SetTrajectory::Request::SharedPtr trajectory_request;
|
||||||
@@ -469,6 +533,7 @@ private:
|
|||||||
float current_speed_y = 0;
|
float current_speed_y = 0;
|
||||||
float current_speed_z = 0;
|
float current_speed_z = 0;
|
||||||
float current_height = 0;
|
float current_height = 0;
|
||||||
|
float start_height = -1;
|
||||||
bool is_landing = false;
|
bool is_landing = false;
|
||||||
bool move_direction_allowed[4] = {true}; // whether the drone can move in a certain direction
|
bool move_direction_allowed[4] = {true}; // whether the drone can move in a certain direction
|
||||||
float collision_prevention_weights[4] = {0}; // the amount to move away from an object in a certain direction if the drone is too close
|
float collision_prevention_weights[4] = {0}; // the amount to move away from an object in a certain direction if the drone is too close
|
||||||
|
|||||||
Reference in New Issue
Block a user