mirror of
https://github.com/CopterExpress/clover.git
synced 2026-06-01 15:39:32 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28e89704e6 | ||
|
|
23da41247f | ||
|
|
1e45ec143c | ||
|
|
26ec42f1e6 | ||
|
|
3edb2f48e0 | ||
|
|
3a08085c69 | ||
|
|
4e4dfc1f07 | ||
|
|
6b0ed144e3 | ||
|
|
91bb9d6e38 | ||
|
|
e1ff92ee1f | ||
|
|
4d2b685b06 | ||
|
|
14c41b21b6 | ||
|
|
70439f172d | ||
|
|
dacaa8ebde | ||
|
|
a5309765f1 | ||
|
|
2e86ed199a | ||
|
|
ad14822684 | ||
|
|
936efa985d |
6
.github/workflows/build-image.yaml
vendored
6
.github/workflows/build-image.yaml
vendored
@@ -13,18 +13,18 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: Build image
|
- name: Build image
|
||||||
run: |
|
run: |
|
||||||
docker run --privileged --rm -v /dev:/dev -v $(pwd):/builder/repo -e TRAVIS_TAG="${{ github.event.release.tag_name }}" sfalexrog/img-tool:qemu-update
|
docker run --privileged --rm -v /dev:/dev -v $(pwd):/builder/repo -e TRAVIS_TAG="${{ github.event.release.tag_name }}" sfalexrog/img-tool:qemu-update
|
||||||
- name: Compress image
|
- name: Compress image
|
||||||
run: |
|
run: |
|
||||||
cd images && sudo chmod -R 777 . && zip -9 $(echo clover_*).zip clover_* && ls -l . && unzip -l clover_*.zip
|
cd images && sudo chmod -R 777 . && zip -9 $(echo *_*).zip *_* && ls -l . && unzip -l *_*.zip
|
||||||
- name: Upload image
|
- name: Upload image
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: ${{ github.event_name == 'release' }}
|
if: ${{ github.event_name == 'release' }}
|
||||||
with:
|
with:
|
||||||
files: images/clover_*.zip
|
files: images/*_*.zip
|
||||||
prerelease: true
|
prerelease: true
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
# melodic:
|
# melodic:
|
||||||
# runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
# steps:
|
# steps:
|
||||||
# - uses: actions/checkout@v2
|
# - uses: actions/checkout@v4
|
||||||
# - name: Native Melodic build
|
# - name: Native Melodic build
|
||||||
# run: |
|
# run: |
|
||||||
# docker run --rm -v $(pwd):/root/catkin_ws/src/clover ros:melodic-ros-base /root/catkin_ws/src/clover/builder/standalone-install.sh
|
# docker run --rm -v $(pwd):/root/catkin_ws/src/clover ros:melodic-ros-base /root/catkin_ws/src/clover/builder/standalone-install.sh
|
||||||
@@ -23,7 +23,7 @@ jobs:
|
|||||||
working-directory: catkin_ws
|
working-directory: catkin_ws
|
||||||
shell: bash
|
shell: bash
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
path: catkin_ws/src/clover
|
path: catkin_ws/src/clover
|
||||||
- name: Install requirements
|
- name: Install requirements
|
||||||
|
|||||||
2
.github/workflows/docs.yml
vendored
2
.github/workflows/docs.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
|||||||
docs:
|
docs:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: Use Node.js
|
- name: Use Node.js
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v1
|
||||||
with: { node-version: '10' }
|
with: { node-version: '10' }
|
||||||
|
|||||||
4
.github/workflows/editorconfig.yaml
vendored
4
.github/workflows/editorconfig.yaml
vendored
@@ -11,9 +11,9 @@ jobs:
|
|||||||
editorconfig:
|
editorconfig:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: .editorconfig Linter
|
- name: .editorconfig Linter
|
||||||
run: |
|
run: |
|
||||||
wget --no-verbose https://github.com/okalachev/editorconfig-checker/releases/download/1.2.1-disable-spaces-amount/ec-linux-amd64
|
wget --no-verbose https://github.com/okalachev/editorconfig-checker/releases/download/1.2.1-disable-spaces-amount/ec-linux-amd64
|
||||||
chmod +x ec-linux-amd64
|
chmod +x ec-linux-amd64
|
||||||
./ec-linux-amd64 -spaces-after-tabs -e "roslib.js|ros3d.js|eventemitter2.js|json-to-pretty-yaml.js|draw.cpp|BinUtils.swift|\.idea|apps/android/app|blockly/|clover_blocks/programs/|highlight/|python.js|Assets.xcassets|test_parser_pass.txt|test_node_failure.txt|aruco_pose/vendor|\.stl|\.dxf|\.dae|\.material"
|
./ec-linux-amd64 -spaces-after-tabs -e "roslib.js|ros3d.js|eventemitter2.js|yaml.js|draw.cpp|BinUtils.swift|\.idea|apps/android/app|blockly/|clover_blocks/programs/|highlight/|python.js|Assets.xcassets|test_parser_pass.txt|test_node_failure.txt|aruco_pose/vendor|\.stl|\.dxf|\.dae|\.material"
|
||||||
|
|||||||
@@ -113,7 +113,9 @@
|
|||||||
"VMware",
|
"VMware",
|
||||||
"DuoCam"
|
"DuoCam"
|
||||||
],
|
],
|
||||||
"code_blocks": false
|
"code_blocks": false,
|
||||||
|
"html_elements": false
|
||||||
},
|
},
|
||||||
"MD045": false
|
"MD045": false,
|
||||||
|
"MD051": false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<package format="3">
|
<package format="3">
|
||||||
<name>aruco_pose</name>
|
<name>aruco_pose</name>
|
||||||
<version>0.24.0</version>
|
<version>0.25.0</version>
|
||||||
<description>Positioning with ArUco markers</description>
|
<description>Positioning with ArUco markers</description>
|
||||||
|
|
||||||
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
||||||
|
|||||||
@@ -140,7 +140,9 @@ my_travis_retry apt-get install -y --no-install-recommends \
|
|||||||
ros-${ROS_DISTRO}-cmake-modules \
|
ros-${ROS_DISTRO}-cmake-modules \
|
||||||
ros-${ROS_DISTRO}-image-view \
|
ros-${ROS_DISTRO}-image-view \
|
||||||
ros-${ROS_DISTRO}-nodelet-topic-tools \
|
ros-${ROS_DISTRO}-nodelet-topic-tools \
|
||||||
ros-${ROS_DISTRO}-stereo-msgs
|
ros-${ROS_DISTRO}-stereo-msgs \
|
||||||
|
ros-${ROS_DISTRO}-vision-msgs \
|
||||||
|
ros-${ROS_DISTRO}-angles
|
||||||
|
|
||||||
# TODO move GeographicLib datasets to Mavros debian package
|
# TODO move GeographicLib datasets to Mavros debian package
|
||||||
echo_stamp "Install GeographicLib datasets (needed for mavros)" \
|
echo_stamp "Install GeographicLib datasets (needed for mavros)" \
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ sed -i "s/updates_available//" /usr/share/byobu/status/status
|
|||||||
# sed -i "s/updates_available//" /home/pi/.byobu/status
|
# sed -i "s/updates_available//" /home/pi/.byobu/status
|
||||||
|
|
||||||
echo_stamp "Installing pip"
|
echo_stamp "Installing pip"
|
||||||
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
|
curl https://bootstrap.pypa.io/pip/3.7/get-pip.py -o get-pip.py
|
||||||
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip2.py
|
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip2.py
|
||||||
python3 get-pip.py
|
python3 get-pip.py
|
||||||
python get-pip2.py
|
python get-pip2.py
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ import os
|
|||||||
import rospy
|
import rospy
|
||||||
from geometry_msgs.msg import PoseStamped
|
from geometry_msgs.msg import PoseStamped
|
||||||
from sensor_msgs.msg import Range, BatteryState
|
from sensor_msgs.msg import Range, BatteryState
|
||||||
|
from vision_msgs.msg import BoundingBox2D, BoundingBox2DArray, BoundingBox3D, BoundingBox3DArray, \
|
||||||
|
Classification2D, Classification3D, Detection2D, Detection2DArray, Detection3D, Detection3DArray, \
|
||||||
|
ObjectHypothesis, ObjectHypothesisWithPose, VisionInfo
|
||||||
|
import angles
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
import cv2.aruco
|
import cv2.aruco
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ rosversion cv_camera
|
|||||||
rosversion web_video_server
|
rosversion web_video_server
|
||||||
rosversion nodelet
|
rosversion nodelet
|
||||||
rosversion image_view
|
rosversion image_view
|
||||||
|
rosversion stereo_msgs
|
||||||
|
rosversion vision_msgs
|
||||||
|
rosversion angles
|
||||||
|
|
||||||
[[ $(rosversion ws281x) == "0.0.13" ]]
|
[[ $(rosversion ws281x) == "0.0.13" ]]
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,52 @@
|
|||||||
Changelog for package clover
|
Changelog for package clover
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
0.25 (2024-07-28)
|
||||||
|
-----------------
|
||||||
|
* Optimize displaying newlines in the topic viewer, add width and indent parameters.
|
||||||
|
* Link assets instead of copying in documentation to save space.
|
||||||
|
* Install image_geometry and dynamic_reconfigure as clover dependencies.
|
||||||
|
* Add dictionary parameter to aruco.launch.
|
||||||
|
* Solve the issue with aruco_detect not running when aruco_map is not enabled.
|
||||||
|
* Documentation improvements.
|
||||||
|
* Rest changes.
|
||||||
|
|
||||||
|
0.24 (2023-10-11)
|
||||||
|
-----------------
|
||||||
|
* Significant update to autonomous flights API.
|
||||||
|
* Updates to selfcheck.py.
|
||||||
|
* Support PX4 v1.14 parameters.
|
||||||
|
* Added scripts for automatic testing of autonomous flights.
|
||||||
|
* Added new examples for working with the camera, including a red circle model and its recognition and following.
|
||||||
|
* Implemented long_callback Python decorator to address the issue #218.
|
||||||
|
* Implemented optical_flow/enabled dynamic parameter.
|
||||||
|
* Updated LED strip native library to support RPi 4 rev. 1.5.
|
||||||
|
* Show number of messages received in web topic viewer.
|
||||||
|
* Run main_camera/image_raw_throttled topic by default.
|
||||||
|
* Added rectify argument to main_camera.launch
|
||||||
|
* Added udev rules for all supported autopilots by PX4.
|
||||||
|
* Various changes.
|
||||||
|
|
||||||
|
0.23 (2022-02-10)
|
||||||
|
-----------------
|
||||||
|
* Web tool for topics monitoring.
|
||||||
|
* Publish optical flow when local position is not available.
|
||||||
|
* Force estimator init.
|
||||||
|
* Web viewer for Clover logs.
|
||||||
|
* selfcheck.py improvements.
|
||||||
|
* Various changes.
|
||||||
|
|
||||||
|
0.22 (2021-06-07)
|
||||||
|
-----------------
|
||||||
|
* Move to ROS Noetic and Python 3.
|
||||||
|
* aruco.launch: add placement, length and map arguments.
|
||||||
|
* Web: add link for viewing the error log.
|
||||||
|
* LED: add error/ignore parameter to not flash on some errors.
|
||||||
|
* Wait for FC and camera devices before launching mavros and camera driver.
|
||||||
|
* clover.launch: disable rc node by default.
|
||||||
|
* optical_flow: publish debug image even when calc_flow_gyro failed.
|
||||||
|
* Various changes.
|
||||||
|
|
||||||
0.21.1 (2020-11-17)
|
0.21.1 (2020-11-17)
|
||||||
-------------------
|
-------------------
|
||||||
* First release of clover package to ROS
|
* First release of clover package to ROS
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<param name="dictionary" value="2"/> <!-- DICT_4X4_250 -->
|
<param name="dictionary" value="2"/> <!-- DICT_4X4_250 -->
|
||||||
<param name="estimate_poses" value="true"/>
|
<param name="estimate_poses" value="true"/>
|
||||||
<param name="send_tf" value="true"/>
|
<param name="send_tf" value="true"/>
|
||||||
<param name="use_map_markers" value="true"/>
|
<param name="use_map_markers" value="$(arg aruco_map)"/>
|
||||||
<param name="known_vertical" value="map" if="$(eval placement == 'floor' or placement == 'ceiling')"/>
|
<param name="known_vertical" value="map" if="$(eval placement == 'floor' or placement == 'ceiling')"/>
|
||||||
<param name="flip_vertical" value="true" if="$(eval placement == 'ceiling')"/>
|
<param name="flip_vertical" value="true" if="$(eval placement == 'ceiling')"/>
|
||||||
<param name="length" value="$(arg length)"/>
|
<param name="length" value="$(arg length)"/>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<package format="3">
|
<package format="3">
|
||||||
<name>clover</name>
|
<name>clover</name>
|
||||||
<version>0.24.0</version>
|
<version>0.25.0</version>
|
||||||
<description>The Clover package</description>
|
<description>The Clover package</description>
|
||||||
|
|
||||||
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
||||||
|
|||||||
@@ -303,6 +303,14 @@ def check_fcu():
|
|||||||
failure('cell voltage is not available, https://clover.coex.tech/power')
|
failure('cell voltage is not available, https://clover.coex.tech/power')
|
||||||
else:
|
else:
|
||||||
cell = battery.cell_voltage[0]
|
cell = battery.cell_voltage[0]
|
||||||
|
# number of cells 1 means this is overall voltage
|
||||||
|
if len(battery.cell_voltage) == 1:
|
||||||
|
n_cells = get_param('BAT1_N_CELLS', strict=False)
|
||||||
|
if n_cells is None:
|
||||||
|
# older PX4
|
||||||
|
n_cells = get_param('BAT_N_CELLS', strict=True)
|
||||||
|
cell /= n_cells
|
||||||
|
|
||||||
if cell > 4.3 or cell < 3.0:
|
if cell > 4.3 or cell < 3.0:
|
||||||
failure('incorrect cell voltage: %.2f V, https://clover.coex.tech/power', cell)
|
failure('incorrect cell voltage: %.2f V, https://clover.coex.tech/power', cell)
|
||||||
elif cell < 3.7:
|
elif cell < 3.7:
|
||||||
|
|||||||
236
clover/www/js/json-to-pretty-yaml.js
vendored
236
clover/www/js/json-to-pretty-yaml.js
vendored
@@ -1,236 +0,0 @@
|
|||||||
// Browserified https://www.npmjs.com/package/json-to-pretty-yaml module
|
|
||||||
|
|
||||||
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
||||||
(function() {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var typeOf = require('remedial').typeOf;
|
|
||||||
var trimWhitespace = require('remove-trailing-spaces');
|
|
||||||
|
|
||||||
function stringify(data) {
|
|
||||||
var handlers, indentLevel = '';
|
|
||||||
|
|
||||||
handlers = {
|
|
||||||
"undefined": function() {
|
|
||||||
// objects will not have `undefined` converted to `null`
|
|
||||||
// as this may have unintended consequences
|
|
||||||
// For arrays, however, this behavior seems appropriate
|
|
||||||
return 'null';
|
|
||||||
},
|
|
||||||
"null": function() {
|
|
||||||
return 'null';
|
|
||||||
},
|
|
||||||
"number": function(x) {
|
|
||||||
return x;
|
|
||||||
},
|
|
||||||
"boolean": function(x) {
|
|
||||||
return x ? 'true' : 'false';
|
|
||||||
},
|
|
||||||
"string": function(x) {
|
|
||||||
// to avoid the string "true" being confused with the
|
|
||||||
// the literal `true`, we always wrap strings in quotes
|
|
||||||
return JSON.stringify(x);
|
|
||||||
},
|
|
||||||
"array": function(x) {
|
|
||||||
var output = '';
|
|
||||||
|
|
||||||
if (0 === x.length) {
|
|
||||||
output += '[]';
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
indentLevel = indentLevel.replace(/$/, ' ');
|
|
||||||
x.forEach(function(y, i) {
|
|
||||||
// TODO how should `undefined` be handled?
|
|
||||||
var handler = handlers[typeOf(y)];
|
|
||||||
|
|
||||||
if (!handler) {
|
|
||||||
throw new Error('what the crap: ' + typeOf(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
output += '\n' + indentLevel + '- ' + handler(y, true);
|
|
||||||
|
|
||||||
});
|
|
||||||
indentLevel = indentLevel.replace(/ /, '');
|
|
||||||
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
"object": function(x, inArray, rootNode) {
|
|
||||||
var output = '';
|
|
||||||
|
|
||||||
if (0 === Object.keys(x).length) {
|
|
||||||
output += '{}';
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rootNode) {
|
|
||||||
indentLevel = indentLevel.replace(/$/, ' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.keys(x).forEach(function(k, i) {
|
|
||||||
var val = x[k],
|
|
||||||
handler = handlers[typeOf(val)];
|
|
||||||
|
|
||||||
if ('undefined' === typeof val) {
|
|
||||||
// the user should do
|
|
||||||
// delete obj.key
|
|
||||||
// and not
|
|
||||||
// obj.key = undefined
|
|
||||||
// but we'll error on the side of caution
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!handler) {
|
|
||||||
throw new Error('what the crap: ' + typeOf(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(inArray && i === 0)) {
|
|
||||||
output += '\n' + indentLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
output += k + ': ' + handler(val);
|
|
||||||
});
|
|
||||||
indentLevel = indentLevel.replace(/ /, '');
|
|
||||||
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
"function": function() {
|
|
||||||
// TODO this should throw or otherwise be ignored
|
|
||||||
return '[object Function]';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return trimWhitespace(handlers[typeOf(data)](data, true, true) + '\n');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
window.yamlStringify = stringify;
|
|
||||||
module.exports.stringify = stringify;
|
|
||||||
}());
|
|
||||||
|
|
||||||
},{"remedial":2,"remove-trailing-spaces":3}],2:[function(require,module,exports){
|
|
||||||
/*jslint onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true */
|
|
||||||
(function () {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var global = Function('return this')()
|
|
||||||
, classes = "Boolean Number String Function Array Date RegExp Object".split(" ")
|
|
||||||
, i
|
|
||||||
, name
|
|
||||||
, class2type = {}
|
|
||||||
;
|
|
||||||
|
|
||||||
for (i in classes) {
|
|
||||||
if (classes.hasOwnProperty(i)) {
|
|
||||||
name = classes[i];
|
|
||||||
class2type["[object " + name + "]"] = name.toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function typeOf(obj) {
|
|
||||||
return (null === obj || undefined === obj) ? String(obj) : class2type[Object.prototype.toString.call(obj)] || "object";
|
|
||||||
}
|
|
||||||
|
|
||||||
function isEmpty(o) {
|
|
||||||
var i, v;
|
|
||||||
if (typeOf(o) === 'object') {
|
|
||||||
for (i in o) { // fails jslint
|
|
||||||
v = o[i];
|
|
||||||
if (v !== undefined && typeOf(v) !== 'function') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!String.prototype.entityify) {
|
|
||||||
String.prototype.entityify = function () {
|
|
||||||
return this.replace(/&/g, "&").replace(/</g,
|
|
||||||
"<").replace(/>/g, ">");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!String.prototype.quote) {
|
|
||||||
String.prototype.quote = function () {
|
|
||||||
var c, i, l = this.length, o = '"';
|
|
||||||
for (i = 0; i < l; i += 1) {
|
|
||||||
c = this.charAt(i);
|
|
||||||
if (c >= ' ') {
|
|
||||||
if (c === '\\' || c === '"') {
|
|
||||||
o += '\\';
|
|
||||||
}
|
|
||||||
o += c;
|
|
||||||
} else {
|
|
||||||
switch (c) {
|
|
||||||
case '\b':
|
|
||||||
o += '\\b';
|
|
||||||
break;
|
|
||||||
case '\f':
|
|
||||||
o += '\\f';
|
|
||||||
break;
|
|
||||||
case '\n':
|
|
||||||
o += '\\n';
|
|
||||||
break;
|
|
||||||
case '\r':
|
|
||||||
o += '\\r';
|
|
||||||
break;
|
|
||||||
case '\t':
|
|
||||||
o += '\\t';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c = c.charCodeAt();
|
|
||||||
o += '\\u00' + Math.floor(c / 16).toString(16) +
|
|
||||||
(c % 16).toString(16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return o + '"';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!String.prototype.supplant) {
|
|
||||||
String.prototype.supplant = function (o) {
|
|
||||||
return this.replace(/{([^{}]*)}/g,
|
|
||||||
function (a, b) {
|
|
||||||
var r = o[b];
|
|
||||||
return typeof r === 'string' || typeof r === 'number' ? r : a;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!String.prototype.trim) {
|
|
||||||
String.prototype.trim = function () {
|
|
||||||
return this.replace(/^\s*(\S*(?:\s+\S+)*)\s*$/, "$1");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// CommonJS / npm / Ender.JS
|
|
||||||
module.exports = {
|
|
||||||
typeOf: typeOf,
|
|
||||||
isEmpty: isEmpty
|
|
||||||
};
|
|
||||||
global.typeOf = global.typeOf || typeOf;
|
|
||||||
global.isEmpty = global.isEmpty || isEmpty;
|
|
||||||
}());
|
|
||||||
|
|
||||||
},{}],3:[function(require,module,exports){
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* removeTrailingSpaces
|
|
||||||
* Remove the trailing spaces from a string.
|
|
||||||
*
|
|
||||||
* @name removeTrailingSpaces
|
|
||||||
* @function
|
|
||||||
* @param {String} input The input string.
|
|
||||||
* @returns {String} The output string.
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = function removeTrailingSpaces(input) {
|
|
||||||
// TODO If possible, use a regex
|
|
||||||
return input.split("\n").map(function (x) {
|
|
||||||
return x.trimRight();
|
|
||||||
}).join("\n");
|
|
||||||
};
|
|
||||||
},{}]},{},[1]);
|
|
||||||
@@ -64,8 +64,11 @@ function viewTopic(topic) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let txt = `<div class=counter>${counter} received</div>${yamlStringify(msg)}`; // JSON.stringify(msg, null, 4);
|
let width = Number(params.width) || 100;
|
||||||
topicMessage.innerHTML = txt;
|
let indent = Number(params.indent) || 2;
|
||||||
|
let txt = YAML.stringify(msg, { lineWidth: width, indent: indent });
|
||||||
|
let html = `<div class=counter>${counter} received</div>${txt}`; // JSON.stringify(msg, null, 4);
|
||||||
|
topicMessage.innerHTML = html;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
19
clover/www/js/yaml.js
Normal file
19
clover/www/js/yaml.js
Normal file
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@
|
|||||||
<script src="js/roslib.js"></script>
|
<script src="js/roslib.js"></script>
|
||||||
<link rel="icon" href="data:,"> <!-- make chrome don't request icon -->
|
<link rel="icon" href="data:,"> <!-- make chrome don't request icon -->
|
||||||
<script type="module" src="js/topics.js"></script>
|
<script type="module" src="js/topics.js"></script>
|
||||||
<script src="js/json-to-pretty-yaml.js"></script>
|
<script src="js/yaml.js"></script>
|
||||||
<style>
|
<style>
|
||||||
#topics { line-height: 1.2em; }
|
#topics { line-height: 1.2em; }
|
||||||
#topic-view {
|
#topic-view {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<package format="2">
|
<package format="2">
|
||||||
<name>clover_blocks</name>
|
<name>clover_blocks</name>
|
||||||
<version>0.24.0</version>
|
<version>0.25.0</version>
|
||||||
<description>Blockly programming support for Clover</description>
|
<description>Blockly programming support for Clover</description>
|
||||||
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
||||||
<license>MIT</license>
|
<license>MIT</license>
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ def load(req):
|
|||||||
return {'names': [], 'programs': [], 'message': str(e)}
|
return {'names': [], 'programs': [], 'message': str(e)}
|
||||||
|
|
||||||
|
|
||||||
name_regexp = re.compile(r'^[a-zA-Z-_.]{0,20}$')
|
name_regexp = re.compile(r'^[a-zA-Z1-9-_.]{0,30}$')
|
||||||
|
|
||||||
def store(req):
|
def store(req):
|
||||||
if not name_regexp.match(req.name):
|
if not name_regexp.match(req.name):
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<package format="2">
|
<package format="2">
|
||||||
<name>clover_description</name>
|
<name>clover_description</name>
|
||||||
<version>0.24.0</version>
|
<version>0.25.0</version>
|
||||||
<description>The clover_description package provides URDF models of the Clover series of quadcopters.</description>
|
<description>The clover_description package provides URDF models of the Clover series of quadcopters.</description>
|
||||||
|
|
||||||
<maintainer email="sfalexrog@gmail.com">Alexey Rogachevskiy</maintainer>
|
<maintainer email="sfalexrog@gmail.com">Alexey Rogachevskiy</maintainer>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<package format="3">
|
<package format="3">
|
||||||
<name>clover_simulation</name>
|
<name>clover_simulation</name>
|
||||||
<version>0.24.0</version>
|
<version>0.25.0</version>
|
||||||
<description>The clover_simulation package provides worlds and launch files for Gazebo.</description>
|
<description>The clover_simulation package provides worlds and launch files for Gazebo.</description>
|
||||||
|
|
||||||
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ navigate(x=2, y=2, z=2, speed=1, frame_id='aruco_map')
|
|||||||
|
|
||||||
### Using a specific marker frame
|
### Using a specific marker frame
|
||||||
|
|
||||||
Starting with the [image](image.md) version 0.18, the drone also can fly relative to a marker in the map, even if it is not currently visible. Like with [single-marker navigation](aruco_marker.md#working-with-detected-markers), this works by setting the frame_id parameter to aruco_ID, where ID is the desired marker number.
|
Starting with the [image](image.md) version 0.18, the drone also can fly relative to a marker in the map, even if it is not currently visible. Like with [single-marker navigation](aruco_marker.md#working-with-detected-markers), this works by setting the frame_id parameter to `aruco_ID`, where ID is the desired marker number.
|
||||||
|
|
||||||
The following code will move the drone to the point 1 meter above the center of marker 5:
|
The following code will move the drone to the point 1 meter above the center of marker 5:
|
||||||
|
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ Most of the parameters for autonomous flight are located in the following direct
|
|||||||
<arg name="aruco_vpe" default="true"/>`
|
<arg name="aruco_vpe" default="true"/>`
|
||||||
```
|
```
|
||||||
|
|
||||||
- Generate the ArUco markers field. See the article [Map-based navigation with ArUco markers] (aruco_map.md # marker map settings) for details. To generate markers, you need to enter a command with specific values.
|
- Generate the ArUco markers field. See the article [Map-based navigation with ArUco markers](aruco_map.md#marker-map-definition) for details. To generate markers, you need to enter a command with specific values.
|
||||||
|
|
||||||
Here is the example generating command where:
|
Here is the example generating command where:
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ Main documentation: http://wiki.ros.org/roslaunch.
|
|||||||
|
|
||||||
The list of nodes / programs declared for running is specified in file `/home/pi/catkin_ws/src/clover/clover/launch/clover.launch`.
|
The list of nodes / programs declared for running is specified in file `/home/pi/catkin_ws/src/clover/clover/launch/clover.launch`.
|
||||||
|
|
||||||
You can add your own node to the list of automatically launched ones. To do this, place your executable file (e.g. `my_program.py`) into folder `/home/pi/catkin_ws/src/clover/clover/src`. Then add the start of your node to `clover.launch`, for example:
|
You can add your own node to the list of automatically launched ones. To do this, place your executable file (e.g. `my_program.py`) into folder `/home/pi/catkin_ws/src/clover/clover`. Then add the start of your node to `clover.launch`, for example:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<node name="my_program" pkg="clover" type="my_program.py" output="screen"/>
|
<node name="my_program" pkg="clover" type="my_program.py" output="screen"/>
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ In case of using EKF2 (official firmware):
|
|||||||
|`EKF2_BARO_CTRL`|0 (*Disabled*)|Barometer is disabled|
|
|`EKF2_BARO_CTRL`|0 (*Disabled*)|Barometer is disabled|
|
||||||
|`EKF2_OF_CTRL`|1 (*Enabled*)|Optical flow is enabled|
|
|`EKF2_OF_CTRL`|1 (*Enabled*)|Optical flow is enabled|
|
||||||
|`EKF2_HGT_REF`|3 (*Vision*)|If the [rangefinder](laser.md) is present and flying over horizontal floor – 2 (*Range sensor*)|
|
|`EKF2_HGT_REF`|3 (*Vision*)|If the [rangefinder](laser.md) is present and flying over horizontal floor – 2 (*Range sensor*)|
|
||||||
|
|`EKF2_RNG_CTRL`|2 (*Enabled*)|Range sensor is enabled|
|
||||||
|
|
||||||
<!-- markdownlint-enable MD031 -->
|
<!-- markdownlint-enable MD031 -->
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ navigate(x=2, y=2, z=2, speed=1, frame_id='aruco_map') # полет в коор
|
|||||||
|
|
||||||
### Полет в координаты по ID маркера
|
### Полет в координаты по ID маркера
|
||||||
|
|
||||||
Начиная с версии [образа](image.md) 0.18, доступны также полёты относительно отдельного маркера в карте, даже если дрон его не видит. По аналогии с [навигацией по отдельным маркерам](aruco_marker.md#навигация-по-маркерам) при настройке карты маркеров дрон сможет лететь в координаты относительно отдельного маркера, используя фрейм aruco_ID с соответствующим ID маркера.
|
Начиная с версии [образа](image.md) 0.18, доступны также полёты относительно отдельного маркера в карте, даже если дрон его не видит. По аналогии с [навигацией по отдельным маркерам](aruco_marker.md#навигация-по-маркерам) при настройке карты маркеров дрон сможет лететь в координаты относительно отдельного маркера, используя фрейм `aruco_ID` с соответствующим ID маркера.
|
||||||
|
|
||||||
Полет в точку над маркером 5 на высоту 1 метр:
|
Полет в точку над маркером 5 на высоту 1 метр:
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ roslaunch
|
|||||||
|
|
||||||
Список объявленных для запуска нод / программ указывается в файле `/home/pi/catkin_ws/src/clover/clover/launch/clover.launch`.
|
Список объявленных для запуска нод / программ указывается в файле `/home/pi/catkin_ws/src/clover/clover/launch/clover.launch`.
|
||||||
|
|
||||||
Вы можете добавить собственную ноду в список автозапускаемых. Для этого разместите ваш запускаемый файл (например, `my_program.py`) в каталог `/home/pi/catkin_ws/src/clover/clover/src`. Затем добавьте запуск вашей ноды в `clover.launch`, например:
|
Вы можете добавить собственную ноду в список автозапускаемых. Для этого разместите ваш запускаемый файл (например, `my_program.py`) в каталог `/home/pi/catkin_ws/src/clover/clover`. Затем добавьте запуск вашей ноды в `clover.launch`, например:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<node name="my_program" pkg="clover" type="my_program.py" output="screen"/>
|
<node name="my_program" pkg="clover" type="my_program.py" output="screen"/>
|
||||||
|
|||||||
@@ -59,6 +59,7 @@
|
|||||||
|`EKF2_BARO_CTRL`|0 (*Disabled*)|Барометр отключен|
|
|`EKF2_BARO_CTRL`|0 (*Disabled*)|Барометр отключен|
|
||||||
|`EKF2_OF_CTRL`|1 (*Enabled*)|Optical flow включен|
|
|`EKF2_OF_CTRL`|1 (*Enabled*)|Optical flow включен|
|
||||||
|`EKF2_HGT_REF`|3 (*Vision*)|При наличии [дальномера](laser.md) и полете над ровным полом — 2 (*Range sensor*)|
|
|`EKF2_HGT_REF`|3 (*Vision*)|При наличии [дальномера](laser.md) и полете над ровным полом — 2 (*Range sensor*)|
|
||||||
|
|`EKF2_RNG_CTRL`|2 (*Enabled*)|Дальномер включен|
|
||||||
|
|
||||||
<!-- markdownlint-enable MD031 -->
|
<!-- markdownlint-enable MD031 -->
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<package format="2">
|
<package format="2">
|
||||||
<name>roswww_static</name>
|
<name>roswww_static</name>
|
||||||
<version>0.24.0</version>
|
<version>0.25.0</version>
|
||||||
<description>Static web pages for ROS packages</description>
|
<description>Static web pages for ROS packages</description>
|
||||||
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
||||||
<license>MIT</license>
|
<license>MIT</license>
|
||||||
|
|||||||
Reference in New Issue
Block a user