mirror of
https://github.com/CopterExpress/clover.git
synced 2026-06-08 18:44:32 +00:00
Compare commits
8 Commits
v0.16-alph
...
v0.16-alph
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c00882def6 | ||
|
|
394af64553 | ||
|
|
7a56a7b231 | ||
|
|
23516b0fc1 | ||
|
|
2b82516a97 | ||
|
|
a9e1015bad | ||
|
|
8257724fcc | ||
|
|
222ea3ecbf |
@@ -1,4 +1,5 @@
|
|||||||
uint32 id
|
uint32 id
|
||||||
|
float32 length
|
||||||
geometry_msgs/Pose pose
|
geometry_msgs/Pose pose
|
||||||
Point2D c1
|
Point2D c1
|
||||||
Point2D c2
|
Point2D c2
|
||||||
|
|||||||
@@ -169,6 +169,7 @@ private:
|
|||||||
|
|
||||||
for (unsigned int i = 0; i < ids.size(); i++) {
|
for (unsigned int i = 0; i < ids.size(); i++) {
|
||||||
marker.id = ids[i];
|
marker.id = ids[i];
|
||||||
|
marker.length = getMarkerLength(marker.id);
|
||||||
fillCorners(marker, corners[i]);
|
fillCorners(marker, corners[i]);
|
||||||
|
|
||||||
if (estimate_poses_) {
|
if (estimate_poses_) {
|
||||||
|
|||||||
@@ -399,12 +399,19 @@ publish_debug:
|
|||||||
|
|
||||||
void publishMapImage()
|
void publishMapImage()
|
||||||
{
|
{
|
||||||
|
cv::Size size(image_width_, image_height_);
|
||||||
cv::Mat image;
|
cv::Mat image;
|
||||||
cv_bridge::CvImage msg;
|
cv_bridge::CvImage msg;
|
||||||
drawPlanarBoard(board_, cv::Size(image_width_, image_height_), image, image_margin_, 1);
|
|
||||||
|
|
||||||
cv::cvtColor(image, image, CV_GRAY2BGR);
|
if (!board_->ids.empty()) {
|
||||||
msg.encoding = sensor_msgs::image_encodings::BGR8;
|
_drawPlanarBoard(board_, size, image, image_margin_, 1);
|
||||||
|
} else {
|
||||||
|
// empty map
|
||||||
|
image.create(size, CV_8UC1);
|
||||||
|
image.setTo(cv::Scalar::all(255));
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.encoding = sensor_msgs::image_encodings::MONO8;
|
||||||
msg.image = image;
|
msg.image = image;
|
||||||
img_pub_.publish(msg.toImageMsg());
|
img_pub_.publish(msg.toImageMsg());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,69 +6,69 @@
|
|||||||
using namespace cv;
|
using namespace cv;
|
||||||
using namespace cv::aruco;
|
using namespace cv::aruco;
|
||||||
|
|
||||||
void drawPlanarBoard(Board *_board, Size outSize, OutputArray _img, int marginSize,
|
void _drawPlanarBoard(Board *_board, Size outSize, OutputArray _img, int marginSize,
|
||||||
int borderBits) {
|
int borderBits) {
|
||||||
|
|
||||||
CV_Assert(outSize.area() > 0);
|
CV_Assert(outSize.area() > 0);
|
||||||
CV_Assert(marginSize >= 0);
|
CV_Assert(marginSize >= 0);
|
||||||
|
|
||||||
_img.create(outSize, CV_8UC1);
|
_img.create(outSize, CV_8UC1);
|
||||||
Mat out = _img.getMat();
|
Mat out = _img.getMat();
|
||||||
out.setTo(Scalar::all(255));
|
out.setTo(Scalar::all(255));
|
||||||
out.adjustROI(-marginSize, -marginSize, -marginSize, -marginSize);
|
out.adjustROI(-marginSize, -marginSize, -marginSize, -marginSize);
|
||||||
|
|
||||||
// calculate max and min values in XY plane
|
// calculate max and min values in XY plane
|
||||||
CV_Assert(_board->objPoints.size() > 0);
|
CV_Assert(_board->objPoints.size() > 0);
|
||||||
float minX, maxX, minY, maxY;
|
float minX, maxX, minY, maxY;
|
||||||
minX = maxX = _board->objPoints[0][0].x;
|
minX = maxX = _board->objPoints[0][0].x;
|
||||||
minY = maxY = _board->objPoints[0][0].y;
|
minY = maxY = _board->objPoints[0][0].y;
|
||||||
|
|
||||||
for(unsigned int i = 0; i < _board->objPoints.size(); i++) {
|
for(unsigned int i = 0; i < _board->objPoints.size(); i++) {
|
||||||
for(int j = 0; j < 4; j++) {
|
for(int j = 0; j < 4; j++) {
|
||||||
minX = min(minX, _board->objPoints[i][j].x);
|
minX = min(minX, _board->objPoints[i][j].x);
|
||||||
maxX = max(maxX, _board->objPoints[i][j].x);
|
maxX = max(maxX, _board->objPoints[i][j].x);
|
||||||
minY = min(minY, _board->objPoints[i][j].y);
|
minY = min(minY, _board->objPoints[i][j].y);
|
||||||
maxY = max(maxY, _board->objPoints[i][j].y);
|
maxY = max(maxY, _board->objPoints[i][j].y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float sizeX = maxX - minX;
|
float sizeX = maxX - minX;
|
||||||
float sizeY = maxY - minY;
|
float sizeY = maxY - minY;
|
||||||
|
|
||||||
// proportion transformations
|
// proportion transformations
|
||||||
float xReduction = sizeX / float(out.cols);
|
float xReduction = sizeX / float(out.cols);
|
||||||
float yReduction = sizeY / float(out.rows);
|
float yReduction = sizeY / float(out.rows);
|
||||||
|
|
||||||
// determine the zone where the markers are placed
|
// determine the zone where the markers are placed
|
||||||
if(xReduction > yReduction) {
|
if(xReduction > yReduction) {
|
||||||
int nRows = int(sizeY / xReduction);
|
int nRows = int(sizeY / xReduction);
|
||||||
int rowsMargins = (out.rows - nRows) / 2;
|
int rowsMargins = (out.rows - nRows) / 2;
|
||||||
out.adjustROI(-rowsMargins, -rowsMargins, 0, 0);
|
out.adjustROI(-rowsMargins, -rowsMargins, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
int nCols = int(sizeX / yReduction);
|
int nCols = int(sizeX / yReduction);
|
||||||
int colsMargins = (out.cols - nCols) / 2;
|
int colsMargins = (out.cols - nCols) / 2;
|
||||||
out.adjustROI(0, 0, -colsMargins, -colsMargins);
|
out.adjustROI(0, 0, -colsMargins, -colsMargins);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now paint each marker
|
// now paint each marker
|
||||||
Dictionary &dictionary = *(_board->dictionary);
|
Dictionary &dictionary = *(_board->dictionary);
|
||||||
Mat marker;
|
Mat marker;
|
||||||
Point2f outCorners[3];
|
Point2f outCorners[3];
|
||||||
Point2f inCorners[3];
|
Point2f inCorners[3];
|
||||||
for(unsigned int m = 0; m < _board->objPoints.size(); m++) {
|
for(unsigned int m = 0; m < _board->objPoints.size(); m++) {
|
||||||
// transform corners to markerZone coordinates
|
// transform corners to markerZone coordinates
|
||||||
for(int j = 0; j < 3; j++) {
|
for(int j = 0; j < 3; j++) {
|
||||||
Point2f pf = Point2f(_board->objPoints[m][j].x, _board->objPoints[m][j].y);
|
Point2f pf = Point2f(_board->objPoints[m][j].x, _board->objPoints[m][j].y);
|
||||||
// move top left to 0, 0
|
// move top left to 0, 0
|
||||||
pf -= Point2f(minX, minY);
|
pf -= Point2f(minX, minY);
|
||||||
pf.x = pf.x / sizeX * float(out.cols);
|
pf.x = pf.x / sizeX * float(out.cols);
|
||||||
pf.y = (1.0f - pf.y / sizeY) * float(out.rows);
|
pf.y = (1.0f - pf.y / sizeY) * float(out.rows);
|
||||||
outCorners[j] = pf;
|
outCorners[j] = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get marker
|
// get marker
|
||||||
Size dst_sz(outCorners[2] - outCorners[0]); // assuming CCW order
|
Size dst_sz(outCorners[2] - outCorners[0]); // assuming CCW order
|
||||||
// dst_sz.width = dst_sz.height = std::min(dst_sz.width, dst_sz.height); //marker should be square
|
// dst_sz.width = dst_sz.height = std::min(dst_sz.width, dst_sz.height); //marker should be square
|
||||||
double diag = std::round(std::hypot(dst_sz.width, dst_sz.height));
|
double diag = std::round(std::hypot(dst_sz.width, dst_sz.height));
|
||||||
int side = std::round(diag / std::sqrt(2));
|
int side = std::round(diag / std::sqrt(2));
|
||||||
|
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
#include <opencv2/opencv.hpp>
|
#include <opencv2/opencv.hpp>
|
||||||
#include <opencv2/aruco.hpp>
|
#include <opencv2/aruco.hpp>
|
||||||
|
|
||||||
void drawPlanarBoard(cv::aruco::Board *_board, cv::Size outSize, cv::OutputArray _img, int marginSize, int borderBits);
|
void _drawPlanarBoard(cv::aruco::Board *_board, cv::Size outSize, cv::OutputArray _img, int marginSize, int borderBits);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class TestArucoPose(unittest.TestCase):
|
|||||||
assert markers.header.frame_id == 'main_camera_optical'
|
assert markers.header.frame_id == 'main_camera_optical'
|
||||||
|
|
||||||
assert markers.markers[0].id == 2
|
assert markers.markers[0].id == 2
|
||||||
|
assert markers.markers[0].length == approx(0.33)
|
||||||
assert markers.markers[0].pose.position.x == approx(0.36706567854)
|
assert markers.markers[0].pose.position.x == approx(0.36706567854)
|
||||||
assert markers.markers[0].pose.position.y == approx(0.290484516644)
|
assert markers.markers[0].pose.position.y == approx(0.290484516644)
|
||||||
assert markers.markers[0].pose.position.z == approx(2.18787602301)
|
assert markers.markers[0].pose.position.z == approx(2.18787602301)
|
||||||
@@ -39,6 +40,7 @@ class TestArucoPose(unittest.TestCase):
|
|||||||
assert markers.markers[0].c4.y == approx(429.442260742)
|
assert markers.markers[0].c4.y == approx(429.442260742)
|
||||||
|
|
||||||
assert markers.markers[3].id == 3
|
assert markers.markers[3].id == 3
|
||||||
|
assert markers.markers[3].length == approx(0.1)
|
||||||
assert markers.markers[3].pose.position.x == approx(-0.1805169666)
|
assert markers.markers[3].pose.position.x == approx(-0.1805169666)
|
||||||
assert markers.markers[3].pose.position.y == approx(-0.200697302327)
|
assert markers.markers[3].pose.position.y == approx(-0.200697302327)
|
||||||
assert markers.markers[3].pose.position.z == approx(0.585767514823)
|
assert markers.markers[3].pose.position.z == approx(0.585767514823)
|
||||||
@@ -56,10 +58,19 @@ class TestArucoPose(unittest.TestCase):
|
|||||||
assert markers.markers[3].c4.y == approx(143.442276001)
|
assert markers.markers[3].c4.y == approx(143.442276001)
|
||||||
|
|
||||||
assert markers.markers[1].id == 1
|
assert markers.markers[1].id == 1
|
||||||
|
assert markers.markers[1].length == approx(0.33)
|
||||||
assert markers.markers[2].id == 4
|
assert markers.markers[2].id == 4
|
||||||
|
assert markers.markers[2].length == approx(0.33)
|
||||||
|
|
||||||
def test_visualization(self):
|
def test_visualization(self):
|
||||||
vis = rospy.wait_for_message('aruco_detect/visualization', VisMarkerArray, timeout=5)
|
vis = rospy.wait_for_message('aruco_detect/visualization', VisMarkerArray, timeout=5)
|
||||||
|
assert len(vis.markers) == 9
|
||||||
|
|
||||||
|
def test_debug(self):
|
||||||
|
img = rospy.wait_for_message('aruco_detect/debug', Image, timeout=5)
|
||||||
|
assert img.width == 640
|
||||||
|
assert img.height == 480
|
||||||
|
assert img.header.frame_id == 'main_camera_optical'
|
||||||
|
|
||||||
def test_map(self):
|
def test_map(self):
|
||||||
pose = rospy.wait_for_message('aruco_map/pose', PoseWithCovarianceStamped, timeout=5)
|
pose = rospy.wait_for_message('aruco_map/pose', PoseWithCovarianceStamped, timeout=5)
|
||||||
@@ -72,6 +83,18 @@ class TestArucoPose(unittest.TestCase):
|
|||||||
assert pose.pose.pose.orientation.z == approx(-0.0300861070302)
|
assert pose.pose.pose.orientation.z == approx(-0.0300861070302)
|
||||||
assert pose.pose.pose.orientation.w == approx(0.0482143590507)
|
assert pose.pose.pose.orientation.w == approx(0.0482143590507)
|
||||||
|
|
||||||
|
def test_map_image(self):
|
||||||
|
img = rospy.wait_for_message('aruco_map/image', Image, timeout=5)
|
||||||
|
assert img.width == 2000
|
||||||
|
assert img.height == 2000
|
||||||
|
assert img.encoding == 'mono8'
|
||||||
|
|
||||||
|
def test_map_visualization(self):
|
||||||
|
vis = rospy.wait_for_message('aruco_map/visualization', VisMarkerArray, timeout=5)
|
||||||
|
|
||||||
|
def test_map_debug(self):
|
||||||
|
img = rospy.wait_for_message('aruco_map/debug', Image, timeout=5)
|
||||||
|
|
||||||
# def test_transforms(self):
|
# def test_transforms(self):
|
||||||
# pass
|
# pass
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<remap from="camera_info" to="main_camera/camera_info"/>
|
<remap from="camera_info" to="main_camera/camera_info"/>
|
||||||
<remap from="markers" to="aruco_detect/markers"/>
|
<remap from="markers" to="aruco_detect/markers"/>
|
||||||
<param name="type" value="map"/>
|
<param name="type" value="map"/>
|
||||||
<param name="map" value="$(find aruco_pose)/map/map.txt"/>
|
<param name="map" value="$(find aruco_pose)/test/basic.txt"/>
|
||||||
</node>
|
</node>
|
||||||
|
|
||||||
<test test-name="test_aruco_pose" pkg="aruco_pose" type="basic.py"/>
|
<test test-name="test_aruco_pose" pkg="aruco_pose" type="basic.py"/>
|
||||||
|
|||||||
5
aruco_pose/test/basic.txt
Normal file
5
aruco_pose/test/basic.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
1 0.33 0 0 0 0 0 0
|
||||||
|
2 0.33 1 0 0 0 0 0
|
||||||
|
3 0.33 0 1 0 0 0 0
|
||||||
|
4 0.33 1 1 0 0 0 0
|
||||||
|
10 0.5 0.5 2 0 1.2 0 0
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
# PixHawk (px4fmu-v2), px4fmu-v3
|
# PixHawk (px4fmu-v2), px4fmu-v3
|
||||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0011", SYMLINK+="px4fmu"
|
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0011", ATTRS{product}=="PX4 FMU v2.x", SYMLINK+="px4fmu"
|
||||||
# PixRacer (px4fmu-v4)
|
# PixRacer (px4fmu-v4)
|
||||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0012", SYMLINK+="px4fmu"
|
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0012", ATTRS{product}=="PX4 FMU v4.x", SYMLINK+="px4fmu"
|
||||||
# px4fmu-v5
|
# px4fmu-v5
|
||||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0012", SYMLINK+="px4fmu"
|
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0032", ATTRS{product}=="PX4 FMU v5.x", SYMLINK+="px4fmu"
|
||||||
# auav
|
# auav
|
||||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0021", SYMLINK+="px4fmu"
|
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0021", ATTRS{product}=="PX4 AUAV x2.1", SYMLINK+="px4fmu"
|
||||||
# crazyflie
|
# crazyflie
|
||||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0016", SYMLINK+="px4fmu"
|
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0016", ATTRS{product}=="PX4 Crazyflie v2.0", SYMLINK+="px4fmu"
|
||||||
# px4fmu-v4pro
|
# px4fmu-v4pro
|
||||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0013", SYMLINK+="px4fmu"
|
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0013", ATTRS{product}=="PX4 FMU v4.x PRO", SYMLINK+="px4fmu"
|
||||||
# Omnibus
|
# Omnibus
|
||||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0001", SYMLINK+="px4fmu"
|
SUBSYSTEM=="tty", ATTRS{idVendor}=="26ac", ATTRS{idProduct}=="0001", ATTRS{product}=="PX4 OmnibusF4SD", SYMLINK+="px4fmu"
|
||||||
|
|
||||||
|
|||||||
@@ -454,10 +454,10 @@ inline void checkState()
|
|||||||
throw std::runtime_error("No connection to FCU, https://clever.copterexpress.com/connection.html");
|
throw std::runtime_error("No connection to FCU, https://clever.copterexpress.com/connection.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void serve(enum setpoint_type_t sp_type, float x, float y, float z, float vx, float vy, float vz,
|
bool serve(enum setpoint_type_t sp_type, float x, float y, float z, float vx, float vy, float vz,
|
||||||
float pitch, float roll, float yaw, float pitch_rate, float roll_rate, float yaw_rate,
|
float pitch, float roll, float yaw, float pitch_rate, float roll_rate, float yaw_rate,
|
||||||
float lat, float lon, float thrust, float speed, string frame_id, bool auto_arm,
|
float lat, float lon, float thrust, float speed, string frame_id, bool auto_arm,
|
||||||
uint8_t& success, string& message)
|
uint8_t& success, string& message)
|
||||||
{
|
{
|
||||||
auto stamp = ros::Time::now();
|
auto stamp = ros::Time::now();
|
||||||
|
|
||||||
@@ -601,42 +601,36 @@ inline void serve(enum setpoint_type_t sp_type, float x, float y, float z, float
|
|||||||
message = e.what();
|
message = e.what();
|
||||||
ROS_INFO("simple_offboard: %s", message.c_str());
|
ROS_INFO("simple_offboard: %s", message.c_str());
|
||||||
busy = false;
|
busy = false;
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
busy = false;
|
busy = false;
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool navigate(Navigate::Request& req, Navigate::Response& res) {
|
bool navigate(Navigate::Request& req, Navigate::Response& res) {
|
||||||
serve(NAVIGATE, req.x, req.y, req.z, 0, 0, 0, 0, 0, req.yaw, 0, 0, req.yaw_rate, 0, 0, 0, req.speed, req.frame_id, req.auto_arm, res.success, res.message);
|
return serve(NAVIGATE, req.x, req.y, req.z, 0, 0, 0, 0, 0, req.yaw, 0, 0, req.yaw_rate, 0, 0, 0, req.speed, req.frame_id, req.auto_arm, res.success, res.message);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool navigateGlobal(NavigateGlobal::Request& req, NavigateGlobal::Response& res) {
|
bool navigateGlobal(NavigateGlobal::Request& req, NavigateGlobal::Response& res) {
|
||||||
serve(NAVIGATE_GLOBAL, 0, 0, req.z, 0, 0, 0, 0, 0, req.yaw, 0, 0, req.yaw_rate, req.lat, req.lon, 0, req.speed, req.frame_id, req.auto_arm, res.success, res.message);
|
return serve(NAVIGATE_GLOBAL, 0, 0, req.z, 0, 0, 0, 0, 0, req.yaw, 0, 0, req.yaw_rate, req.lat, req.lon, 0, req.speed, req.frame_id, req.auto_arm, res.success, res.message);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setPosition(SetPosition::Request& req, SetPosition::Response& res) {
|
bool setPosition(SetPosition::Request& req, SetPosition::Response& res) {
|
||||||
serve(POSITION, req.x, req.y, req.z, 0, 0, 0, 0, 0, req.yaw, 0, 0, req.yaw_rate, 0, 0, 0, 0, req.frame_id, req.auto_arm, res.success, res.message);
|
return serve(POSITION, req.x, req.y, req.z, 0, 0, 0, 0, 0, req.yaw, 0, 0, req.yaw_rate, 0, 0, 0, 0, req.frame_id, req.auto_arm, res.success, res.message);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setVelocity(SetVelocity::Request& req, SetVelocity::Response& res) {
|
bool setVelocity(SetVelocity::Request& req, SetVelocity::Response& res) {
|
||||||
serve(VELOCITY, 0, 0, 0, req.vx, req.vy, req.vz, 0, 0, req.yaw, 0, 0, req.yaw_rate, 0, 0, 0, 0, req.frame_id, req.auto_arm, res.success, res.message);
|
return serve(VELOCITY, 0, 0, 0, req.vx, req.vy, req.vz, 0, 0, req.yaw, 0, 0, req.yaw_rate, 0, 0, 0, 0, req.frame_id, req.auto_arm, res.success, res.message);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setAttitude(SetAttitude::Request& req, SetAttitude::Response& res) {
|
bool setAttitude(SetAttitude::Request& req, SetAttitude::Response& res) {
|
||||||
serve(ATTITUDE, 0, 0, 0, 0, 0, 0, req.pitch, req.roll, req.yaw, 0, 0, 0, 0, 0, req.thrust, 0, req.frame_id, req.auto_arm, res.success, res.message);
|
return serve(ATTITUDE, 0, 0, 0, 0, 0, 0, req.pitch, req.roll, req.yaw, 0, 0, 0, 0, 0, req.thrust, 0, req.frame_id, req.auto_arm, res.success, res.message);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setRates(SetRates::Request& req, SetRates::Response& res) {
|
bool setRates(SetRates::Request& req, SetRates::Response& res) {
|
||||||
serve(RATES, 0, 0, 0, 0, 0, 0, 0, 0, 0, req.pitch_rate, req.roll_rate, req.yaw_rate, 0, 0, req.thrust, 0, "", req.auto_arm, res.success, res.message);
|
return serve(RATES, 0, 0, 0, 0, 0, 0, 0, 0, 0, req.pitch_rate, req.roll_rate, req.yaw_rate, 0, 0, req.thrust, 0, "", req.auto_arm, res.success, res.message);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool land(std_srvs::Trigger::Request& req, std_srvs::Trigger::Response& res)
|
bool land(std_srvs::Trigger::Request& req, std_srvs::Trigger::Response& res)
|
||||||
|
|||||||
Reference in New Issue
Block a user