mirror of
https://github.com/CopterExpress/clover.git
synced 2026-06-01 15:39:32 +00:00
Compare commits
57 Commits
test_resul
...
vuepress
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72b343575f | ||
|
|
0849413fe2 | ||
|
|
2cab14c52f | ||
|
|
c20957cbf1 | ||
|
|
e9f892466f | ||
|
|
91061cc9f1 | ||
|
|
9db0c44177 | ||
|
|
5b3c3f0722 | ||
|
|
84b1318f3d | ||
|
|
955011e812 | ||
|
|
2561e8e6cb | ||
|
|
d1209fd064 | ||
|
|
e68fac8aad | ||
|
|
4f64fdf2e4 | ||
|
|
b77d4ed045 | ||
|
|
e2b8cb4be2 | ||
|
|
8db8075f15 | ||
|
|
578728b3a9 | ||
|
|
7154f5afc2 | ||
|
|
48fd45ea9a | ||
|
|
12ca9c0eb9 | ||
|
|
784ce35080 | ||
|
|
6c42c522ce | ||
|
|
b36d69b54f | ||
|
|
0056bb1810 | ||
|
|
37ec19a19f | ||
|
|
ea5151db51 | ||
|
|
bc032e5afb | ||
|
|
ed619935ce | ||
|
|
3b3b5b6a89 | ||
|
|
4190353569 | ||
|
|
7c2e020a89 | ||
|
|
6321ef8aa0 | ||
|
|
172890ed13 | ||
|
|
ae1e39dd82 | ||
|
|
241b766bad | ||
|
|
84bbe2e565 | ||
|
|
169680129b | ||
|
|
6541d60d08 | ||
|
|
e3addb9eb0 | ||
|
|
b7d74ef6c9 | ||
|
|
da92aea727 | ||
|
|
0b78c84ac0 | ||
|
|
de2467acb1 | ||
|
|
3d6b8b6a10 | ||
|
|
b6f1ca5d20 | ||
|
|
850b49b2b6 | ||
|
|
f21ba3feb4 | ||
|
|
9c3a97f945 | ||
|
|
293448028a | ||
|
|
b5cd9512ef | ||
|
|
dd74ceb383 | ||
|
|
e217678f7d | ||
|
|
dc06ba1bd2 | ||
|
|
21bbc8a86c | ||
|
|
76ef764143 | ||
|
|
d282098134 |
13
.github/workflows/docs.yml
vendored
13
.github/workflows/docs.yml
vendored
@@ -38,7 +38,11 @@ jobs:
|
||||
gitbook install
|
||||
gitbook build
|
||||
- name: Generate PDF
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
id: generate-pdf
|
||||
env:
|
||||
GITBOOK_SKIP_PDF: ${{ secrets.GITBOOK_SKIP_PDF }}
|
||||
continue-on-error: ${{ env.GITBOOK_SKIP_PDF != '' }}
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
run: |
|
||||
for i in 1 2 3 4; do gitbook pdf ./ _book/clover.pdf && break || sleep 1; done
|
||||
sudo apt-get -q install ghostscript
|
||||
@@ -47,6 +51,13 @@ jobs:
|
||||
rm _book/clover_ru.pdf && mv _book/clover_ru_compressed.pdf _book/clover_ru.pdf
|
||||
rm _book/clover_en.pdf && mv _book/clover_en_compressed.pdf _book/clover_en.pdf
|
||||
ls -lah _book/clover*.pdf
|
||||
echo '::set-output name=GITBOOK_PDF_OK::1'
|
||||
- name: Download older PDFs
|
||||
if: ${{ !steps.generate-pdf.outputs.GITBOOK_PDF_OK }}
|
||||
run: |
|
||||
rm _book/clover*.pdf
|
||||
wget --no-verbose https://clover.coex.tech/clover_ru.pdf -P _book/
|
||||
wget --no-verbose https://clover.coex.tech/clover_en.pdf -P _book/
|
||||
- name: Deploy
|
||||
uses: JamesIves/github-pages-deploy-action@4.1.3
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -7,3 +7,6 @@ package-lock.json
|
||||
clover_blocks/programs/*.*
|
||||
!clover_blocks/programs/examples/*
|
||||
/.vscode/
|
||||
docs/.vuepress/.cache/
|
||||
docs/.vuepress/.temp/
|
||||
docs/.vuepress/dist
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
|
||||
<!-- For additional help go to https://clover.coex.tech/aruco -->
|
||||
|
||||
<arg name="force_init" default="false"/>
|
||||
<arg name="disable" default="false"/> <!-- only force init -->
|
||||
|
||||
<!-- aruco_detect: detect aruco markers, estimate poses -->
|
||||
<node name="aruco_detect" pkg="nodelet" if="$(arg aruco_detect)" type="nodelet" args="load aruco_pose/aruco_detect main_camera_nodelet_manager" output="screen" clear_params="true" respawn="true">
|
||||
<node name="aruco_detect" pkg="nodelet" if="$(eval aruco_detect and not disable)" type="nodelet" args="load aruco_pose/aruco_detect main_camera_nodelet_manager" output="screen" clear_params="true" respawn="true">
|
||||
<remap from="image_raw" to="main_camera/image_raw"/>
|
||||
<remap from="camera_info" to="main_camera/camera_info"/>
|
||||
<remap from="map_markers" to="aruco_map/markers"/>
|
||||
@@ -26,7 +29,7 @@
|
||||
</node>
|
||||
|
||||
<!-- aruco_map: estimate aruco map pose -->
|
||||
<node name="aruco_map" pkg="nodelet" type="nodelet" if="$(arg aruco_map)" args="load aruco_pose/aruco_map main_camera_nodelet_manager" output="screen" clear_params="true" respawn="true">
|
||||
<node name="aruco_map" pkg="nodelet" type="nodelet" if="$(eval aruco_map and not disable)" args="load aruco_pose/aruco_map main_camera_nodelet_manager" output="screen" clear_params="true" respawn="true">
|
||||
<remap from="image_raw" to="main_camera/image_raw"/>
|
||||
<remap from="camera_info" to="main_camera/camera_info"/>
|
||||
<remap from="markers" to="aruco_detect/markers"/>
|
||||
@@ -41,11 +44,11 @@
|
||||
</node>
|
||||
|
||||
<!-- vpe publisher from aruco markers -->
|
||||
<node name="vpe_publisher" pkg="clover" type="vpe_publisher" if="$(arg aruco_vpe)" output="screen" clear_params="true">
|
||||
<remap from="~pose_cov" to="aruco_map/pose"/>
|
||||
<node name="vpe_publisher" pkg="clover" type="vpe_publisher" if="$(eval aruco_vpe or force_init)" output="screen" clear_params="true">
|
||||
<remap from="~pose_cov" to="aruco_map/pose" if="$(arg aruco_vpe)"/>
|
||||
<remap from="~vpe" to="mavros/vision_pose/pose"/>
|
||||
<param name="frame_id" value="aruco_map_detected"/>
|
||||
<param name="publish_zero" value="true"/>
|
||||
<param name="frame_id" value="aruco_map_detected" if="$(arg aruco_vpe)"/>
|
||||
<param name="force_init" value="$(arg force_init)"/>
|
||||
<param name="offset_frame_id" value="aruco_map"/>
|
||||
</node>
|
||||
</launch>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<arg name="led" default="true"/>
|
||||
<arg name="blocks" default="false"/>
|
||||
<arg name="rc" default="false"/>
|
||||
<arg name="force_init" value="true"/> <!-- force estimator to init by publishing zero pose -->
|
||||
|
||||
<arg name="simulator" default="false"/> <!-- flag that we are operating on a simulated drone -->
|
||||
|
||||
@@ -33,7 +34,10 @@
|
||||
</node>
|
||||
|
||||
<!-- aruco markers -->
|
||||
<include file="$(find clover)/launch/aruco.launch" if="$(arg aruco)"/>
|
||||
<include file="$(find clover)/launch/aruco.launch" if="$(eval aruco or force_init)">
|
||||
<arg name="force_init" value="$(arg force_init)"/>
|
||||
<arg name="disable" value="$(eval not aruco)"/>
|
||||
</include>
|
||||
|
||||
<!-- optical flow -->
|
||||
<node pkg="nodelet" type="nodelet" name="optical_flow" args="load clover/optical_flow main_camera_nodelet_manager" if="$(arg optical_flow)" clear_params="true" output="screen" respawn="true">
|
||||
|
||||
@@ -30,6 +30,7 @@ from visualization_msgs.msg import MarkerArray as VisualizationMarkerArray
|
||||
import tf.transformations as t
|
||||
from aruco_pose.msg import MarkerArray
|
||||
from mavros import mavlink
|
||||
import locale
|
||||
|
||||
|
||||
# TODO: check attitude is present
|
||||
@@ -45,6 +46,8 @@ rospy.init_node('selfcheck')
|
||||
|
||||
os.environ['ROSCONSOLE_FORMAT']='[${severity}]: ${message}'
|
||||
|
||||
# use user's locale to convert numbers, etc
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
|
||||
tf_buffer = tf2_ros.Buffer()
|
||||
tf_listener = tf2_ros.TransformListener(tf_buffer)
|
||||
@@ -195,24 +198,27 @@ def check_fcu():
|
||||
failure('no connection to the FCU (check wiring)')
|
||||
return
|
||||
|
||||
clover_tag = re.compile(r'-cl[oe]ver\.\d+$')
|
||||
clover_fw = False
|
||||
|
||||
# Make sure the console is available to us
|
||||
mavlink_exec('\n')
|
||||
version_str = mavlink_exec('ver all')
|
||||
if version_str == '':
|
||||
info('no version data available from SITL')
|
||||
|
||||
r = re.compile(r'^FW (git tag|version): (v?\d\.\d\.\d.*)$')
|
||||
is_clover_firmware = False
|
||||
for ver_line in version_str.split('\n'):
|
||||
match = r.search(ver_line)
|
||||
if match is not None:
|
||||
field, version = match.groups()
|
||||
info('firmware %s: %s' % (field, version))
|
||||
if 'clover' in version or 'clever' in version:
|
||||
is_clover_firmware = True
|
||||
for line in version_str.split('\n'):
|
||||
if line.startswith('FW version: '):
|
||||
info(line[len('FW version: '):])
|
||||
elif line.startswith('FW git tag: '): # only Clover's firmware
|
||||
tag = line[len('FW git tag: '):]
|
||||
clover_fw = clover_tag.search(tag)
|
||||
info(tag)
|
||||
elif line.startswith('HW arch: '):
|
||||
info(line[len('HW arch: '):])
|
||||
|
||||
if not is_clover_firmware:
|
||||
failure('not running Clover PX4 firmware, https://clover.coex.tech/firmware')
|
||||
if not clover_fw:
|
||||
info('not Clover PX4 firmware, check https://clover.coex.tech/firmware')
|
||||
|
||||
est = get_param('SYS_MC_EST_GROUP')
|
||||
if est == 1:
|
||||
@@ -635,7 +641,7 @@ def check_cpu_usage():
|
||||
continue
|
||||
pid, cpu, cmd = process.split('\t')
|
||||
|
||||
if cmd.strip() not in WHITELIST and float(cpu) > 30:
|
||||
if cmd.strip() not in WHITELIST and locale.atof(cpu) > 30:
|
||||
failure('high CPU usage (%s%%) detected: %s (PID %s)',
|
||||
cpu.strip(), cmd.strip(), pid.strip())
|
||||
|
||||
|
||||
@@ -141,11 +141,11 @@ int main(int argc, char **argv) {
|
||||
vpe_pub = nh_priv.advertise<PoseStamped>("vpe", 1);
|
||||
//vpe_cov_pub = nh_priv_.advertise<PoseStamped>("pose_cov_pub", 1);
|
||||
|
||||
if (nh_priv.param("publish_zero", false)) {
|
||||
if (nh_priv.param("force_init", false) || nh_priv.param("publish_zero", false)) { // publish_zero is old name
|
||||
// publish zero to initialize the local position
|
||||
zero_timer = nh.createTimer(ros::Duration(0.1), &publishZero);
|
||||
publish_zero_timout = ros::Duration(nh_priv.param("publish_zero_timout", 5.0));
|
||||
publish_zero_duration = ros::Duration(nh_priv.param("publish_zero_duration", 5.0));
|
||||
publish_zero_timout = ros::Duration(nh_priv.param("force_init_timeout", 5.0));
|
||||
publish_zero_duration = ros::Duration(nh_priv.param("force_init_duration", 5.0));
|
||||
local_position_sub = nh.subscribe("mavros/local_position/pose", 1, &localPositionCallback);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,12 @@
|
||||
<!-- <gazebo>
|
||||
<static>true</static>
|
||||
</gazebo> -->
|
||||
<gazebo>
|
||||
<plugin name="${name}_ros_controller" filename="libsim_leds_controller.so">
|
||||
<robotNamespace></robotNamespace>
|
||||
<ledCount>${led_count}</ledCount>
|
||||
</plugin>
|
||||
</gazebo>
|
||||
</xacro:macro>
|
||||
|
||||
</robot>
|
||||
|
||||
@@ -37,6 +37,14 @@ target_compile_options(sim_leds PRIVATE -std=c++11)
|
||||
|
||||
add_dependencies(sim_leds ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
|
||||
|
||||
add_library(sim_leds_controller src/sim_leds_controller.cpp)
|
||||
|
||||
target_include_directories(sim_leds_controller PRIVATE ${catkin_INCLUDE_DIRS} ${GAZEBO_INCLUDE_DIRS})
|
||||
target_link_libraries(sim_leds_controller PRIVATE ${catkin_LIBRARIES} ${GAZEBO_LIBRARIES})
|
||||
target_compile_options(sim_leds_controller PRIVATE -std=c++11)
|
||||
|
||||
add_dependencies(sim_leds_controller ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
|
||||
|
||||
# Gazebo throttling camera plugin
|
||||
# for some reason, CMake does not support per-target link directories, and Gazebo does not put
|
||||
# CameraPlugin into ${GAZEBO_LIBRARIES}
|
||||
|
||||
@@ -21,7 +21,7 @@ param set LPE_VIS_Z 0.1
|
||||
param set LPE_FUSION 86
|
||||
|
||||
param set SENS_FLOW_ROT 0
|
||||
param set SENS_FLOW_MINHGT 0.01
|
||||
param set SENS_FLOW_MINHGT 0.0
|
||||
param set SENS_FLOW_MAXHGT 4.0
|
||||
param set SENS_FLOW_MAXR 10.0
|
||||
|
||||
|
||||
@@ -49,14 +49,9 @@ private:
|
||||
|
||||
std::unique_ptr<ros::NodeHandle> nh;
|
||||
|
||||
ros::ServiceServer setLedsSrv;
|
||||
// Note: LED state should only be published by the /gazebo node
|
||||
led_msgs::LEDStateArray ledState;
|
||||
ros::Publisher statePublisher;
|
||||
// LED state will be read from the topic to avoid creating more services
|
||||
ros::Subscriber stateSubscriber;
|
||||
|
||||
bool setLeds(led_msgs::SetLEDs::Request& req, led_msgs::SetLEDs::Response& resp);
|
||||
void handleLedsMsg(const led_msgs::LEDStateArrayConstPtr& leds);
|
||||
|
||||
public:
|
||||
@@ -73,16 +68,8 @@ public:
|
||||
ROS_INFO_NAMED(("LedController_" + robotNamespace).c_str(), "LedController has started (as %s)", role == Role::Client ? "client" : "server");
|
||||
|
||||
nh.reset(new ros::NodeHandle(robotNamespace));
|
||||
if (role == Role::Server)
|
||||
{
|
||||
setLedsSrv = nh->advertiseService("led/set_leds", &LedController::setLeds, this);
|
||||
statePublisher = nh->advertise<led_msgs::LEDStateArray>("led/state", 1, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// LED state should be published to the "led/state" topic, so we grab our data there
|
||||
stateSubscriber = nh->subscribe<led_msgs::LEDStateArray>("led/state", 1, &LedController::handleLedsMsg, this);
|
||||
}
|
||||
|
||||
stateSubscriber = nh->subscribe<led_msgs::LEDStateArray>("led/state", 1, &LedController::handleLedsMsg, this);
|
||||
};
|
||||
|
||||
~LedController()
|
||||
@@ -96,13 +83,9 @@ public:
|
||||
std::lock_guard<std::mutex> lock(registryMutex);
|
||||
if (totalLeds > 0) {
|
||||
registeredLeds.resize(totalLeds);
|
||||
ledState.leds.resize(totalLeds);
|
||||
}
|
||||
ROS_DEBUG_NAMED(("LedController_" + robotNamespace).c_str(), "Registering LED visual plugin to %s (LED id=%d)", (role == Role::Client) ? "client" : "server", ledIdx);
|
||||
registeredLeds[ledIdx] = plugin;
|
||||
ledState.leds[ledIdx].index = ledIdx;
|
||||
if (role == Role::Server)
|
||||
statePublisher.publish(ledState);
|
||||
}
|
||||
|
||||
void unregisterPlugin(sim_led::LedVisualPlugin* plugin)
|
||||
@@ -157,7 +140,8 @@ public:
|
||||
{
|
||||
auto indexStr = parentName.substr(lastDashPos + 1);
|
||||
try {
|
||||
myIndex = std::stoi(indexStr);
|
||||
if (indexStr == "visual") myIndex = 0; // the first visual doesn't have index
|
||||
else myIndex = std::stoi(indexStr);
|
||||
} catch(const std::exception &e) {
|
||||
gzwarn << "Failed to convert " << indexStr << " to integer: " << e.what() << ", assuming 0\n";
|
||||
myIndex = 0;
|
||||
@@ -195,26 +179,6 @@ public:
|
||||
};
|
||||
}
|
||||
|
||||
// FIXME: These two functions basically do the same thing, maybe they can be merged?
|
||||
bool led_controller::LedController::setLeds(led_msgs::SetLEDs::Request &req, led_msgs::SetLEDs::Response &resp)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(registryMutex);
|
||||
for(const auto& led : req.leds)
|
||||
{
|
||||
if (led.index < registeredLeds.size()) {
|
||||
auto color = GazeboColor(led.r / 255.0f, led.g / 255.0f, led.b / 255.0f);
|
||||
auto ledPlugin = registeredLeds[led.index];
|
||||
if (ledPlugin) ledPlugin->SetColor(color);
|
||||
ledState.leds[led.index].r = led.r;
|
||||
ledState.leds[led.index].g = led.g;
|
||||
ledState.leds[led.index].b = led.b;
|
||||
}
|
||||
}
|
||||
statePublisher.publish(ledState);
|
||||
resp.success = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void led_controller::LedController::handleLedsMsg(const led_msgs::LEDStateArrayConstPtr& leds)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(registryMutex);
|
||||
|
||||
71
clover_simulation/src/sim_leds_controller.cpp
Normal file
71
clover_simulation/src/sim_leds_controller.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#include <led_msgs/SetLEDs.h>
|
||||
#include <led_msgs/LEDStateArray.h>
|
||||
|
||||
#include <ros/ros.h>
|
||||
|
||||
#include <gazebo/gazebo.hh>
|
||||
#include <gazebo/physics/physics.hh>
|
||||
#include <gazebo/common/common.hh>
|
||||
|
||||
class LedControllerPlugin : public gazebo::ModelPlugin {
|
||||
private:
|
||||
std::unique_ptr<ros::NodeHandle> nh;
|
||||
std::string ns;
|
||||
ros::ServiceServer setLedsSrv;
|
||||
led_msgs::LEDStateArray ledState;
|
||||
ros::Publisher statePublisher;
|
||||
std::mutex handleMutex;
|
||||
|
||||
public:
|
||||
bool setLeds(led_msgs::SetLEDs::Request &req, led_msgs::SetLEDs::Response &resp)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(handleMutex);
|
||||
for(const auto& led : req.leds)
|
||||
{
|
||||
if (led.index < ledState.leds.size()) {
|
||||
ledState.leds[led.index].r = led.r;
|
||||
ledState.leds[led.index].g = led.g;
|
||||
ledState.leds[led.index].b = led.b;
|
||||
}
|
||||
}
|
||||
statePublisher.publish(ledState);
|
||||
resp.success = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Load(gazebo::physics::ModelPtr model, sdf::ElementPtr sdf) override
|
||||
{
|
||||
ROS_INFO("Initialize LED Controller");
|
||||
|
||||
// We need "libgazebo_ros_api.so" to be loaded
|
||||
if (!ros::isInitialized())
|
||||
{
|
||||
ROS_FATAL_NAMED("LedController", "Tried to load ROS plugin when ROS Gazebo API is not loaded. Please use gazebo_ros node to"
|
||||
"launch Gazebo.");
|
||||
}
|
||||
|
||||
ns = "";
|
||||
|
||||
if (sdf->HasElement("robotNamespace")) {
|
||||
ns = sdf->Get<std::string>("robotNamespace");
|
||||
}
|
||||
if (!sdf->HasElement("ledCount")) {
|
||||
gzerr << "ledCount is not set, but is required for the plugin to function correctly\n";
|
||||
return;
|
||||
}
|
||||
int totalLeds = sdf->Get<int>("ledCount");
|
||||
ledState.leds.resize(totalLeds);
|
||||
for (int i = 0; i < totalLeds; i++) {
|
||||
ledState.leds[i].index = i;
|
||||
}
|
||||
|
||||
nh.reset(new ros::NodeHandle(ns));
|
||||
|
||||
setLedsSrv = nh->advertiseService("led/set_leds", &LedControllerPlugin::setLeds, this);
|
||||
statePublisher = nh->advertise<led_msgs::LEDStateArray>("led/state", 1, true);
|
||||
|
||||
statePublisher.publish(ledState);
|
||||
}
|
||||
};
|
||||
|
||||
GZ_REGISTER_MODEL_PLUGIN(LedControllerPlugin);
|
||||
83
docs/.vuepress/config.js
Normal file
83
docs/.vuepress/config.js
Normal file
@@ -0,0 +1,83 @@
|
||||
const sidebar = require('./sidebar');
|
||||
|
||||
const hostname = 'https://clover.coex.tech/';
|
||||
const allowedTags = ['font', 'center', 'nobr']; // allow using some deprecated and non-standard html tags
|
||||
|
||||
module.exports = {
|
||||
lang: 'en-US',
|
||||
title: 'Clover',
|
||||
description: 'Clover Drone Kit',
|
||||
// theme and its config
|
||||
theme: '@vuepress/theme-default',
|
||||
themeConfig: {
|
||||
logo: 'clover-logo.png',
|
||||
sidebar: {
|
||||
'/ru/': sidebar.readSummary("./ru/SUMMARY.md"),
|
||||
'/en/': sidebar.readSummary("./en/SUMMARY.md"),
|
||||
},
|
||||
sidebarDepth: 0,
|
||||
locales: {
|
||||
'/en/': {
|
||||
selectLanguageName: 'English',
|
||||
navbar: [
|
||||
{ text: 'Official Site', link: 'https://coex.tech' },
|
||||
{ text: 'Support Chat', link: 'https://t.me/COEXHelpdesk' },
|
||||
]
|
||||
},
|
||||
'/ru/': {
|
||||
selectLanguageName: 'Русский',
|
||||
tip: 'СОВЕТ',
|
||||
warning: 'ВНИМАНИЕ',
|
||||
danger: 'ОПАСНО',
|
||||
toggleDarkMode: 'Переключить темную тему',
|
||||
navbar: [
|
||||
{ text: 'Сайт', link: 'https://coex.tech' },
|
||||
{ text: 'Чат поддержки', link: 'https://t.me/COEXHelpdesk' },
|
||||
]
|
||||
},
|
||||
},
|
||||
toggleSidebar: true,
|
||||
repo: 'CopterExpress/clover',
|
||||
docsBranch: 'master',
|
||||
docsDir: 'docs',
|
||||
lastUpdated: false,
|
||||
contributors: false
|
||||
},
|
||||
pagePatterns: ['**/*.md', '!.vuepress', '!node_modules', '!ru/metodmaterials.md'],
|
||||
locales: {
|
||||
'/en/': {
|
||||
lang: 'en',
|
||||
title: 'Clover',
|
||||
description: 'Clover Drone Kit'
|
||||
},
|
||||
'/ru/': {
|
||||
lang: 'ru',
|
||||
title: 'Клевер',
|
||||
description: 'Конструктор квадрокоптера «Клевер»'
|
||||
}
|
||||
},
|
||||
markdown: {
|
||||
code: {
|
||||
lineNumbers: false
|
||||
},
|
||||
linkify: true,
|
||||
},
|
||||
extendsMarkdown(md) {
|
||||
md.use(require('markdown-it-attrs')); // to use custom headers anchors
|
||||
},
|
||||
bundlerConfig: {
|
||||
vuePluginOptions: {
|
||||
template: {
|
||||
compilerOptions: {
|
||||
isCustomElement: tag => allowedTags.includes(tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
'@vuepress/plugin-search',
|
||||
'vuepress-plugin-copy-code2',
|
||||
['sitemap2', { hostname, excludeUrls: ['/', '/LANGS.html'] }],
|
||||
require('./rich-quotes')
|
||||
]
|
||||
}
|
||||
BIN
docs/.vuepress/public/clover-logo.png
Normal file
BIN
docs/.vuepress/public/clover-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 110 KiB |
37
docs/.vuepress/rich-quotes.js
Normal file
37
docs/.vuepress/rich-quotes.js
Normal file
@@ -0,0 +1,37 @@
|
||||
// Plugin to convert GitBook rich quotes to custom containers
|
||||
|
||||
const types = {
|
||||
info: 'tip',
|
||||
note: 'tip',
|
||||
tag: 'tip',
|
||||
comment: 'tip',
|
||||
hint: 'tip',
|
||||
success: 'tip',
|
||||
warning: 'warning',
|
||||
caution: 'warning',
|
||||
danger: 'danger',
|
||||
quote: 'tip'
|
||||
}
|
||||
|
||||
function replace(src) {
|
||||
return src.replace(/^> \*\*(.*?)\*\* (.*\n(>.*\n)*)/gm, function (match, type, text) {
|
||||
text = text.replace(/^>/gm, '');
|
||||
return `::: ${types[type.toLowerCase()]}\n${text}\n:::`;
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
name: 'vuepress-plugin-rich-quotes',
|
||||
extendsMarkdown: (md) => {
|
||||
var _render = md.render;
|
||||
|
||||
// TODO: a rough hack to replace rich quotes
|
||||
// TODO: use proper plugin api
|
||||
|
||||
md.render = function(src, env) {
|
||||
src = replace(src);
|
||||
return _render.call(md, src, env);
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
50
docs/.vuepress/sidebar.js
Normal file
50
docs/.vuepress/sidebar.js
Normal file
@@ -0,0 +1,50 @@
|
||||
const fs = require('fs')
|
||||
|
||||
const regex = /(\s*?)\*\s\[(.*?)\]\((.*?)\)/;
|
||||
|
||||
exports.readSummary = function (path) {
|
||||
let sidebar = [];
|
||||
let lines = fs.readFileSync(path).toString().split('\n');
|
||||
let item = {};
|
||||
|
||||
for (let line of lines) {
|
||||
if (line.startsWith('#')) continue;
|
||||
if (!line.trim()) continue;
|
||||
|
||||
let match = regex.exec(line);
|
||||
if (!match) {
|
||||
console.log('cannot parse', line);
|
||||
continue;
|
||||
}
|
||||
level = match[1].length / 2;
|
||||
text = match[2];
|
||||
path = match[3].trim();
|
||||
|
||||
if (level == 0) {
|
||||
if (item.path) {
|
||||
// push new item
|
||||
if (item.children) {
|
||||
sidebar.push(item);
|
||||
} else {
|
||||
sidebar.push(item.path)
|
||||
}
|
||||
item = {};
|
||||
}
|
||||
item.text = text;
|
||||
item.path = path;
|
||||
item.collapsible = true;
|
||||
|
||||
} else if (level == 1 || level == 2) {
|
||||
if (!item.children) {
|
||||
item.children = [];
|
||||
if (item.path) item.children.push(item.path);
|
||||
}
|
||||
item.children.push(path);
|
||||
|
||||
} else {
|
||||
console.log('skip', text);
|
||||
}
|
||||
}
|
||||
|
||||
return sidebar;
|
||||
}
|
||||
49
docs/.vuepress/styles/index.scss
Normal file
49
docs/.vuepress/styles/index.scss
Normal file
@@ -0,0 +1,49 @@
|
||||
.big-clover {
|
||||
max-width: 80% !important;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
/* change image for dark theme */
|
||||
html .big-clover.dark { display: none; }
|
||||
html.dark .big-clover { display: none; }
|
||||
html.dark .big-clover.dark { display: block; }
|
||||
|
||||
img.logo {
|
||||
transform: scale(2.5) translateX(-5%);
|
||||
}
|
||||
|
||||
/* Centered images */
|
||||
img.center {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
/* Images with border */
|
||||
img.border {
|
||||
border: 1px #e9e9e9 solid;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
html.dark img.border {
|
||||
border: none;
|
||||
background: #fffffa;
|
||||
}
|
||||
|
||||
table.versions td {
|
||||
text-align: center;
|
||||
background: white;
|
||||
}
|
||||
table.versions .subversion {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
.circle {
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
4
docs/README.md
Normal file
4
docs/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# Languages
|
||||
|
||||
* [English](en/)
|
||||
* [Русский](ru/)
|
||||
BIN
docs/assets/lane_control_with_color.jpg
Normal file
BIN
docs/assets/lane_control_with_color.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 151 KiB |
BIN
docs/assets/lane_control_without_any_color.jpg
Normal file
BIN
docs/assets/lane_control_without_any_color.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 112 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 244 KiB |
BIN
docs/assets/simulation_ubuntu_account.png
Normal file
BIN
docs/assets/simulation_ubuntu_account.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 178 KiB |
BIN
docs/assets/simulation_utm.png
Normal file
BIN
docs/assets/simulation_utm.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 395 KiB |
@@ -1,6 +1,7 @@
|
||||
# COEX Clover
|
||||
|
||||
<img class="center zoom big-clover" src="../assets/clover42-main.png" width="80%" alt="Clover 4.2">
|
||||
<img class="big-clover light" src="../assets/clover42-main.png" alt="Clover 4.2">
|
||||
<img class="big-clover dark" src="../assets/clover42-black.png" alt="Clover 4.2">
|
||||
|
||||
**Clover** is an educational kit of a programmable quadcopter that consists of popular open source components, and a set of necessary documentation and libraries for working with it.
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
* [Power setup](power.md)
|
||||
* [Failsafe configuration](failsafe.md)
|
||||
* [Manual flight](flight.md)
|
||||
* [Basics](flight.md)
|
||||
* [Exercises](flight_exercises.md)
|
||||
* [Working with Raspberry Pi](raspberry.md)
|
||||
* [RPi Image](image.md)
|
||||
@@ -50,6 +49,7 @@
|
||||
* [Native setup](simulation_native.md)
|
||||
* [VM setup](simulation_vm.md)
|
||||
* [Usage](simulation_usage.md)
|
||||
* [Setup on M1 computers](simulation_m1.md)
|
||||
* [ROS](ros.md)
|
||||
* [MAVROS](mavros.md)
|
||||
* [Supplementary materials](supplementary.md)
|
||||
|
||||
@@ -49,7 +49,7 @@ This feature allows getting rid of the system interface elements. Let's go ahead
|
||||
|
||||
This is how the transmitter looks at this stage:
|
||||
|
||||
<img src="../assets/IMG_4397.PNG" width="50%">
|
||||
<img src="../assets/IMG_4397.png" width="50%">
|
||||
|
||||
If you run your application, you will see that the sticks are not functioning. This is due to the fact that *JavaScript* is disabled in our page. To enable it, write the following code:
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ If the drone's altitude is not stable, try increasing the `MPC_Z_VEL_P` paramete
|
||||
|
||||
## Placing markers on the ceiling
|
||||
|
||||

|
||||

|
||||
|
||||
In order to navigate using markers on the ceiling, mount the onboard camera so that it points up and [adjust the camera frame accordingly](camera_setup.md).
|
||||
|
||||
|
||||
@@ -113,7 +113,3 @@ rospy.spin()
|
||||
```
|
||||
|
||||
Each message contains the marker ID, its corner points on the image and its position relative to the camera.
|
||||
|
||||
---
|
||||
|
||||
Suggested reading: [map-based navigation](aruco_map.md)
|
||||
|
||||
@@ -341,7 +341,7 @@ should be increased up to 4 – 5.
|
||||
|
||||
### ESC assembly
|
||||
|
||||
1. Stick the double-sided adhesive tape to the base of the ESC protective case 
|
||||
1. Stick the double-sided adhesive tape to the base of the ESC protective case.
|
||||
2. Put the ESCs into protective cases. Fasten the assembly to the motor mounts of the frame. 
|
||||
|
||||
### Installation of guard
|
||||
|
||||
@@ -36,7 +36,7 @@ TODO
|
||||
|
||||
Cut the remaining part of the clamp (cable tie) with scissors.
|
||||
|
||||

|
||||

|
||||
|
||||
## Frame elements installation
|
||||
|
||||
@@ -45,7 +45,7 @@ TODO
|
||||
3. Attach the assembled unit to the frame with M3x16 screws, complying with the layout.
|
||||
4. Install the frame for the LED strip, using the slots in the leg holders.
|
||||
|
||||

|
||||

|
||||
|
||||
## BEC voltage converter installation(to be soldered and tested)
|
||||
|
||||
@@ -93,7 +93,7 @@ TODO
|
||||
Black -> GND
|
||||
Blue -> Din
|
||||
|
||||

|
||||

|
||||
|
||||
## 4 in 1 ESC board and the PDB power-board installation
|
||||
|
||||
@@ -108,7 +108,7 @@ TODO
|
||||
3. Install the PDB power distribution board as shown in the picture (the XT60 connector should point to the tail of the drone).
|
||||
4. Connect the wires of the PCB power supply board and ESC XT30 board.
|
||||
|
||||

|
||||

|
||||
|
||||
## Pairing the receiver and transmitter
|
||||
|
||||
@@ -125,7 +125,7 @@ TODO
|
||||
* Remove the BIND connector from the receiver.
|
||||
* Disconnect the battery.
|
||||
|
||||

|
||||

|
||||
|
||||
> **Hint** If the remote cannot be powered on, or is blocked, see
|
||||
article [remote faults](radioerrors.md).
|
||||
@@ -145,7 +145,7 @@ article [remote faults](radioerrors.md).
|
||||
4. Check the motor rotation direction according to the scheme. Repeat for each motor. Thus, it will be clear which motor is controlled.
|
||||
5. If you have to change the rotation direction, swap any two phase wires of the motor (needs re-connection).
|
||||
|
||||

|
||||

|
||||
|
||||
## Installation and connection of the Pixracer flight controller
|
||||
|
||||
@@ -162,7 +162,7 @@ article [remote faults](radioerrors.md).
|
||||
|
||||
4. Connect the ribbon cable from the radio receiver to the RCIN connector in Pixracer.
|
||||
|
||||

|
||||

|
||||
|
||||
## Raspberry installation
|
||||
|
||||
@@ -186,7 +186,7 @@ article [remote faults](radioerrors.md).
|
||||
|
||||
Use an M3x16 screw and an M3 nut
|
||||
|
||||

|
||||

|
||||
|
||||
## Arduino and FlySky radio receiver installation
|
||||
|
||||
@@ -200,7 +200,7 @@ article [remote faults](radioerrors.md).
|
||||
black -> GND
|
||||
orange, green -> currently not used. They are set to the unused pins of the radio receiver.
|
||||
|
||||

|
||||

|
||||
|
||||
## RPi camera installation
|
||||
|
||||
@@ -213,7 +213,7 @@ article [remote faults](radioerrors.md).
|
||||
|
||||
5. Install the legs into the mounts (4 pcs).
|
||||
|
||||

|
||||

|
||||
|
||||
## Installation of the remaining structural elements
|
||||
|
||||
@@ -223,13 +223,13 @@ article [remote faults](radioerrors.md).
|
||||
|
||||
Secure the upper deck with M3x8 screws (4 pcs.)
|
||||
|
||||

|
||||

|
||||
|
||||
## USB connectors installation
|
||||
|
||||
1. Connect Pixracer to Raspberry using the micro USB - USB cable.
|
||||
2. Connect Arduino to Raspberry using the micro USB - USB cable.
|
||||
|
||||
.
|
||||
.
|
||||
|
||||
Read more about connection in [article](connection.md).
|
||||
|
||||
@@ -49,7 +49,7 @@ The rest of categories contains standard Blockly's blocks.
|
||||
|
||||
### take_off
|
||||
|
||||
<img src="../assets/blocks/take-off.png" srcset="../assets/blocks/take-off.png 2x">
|
||||
<img src="../assets/blocks/take-off.png" srcset="@source/assets/blocks/take-off.png 2x">
|
||||
|
||||
Take off to specified altitude in meters. The altitude may be an arbitrary block, that returns a number.
|
||||
|
||||
@@ -57,7 +57,7 @@ The `wait` flag specifies, if the drone should wait until take off is complete,
|
||||
|
||||
### navigate
|
||||
|
||||
<img src="../assets/blocks/navigate.png" srcset="../assets/blocks/navigate.png 2x">
|
||||
<img src="../assets/blocks/navigate.png" srcset="@source/assets/blocks/navigate.png 2x">
|
||||
|
||||
Navigate to specified point. Coordinates are specified in meters.
|
||||
|
||||
@@ -77,7 +77,7 @@ This block allows to specify the [coordinate frame](frames.md) of the target poi
|
||||
|
||||
### land
|
||||
|
||||
<img src="../assets/blocks/land.png" srcset="../assets/blocks/land.png 2x">
|
||||
<img src="../assets/blocks/land.png" srcset="@source/assets/blocks/land.png 2x">
|
||||
|
||||
Land the drone.
|
||||
|
||||
@@ -85,31 +85,31 @@ The `wait` flag specifies, if the drone should wait until landing is complete, b
|
||||
|
||||
### wait
|
||||
|
||||
<img src="../assets/blocks/wait.png" srcset="../assets/blocks/wait.png 2x">
|
||||
<img src="../assets/blocks/wait.png" srcset="@source/assets/blocks/wait.png 2x">
|
||||
|
||||
Wait specified time period in seconds. The time period may be an arbitrary block, that returns a number.
|
||||
|
||||
### wait_arrival
|
||||
|
||||
<img src="../assets/blocks/wait-arrival.png" srcset="../assets/blocks/wait-arrival.png 2x">
|
||||
<img src="../assets/blocks/wait-arrival.png" srcset="@source/assets/blocks/wait-arrival.png 2x">
|
||||
|
||||
Wait, until the drone reaches [navigate](#navigate)-block's target point.
|
||||
|
||||
### get_position
|
||||
|
||||
<img src="../assets/blocks/get-position.png" srcset="../assets/blocks/get-position.png 2x">
|
||||
<img src="../assets/blocks/get-position.png" srcset="@source/assets/blocks/get-position.png 2x">
|
||||
|
||||
The block returns current position, velocity or yaw angle of the drone relative to the specified [coordinate frame](#relative_to).
|
||||
|
||||
### set_effect
|
||||
|
||||
<img src="../assets/blocks/set-effect.png" srcset="../assets/blocks/set-effect.png 2x">
|
||||
<img src="../assets/blocks/set-effect.png" srcset="@source/assets/blocks/set-effect.png 2x">
|
||||
|
||||
The block allows to set animations to LED strip, similarly to [`set_effect`](leds.md#set_effect) ROS-service.
|
||||
|
||||
Example of using the block with a random color (colors-related blocks are located in *Colour* category):
|
||||
|
||||
<img src="../assets/blocks/random-color.png" srcset="../assets/blocks/random-color.png 2x">
|
||||
<img src="../assets/blocks/random-color.png" srcset="@source/assets/blocks/random-color.png 2x">
|
||||
|
||||
### Work with GPIO {#GPIO}
|
||||
|
||||
|
||||
@@ -51,5 +51,3 @@ Read more in the PX4 docs: https://docs.px4.io/master/en/config/accelerometer.ht
|
||||
5. Wait for the calibration to finish.
|
||||
|
||||
Read more in the PX4 docs: https://docs.px4.io/master/en/config/level_horizon_calibration.html.
|
||||
|
||||
**Next**: [RC setup](radio.md).
|
||||
|
||||
@@ -50,5 +50,3 @@ In order to connect to a local or a remote [SITL](sitl.md) instance set the `fcu
|
||||
<arg name="fcu_conn" default="udp"/>
|
||||
<arg name="fcu_ip" default="127.0.0.1"/>
|
||||
```
|
||||
|
||||
**Next**: [Using QGroundControl over Wi-Fi](gcs_bridge.md)
|
||||
|
||||
@@ -12,24 +12,24 @@ The proposed projects have to be open-source and be compatible with the Clover q
|
||||
|
||||
|Place|Team|Project|Points|
|
||||
|:-:|-|-|-|
|
||||
||🇰🇬 Alatoo University Team|[Облачная платформа для симулятора Клевера](https://github.com/pteacher/clover/blob/clover_simulator/docs/ru/clover-development-studio.md)||
|
||||
||🇧🇾 FTL|[Advanced Clover 2](https://github.com/FTL-team/clover/blob/FTL-advancedClover2/docs/ru/advanced_clover_simulator.md)||
|
||||
||🇷🇺 Stereo|[Neural obstacle avoidance](https://github.com/den250400/clover/blob/neural-obstacle-avoidance/docs/en/neural-obstacle-avoidance.md)||
|
||||
||🇷🇺 Space clowns|[Copter For Space](https://github.com/slavikyd/clover/blob/patch-3/docs/ru/c4s.md)||
|
||||
||🇷🇺 R.S.|[Drone Hawk](https://github.com/slavaroot/clover/blob/droneHawkSecurity/docs/ru/drone-hawk-security.md)||
|
||||
||🇲🇾 Moopt|[IoT Water Monitoring & Optimization](https://github.com/kafechew/clover/blob/master/docs/en/moopt-uav.md)||
|
||||
||🇧🇷 Atena - Grupo SEMEAR|[Swarm in Blocks](https://github.com/Grupo-SEMEAR-USP/clover/blob/Swarm_in_Blocks/docs/en/swarm_in_blocks.md)||
|
||||
||🇷🇺 Clevertron|[Clevertron](https://github.com/Daniel-drone/clover/blob/Clevertron-1/docs/ru/clevertron.md)||
|
||||
||🇷🇺 Clover Rescue Team|[Rescue Clover](https://github.com/DevMBS/clover/blob/CloverRescueTeam/docs/ru/clover-rescue-team.md)||
|
||||
||🇵🇱 Edgenoon|[Neural and vision-based landing method](https://github.com/edgenoon-ai/clover/blob/neural_vision_based_landing_method/docs/en/neural_vision_based_landing_method.md)||
|
||||
||🇷🇺 CopterCat|[CopterCat](https://github.com/matveylapin/clover/blob/CopterCat/docs/ru/сopter_сat.md)||
|
||||
||🇷🇺 Дрой Ронов|[Clover Swarm](https://github.com/stinger000/clever/blob/clover_swarm_request/docs/ru/clover-swarm.md)||
|
||||
||🇩🇪 Inondro|[Inondro Pix](https://github.com/Inondro/clover/blob/inondro-pix/docs/en/inondro_copterhack22_pix.md)||
|
||||
||🇮🇳 DJS Phoenix|[Autonomous valet parking drone assistance](https://github.com/DJSPhoenix/clover/blob/DJSPhoenix-Ikshana/docs/en/djs_phoenix_ikshana.md)||
|
||||
||🇷🇺 SPECTRE|[SPECTRE](https://github.com/alakhmenev/clover/blob/spectre_team/docs/ru/spectre_team.md)||
|
||||
||🇷🇺 SolidEye|[Разработка лидара без движущихся частей](https://github.com/feanorgg/clover/blob/solideye/docs/ru/solid_eye.md)||
|
||||
||🇰🇬 AI_U_CLOVER|[AIU_CLOVER](https://github.com/zhibekm/clover/blob/zhibekm-patch-1/docs/en/aiu-article.md)||
|
||||
||🇷🇺 С305|[Система мониторинга воздуха](https://github.com/Ruslan2288/clover/blob/master/docs/ru/air_monitor.md)| |
|
||||
|✕|🇰🇬 Alatoo University Team|[Облачная платформа для симулятора Клевера](https://github.com/pteacher/clover/blob/clover_simulator/docs/ru/clover-development-studio.md)||
|
||||
|✕|🇷🇺 Clevertron|[Clevertron](https://github.com/Daniel-drone/clover/blob/Clevertron-1/docs/ru/clevertron.md)||
|
||||
|✕|🇵🇱 Edgenoon|[Neural and vision-based landing method](https://github.com/edgenoon-ai/clover/blob/neural_vision_based_landing_method/docs/en/neural_vision_based_landing_method.md)||
|
||||
|✕|🇩🇪 Inondro|[Inondro Pix](https://github.com/Inondro/clover/blob/inondro-pix/docs/en/inondro_copterhack22_pix.md)||
|
||||
|✕|🇷🇺 SolidEye|[Разработка лидара без движущихся частей](https://github.com/feanorgg/clover/blob/solideye/docs/ru/solid_eye.md)||
|
||||
|✕|🇰🇬 AI_U_CLOVER|[AIU_CLOVER](https://github.com/zhibekm/clover/blob/zhibekm-patch-1/docs/en/aiu-article.md)||
|
||||
|✕|🇻🇳 Dragon&Tanker|[Dragon&Tanker](https://github.com/uml4/clover/blob/drone_observe_autonomous_car/docs/en/dragon_and_tanker_team.md)||
|
||||
|✕|🇷🇺 V-NAV|[Visual Navigation](https://github.com/v-nav/clover/blob/v-nav_article/docs/ru/v-nav.md)||
|
||||
|✕|🇷🇺 Джедаи 1581|[Ретранслятор на базе Клевера](https://github.com/JJNIK/clover/blob/patch-1/docs/ru/1581.md)||
|
||||
|
||||
@@ -10,9 +10,9 @@ People strive to teach artificial intelligence everything they can do themselves
|
||||
|
||||
## Models and assembly
|
||||
|
||||
<img class="center" src="../assets/ddrone/full_holder.png" width="300" class="zoom">
|
||||
<img class="center zoom" src="../assets/ddrone/full_holder.png" width="300">
|
||||
|
||||
<img class="center" src="../assets/ddrone/full_holder_in_real.jpg" width="300" class="zoom">
|
||||
<img class="center zoom" src="../assets/ddrone/full_holder_in_real.jpg" width="300">
|
||||
|
||||
To complete the project you need to have in stock:
|
||||
|
||||
@@ -43,9 +43,9 @@ If the diameter of the can is less than the diameter of the holder, we use the p
|
||||
|
||||
**Pressing mechanism.** To push the valve, we will use a screw drive with a fixed nut. A bar with holes will be attached to the servo, which will include the racks attached to the nut. This helps the servo to move only on one axis, up and down. We also modeled the cap for the spray can button, since the surface of the nozzle is uneven.
|
||||
|
||||
<img class="center" src="../assets/ddrone/pressing_mechanism.png" width="300" class="zoom">
|
||||
<img class="center zoom" src="../assets/ddrone/pressing_mechanism.png" width="300">
|
||||
|
||||
<img class="center" src="../assets/ddrone/pressing_mechanism_in_real.jpg" width="300" class="zoom">
|
||||
<img class="center zoom" src="../assets/ddrone/pressing_mechanism_in_real.jpg" width="300">
|
||||
|
||||
## Before launching
|
||||
|
||||
@@ -81,11 +81,11 @@ Now to open the web interface, click on the link [http://192.168.11.1/clover/dro
|
||||
|
||||
Our drone is launched via [website](https://perizatkurmanbaeva.github.io/visual_ddrone). The web interface allows you to draw and encode what you draw in G-code. The coordinate data will be transmitted for further processing and execution by the copter.
|
||||
|
||||
<img class="center" src="../assets/ddrone/screen_2.png" width="600" class="zoom">
|
||||
<img class="center zoom" src="../assets/ddrone/screen_2.png" width="600">
|
||||
|
||||
We pick the web interface to control the copter because it is easier for the user.
|
||||
|
||||
<img class="center" src="../assets/ddrone/instruction.png" width="300" class="zoom">
|
||||
<img class="center zoom" src="../assets/ddrone/instruction.png" width="300">
|
||||
|
||||
## Flights
|
||||
|
||||
|
||||
@@ -77,19 +77,19 @@ PX4 may be compiled from the source and automatically flashed to the flight cont
|
||||
To do this, clone the PX4 repository:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/PX4/Firmware.git
|
||||
git clone https://github.com/PX4/PX4-Autopilot.git
|
||||
```
|
||||
|
||||
Select the appropriate version (tag) using `git checkout`. Then compile and upload the firmware:
|
||||
|
||||
```
|
||||
make px4fmu-v4_default upload
|
||||
```bash
|
||||
make px4_fmu-v4_default upload
|
||||
```
|
||||
|
||||
Where `px4fmu-v4_default` is the required firmware variant.
|
||||
Where `px4_fmu-v4_default` is the required firmware variant.
|
||||
|
||||
In order to upload the `v3` firmware to Pixhawk, you may need to use the `force_upload` option:
|
||||
|
||||
```
|
||||
make px4fmu-v3_default force-upload
|
||||
```bash
|
||||
make px4_fmu-v3_default force-upload
|
||||
```
|
||||
|
||||
@@ -106,5 +106,3 @@ When the *Kill Switch* is activated, no control signals are sent to the motors a
|
||||
> **Caution** Be careful, *Kill Switch* does not put the copter into *Disarmed* state!
|
||||
|
||||
Before disabling the *Kill Switch*, make sure the throttle stick is its down position and the aircraft is in *Disarmed* state. If the throttle stick is not in the lower position, when the *Kill Switch* is turned off, a signal corresponding to the stick position will be sent to the motors, which will lead your copter to jerk.
|
||||
|
||||
**Next**: [Drone control exercises](flight_exercises.md).
|
||||
|
||||
@@ -67,5 +67,3 @@ Change parameter `gcs_bridge` in the launch file:
|
||||
```
|
||||
|
||||
After opening the QGroundControl application, the connection should be established automatically.
|
||||
|
||||
**Next**: [Remote access using SSH](ssh.md)
|
||||
|
||||
@@ -43,14 +43,14 @@ After printing the first version of the frame we discovered the following proble
|
||||
|
||||
To conquer those problems we made several changes. We increased the minimal thickness for the generated structures and generated a new model. We changed the settings in the slicer so that the support structure could be removed easier as well as changed the infill structure. Finally we changed the filament and increased the printing temperature. Further we concluded that printing with a water dissolvable support structure would be optimal, however as of right now we don’t have access to a printer capable of that.
|
||||
|
||||

|
||||

|
||||
|
||||
#### Prototype 2
|
||||
|
||||
This prototype took 48 hours of printing and used 277 grams of filament including 100 grams for the support. Installation of the components is very easy as no other tools than a screwdriver are needed. This prototype was the first to take flight in January 2021. Please see [this](https://youtu.be/M4f8_JmJADM) video.
|
||||
|
||||
<p float="left">
|
||||
<img src="../assets/generative-design-frame/p21.JPG" width="32%" class="zoom"/>
|
||||
<img src="../assets/generative-design-frame/p21.jpg" width="32%" class="zoom"/>
|
||||
<img src="../assets/generative-design-frame/p22.jpg" width="32%" class="zoom"/>
|
||||
<img src="../assets/generative-design-frame/p23.jpg" width="32%" class="zoom"/>
|
||||
</p>
|
||||
@@ -73,7 +73,7 @@ Videos:
|
||||
|
||||
In this final prototype we have changed the preserved geometry on the bottom to form a rectangle for added stability. We have also changed some of the forces on the points we observed breakings in our previous tests. We have also updated the prop guard to make it more stable and increased the area around the screws, so it would break harder. The frame without the prop guard weighs only 150g making it significantly lighter than the default frame.
|
||||
|
||||

|
||||

|
||||
|
||||
### Benefits
|
||||
|
||||
|
||||
@@ -15,5 +15,3 @@ The RPi image for Clover contains all the necessary software for working with Cl
|
||||
<img src="../assets/etcher.png" class="zoom">
|
||||
|
||||
After flashing the image on the MicroSD-card, you can [connect to the Clover over Wi-Fi](wifi.md), use [wireless connection in QGroundControl](gcs_bridge.md), gain access to the Raspberry [over SSH](ssh.md) and use all the other features.
|
||||
|
||||
**Next:** [Connecting over Wi-Fi](wifi.md).
|
||||
|
||||
@@ -75,7 +75,7 @@ from sensor_msgs.msg import Range
|
||||
|
||||
# ...
|
||||
|
||||
data = rospy.wait_for_message('rangefinder/range', Range)
|
||||
dist = rospy.wait_for_message('rangefinder/range', Range).range
|
||||
```
|
||||
|
||||
### Data visualization
|
||||
|
||||
@@ -158,3 +158,9 @@ Current LED strip state is published in the `/led/state` ROS topic. You can view
|
||||
```bash
|
||||
rostopic echo /led/state
|
||||
```
|
||||
|
||||
Using the same topic you can get the configured number os LEDs, using Python:
|
||||
|
||||
```python
|
||||
led_count = len(rospy.wait_for_message('led/state', LEDStateArray, timeout=10).leds)
|
||||
```
|
||||
|
||||
@@ -63,3 +63,64 @@ Then connect the signal output of the circuit to the selected port and solder th
|
||||
2. Use a zip tie to pull the assembled circuit to the back of the deck.
|
||||
3. Plug the Arduino *D11* signal pin into one of the *AUX* pins on the flight controller.
|
||||
4. Plug the power wire of the electromagnetic gripper to JST 5V.
|
||||
|
||||
## Setting up electromagnetic gripper
|
||||
|
||||
To control the magnet through Arduino Nano, use the following code:
|
||||
|
||||
```cpp
|
||||
void setup() {
|
||||
pinMode(11, INPUT);
|
||||
pinMode(13, OUTPUT);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (int duration = pulseIn(11, HIGH) > 1200) {
|
||||
digitalWrite(13, HIGH);
|
||||
} else {
|
||||
digitalWrite(13, LOW);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To monitor the status of the electromagnetic gripper, you can connect the *ws281x* LED strip (included to Clover kit). Connect it to power +5v – 5v, ground GND – GND, and signal wire DIN – Arduino D12.
|
||||
|
||||
To control the magnet and monitor it using the LED strip, use the following code:
|
||||
|
||||
```cpp
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
#define NUMPIXELS 72
|
||||
#define PIN 12
|
||||
int pin = 11;
|
||||
int led = 13;
|
||||
|
||||
unsigned long duration;
|
||||
Adafruit_NeoPixel strip (NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
|
||||
|
||||
void setup() {
|
||||
strip.begin();
|
||||
strip.setBrightness(10);
|
||||
Serial.begin(9600);
|
||||
pinMode(pin, INPUT);
|
||||
pinMode(led, OUTPUT);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
duration = pulseIn(pin, HIGH);
|
||||
Serial.println(duration);
|
||||
delay(100);
|
||||
if (duration >= 1500) {
|
||||
digitalWrite(led, HIGH);
|
||||
for (int i = -1; i < NUMPIXELS; i++) {
|
||||
strip.setPixelColor(i, strip.Color(255, 0, 0));
|
||||
strip.show();
|
||||
}
|
||||
} else {
|
||||
digitalWrite(led, LOW);
|
||||
for (int i = -1; i < NUMPIXELS; i++) {
|
||||
strip.setPixelColor(i, strip.Color(0, 255, 0));
|
||||
strip.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -56,13 +56,13 @@
|
||||
12. Install the assembled grip onto the aircraft from below.
|
||||
|
||||
<div class="image-group">
|
||||
<img src="../assets/mechanical_grip/mech_grip_15.png" width=300 class="zoom border">
|
||||
<img src="../assets/mechanical_grip/mech_grip_16.png" width=300 class="zoom border">
|
||||
<img src="../assets/mechanical_grip/mech_grip_17.png" width=300 class="zoom border">
|
||||
</div>
|
||||
|
||||
13. Insert the servo cable into the *AUX* 1-2 output on the flight controller.
|
||||
|
||||
<img src="../assets/mechanical_grip/mech_grip_18.png" width=300 class="zoom border center">
|
||||
<img src="../assets/mechanical_grip/mech_grip_17.png" width=300 class="zoom border center">
|
||||
|
||||
14. Go to the *Radio* tab to control capture with the remote control.
|
||||
15. In the *AUX 1/2 Passthrough RC channel* parameter, select the desired channel.
|
||||
|
||||
@@ -46,5 +46,3 @@ In autonomous flight modes the quadcopter ignores the control signals from the t
|
||||
* **AUTO.LAND** – the copter lands at the current position.
|
||||
|
||||
Additional information: https://dev.px4.io/en/concept/flight_modes.html.
|
||||
|
||||
**Next**: [Power setup](power.md).
|
||||
|
||||
@@ -29,7 +29,7 @@ When using **EKF2** (parameter `SYS_MC_EST_GROUP` = `ekf2`):
|
||||
* `EKF2_OF_N_MAX` - 0.2.
|
||||
* `SENS_FLOW_ROT` – No rotation.
|
||||
* `SENS_FLOW_MAXHGT` – 4.0 (for the rangefinder VL53L1X)
|
||||
* `SENS_FLOW_MINHGT` – 0.01 (for the rangefinder VL53L1X)
|
||||
* `SENS_FLOW_MINHGT` – 0.0 (for the rangefinder VL53L1X)
|
||||
* Optional: `EKF2_HGT_MODE` – range sensor (cf. [rangefinder setup](laser.md)).
|
||||
|
||||
When using **LPE** (parameter `SYS_MC_EST_GROUP` = `local_position_estimator, attitude_estimator_q`):
|
||||
@@ -41,7 +41,7 @@ When using **LPE** (parameter `SYS_MC_EST_GROUP` = `local_position_estimator, at
|
||||
* `LPE_FLW_RR` – 0.0.
|
||||
* `SENS_FLOW_ROT` – No rotation.
|
||||
* `SENS_FLOW_MAXHGT` – 4.0 (for the rangefinder VL53L1X)
|
||||
* `SENS_FLOW_MINHGT` – 0.01 (for the rangefinder VL53L1X)
|
||||
* `SENS_FLOW_MINHGT` – 0.0 (for the rangefinder VL53L1X)
|
||||
* Optional: `LPE_FUSION` – flag 'pub agl as lpos down' is on (see [rangefinder setup](laser.md).
|
||||
|
||||
[The `selfcheck.py` utility](selfcheck.md) will help you verify that all settings are correctly set.
|
||||
|
||||
@@ -1,20 +1,64 @@
|
||||
# PX4 Parameters
|
||||
|
||||
Main article: https://dev.px4.io/en/advanced/parameter_reference.html
|
||||
Full documentation on PX4 parameters: https://docs.px4.io/master/en/advanced_config/parameter_reference.html.
|
||||
|
||||
> **Note** This is a description some of the most important PX4 parameters as of version 1.8.0. The full list is available at the link above.
|
||||
For changing PX4 parameters, use QGroundControl software, [connect to Clover over Wi-Fi](gcs_bridge.md) or USB. Go to *Vehicle Setup* panel (click on the QGroundControl logo in the top-left corner) and choose *Parameters* menu.
|
||||
|
||||
To change PX4 parameters, you can use the QGroundControl application [by connecting to Clover via Wi-Fi](gcs_bridge.md):
|
||||
## Recommended values
|
||||
|
||||

|
||||
### Common parameters
|
||||
|
||||
## Main parameters
|
||||
|Parameter|Value|Comment|
|
||||
|-|-|-|
|
||||
|`SENS_FLOW_ROT`|0 (*No rotation*)|If using *PX4Flow* hardware, keep the default value|
|
||||
|`SENS_FLOW_MINHGT`|0.0|For [VL53L1X](laser.md) rangefinder|
|
||||
|`SENS_FLOW_MAXHGT`|4.0|For [VL53L1X](laser.md) rangefinder|
|
||||
|`SENS_FLOW_MAXR`|10.0||
|
||||
|`SYS_HAS_MAG`|0|If impossible to run the magnetometer (*No mags found* error)|
|
||||
|
||||
The most important parameters are listed in this paragraph.
|
||||
### Estimator subsystem parameters
|
||||
|
||||
`SYS_MC_EST_GROUP` – select the estimator module.
|
||||
In case of using LPE ([COEX patched firmware](firmware.md)):
|
||||
|
||||
This is a group of modules that calculates the current state of the copter using readings from the sensors. The copter state includes:
|
||||
|Parameter|Value|Comment|
|
||||
|-|-|-|
|
||||
|`LPE_FUSION`|86|Checkboxes: *flow* + *vis* + *land Detector* + *gyro comp*. If flying over horizontal floor *pub agl as lpos down* checkbox is allowed.<br>Details: [Optical Flow](optical_flow.md), [ArUco markers](aruco_map.md), [GPS](gps.md).|
|
||||
|`LPE_VIS_DELAY`|0.0||
|
||||
|`LPE_VIS_Z`|0.1||
|
||||
|`LPE_FLW_SCALE`|1.0||
|
||||
|`LPE_FLW_R`|0.2||
|
||||
|`LPE_FLW_RR`|0.0||
|
||||
|`LPE_FLW_QMIN`|10||
|
||||
|`ATT_W_EXT_HDG`|0.5|Enabling usage of external yaw angle (when navigating using [markers map](aruco_map.md))|
|
||||
|`ATT_EXT_HDG_M`|1 (*Vision*)||
|
||||
|`ATT_W_MAG`|0|Disabling usage of the magnetometer (when navigating indoor)|
|
||||
|
||||
In case of using EKF2 (official firmware):
|
||||
|
||||
<!-- markdownlint-disable MD044 -->
|
||||
|
||||
|Parameter|Value|Comment|
|
||||
|-|-|-|
|
||||
|`EKF2_AID_MASK`|27|Checkboxes: (optionally) *gps* + *flow* + *vision position* + *vision yaw*.<br>Details: [Optical Flow](optical_flow.md), [ArUco markers](aruco_map.md), [GPS](gps.md).|
|
||||
|`EKF2_OF_DELAY`|0||
|
||||
|`EKF2_OF_QMIN`|10||
|
||||
|`EKF2_OF_N_MIN`|0.05||
|
||||
|`EKF2_OF_N_MAX`|0.2||
|
||||
|`EKF2_HGT_MODE`|2 (*Range sensor*)|If the [rangefinder](laser.md) is present and flying over horizontal floor|
|
||||
|`EKF2_EVA_NOISE`|0.1||
|
||||
|`EKF2_EVP_NOISE`|0.1||
|
||||
|`EKF2_EV_DELAY`|0||
|
||||
|`EKF2_MAG_TYPE`|5 (*None*)|Disabling usage of the magnetometer (when navigating indoor)|
|
||||
|
||||
<!-- markdownlint-enable MD031 -->
|
||||
|
||||
> **Info** See also: list of default parameters of the [Clover simulator](simulation.md): https://github.com/CopterExpress/clover/blob/master/clover_simulation/airframes/4500_clover.
|
||||
|
||||
## Additional information
|
||||
|
||||
The `SYS_MC_EST_GROUP` parameter defines the estimator subsystem to use.
|
||||
|
||||
Estimator subsystem is a group of modules that calculates the current state of the copter using readings from the sensors. The copter state includes:
|
||||
|
||||
* Angle rate of the copter – pitch_rate, roll_rate, yaw_rate;
|
||||
* Copter orientation (in the local coordinate system) – pitch, roll, yaw (one of presentations);
|
||||
@@ -57,9 +101,7 @@ These parameters adjust the flight of the copter by position (POSCTL, OFFBOARD,
|
||||
|
||||
## LPE + Q attitude estimator
|
||||
|
||||
These parameters configure the behavior of the `lpe` and `q` modules, which compute the state (orientation, position) of the copter. These parameters apply **only** if the `SYS_MC_EST_GROUP` parameter is set to `1` (local_position_estimator, attitude_estimator_q)
|
||||
|
||||
TODO
|
||||
These parameters configure the behavior of the `lpe` and `q` modules, which compute the state (orientation, position) of the copter. These parameters apply **only** if the `SYS_MC_EST_GROUP` parameter is set to `1` (local_position_estimator, attitude_estimator_q).
|
||||
|
||||
## Commander
|
||||
|
||||
@@ -68,5 +110,3 @@ Prearm checks, switching the modes and states of the copter.
|
||||
## Sensors
|
||||
|
||||
Enabling, disabling and configuring various sensors.
|
||||
|
||||
TODO
|
||||
|
||||
@@ -32,5 +32,3 @@ Further reading: https://docs.qgroundcontrol.com/en/SetupView/Power.html.
|
||||
<img src="../assets/qgc-power.png" class="zoom">
|
||||
|
||||
Further reading: https://docs.px4.io/master/en/advanced_config/esc_calibration.html.
|
||||
|
||||
**Next**: [Failsafe configuration](failsafe.md)
|
||||
|
||||
@@ -36,5 +36,3 @@ Before connecting and calibrating the RC, make sure that:
|
||||
8. When you get the *"All settings have been captured. Click Next to write the new parameters to your board"*, press *Next*.
|
||||
|
||||
Further reading: https://docs.qgroundcontrol.com/en/SetupView/Radio.html
|
||||
|
||||
**Next**: [Flight modes](modes.md).
|
||||
|
||||
@@ -15,5 +15,3 @@ Technical specifications:
|
||||
* An HDMI port.
|
||||
|
||||
Raspberry Pi is connected to the flight controller in the Clover kit and is used as a companion computer. It can be used to [connect to the drone over Wi-Fi](wifi.md), perform autonomous flights, access peripherals and much more.
|
||||
|
||||
**Next**: [Raspberry Pi image](image.md)
|
||||
|
||||
@@ -5,7 +5,7 @@ Controlling Clover from a smartphone
|
||||
|
||||
To control Clover from a smartphone via Wi-Fi, you have to install the appropriate application – [iOS](https://itunes.apple.com/ru/app/clever-rc/id1396166572?mt=8), Android (https://play.google.com/store/apps/details?id=express.copter.cleverrc).
|
||||
|
||||

|
||||

|
||||
|
||||
> **Warning** The mobile transmitter is mainly intended for indoor flights to the range not exceeding 10-15 m. Many Wi-Fi networks may also impair responsiveness and the range of the transmitter.
|
||||
|
||||
|
||||
@@ -66,8 +66,9 @@ Connect your receiver to the RC IN port on your flight controller:
|
||||
<img src="../assets/flysky_a8s/14_coexpix_rcin.png" width=300 class="zoom border center" alt="coex pix connection">
|
||||
</div>
|
||||
|
||||
> **Hint** Double check that you're using the RC IN port on the COEX Pix:
|
||||
<img src="../assets/coexpix-bottom.jpg" width=300 class="zoom border center" alt="coex pix pinout">
|
||||
Double check that you're using the RC IN port on the COEX Pix:
|
||||
|
||||
<img src="../assets/coex_pix/coexpix-bottom.jpg" width=300 class="zoom border center" alt="coex pix pinout">
|
||||
|
||||
## Binding your transmitter {#rc_bind}
|
||||
|
||||
|
||||
@@ -115,23 +115,23 @@ After finishing step 4, at section Installing guard of Clover 4.2 assembly.
|
||||
|
||||
1. Install the Lower Tank Holders to top Deck mount and fix with the M3x8 screws.
|
||||
|
||||
<img src="../assets/seeding_drone/mechanismpictures/1.PNG" width="400px" class="center"/>
|
||||
<img src="../assets/seeding_drone/mechanismpictures/1.png" width="400px" class="center"/>
|
||||
|
||||
2. Install Nylon rack(40 mm) to 4 sides of the Deck mount.
|
||||
|
||||
<img src="../assets/seeding_drone/mechanismpictures/2.PNG" width="400px" class="center"/>
|
||||
<img src="../assets/seeding_drone/mechanismpictures/2.png" width="400px" class="center"/>
|
||||
|
||||
3. Install the Grab deck and fix with the M3x8 screws.
|
||||
|
||||
<img src="../assets/seeding_drone/mechanismpictures/3.PNG" width="400px" class="center"/>
|
||||
<img src="../assets/seeding_drone/mechanismpictures/3.png" width="400px" class="center"/>
|
||||
|
||||
4. Install the Upper Tank Holders to top Grab mount and fix with the M3x8 screws.
|
||||
|
||||
<img src="../assets/seeding_drone/mechanismpictures/4.PNG" width="400px" class="center"/>
|
||||
<img src="../assets/seeding_drone/mechanismpictures/4.png" width="400px" class="center"/>
|
||||
|
||||
5. Connect the Tanks carefully to Tank Holders.
|
||||
|
||||
<img src="../assets/seeding_drone/mechanismpictures/5.PNG" width="400px" class="center"/>
|
||||
<img src="../assets/seeding_drone/mechanismpictures/5.png" width="400px" class="center"/>
|
||||
|
||||
6. Connect SG90 servo motors to Tank using zip tie.
|
||||
|
||||
|
||||
@@ -27,28 +27,29 @@ Main article: https://docs.qgroundcontrol.com/en/SetupView/Firmware.html
|
||||
|
||||
> **Note** Do not connect your flight controller prior to flashing.
|
||||
|
||||
We recommend using the modified version of PX4 by CopterExpress for the Clover drone, especially for autonomous flights. Download the latest stable version **<a class="latest-firmware v4" href="https://github.com/CopterExpress/Firmware/releases">from our GitHub</a>**.
|
||||
We recommend using the modified version of [PX4 with COEX patches](firmware.md) for the Clover drone, especially for autonomous flights. Download the latest stable version **<a class="latest-firmware v4" href="https://github.com/CopterExpress/Firmware/releases">from our GitHub</a>**.
|
||||
|
||||
> **Info** For Pixhawk-based quadcopters there is a separate firmware version. See details in "[Pixhawk / Pixracer firmware flashing](firmware.md)" article.
|
||||
To use all the most recent PX4 functions you also can use the latest official firmware version (experimentally).
|
||||
|
||||
Flash the flight controller with this firmware:
|
||||
|
||||
<img src="../assets/qgc-firmware.png" alt="QGroundControl firmware upload" class="zoom">
|
||||
|
||||
1. Launch QGroundControl software.
|
||||
2. Open the *Vehicle Setup* tab.
|
||||
3. Select the *Firmware* menu.
|
||||
1. Disconnect the flight controller from computer (if connected).
|
||||
2. Launch QGroundControl software.
|
||||
3. Go to *Vehicle Setup* panel (click on the QGroundControl logo in the top-left corner) and select *Firmware* menu.
|
||||
4. Connect your flight controller to your PC over USB.
|
||||
5. Wait for the flight controller to connect to QGroundControl.
|
||||
6. Select *PX4 Flight Stack* in the right bar.
|
||||
5. Select *PX4 Flight Stack* in the right bar appeared.
|
||||
|
||||
To use the recommended Copter Express firmware:
|
||||
<img src="../assets/qgc-firmware.png" alt="QGroundControl firmware upload" class="zoom">
|
||||
|
||||
* Check *Advanced Settings* checkbox.
|
||||
* Select *Custom firmware file...* from the dropdown list.
|
||||
* Press *OK* and select the file that you've downloaded.
|
||||
6. To use **COEX patched firmware**:
|
||||
|
||||
To use the latest official stable firmware just press *OK*.
|
||||
* Check *Advanced Settings* checkbox.
|
||||
* Select *Custom firmware file...* from the dropdown list.
|
||||
* Press *OK* and select the file that you've downloaded.
|
||||
|
||||
To use the latest **official stable firmware** just press *OK*.
|
||||
|
||||
Wait for QGroundControl to finish flashing the flight controller.
|
||||
|
||||
@@ -82,7 +83,7 @@ This is how the main QGroundControl settings window will look like:
|
||||
|
||||
### Setting parameters
|
||||
|
||||
Open the *Vehicle Setup* tab and select the *Parameters* menu. You can use the *Search* field to find parameters by name.
|
||||
Open the *Vehicle Setup* tab and select the *Parameters* menu. You can use the *Search* field to find parameters by name. Recommended parameters values are given in the further documentation and also in the [parameters summary article](parameters.md).
|
||||
|
||||
<img src="../assets/qgc-parameters.png" alt="QGroundControl parameters" class="zoom">
|
||||
|
||||
@@ -123,5 +124,3 @@ Press the *Save* button to save the changed value to the flight controller. Chan
|
||||
|
||||
1. Set `CBRK_USB_CHK` to 197848 to allow flights with the USB cable connected.
|
||||
2. Disable safety switch check: `CBRK_IO_SAFETY` = 22027.
|
||||
|
||||
**Next**: [Sensor calibration](calibration.md).
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
Autonomous flight (OFFBOARD)
|
||||
===
|
||||
|
||||
> **Note** In the image version **0.20** `clever` package was renamed to `clover`. See [previous version of the article](https://github.com/CopterExpress/clover/blob/v0.19/docs/en/simple_offboard.md) for older images.
|
||||
|
||||
<!-- -->
|
||||
|
||||
> **Hint** We recommend using our [custom PX4 firmware for Clover](firmware.md#modified-firmware-for-clover) for autonomous flights.
|
||||
# Autonomous flight
|
||||
|
||||
The `simple_offboard` module of the `clover` package is intended for simplified programming of the autonomous drone flight (`OFFBOARD` [flight mode](modes.md)). It allows setting the desired flight tasks, and automatically transforms [coordinates between frames](frames.md).
|
||||
|
||||
@@ -13,8 +6,7 @@ The `simple_offboard` module of the `clover` package is intended for simplified
|
||||
|
||||
Main services are [`get_telemetry`](#gettelemetry) (receive telemetry data), [`navigate`](#navigate) (fly to a given point along a straight line), [`navigate_global`](#navigateglobal) (fly to a point specified as latitude and longitude along a straight line), [`land`](#land) (switch to landing mode).
|
||||
|
||||
Python examples
|
||||
---
|
||||
## Python usage
|
||||
|
||||
You need to create proxies for services before calling them. Use the following template for your programs:
|
||||
|
||||
@@ -37,8 +29,7 @@ land = rospy.ServiceProxy('land', Trigger)
|
||||
|
||||
Unused proxy functions may be removed from the code.
|
||||
|
||||
API description
|
||||
---
|
||||
## API description
|
||||
|
||||
> **Note** Omitted numeric parameters are set to 0.
|
||||
|
||||
@@ -312,14 +303,9 @@ Landing the drone (command line):
|
||||
rosservice call /land "{}"
|
||||
```
|
||||
|
||||
<!--
|
||||
### release
|
||||
> **Caution** In recent PX4 versions, the vehicle will be switched out of LAND mode to manual mode, if the remote control sticks are moved significantly.
|
||||
|
||||
Stop publishing setpoints to the drone (release control). Required to continue monitoring by means of [MAVROS](mavros.md).
|
||||
-->
|
||||
|
||||
Additional materials
|
||||
------------------------
|
||||
## Additional materials
|
||||
|
||||
* [ArUco-based position estimation and navigation](aruco.md).
|
||||
* [Program samples and snippets](snippets.md).
|
||||
|
||||
56
docs/en/simulation_m1.md
Normal file
56
docs/en/simulation_m1.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Running simulator on M1 powered computer
|
||||
|
||||
There is no preconfigured VM image for ARM64 architecture of M1 chip (Apple Silicon), so the only possibility is to install the simulation software manually.
|
||||
|
||||
The recommended virtual machine hypervisor is [UTM app](https://mac.getutm.app/). Also it's possible to use **VMware Fusion Public Tech Preview** with M1 support.
|
||||
|
||||
## Simulation installation with UTM
|
||||
|
||||
<img src="../assets/simulation_utm.png" width=500 class="center zoom">
|
||||
|
||||
1. Download UTM App from the official site [mac.getutm.app](https://mac.getutm.app/) and install it.
|
||||
2. Download Ubuntu Linux 20.04 installation iso-file for ARM64 architecture using the link: https://cdimage.ubuntu.com/focal/daily-live/current/focal-desktop-arm64.iso.
|
||||
3. Create a new virtual machine in UTM, using the following settings:
|
||||
|
||||
* **Type**: Virtualize.
|
||||
* **Operating System**: Linux.
|
||||
* **Boot ISO Image**: choose downloaded file `focal-desktop-arm64.iso`.
|
||||
* **Memory**: 4096 MB or more.
|
||||
* **CPU Cores**: 4 or more.
|
||||
* Turn on *Enable hardware OpenGL acceleration* option.
|
||||
* **Storage**: 20 GB or more.
|
||||
|
||||
4. Run the created virtual machine.
|
||||
5. Choose *Install Ubuntu* in the menu and install it using the installation master.
|
||||
|
||||
* Recommended apps: *Minimal installation*.
|
||||
* Installation type: *Erase disk and install Ubuntu*.
|
||||
* Input your account parameters, for example:
|
||||
|
||||
<img src="../assets/simulation_ubuntu_account.png" width=400 class="center zoom">
|
||||
|
||||
6. Finish the installation and run the system.
|
||||
7. Install the simulation using the [native setup manual](simulation_native.md).
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
#### Black screen
|
||||
|
||||
If you see a black screen on your virtual machine, try to run the machine without the GPU support.
|
||||
|
||||
In virtual machine settings, choose *Display*, and set *Emulated Display Card* menu to *virtio-ramfb*. Run you machine. If it runs successfully, change the setting back to *virtio-ramfb-gl (GPU Supported)* and run it again.
|
||||
|
||||
#### Problem with `git clone`
|
||||
|
||||
The following error can occur while performing `git clone`:
|
||||
|
||||
```txt
|
||||
on git clone if error: RPC failed; curl 56 GnuTLS recv error (-54): Error in the pull function.
|
||||
fatal: the remote end hung up unexpectedly
|
||||
fatal: early EOF
|
||||
fatal: index-pack failed
|
||||
```
|
||||
|
||||
In this case, change the type of the network card to bridged. In the virtual machine settings, choose *Network*, and set *Network Mode* menu to *Bridged (Advanced)*.
|
||||
|
||||
Later, if some network issues occur, change the network mode back to *Shared Network*.
|
||||
@@ -144,10 +144,10 @@ sudo systemctl start roscore
|
||||
Install any web server to serve Clover's web tools (`~/.ros/www` directory), e. g. Monkey:
|
||||
|
||||
```bash
|
||||
wget https://github.com/CopterExpress/clover_vm/raw/master/assets/packages/monkey_1.6.9-1_amd64.deb -O /tmp/monkey_1.6.9-1_amd64.deb
|
||||
sudo apt-get install -y /tmp/monkey_1.6.9-1_amd64.deb
|
||||
wget https://github.com/CopterExpress/clover_vm/raw/master/assets/packages/monkey_1.6.9-1_$(dpkg --print-architecture).deb -P /tmp
|
||||
sudo dpkg -i /tmp/monkey_*.deb
|
||||
sed "s/pi/$USER/g" ~/catkin_ws/src/clover/builder/assets/monkey | sudo tee /etc/monkey/sites/default
|
||||
sudo -E sh -c "sed -i 's/SymLink Off/SymLink On/' /etc/monkey/monkey.conf"
|
||||
sudo sed -i 's/SymLink Off/SymLink On/' /etc/monkey/monkey.conf
|
||||
sudo cp ~/catkin_ws/src/clover/builder/assets/monkey.service /etc/systemd/system/monkey.service
|
||||
sudo systemctl enable monkey
|
||||
sudo systemctl start monkey
|
||||
|
||||
@@ -25,5 +25,3 @@ Web access
|
||||
Starting with version 0.11.4 [of the image](image.md), access to the shell is also available via a web browser (using [Butterfly](https://github.com/paradoxxxzero/butterfly)). To gain access, open web page http://192.168.11.1, and select link *Open web terminal*:
|
||||
|
||||
<img src="../assets/butterfly.png">
|
||||
|
||||
**Next**: [Command-line interface](cli.md)
|
||||
|
||||
@@ -10,7 +10,7 @@ Using a multimeter, check the absence of a short circuit (check the loop):
|
||||
* Test the multimeter by shorting the probes. A unit that operated properly makes a distinctive sound.
|
||||
* The red probe is connected to the “+ ”pin, the black probe — to the “-” / ”GND” pin. If the circuit is short, a sound is heard.
|
||||
|
||||

|
||||

|
||||
|
||||
1\. Check OPEN CONDITION of the following circuits (absence of the multimeter sound signal):
|
||||
|
||||
|
||||
@@ -19,5 +19,3 @@ To edit Wi-Fi settings, or to obtain more detailed information about the network
|
||||
After connecting to Clover Wi-Fi, open http://192.168.11.1 in you web browser. It contains all the basic web tools of Clover: viewing image topics, web terminal (Butterfly), and the full copy of this documentation.
|
||||
|
||||
<img src="../assets/web.png" alt="Clover Web Interface" class="zoom">
|
||||
|
||||
**Next**: [Connecting Raspberry Pi to the flight controller](connection.md).
|
||||
|
||||
14
docs/package.json
Normal file
14
docs/package.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"@vuepress/plugin-search": "^2.0.0-beta.38",
|
||||
"glob": "^7.2.0",
|
||||
"markdown-it-attrs": "^4.1.3",
|
||||
"vuepress": "^2.0.0-beta.38",
|
||||
"vuepress-plugin-copy-code2": "^2.0.0-beta.36",
|
||||
"vuepress-plugin-sitemap2": "^2.0.0-beta.45"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vuepress dev .",
|
||||
"build": "vuepress build ."
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
# Клевер
|
||||
|
||||
<img class="center zoom big-clover" src="../assets/clover42-main.png" width="80%" alt="Клевер 4.2">
|
||||
<img class="center zoom big-clover" src="../assets/clover42-main.png" _width="80%" alt="Клевер 4.2">
|
||||
|
||||
**«Клевер»** — это учебный конструктор программируемого квадрокоптера, состоящего из популярных открытых компонентов, а также набор необходимой документации и библиотек для работы с ним.
|
||||
|
||||
|
||||
@@ -51,9 +51,10 @@
|
||||
* [Сборка на собственной машине](simulation_native.md)
|
||||
* [Установка виртуальной машины](simulation_vm.md)
|
||||
* [Использование симулятора](simulation_usage.md)
|
||||
* [Установка на компьютеры c M1](simulation_m1.md)
|
||||
* [ROS](ros.md)
|
||||
* [MAVROS](mavros.md)
|
||||
* [Дополнительные материалы](supplementary.md)
|
||||
* [Дополнительно](supplementary.md)
|
||||
* [COEX Pix](coex_pix.md)
|
||||
* [COEX PDB](coex_pdb.md)
|
||||
* [COEX GPS](coex_gps.md)
|
||||
@@ -117,7 +118,8 @@
|
||||
* [CopterHack-2017](copterhack2017.md)
|
||||
* [Конкурс видео](video_contest.md)
|
||||
* [Образовательные конкурсы](educational_contests.md)
|
||||
* [Проекты на базе Клевера](projects.md)
|
||||
* [Проекты](projects.md)
|
||||
* [Контроль соблюдения ПДД на выделенной полосе с дроном](lane_control.md)
|
||||
* [Система автоматической посадки (AMLS)](amls.md)
|
||||
* [Разработка системы для управления БПЛА с помощью шлема виртуальной реальности](remote-control-with-oculusvr.md)
|
||||
* [Шоу коптеров](clever-show.md)
|
||||
|
||||
@@ -50,7 +50,7 @@ private fun fullScreenCall() {
|
||||
|
||||
Вот так выглядит пульт на этом этапе:
|
||||
|
||||
<img src="../assets/IMG_4397.PNG" width="50%">
|
||||
<img src="../assets/IMG_4397.png" width="50%">
|
||||
|
||||
Если вы запустите приложение, то заметите что стики не работают. Это происходит по тому, что на нашей странице отключен *JavaScript*. чтобы его включить надо прописать следующее:
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ navigate(frame_id='aruco_5', x=0, y=0, z=1)
|
||||
|
||||
## Расположение маркеров на потолке
|
||||
|
||||

|
||||

|
||||
|
||||
Для навигации по маркерам, расположенным на потолке, необходимо поставить основную камеру так, чтобы она смотрела вверх и [установить соответствующий фрейм камеры](camera_setup.md#frame).
|
||||
|
||||
|
||||
@@ -125,7 +125,3 @@ rospy.spin()
|
||||
```
|
||||
|
||||
Сообщения будут содержать ID маркера, его угловые точки на изображении и его позицию (относительно камеры).
|
||||
|
||||
---
|
||||
|
||||
См. далее: [навигация по картам маркеров](aruco_map.md).
|
||||
|
||||
@@ -4,22 +4,22 @@
|
||||
|
||||
Начиная с образа версии *0.16* изменился подход к созданию карт маркеров: маркеры больше не привязаны к сетке и каждый из них теперь можно повернуть на любой угол вокруг всех трёх осей. Вместе с этим изменился и способ задания карт маркеров. Теперь карта загружается из текстового файла (подробнее в статье [**Навигация по картам ArUco-маркеров**](aruco_map.md)). Для упрощения процесса создания текстового файла был создан [*конструктор полей*](https://aruco.tenessinum.ru/).
|
||||
|
||||
<img alt="" src="../assets/arucogenmap.PNG"/>
|
||||
<img alt="" src="../assets/arucogenmap.png"/>
|
||||
|
||||
## Создание поля
|
||||
|
||||
<div style="display: flex; flex-direction: row"><img src="../assets/fieldsetup.PNG" alt=""><div style="padding-left: 20px">Перед началом работы надо задать размеры поля. Оно нужно только для удобства. Для перемещения по "полотну" используйте тачпад или колёсико мыши для перемещения по карте. При использовании мыши зажмите Shift для перемещения в горизонтальном направлении и Ctrl для увеличения/уменьшения поля.</div></div>
|
||||
<div style="display: flex; flex-direction: row"><img src="../assets/fieldsetup.png" alt=""><div style="padding-left: 20px">Перед началом работы надо задать размеры поля. Оно нужно только для удобства. Для перемещения по "полотну" используйте тачпад или колёсико мыши для перемещения по карте. При использовании мыши зажмите Shift для перемещения в горизонтальном направлении и Ctrl для увеличения/уменьшения поля.</div></div>
|
||||
|
||||
## Инструмент творения
|
||||
|
||||
<div style="display: flex; flex-direction: row; justify-content: flex-end;"><div style="padding: 20px">Нажав на плюсик в левом углу экрана откроется меню в котором можно создать какой-либо элемент.
|
||||
<ui>
|
||||
<ul>
|
||||
<li><strong>Одна метка</strong> - просто одинокая метка в поле</li>
|
||||
<li><strong>Несколько меток</strong> - группа меток выстроенная в сетку</li>
|
||||
<li><strong>Сетка - инструмент</strong> к которому можно привязывать метки</li>
|
||||
</ui></div><img src="../assets/tvorec.PNG"></div>
|
||||
</ul></div><img src="../assets/tvorec.png"></div>
|
||||
|
||||
## Экспорт
|
||||
|
||||
Карту можно экспортировать в двух форматах: ***txt*** (для Клевера) и ***svg*** (для печати)
|
||||
<img style="margin: 10px;" src="../assets/expotivka.PNG" alt=""/>
|
||||
<img style="margin: 10px;" src="../assets/expotivka.png" alt=""/>
|
||||
|
||||
@@ -339,7 +339,7 @@
|
||||
|
||||
### Сборка регуляторов
|
||||
|
||||
1. Клеим 2х сторонний скотч на основание защитного бокса регуляторов. 
|
||||
1. Клеим 2х сторонний скотч на основание защитного бокса регуляторов.
|
||||
2. Укладываем регуляторы в защитные боксы. Крепим полученную сборку к лучам рамы. 
|
||||
|
||||
### Установка защиты
|
||||
|
||||
@@ -36,7 +36,7 @@ TODO
|
||||
|
||||
Хвост от хомута (стяжки) отрезать ножницами.
|
||||
|
||||

|
||||

|
||||
|
||||
## Монтаж каркасных элементов
|
||||
|
||||
@@ -45,7 +45,7 @@ TODO
|
||||
3. Установить на раму собранную конструкцию, соблюдая схему, винтами М3х16.
|
||||
4. Установить каркас для светодиодной ленты, используя прорези в держателях для ножек.
|
||||
|
||||

|
||||

|
||||
|
||||
## Монтаж преобразователя напряжения BEC (припаять и проверить)
|
||||
|
||||
@@ -93,7 +93,7 @@ TODO
|
||||
Черный -> GND
|
||||
Синий -> Din
|
||||
|
||||

|
||||

|
||||
|
||||
## Монтаж регуляторов
|
||||
|
||||
@@ -131,7 +131,7 @@ TODO
|
||||
3. Установить плату распределения питания PDB, как показано на картинке (разъем XT60 направлен к хвосту коптера).
|
||||
4. Соединить разъемы питания платы питания и платы регуляторов XT30.
|
||||
|
||||

|
||||

|
||||
|
||||
## Сопряжение приемника и пульта
|
||||
|
||||
@@ -148,7 +148,7 @@ TODO
|
||||
* Убрать BIND разъем из приемника.
|
||||
* Отключить АКБ.
|
||||
|
||||

|
||||

|
||||
|
||||
> **Hint** Если пульт не включается или заблокирован, см.
|
||||
статью [неисправности пульта](radioerrors.md).
|
||||
@@ -168,7 +168,7 @@ TODO
|
||||
4. Проверить направления вращения мотора по схеме.Повторить для каждого мотора. Таким образом, будет понятно каким именно мотором мы управляем.
|
||||
5. Если необходимо изменить направление вращения, то меняем любые два фазных провода мотора (нужно переподключить).
|
||||
|
||||

|
||||

|
||||
|
||||
## Монтаж и подключение полетного контроллера Pixracer
|
||||
|
||||
@@ -185,7 +185,7 @@ TODO
|
||||
|
||||
4. Подключить шлейф радиоприемника в разъем RCIN в Pixracer.
|
||||
|
||||

|
||||

|
||||
|
||||
## Монтаж Raspberry
|
||||
|
||||
@@ -209,7 +209,7 @@ TODO
|
||||
|
||||
Используйте винт М3х16 и гайку М3
|
||||
|
||||

|
||||

|
||||
|
||||
## Монтаж Arduino и радиоприемника FlySky
|
||||
|
||||
@@ -223,7 +223,7 @@ TODO
|
||||
черный -> GND
|
||||
оранжевый, зеленый -> не используются. Выньте эти провода из разъёма или обрежьте их.
|
||||
|
||||

|
||||

|
||||
|
||||
## Монтаж камеры RPi
|
||||
|
||||
@@ -236,7 +236,7 @@ TODO
|
||||
|
||||
5. Установить ножки в маунты (4 шт.).
|
||||
|
||||

|
||||

|
||||
|
||||
## Монтаж остальных конструктивных элементов
|
||||
|
||||
@@ -246,13 +246,13 @@ TODO
|
||||
|
||||
Закрепить верхнюю деку винтами М3х8 (4 шт.)
|
||||
|
||||

|
||||

|
||||
|
||||
## Монтаж USB соединителей
|
||||
|
||||
1. Соедините Pixracer и Raspberry, используя micro USB - USB кабель.
|
||||
2. Соедините Arduino и Raspberry, используя micro USB - USB кабель.
|
||||
|
||||
.
|
||||
.
|
||||
|
||||
Подробнее про подключение см. [статью](connection.md).
|
||||
|
||||
@@ -22,7 +22,7 @@ sudo systemctl restart clover
|
||||
journalctl -u clover
|
||||
```
|
||||
|
||||
Для того, запустить ПО Клевера непосредственно в текущей консольной сессии, вы можете использовать `roslaunch`:
|
||||
Для того чтобы запустить ПО Клевера непосредственно в текущей консольной сессии, вы можете использовать `roslaunch`:
|
||||
|
||||
```bash
|
||||
sudo systemctl stop clover
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
### take_off
|
||||
|
||||
<img src="../assets/blocks/take-off.png" srcset="../assets/blocks/take-off.png 2x">
|
||||
<img src="../assets/blocks/take-off.png" srcset="@source/assets/blocks/take-off.png 2x">
|
||||
|
||||
Взлететь на указанную высоту в метрах. Высота может быть произвольным блоком, возвращающим числовое значение.
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
### navigate
|
||||
|
||||
<img src="../assets/blocks/navigate.png" srcset="../assets/blocks/navigate.png 2x">
|
||||
<img src="../assets/blocks/navigate.png" srcset="@source/assets/blocks/navigate.png 2x">
|
||||
|
||||
Прилететь в заданную точку. Координаты точки задаются в метрах.
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
### land
|
||||
|
||||
<img src="../assets/blocks/land.png" srcset="../assets/blocks/land.png 2x">
|
||||
<img src="../assets/blocks/land.png" srcset="@source/assets/blocks/land.png 2x">
|
||||
|
||||
Произвести посадку.
|
||||
|
||||
@@ -84,31 +84,31 @@
|
||||
|
||||
### wait
|
||||
|
||||
<img src="../assets/blocks/wait.png" srcset="../assets/blocks/wait.png 2x">
|
||||
<img src="../assets/blocks/wait.png" srcset="@source/assets/blocks/wait.png 2x">
|
||||
|
||||
Ожидать заданное время в секундах. Время ожидания может быть произвольным блоком, возвращающим числовое значение.
|
||||
|
||||
### wait_arrival
|
||||
|
||||
<img src="../assets/blocks/wait-arrival.png" srcset="../assets/blocks/wait-arrival.png 2x">
|
||||
<img src="../assets/blocks/wait-arrival.png" srcset="@source/assets/blocks/wait-arrival.png 2x">
|
||||
|
||||
Ожидать, пока дрон долетит до целевой точки (заданной в [navigate](#navigate)-блоке).
|
||||
|
||||
### get_position
|
||||
|
||||
<img src="../assets/blocks/get-position.png" srcset="../assets/blocks/get-position.png 2x">
|
||||
<img src="../assets/blocks/get-position.png" srcset="@source/assets/blocks/get-position.png 2x">
|
||||
|
||||
Блок позволяет получить позицию, скорость и угол по рысканью дрона в заданной [системе координат](#relative_to).
|
||||
|
||||
### set_effect
|
||||
|
||||
<img src="../assets/blocks/set-effect.png" srcset="../assets/blocks/set-effect.png 2x">
|
||||
<img src="../assets/blocks/set-effect.png" srcset="@source/assets/blocks/set-effect.png 2x">
|
||||
|
||||
Блок позволяет устанавливать различные анимации на LED-ленту аналогично [ROS-сервису `set_effect`](leds.md#set_effect).
|
||||
|
||||
Пример использования блока для установки случайного цвета (блоки, связанные с цветами находятся в категории *Colour*):
|
||||
|
||||
<img src="../assets/blocks/random-color.png" srcset="../assets/blocks/random-color.png 2x">
|
||||
<img src="../assets/blocks/random-color.png" srcset="@source/assets/blocks/random-color.png 2x">
|
||||
|
||||
### Работа с GPIO {#GPIO}
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
4. Последовательно устанавливайте квадрокоптер в каждую из указанных ориентаций до появления желтой рамки.
|
||||
5. Вращайте квадрокоптер по направлению стрелки до появления зеленой рамки.
|
||||
|
||||
> **Warning** Последние версии прошивки PX4 не поддерживают внутренний компас на полетном контроллере COEX Pix. При появлении ошибки *No mags found* перейдите во вкладку *Parameters*, установите параметры `SYS_HAS_MAG` в `0`, `EKF2_MAG_TYPE` в `None` и перезагрузите полетный контроллер (*Tools* => *Reboot Vehicle*).
|
||||
|
||||
Дополнительная информация: https://docs.px4.io/master/en/config/compass.html.
|
||||
|
||||
## Гироскоп
|
||||
@@ -51,5 +53,3 @@
|
||||
5. Дождитесь окончания калибровки.
|
||||
|
||||
Дополнительная информация: https://docs.px4.io/master/en/config/level_horizon_calibration.html.
|
||||
|
||||
**Далее**: [Настройка пульта](radio.md).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# COEX PDB
|
||||
|
||||
**COEX PDB** (Power Distribution Board) – плата распределения питания для квадрокоптеров <a href="assemble_4_2.md">Клевер 4</a>.
|
||||
**COEX PDB** (Power Distribution Board) – плата распределения питания для квадрокоптеров [Клевер 4](assemble_4_2.md).
|
||||
|
||||
Габаритные размеры платы: 35x35 мм.
|
||||
|
||||
|
||||
@@ -50,5 +50,3 @@
|
||||
<arg name="fcu_conn" default="udp"/>
|
||||
<arg name="fcu_ip" default="127.0.0.1"/>
|
||||
```
|
||||
|
||||
**Далее**: [Подключение QGroundControl по Wi-Fi](gcs_bridge.md).
|
||||
|
||||
@@ -12,24 +12,24 @@ CopterHack 2022 — это международный конкурс по ра
|
||||
|
||||
|Место|Команда|Проект|Балл|
|
||||
|:-:|-|-|-|
|
||||
||🇰🇬 Alatoo University Team|[Облачная платформа для симулятора Клевера](https://github.com/pteacher/clover/blob/clover_simulator/docs/ru/clover-development-studio.md)||
|
||||
||🇧🇾 FTL|[Advanced Clover 2](https://github.com/FTL-team/clover/blob/FTL-advancedClover2/docs/ru/advanced_clover_simulator.md)||
|
||||
||🇷🇺 Stereo|[Neural obstacle avoidance](https://github.com/den250400/clover/blob/neural-obstacle-avoidance/docs/en/neural-obstacle-avoidance.md)||
|
||||
||🇷🇺 Space clowns|[Copter For Space](https://github.com/slavikyd/clover/blob/patch-3/docs/ru/c4s.md)||
|
||||
||🇷🇺 R.S.|[Drone Hawk](https://github.com/slavaroot/clover/blob/droneHawkSecurity/docs/ru/drone-hawk-security.md)||
|
||||
||🇲🇾 Moopt|[IoT Water Monitoring & Optimization](https://github.com/kafechew/clover/blob/master/docs/en/moopt-uav.md)||
|
||||
||🇧🇷 Atena - Grupo SEMEAR|[Swarm in Blocks](https://github.com/Grupo-SEMEAR-USP/clover/blob/Swarm_in_Blocks/docs/en/swarm_in_blocks.md)||
|
||||
||🇷🇺 Clevertron|[Clevertron](https://github.com/Daniel-drone/clover/blob/Clevertron-1/docs/ru/clevertron.md)||
|
||||
||🇷🇺 Clover Rescue Team|[Rescue Clover](https://github.com/DevMBS/clover/blob/CloverRescueTeam/docs/ru/clover-rescue-team.md)||
|
||||
||🇵🇱 Edgenoon|[Neural and vision-based landing method](https://github.com/edgenoon-ai/clover/blob/neural_vision_based_landing_method/docs/en/neural_vision_based_landing_method.md)||
|
||||
||🇷🇺 CopterCat|[CopterCat](https://github.com/matveylapin/clover/blob/CopterCat/docs/ru/сopter_сat.md)||
|
||||
||🇷🇺 Дрой Ронов|[Clover Swarm](https://github.com/stinger000/clever/blob/clover_swarm_request/docs/ru/clover-swarm.md)||
|
||||
||🇩🇪 Inondro|[Inondro Pix](https://github.com/Inondro/clover/blob/inondro-pix/docs/en/inondro_copterhack22_pix.md)||
|
||||
||🇮🇳 DJS Phoenix|[Autonomous valet parking drone assistance](https://github.com/DJSPhoenix/clover/blob/DJSPhoenix-Ikshana/docs/en/djs_phoenix_ikshana.md)||
|
||||
||🇷🇺 SPECTRE|[SPECTRE](https://github.com/alakhmenev/clover/blob/spectre_team/docs/ru/spectre_team.md)||
|
||||
||🇷🇺 SolidEye|[Разработка лидара без движущихся частей](https://github.com/feanorgg/clover/blob/solideye/docs/ru/solid_eye.md)||
|
||||
||🇰🇬 AI_U_CLOVER|[AIU_CLOVER](https://github.com/zhibekm/clover/blob/zhibekm-patch-1/docs/en/aiu-article.md)||
|
||||
||🇷🇺 С305|[Система мониторинга воздуха](https://github.com/Ruslan2288/clover/blob/master/docs/ru/air_monitor.md)| |
|
||||
|✕|🇰🇬 Alatoo University Team|[Облачная платформа для симулятора Клевера](https://github.com/pteacher/clover/blob/clover_simulator/docs/ru/clover-development-studio.md)||
|
||||
|✕|🇷🇺 Clevertron|[Clevertron](https://github.com/Daniel-drone/clover/blob/Clevertron-1/docs/ru/clevertron.md)||
|
||||
|✕|🇵🇱 Edgenoon|[Neural and vision-based landing method](https://github.com/edgenoon-ai/clover/blob/neural_vision_based_landing_method/docs/en/neural_vision_based_landing_method.md)||
|
||||
|✕|🇩🇪 Inondro|[Inondro Pix](https://github.com/Inondro/clover/blob/inondro-pix/docs/en/inondro_copterhack22_pix.md)||
|
||||
|✕|🇷🇺 SolidEye|[Разработка лидара без движущихся частей](https://github.com/feanorgg/clover/blob/solideye/docs/ru/solid_eye.md)||
|
||||
|✕|🇰🇬 AI_U_CLOVER|[AIU_CLOVER](https://github.com/zhibekm/clover/blob/zhibekm-patch-1/docs/en/aiu-article.md)||
|
||||
|✕|🇻🇳 Dragon&Tanker|[Dragon&Tanker](https://github.com/uml4/clover/blob/drone_observe_autonomous_car/docs/en/dragon_and_tanker_team.md)||
|
||||
|✕|🇷🇺 V-NAV|[Visual Navigation](https://github.com/v-nav/clover/blob/v-nav_article/docs/ru/v-nav.md)||
|
||||
|✕|🇷🇺 Джедаи 1581|[Ретранслятор на базе Клевера](https://github.com/JJNIK/clover/blob/patch-1/docs/ru/1581.md)||
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
## Модели и сборка
|
||||
|
||||
<img class="center" src="../assets/ddrone/full_holder.png" width="300" class="zoom">
|
||||
<img class="center" src="../assets/ddrone/full_holder.png" width="300">
|
||||
|
||||
<img class="center" src="../assets/ddrone/full_holder_in_real.jpg" width="300" class="zoom">
|
||||
<img class="center" src="../assets/ddrone/full_holder_in_real.jpg" width="300">
|
||||
|
||||
Для выполнения проекта вам нужно иметь в наличии:
|
||||
|
||||
@@ -36,15 +36,15 @@
|
||||
|
||||
Вес держателя: 90 г.
|
||||
|
||||
<img class="center" src="../assets/ddrone/holder.png" width="300" class="zoom">
|
||||
<img class="center" src="../assets/ddrone/holder.png" width="300">
|
||||
|
||||
Если диаметр баллончика меньше диаметра держателя, мы используем деталь в виде дуги, размером разницей между ними. Это помогает нам устойчиво закрепить баллончик.
|
||||
|
||||
**Схема нажатия.** Для нажатия клапана будем использовать винтовую передачу с неподвижной гайкой. К сервоприводу будут прикреплена планка с отверстиями, в которых будут входить стойки, закрепленные к гайке. Это помогает сервоприводу двигаться только по одной оси, вверх вниз. Также мы смоделировали крышку для кнопки баллончика, так как поверхность насадки не ровная.
|
||||
|
||||
<img class="center" src="../assets/ddrone/pressing_mechanism.png" width="300" class="zoom">
|
||||
<img class="center" src="../assets/ddrone/pressing_mechanism.png" width="300">
|
||||
|
||||
<img class="center" src="../assets/ddrone/pressing_mechanism_in_real.jpg" width="300" class="zoom">
|
||||
<img class="center" src="../assets/ddrone/pressing_mechanism_in_real.jpg" width="300">
|
||||
|
||||
## Перед запуском
|
||||
|
||||
@@ -80,11 +80,11 @@ mv visual_ddrone-master ddrone
|
||||
|
||||
Запуск нашего дрона осуществляется с помощью [веб-сайта](https://perizatkurmanbaeva.github.io/visual_ddrone). Веб-интерфейс позволяет рисовать и кодировать нарисованное в G-code. Данные координат будут переданы для дальнейшей обработки и исполнением коптером.
|
||||
|
||||
<img class="center" src="../assets/ddrone/screen_2.png" width="600" class="zoom">
|
||||
<img class="center" src="../assets/ddrone/screen_2.png" width="600">
|
||||
|
||||
Мы выбрали веб-интерфейс для управления коптера, потому что он легче и ближе для пользователя.
|
||||
|
||||
<img class="center" src="../assets/ddrone/instruction.png" width="300" class="zoom">
|
||||
<img class="center" src="../assets/ddrone/instruction.png" width="300">
|
||||
|
||||
## Полеты
|
||||
|
||||
|
||||
@@ -79,19 +79,19 @@ PX4 может быть собран из исходников и загруже
|
||||
Для это склонируйте репозиторий PX4:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/PX4/Firmware.git
|
||||
git clone https://github.com/PX4/PX4-Autopilot.git
|
||||
```
|
||||
|
||||
Выберите необходимую версию (тэг) с помощью `git checkout`. Затем соберите и загрузите прошивку:
|
||||
|
||||
```
|
||||
make px4fmu-v4_default upload
|
||||
```bash
|
||||
make px4_fmu-v4_default upload
|
||||
```
|
||||
|
||||
Где `px4fmu-v4_default` – требуемый вариант прошивки.
|
||||
Где `px4_fmu-v4_default` – требуемый вариант прошивки.
|
||||
|
||||
Для загрузки прошивки `v3` в Pixhawk может понадобиться команда `force_upload`:
|
||||
|
||||
```
|
||||
make px4fmu-v3_default force-upload
|
||||
```bash
|
||||
make px4_fmu-v3_default force-upload
|
||||
```
|
||||
|
||||
@@ -104,5 +104,3 @@
|
||||
> **Caution** Будьте внимательны, *Kill Switch* не переводит коптер в состояние *Disarmed*!
|
||||
|
||||
Перед отключением *Kill Switch* убедитесь, что стик газа находится в нижнем положении и коптер находится в состоянии *Disarmed*. В случае, если стик газа не находится в нижнем положении, при отключении *Kill Switch* на моторы будет подан сигнал соответствующий положению стика в данный момент, что приведет к резкому рывку коптера.
|
||||
|
||||
**Далее**: [Упражнения для управления коптером](flight_exercises.md).
|
||||
|
||||
@@ -48,5 +48,3 @@ sudo systemctl restart clover
|
||||
|
||||
1. Измените параметр `gcs_bridge` на `udp-pb`.
|
||||
2. При открытии программы QGroundControl соединение должно установиться автоматически.
|
||||
|
||||
**Далее**: [Доступ по SSH](ssh.md).
|
||||
|
||||
@@ -15,5 +15,3 @@
|
||||
<img src="../assets/etcher.png" class="zoom">
|
||||
|
||||
После записи образа на SD-карту, вы можете подключаться к [Клеверу по Wi-Fi](wifi.md), использовать [беспроводное соединение в QGroundControl](gcs_bridge.md), получать [доступ по SSH](ssh.md) и использовать остальные функции. При необходимости узнать версию записанного на карту образа используйте [утилиту selfcheck.py](selfcheck.md).
|
||||
|
||||
**Далее:** [Подключение по Wi-Fi](wifi.md).
|
||||
|
||||
338
docs/ru/lane_control.md
Normal file
338
docs/ru/lane_control.md
Normal file
@@ -0,0 +1,338 @@
|
||||
# Контроль соблюдения ПДД на выделенной полосе с дроном
|
||||
|
||||
## Автор
|
||||
|
||||
- [Смирнов Даниил](https://github.com/londrwus), Telegram: [londrwus](https://t.me/londrwus).
|
||||
|
||||
## Введение
|
||||
|
||||
Автобусная полоса — это часть дороги только для пассажирского транспорта. Выделяют ее специально, чтобы горожане без машин быстрее добирались на работу и обратно домой в час пик. Благодаря выделенным полосам общественный транспорт не стоит в дорожной пробке и удобен для пассажиров. Если водитель обычной легковушки объедет по ней пробку, он получит штраф за выделенную полосу для общественного транспорта
|
||||
|
||||
## Соблюдение контроля полосы
|
||||
|
||||
На данный момент, контроль соблюдения полосы происходит с стационарных камер дорожного движения. Однако, не на всех участках дорог можно расположить подобного вида камеры или камеры могут не работать или вообще не выделять автобусную полосу. Поэтому было создано решения контроля полосы с помощью беспилотника.
|
||||
|
||||
## Объяснение кода. Написание
|
||||
|
||||
Подключаем библиотеки:
|
||||
|
||||
```python
|
||||
import rospy
|
||||
import cv2 #OpenCV
|
||||
from sensor_msgs.msg import Image
|
||||
from cv_bridge import CvBridge
|
||||
from std_srvs.srv import Trigger
|
||||
from pyzbar import pyzbar
|
||||
import numpy as np
|
||||
```
|
||||
|
||||
Создаём некоторые переменные:
|
||||
|
||||
```python
|
||||
rospy.init_node('flight')
|
||||
bridge = CvBridge()
|
||||
dict_flag = []
|
||||
detect_flag = True
|
||||
i = -1
|
||||
```
|
||||
|
||||
Для реализации контроля полосы и нахождения машин, автобусов, нам понадобится библиотека OpenCV. Создаём скриншот с изображением с основной камеры для обработки с использованием OpenCV:
|
||||
|
||||
```python
|
||||
def lane_control():
|
||||
global dict_flag, i, detect_flag, detected_blue_bus
|
||||
cv_image = bridge.imgmsg_to_cv2(rospy.wait_for_message('main_camera/image_raw', Image), 'bgr8')
|
||||
filtered_image = cv2.cvtColor(cv_image, cv2.COLOR_HSV2BGR)
|
||||
```
|
||||
|
||||
На данный момент, автобусы производятся в синем цвете. Поэтому, автобус у нас будет синего цвета.
|
||||
|
||||
<img src="../assets/lane_control_without_any_color.jpg" width="75%">
|
||||
|
||||
Прописываем диапазоны цветов для автобуса и машины:
|
||||
|
||||
```python
|
||||
# Автобус
|
||||
lower_blue = np.array([90, 60, 100])
|
||||
upper_blue = np.array([119, 255, 255])
|
||||
# Другие машины, допустим, цвет red
|
||||
lower_red = np.array([160, 20, 50])
|
||||
upper_red = np.array([190, 255, 255])
|
||||
```
|
||||
|
||||
Данный скрипт требует больших вычислительных мощностей Raspberry Pi. Для ограничения работы скрипта, мы замедляем работу камеры до частоты 10 Гц (`main_camera.launch`):
|
||||
|
||||
```xml
|
||||
<node pkg="topic_tools" name="cam_throttle" type="throttle" args="messages main_camera/image_raw 10.0 main_camera/image_raw_throttled"/>
|
||||
```
|
||||
|
||||
Топик для камеры в этом случае необходимо поменять на `main_camera/image_raw_throttled` c `main_camera/image_raw`.
|
||||
|
||||
```python
|
||||
# car
|
||||
frame = cv2.inRange(filtered_image, lower_red, upper_red)
|
||||
cnt = cv2.findContours(frame, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
||||
try:
|
||||
for c in cnt:
|
||||
moments = cv2.moments(c, 1)
|
||||
sum_pixel = moments['m01']
|
||||
|
||||
if sum_pixel >= 100000:
|
||||
dict_flag[i][1] = [sum_pixel, int(moments['m10'] / sum_pixel), int(moments['m01'] / sum_pixel)]
|
||||
detected_red_car = True
|
||||
cv2.drawContours(image_src, [c], 0, (0,255,255), 6)
|
||||
except:
|
||||
pass
|
||||
|
||||
# bus
|
||||
frame = cv2.inRange(filtered_image, lower_blue, upper_blue)
|
||||
cnt = cv2.findContours(frame, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
||||
try:
|
||||
for c in cnt:
|
||||
moments = cv2.moments(c, 1)
|
||||
sum_pixel = moments['m01']
|
||||
|
||||
if sum_pixel >= 100000:
|
||||
dict_flag[i][0] = [sum_pixel, int(moments['m10'] / sum_pixel), int(moments['m01'] / sum_pixel)]
|
||||
detected_blue_bus = True
|
||||
cv2.drawContours(image_src, [c], 0, (0,255,0), 10)
|
||||
except:
|
||||
pass
|
||||
|
||||
if detected_red_car == True:
|
||||
print("[DEBUG] detected car")
|
||||
else:
|
||||
print("[DEBUG] No cars")
|
||||
```
|
||||
|
||||
Данная программа будет определять машины по её оттенку. Вот что у нас в итоге получилось.
|
||||
|
||||
<img src="../assets/lane_control_with_color.jpg" width="75%">
|
||||
|
||||
Вот примеры других цветовых диапазонов. Стоит подметить, что цветовые диапазоны вычисляются в HSV, а не в RGB:
|
||||
|
||||
```python
|
||||
# Красный в одном диапазоне
|
||||
red_low1 = np.array([0, 40, 20])
|
||||
red_high1 = np.array([14, 255, 255])
|
||||
# Красный в другом
|
||||
red_low2 = np.array([165, 40, 20])
|
||||
red_high2 = np.array([180, 255, 255])
|
||||
# Голубой
|
||||
lower_blue = np.array([90, 100, 31])
|
||||
upper_blue = np.array([119, 255, 190])
|
||||
# Желтый
|
||||
lower_yellow = np.array([17, 55, 55])
|
||||
upper_yellow = np.array([32, 200, 200])
|
||||
#...
|
||||
```
|
||||
|
||||
Иногда надо использовать два значения HSV красного, т. к. они попадают под начало и конец диапазона HSV.
|
||||
|
||||
Данная программа будет только обнаруживать, выдавать отчет об объекте, рисовать контуры объектов. Если же мы захотим, чтобы выводить на LED-ленту нарушило ли ПДД данный объект, то можно добавить переменные и добавить функцию:
|
||||
|
||||
```python
|
||||
Led = { "red": [255, 0, 0], "blue": [0, 0, 255] }
|
||||
count_led = 72 #Если же на вашей LED-ленте 72 светодиода, если 58 - ставьте значение 58
|
||||
Led_full = [0]*count_led
|
||||
def led_print():
|
||||
global count_led, Led_full
|
||||
set_effect(r=0, g=0, b=0)
|
||||
rospy.sleep(4)
|
||||
a = []
|
||||
for i in range(count_led):
|
||||
a.append(LEDState(i, Led[Led_full[i][0]][0], Led[Led_full[i][0]][1], Led[Led_full[i][0]][2]))
|
||||
set_leds(a)
|
||||
```
|
||||
|
||||
Дополним функцию `lane_control`:
|
||||
|
||||
```python
|
||||
S = sum([ dict_flag[i][0] for j in range (len(dict_flag[i]))])
|
||||
j, k = 0, 0
|
||||
print(dict_flag[i][0][0])
|
||||
for k in range(int(dict_flag[i][0][0]/S * count_led)):
|
||||
Led_full[k+j] = ["red", dict_flag[i][0][1], dict_flag[i][0][2]]
|
||||
j+=k
|
||||
k = 0
|
||||
print(j, k )
|
||||
for k in range(int(dict_flag[i][1][0]/S * count_led)):
|
||||
Led_full[k+j] = ["blue", dict_flag[i][1][1], dict_flag[i][1][2]]
|
||||
j+=k
|
||||
k = 0
|
||||
print(j, k)
|
||||
|
||||
if abs(Led_full[0][1] - Led_full[count_led/2][1]) > 50:
|
||||
Led_full.sort(key=lambda Led_full: Led_full[1]) # сортировка по x
|
||||
else:
|
||||
Led_full.sort(key=lambda Led_full: Led_full[2]) # сортировка по y
|
||||
|
||||
print(Led_full)
|
||||
```
|
||||
|
||||
После этого наша светодиодная лента будет обозначать нарушил ли данный объект ПДД или нет.
|
||||
|
||||
Но даже после такого количества кода, наш дрон не будет следовать за нарушителем. Давайте сделаем так, чтобы дрон мог преследовать нарушителя постоянно, чтобы он не мог скрыться с места нарушения. Создадим базовые значения
|
||||
|
||||
```python
|
||||
# Библиотеки
|
||||
import tf
|
||||
import tf2_ros
|
||||
import geometry_msgs.msg
|
||||
import tf2_geometry_msgs
|
||||
import numpy as np
|
||||
from geometry_msgs.msg import Vector3Stamped, Point, PointStamped
|
||||
|
||||
ar = "aruco_13" # ID нарушителя
|
||||
tfBuffer = tf2_ros.Buffer()
|
||||
listener = tf2_ros.TransformListener(tfBuffer)
|
||||
|
||||
l_z = 2 # Для будущего кода дальномера
|
||||
|
||||
def range_callback(msg):
|
||||
global l_z
|
||||
l_z = msg.range # Вывод Z по дальномеру
|
||||
|
||||
rospy.Subscriber('rangefinder/range', Range, range_callback)
|
||||
|
||||
def get_aruco_pose(frame_id): # Возвращает координаты, с помощью преобразование нового кадра
|
||||
global tfBuffer, listener
|
||||
try:
|
||||
trans = tfBuffer.lookup_transform(frame_id, ar, rospy.Time())
|
||||
except:
|
||||
return None
|
||||
pnt_l0 = tf2_geometry_msgs.do_transform_point(PointStamped(point=Point(x=0, y=0, z=0)), trans)
|
||||
l0 = np.array([pnt_l0.point.x, pnt_l0.point.y, pnt_l0.point.z])
|
||||
return l0
|
||||
|
||||
def get_body_pose(frame_id): # Возвращает координаты, с помощью преобразование нового кадра
|
||||
global tfBuffer, listener
|
||||
try:
|
||||
trans = tfBuffer.lookup_transform(frame_id, "body", rospy.Time())
|
||||
except:
|
||||
return None
|
||||
pnt_l0 = tf2_geometry_msgs.do_transform_point(PointStamped(point=Point(x=0, y=0, z=0)), trans)
|
||||
l0 = np.array([pnt_l0.point.x, pnt_l0.point.y, pnt_l0.point.z])
|
||||
return l0
|
||||
|
||||
def remove_0_vel(vel): # Скорости полета в POSITION
|
||||
if np.linalg.norm(vel[:2]) < 0.045:
|
||||
vel[0] = 0
|
||||
vel[1] = 0
|
||||
return vel
|
||||
```
|
||||
|
||||
Создадим функцию, которая будет производить весь этот полет. Для начала сделаем так, чтобы дрон находил нарушителя.
|
||||
|
||||
```python
|
||||
def follow_violator():
|
||||
z = 1.5
|
||||
|
||||
navigate_wait(z=1.5, speed=1, frame_id="body", auto_arm = True)
|
||||
rospy.sleep(2)
|
||||
set_effect(r=255, g=255, b=0)
|
||||
print("[DEBUG] started navigation")
|
||||
navigate_wait(x=0, y=0, z=z, speed=0.8, frame_id=ar, yaw=float('nan'), tolerance=0.2)
|
||||
```
|
||||
|
||||
В итоге, мы написали код, но давайте сделаем так, чтобы он постоянно двигался за ним и улучшал его позиционирование.
|
||||
|
||||
```python
|
||||
FRQ = 5
|
||||
r = rospy.Rate(FRQ)
|
||||
prev_vel = None
|
||||
prev_pa = None
|
||||
prev_t = rospy.get_time()
|
||||
st_t = rospy.get_time()
|
||||
d = 10
|
||||
# Вычисляет на сколько надо перемещаться, за счет изменения кадров (прошлого и нынешнего)
|
||||
while d > 1 or (rospy.get_time() - st_t < 0.5):
|
||||
pb = get_body_pose("aruco_map")
|
||||
pa = get_aruco_pose("aruco_map")
|
||||
now = rospy.get_time()
|
||||
if prev_pa is None:
|
||||
if pb is None:
|
||||
r.sleep()
|
||||
continue
|
||||
navigate(x=pb[0], y=pb[1], z=z, speed=1, frame_id="aruco_map") # Снижение высоты к подлету к маркеру
|
||||
set_effect(r=150, g=0, b=255, effect='blink')
|
||||
prev_pa = pa
|
||||
prev_t = now
|
||||
else:
|
||||
if pb is not None:
|
||||
d = np.linalg.norm(pb[:1]-pa[:1])
|
||||
if pa is not None:
|
||||
set_effect(r=150, g=0, b=255)
|
||||
vel = (pa-prev_pa)/(now-prev_t+0.0001)
|
||||
vel = np.clip(vel, -0.7, 0.7)
|
||||
|
||||
vel = remove_0_vel(vel)
|
||||
if prev_vel is not None:
|
||||
vel = vel*0.1 + prev_vel*0.1
|
||||
|
||||
t = pa[:1] + vel[:1]*(0.1/FRQ)*2.7
|
||||
set_position(x=t[0], y=t[1], z=z, frame_id="aruco_map")
|
||||
prev_pa = pa.copy()
|
||||
prev_vel = vel.copy()
|
||||
prev_t = now
|
||||
else:
|
||||
navigate(x=pb[0], y=pb[1], z=z, frame_id="aruco_map")
|
||||
set_effect(r=150, g=0, b=255, effect='blink_fast')
|
||||
print("NO pa and vel")
|
||||
|
||||
r.sleep()
|
||||
|
||||
set_effect(r=255, g=150, b=0)
|
||||
z_st = 1.5
|
||||
|
||||
st_t = rospy.get_time()
|
||||
z_vel = 0.35
|
||||
|
||||
Z = z_st
|
||||
r = rospy.Rate(20)
|
||||
# Вычисляет на сколько надо изменить координату Z, за счет изменения кадров (прошлого и нынешнего) и времени
|
||||
while l_z > 0.09:
|
||||
pb = get_body_pose("aruco_map")
|
||||
pa = get_aruco_pose("aruco_map")
|
||||
now = rospy.get_time()
|
||||
if prev_pa is None:
|
||||
set_position(x=0, y=0, z=-0.01, frame_id="body")
|
||||
set_effect(r=255, g=150, b=0, effect='blink_fast')
|
||||
print("NO prev_pa")
|
||||
prev_pa = pa
|
||||
prev_t = now
|
||||
else:
|
||||
if pb is not None:
|
||||
d = np.linalg.norm(pb[:1]-pa[:1])
|
||||
if pa is not None:
|
||||
set_effect(r=255, g=150, b=0)
|
||||
if np.linalg.norm(pa - prev_pa) < 0.0001 and prev_vel is not None:
|
||||
vel = prev_vel.copy()*0.97
|
||||
else:
|
||||
vel = (pa-prev_pa)/(now-prev_t+0.0001)
|
||||
if l_z > 0.5:
|
||||
vel = np.clip(vel, -0.7, 0.7)
|
||||
else:
|
||||
vel = np.clip(vel, -0.5, 0.5)
|
||||
|
||||
vel = remove_0_vel(vel)
|
||||
if np.linalg.norm(vel[:1]) < 0.02 and d <= 0.07:
|
||||
Z = -(rospy.get_time()-st_t)*(0.1) + z_st
|
||||
else:
|
||||
Z = -(rospy.get_time()-st_t)*z_vel + z_st
|
||||
|
||||
t = pa[:1] + vel[:1]*(0.1/FRQ)*2.2
|
||||
set_position(x=t[0], y=t[1], z=Z, frame_id="aruco_map")
|
||||
prev_pa = pa.copy()
|
||||
print("Z = ", Z)
|
||||
prev_vel = vel.copy()
|
||||
prev_t = now
|
||||
else:
|
||||
set_position(x=0, y=0, z=-0.01, frame_id="body")
|
||||
set_effect(r=255, g=150, b=0, effect='blink_fast')
|
||||
print("NO pa and vel")
|
||||
|
||||
r.sleep()
|
||||
```
|
||||
|
||||
Вывод: мы написали довольно короткий, для поставленных перед ним задач, код. Данный код фиксирует правонарушение, регулирует вариативность определения транспортного средства и совершает преследование нарушителя
|
||||
@@ -75,7 +75,7 @@ from sensor_msgs.msg import Range
|
||||
|
||||
# ...
|
||||
|
||||
data = rospy.wait_for_message('rangefinder/range', Range)
|
||||
dist = rospy.wait_for_message('rangefinder/range', Range).range
|
||||
```
|
||||
|
||||
### Визуализация данных
|
||||
|
||||
@@ -101,12 +101,12 @@ disconnected: { effect: blink, r: 255, g: 50, b: 50 }
|
||||
|
||||
<table>
|
||||
<tr><th>Событие</th><th>Описание</th><th>Эффект по умолчанию</th></tr>
|
||||
<tr><td><code>startup</code></td><td>Запуск всех систем Клевера</td><td>Белый</div></td></tr>
|
||||
<tr><td><code>startup</code></td><td>Запуск всех систем Клевера</td><td>Белый</td></tr>
|
||||
<tr><td><code>connected</code></td><td>Успешное подключение к полетному контроллеру</td><td>Эффект радуги</td></tr>
|
||||
<tr><td><code>disconnected</code></td><td>Разрыв связи с полетным контроллером</td><td><div class=circle style="background:rgb(255,50,50)"></div>Мигание красным</div></td></tr>
|
||||
<tr><td><code>disconnected</code></td><td>Разрыв связи с полетным контроллером</td><td><div class=circle style="background:rgb(255,50,50)"></div>Мигание красным</td></tr>
|
||||
<tr><td><code>armed</code></td><td>Переход в состояние Armed</td><td></td></tr>
|
||||
<tr><td><code>disarmed</code></td><td>Переход в состояние Disarmed</td><td></td></tr>
|
||||
<tr><td><code>acro</code></td><td>Режим Acro</td><td><div class=circle style="background:rgb(245,155,0)"></div>Оранжевый</div></td></tr>
|
||||
<tr><td><code>acro</code></td><td>Режим Acro</td><td><div class=circle style="background:rgb(245,155,0)"></div>Оранжевый</td></tr>
|
||||
<tr><td><code>stabilized</code></td><td>Режим Stabilized</td><td><div class=circle style="background:rgb(30,180,50)"></div>Зеленый</td></tr>
|
||||
<tr><td><code>altctl</code></td><td>Режим Altitude</td><td><div class=circle style="background:rgb(255,255,40)"></div>Желтый</td></tr>
|
||||
<tr><td><code>posctl</code></td><td>Режим Position</td><td><div class=circle style="background:rgb(50,100,220)"></div>Синий</td></tr>
|
||||
@@ -158,3 +158,9 @@ rosservice call /led/set_leds "leds:
|
||||
```bash
|
||||
rostopic echo /led/state
|
||||
```
|
||||
|
||||
Используя этот же топик можно получить общее выставленное в настройках количество светодиодов:
|
||||
|
||||
```python
|
||||
led_count = len(rospy.wait_for_message('led/state', LEDStateArray, timeout=10).leds)
|
||||
```
|
||||
|
||||
@@ -63,3 +63,64 @@
|
||||
2. Стяжкой притяните собранную схему к обратной стороне деки.
|
||||
3. Сигнальный вывод Arduino *D11* вставьте в один из выводов *AUX* на полетном контроллере.
|
||||
4. Вставьте силовой вывод электромагнитного захвата в JST 5В.
|
||||
|
||||
## Настройка электромагнитного захвата
|
||||
|
||||
Для управления магнитом через плату Arduino Nano, используйте код ниже:
|
||||
|
||||
```cpp
|
||||
void setup() {
|
||||
pinMode(11, INPUT);
|
||||
pinMode(13, OUTPUT);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (int duration = pulseIn(11, HIGH) > 1200) {
|
||||
digitalWrite(13, HIGH);
|
||||
} else {
|
||||
digitalWrite(13, LOW);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Для однозначного определения статуса магнитного захвата, можно подключить светодиодную ленту типа *ws281x* (входит в наборы "Клевер"). Подключите ее к питанию +5v – 5v, земле GND – GND и сигнальный контакт DIN – Arduino D12.
|
||||
|
||||
Для управления магнитным захватом со светодиодной лентой через плату Arduino Nano используйте код ниже:
|
||||
|
||||
```cpp
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
#define NUMPIXELS 72
|
||||
#define PIN 12
|
||||
int pin = 11;
|
||||
int led = 13;
|
||||
|
||||
unsigned long duration;
|
||||
Adafruit_NeoPixel strip (NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
|
||||
|
||||
void setup() {
|
||||
strip.begin();
|
||||
strip.setBrightness(10);
|
||||
Serial.begin(9600);
|
||||
pinMode(pin, INPUT);
|
||||
pinMode(led, OUTPUT);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
duration = pulseIn(pin, HIGH);
|
||||
Serial.println(duration);
|
||||
delay(100);
|
||||
if (duration >= 1500) {
|
||||
digitalWrite(led, HIGH);
|
||||
for (int i = -1; i < NUMPIXELS; i++) {
|
||||
strip.setPixelColor(i, strip.Color(255, 0, 0));
|
||||
strip.show();
|
||||
}
|
||||
} else {
|
||||
digitalWrite(led, LOW);
|
||||
for (int i = -1; i < NUMPIXELS; i++) {
|
||||
strip.setPixelColor(i, strip.Color(0, 255, 0));
|
||||
strip.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -46,5 +46,3 @@
|
||||
* **AUTO.LAND** – коптер выполняет посадку.
|
||||
|
||||
Дополнительная информация: https://dev.px4.io/en/concept/flight_modes.html.
|
||||
|
||||
**Далее**: [Настройка питания](power.md).
|
||||
|
||||
@@ -29,7 +29,7 @@ Optical Flow публикует данные в топик `/mavros/px4flow/raw/
|
||||
* `LPE_FLW_RR` – 0.0.
|
||||
* `SENS_FLOW_ROT` – No rotation (отсутствие поворота).
|
||||
* `SENS_FLOW_MAXHGT` – 4.0 (для дальномера VL53L1X)
|
||||
* `SENS_FLOW_MINHGT` – 0.01 (для дальномера VL53L1X)
|
||||
* `SENS_FLOW_MINHGT` – 0.0 (для дальномера VL53L1X)
|
||||
* Опционально: `LPE_FUSION` – включен флажок pub agl as lpos down (см. [конфигурирование дальномера](laser.md).
|
||||
|
||||
При использовании **EKF2** (параметр `SYS_MC_EST_GROUP` = `ekf2`):
|
||||
@@ -41,7 +41,7 @@ Optical Flow публикует данные в топик `/mavros/px4flow/raw/
|
||||
* `EKF2_OF_N_MAX` - 0.2.
|
||||
* `SENS_FLOW_ROT` – No rotation (отсутствие поворота).
|
||||
* `SENS_FLOW_MAXHGT` – 4.0 (для дальномера VL53L1X)
|
||||
* `SENS_FLOW_MINHGT` – 0.01 (для дальномера VL53L1X)
|
||||
* `SENS_FLOW_MINHGT` – 0.0 (для дальномера VL53L1X)
|
||||
* Опционально: `EKF2_HGT_MODE` – range sensor (см. [конфигурирование дальномера](laser.md)).
|
||||
|
||||
Для проверки правильности всех настроек можно [воспользоваться утилитой `selfcheck.py`](selfcheck.md).
|
||||
|
||||
@@ -1,20 +1,64 @@
|
||||
# Параметры PX4
|
||||
|
||||
Основная статья: https://dev.px4.io/en/advanced/parameter_reference.html
|
||||
Полная документация по параметрам PX4: https://docs.px4.io/master/en/advanced_config/parameter_reference.html.
|
||||
|
||||
> **Note** Это описание некоторых, наиболее важных параметров PX4 по состоянию на версию 1.8.0. Полный список см. по ссылке выше.
|
||||
Для изменения параметров PX4 используйте программу QGroundControl, [подключившись к Клеверу по Wi-Fi](gcs_bridge.md) или USB. Перейдите в панель *Vehicle Setup* (кликнув на логотип QGroundControl в левом верхнем углу и выберите меню *Parameters*.
|
||||
|
||||
Для изменения параметров PX4 можно воспользоваться программой QGroundControl, [подключившись к Клеверу по Wi-Fi](gcs_bridge.md):
|
||||
## Рекомендованные значения
|
||||
|
||||

|
||||
### Общие параметры
|
||||
|
||||
## Основные параметры
|
||||
|Параметр|Значение|Примечание|
|
||||
|-|-|-|
|
||||
|`SENS_FLOW_ROT`|0 (*No rotation*)|В случае использования "железного" [PX4Flow](px4flow.md), оставьте значение по умолчанию|
|
||||
|`SENS_FLOW_MINHGT`|0.0|Для [дальномера VL53L1X](laser.md)|
|
||||
|`SENS_FLOW_MAXHGT`|4.0|Для [дальномера VL53L1X](laser.md)|
|
||||
|`SENS_FLOW_MAXR`|10.0||
|
||||
|`SYS_HAS_MAG`|0|При невозможности запуска магнитометра (ошибка *No mags found*)|
|
||||
|
||||
Наиболее важные параметры вынесены в этот параграф.
|
||||
### Настройки подсистемы Estimator
|
||||
|
||||
`SYS_MC_EST_GROUP` – выбор модуля estimator'а.
|
||||
В случае использования LPE ([прошивка COEX](firmware.md)):
|
||||
|
||||
Это группа модулей, которая вычисляет текущее состояние (state) коптера, используя показания с датчиков. В состояние коптера входит:
|
||||
|Параметр|Значение|Примечание|
|
||||
|-|-|-|
|
||||
|`LPE_FUSION`|86|Чекбоксы: *flow* + *vis* + *land Detector* + *gyro comp*. При полете над ровным полом возможно включение *pub agl as lpos down*. <br>Подробнее: [Optical Flow](optical_flow.md), [ArUco-маркеры](aruco_map.md), [GPS](gps.md).|
|
||||
|`LPE_VIS_DELAY`|0.0||
|
||||
|`LPE_VIS_Z`|0.1||
|
||||
|`LPE_FLW_SCALE`|1.0||
|
||||
|`LPE_FLW_R`|0.2||
|
||||
|`LPE_FLW_RR`|0.0||
|
||||
|`LPE_FLW_QMIN`|10||
|
||||
|`ATT_W_EXT_HDG`|0.5|Включение использования внешнего угла по рысканью (при навигации по [карте маркеров](aruco_map.md))|
|
||||
|`ATT_EXT_HDG_M`|1 (*Vision*)||
|
||||
|`ATT_W_MAG`|0|Выключение магнитометра (при навигации внутри помещения)|
|
||||
|
||||
В случае использования EKF2 (официальная прошивка):
|
||||
|
||||
<!-- markdownlint-disable MD044 -->
|
||||
|
||||
|Параметр|Значение|Примечание|
|
||||
|-|-|-|
|
||||
|`EKF2_AID_MASK`|27|Чекбоксы: (опционально) *gps* + *flow* + *vision position* + *vision yaw*.<br>Подробнее: [Optical Flow](optical_flow.md), [ArUco-маркеры](aruco_map.md), [GPS](gps.md).|
|
||||
|`EKF2_OF_DELAY`|0||
|
||||
|`EKF2_OF_QMIN`|10||
|
||||
|`EKF2_OF_N_MIN`|0.05||
|
||||
|`EKF2_OF_N_MAX`|0.2||
|
||||
|`EKF2_HGT_MODE`|2 (*Range sensor*)|При наличии [дальномера](laser.md) и полете над ровным полом|
|
||||
|`EKF2_EVA_NOISE`|0.1||
|
||||
|`EKF2_EVP_NOISE`|0.1||
|
||||
|`EKF2_EV_DELAY`|0||
|
||||
|`EKF2_MAG_TYPE`|5 (*None*)|Выключение магнитометра (при навигации внутри помещения)|
|
||||
|
||||
<!-- markdownlint-enable MD031 -->
|
||||
|
||||
> **Info** См. также: список параметров по умолчанию в [симуляторе](simulation.md): https://github.com/CopterExpress/clover/blob/master/clover_simulation/airframes/4500_clover.
|
||||
|
||||
## Дополнительная информация
|
||||
|
||||
Параметр `SYS_MC_EST_GROUP` отвечает за выбор Estimator'а.
|
||||
|
||||
Estimator это подсистема, которая вычисляет текущее состояние (state) коптера, используя показания с датчиков. В состояние коптера входит:
|
||||
|
||||
* угловая скорость коптера – pitch_rate, roll_rate, yaw_rate;
|
||||
* ориентация коптера (в локальной системе координат) – pitch (тангаж), roll (крен), yaw (рысканье) (одно из представлений);
|
||||
@@ -57,9 +101,7 @@
|
||||
|
||||
## LPE + Q attitude estimator
|
||||
|
||||
Данные параметры настраивают поведение модулей `lpe` и `q`, которые вычисляют состояние (ориентацию, позицию) коптера. Эти параметры применяются **только** если параметр `SYS_MC_EST_GROUP` установлен в значение `1` (local_position_estimator, attitude_estimator_q)
|
||||
|
||||
TODO
|
||||
Данные параметры настраивают поведение модулей `lpe` и `q`, которые вычисляют состояние (ориентацию, позицию) коптера. Эти параметры применяются **только** если параметр `SYS_MC_EST_GROUP` установлен в значение `1` (local_position_estimator, attitude_estimator_q).
|
||||
|
||||
## Commander
|
||||
|
||||
@@ -68,5 +110,3 @@ TODO
|
||||
## Sensors
|
||||
|
||||
Включение, выключение и настройка различных датчиков.
|
||||
|
||||
TODO
|
||||
|
||||
@@ -32,5 +32,3 @@
|
||||
<img src="../assets/qgc-power.png" class="zoom">
|
||||
|
||||
Дополнительная информация: https://docs.px4.io/master/en/advanced_config/esc_calibration.html.
|
||||
|
||||
**Далее**: [настройка Failsafe](failsafe.md).
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
Вы можете посмотреть короткую видеопрезентацию:
|
||||
|
||||
<iframe width="640" height="480"src="https://www.youtube.com/embed/MEJdM9arz5c" frameborder="0" ; autoplay; encrypted-media; gyroscope; picture-in-picture"> </iframe>
|
||||
<iframe width="640" height="480" src="https://www.youtube.com/embed/MEJdM9arz5c" frameborder="0" allow="autoplay; encrypted-media; gyroscope; picture-in-picture"></iframe>
|
||||
|
||||
## Использование
|
||||
|
||||
|
||||
@@ -36,5 +36,3 @@
|
||||
8. При появлении надписи *"All settings have been captured. Click Next to write the new parameters to your board"* нажмите *Next*.
|
||||
|
||||
Дополнительная информация: https://docs.qgroundcontrol.com/en/SetupView/Radio.html.
|
||||
|
||||
**Далее**: [Настройка полетных режимов](modes.md).
|
||||
|
||||
@@ -15,5 +15,3 @@ Raspberry Pi
|
||||
* HDMI-порт.
|
||||
|
||||
В Клевере Raspberry Pi подключается к полетному контроллеру и используется как вспомогательный компьютер. Он позволяет [подключаться к дрону по Wi-Fi](wifi.md), программировать автономные полеты, работать с периферией и многое другое.
|
||||
|
||||
**Далее**: [образ для Raspberry Pi](image.md).
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
Для управления Клевером со смартфона через Wi-Fi необходимо установить приложение – [iOS](https://itunes.apple.com/ru/app/clever-rc/id1396166572?mt=8), [Android](https://play.google.com/store/apps/details?id=express.copter.cleverrc).
|
||||
|
||||

|
||||

|
||||
|
||||
> **Warning** Мобильный пульт предназначен в первую очередь для полетов в помещении на дальность не более 10-15 м. Большое количество Wi-Fi сетей также может ухудшить отзывчивость и дальность пульта.
|
||||
|
||||
|
||||
@@ -66,8 +66,9 @@
|
||||
<img src="../assets/flysky_a8s/14_coexpix_rcin.png" width=300 class="zoom border center" alt="coex pix connection">
|
||||
</div>
|
||||
|
||||
> **Hint** Убедитесь, что провод, идущий в COEX Pix, подключен к порту RC IN:
|
||||
<img src="../assets/coexpix-bottom.jpg" width=300 class="zoom border center" alt="coex pix pinout">
|
||||
Убедитесь, что провод, идущий в COEX Pix, подключен к порту RC IN:
|
||||
|
||||
<img src="../assets/coex_pix/coexpix-bottom.jpg" width=300 class="zoom border center" alt="coex pix pinout">
|
||||
|
||||
## Сопряжение приёмника с пультом {#rc_bind}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
На юге Японии японский фермер и философ Масанобу Фукуока изобрел технику посадки семенных шариков. Этот метод считается естественной техникой земледелия, не требующей машин, химикатов и очень небольшого количества прополки. При использовании семенных шариков земля обрабатывается без какой-либо подготовки почвы.
|
||||
|
||||
<img src = "../assets/seeding_drone/seedcapsules/1.jpg" width="250px" class="center" />
|
||||
<img src="../assets/seeding_drone/seedcapsules/1.jpg" width="250px" class="center" />
|
||||
|
||||
### Преимущества семенных шариков
|
||||
|
||||
@@ -114,39 +114,39 @@
|
||||
|
||||
1. Установите нижние держатели бака на крепление верхней палубы и закрепите винтами M3x8.
|
||||
|
||||
<img src = "../assets/seeding_drone/mechanismpictures/1.PNG" width = "400px" class = "center" />
|
||||
<img src="../assets/seeding_drone/mechanismpictures/1.png" width="400px" class="center" />
|
||||
|
||||
2. Установите нейлоновую стойку (40 мм) с 4 сторон крепления для деки.
|
||||
|
||||
<img src = "../assets/seeding_drone/mechanismpictures/2.PNG" width = "400px" class= "center" />
|
||||
<img src="../assets/seeding_drone/mechanismpictures/2.png" width="400px" class="center" />
|
||||
|
||||
3. Установите поручень и закрепите винтами M3x8.
|
||||
|
||||
<img src = "../assets/seeding_drone/mechanismpictures/3.PNG" width = "400px" class = "center" />
|
||||
<img src="../assets/seeding_drone/mechanismpictures/3.png" width="400px" class="center" />
|
||||
|
||||
4. Установите верхние держатели бака на верхнее захватное крепление и закрепите винтами M3x8.
|
||||
|
||||
<img src = "../assets/seeding_drone/mechanismpictures/4.PNG" width = "400px" class = "center" />
|
||||
<img src="../assets/seeding_drone/mechanismpictures/4.png" width="400px" class="center" />
|
||||
|
||||
5. Осторожно подсоедините резервуары к держателям резервуаров.
|
||||
|
||||
<img src = "../assets/seeding_drone/mechanismpictures/5.PNG" width = "400px" class = "center" />
|
||||
<img src="../assets/seeding_drone/mechanismpictures/5.png" width="400px" class="center" />
|
||||
|
||||
6. Подсоедините серводвигатели SG90 к резервуару с помощью стяжки.
|
||||
|
||||
Окончательный вид сеялки дрона:
|
||||
|
||||
<img src = "../assets/seeding_drone/mechanismpictures/6.jpg" width = "400px" class = "center" />
|
||||
<img src="../assets/seeding_drone/mechanismpictures/6.jpg" width="400px" class="center" />
|
||||
|
||||
### Модуль GPS
|
||||
|
||||
Мы установили модуль GPS наверх, используя 2 нейлоновые стойки (40 мм).
|
||||
|
||||
<img src = "../assets/seeding_drone/mechanismpictures/7.jpg" alt = "" width = "400px" class = "center" />
|
||||
<img src="../assets/seeding_drone/mechanismpictures/7.jpg" alt="" width="400px" class="center" />
|
||||
|
||||
Мы покрыли аккумулятор, чтобы защитить его от холода.
|
||||
|
||||
<img src = "../assets/seeding_drone/mechanismpictures/8.jpg" alt = "" width = "400px" class = "center" />
|
||||
<img src="../assets/seeding_drone/mechanismpictures/8.jpg" alt="" width="400px" class="center" />
|
||||
|
||||
## Как управлять механизмом высева
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
|
||||
Сигнальные контакты серводвигателя подключены к контактам 32 и 33 аппаратной ШИМ Raspberry Pi, а питание снимается с платы распределения питания (5 В).
|
||||
|
||||
<img src = "../assets/seeding_drone/electronicspictures/electronic1.png" width = "400px" class = "center" />
|
||||
<img src="../assets/seeding_drone/electronicspictures/electronic1.png" width="400px" class="center" />
|
||||
|
||||
### Пояснение кода для управления серводвигателями
|
||||
|
||||
@@ -172,7 +172,7 @@
|
||||
- Угол поворота 90° или рабочий цикл 2 мс => 2/20 * 100% = рабочий цикл 10%.
|
||||
- Угол поворота 0° или рабочий цикл 1,5 мс => 1,5 / 20 * 100% = 7,5% рабочий цикл.
|
||||
|
||||
<img src = "../assets/seeding_drone/electronicspictures/electronic2.png" width = "400px" class = "center" />
|
||||
<img src="../assets/seeding_drone/electronicspictures/electronic2.png" width="400px" class="center" />
|
||||
|
||||
Мы сделаем это с помощью библиотеки RPi.GPIO и написания кода Python на Raspberry Pi.
|
||||
|
||||
|
||||
@@ -16,39 +16,32 @@
|
||||
|
||||
<img src="../assets/pix-sd.png" alt="Pixracer и MicroSD-карта" class="zoom center" width=400>
|
||||
|
||||
* Установите карту в компьютер (используйте адаптер при необходимости).
|
||||
* Отформатируйте карту в файловую систему FAT32. Для этого кликните на значок SD-карты в "Проводнике" и нажмите "Форматирование" в Windows. Используйте "Дисковую утилиту" в macOS.
|
||||
* Выполните "Безопасное извлечение" карты, извлеките карту.
|
||||
* Установите карту в полетный контроллер.
|
||||
1. Установите карту в компьютер (используйте адаптер при необходимости).
|
||||
2. Отформатируйте карту в файловую систему FAT32. Для этого кликните на значок SD-карты в "Проводнике" и нажмите "Форматирование" в Windows. Используйте "Дисковую утилиту" в macOS.
|
||||
3. Выполните "Безопасное извлечение" карты, извлеките карту.
|
||||
4. Установите карту в полетный контроллер.
|
||||
|
||||
## Загрузка прошивки в полетный контроллер
|
||||
|
||||
Основная статья: https://docs.qgroundcontrol.com/en/SetupView/Firmware.html.
|
||||
Наиболее оттестированной, в особенности для осуществления автономных полетов, является [версия прошивки с патчами COEX](firmware.md). Скачайте актуальную версию прошивки на GitHub — **<a class="latest-firmware v4" href="https://github.com/CopterExpress/Firmware/releases">скачать</a>**.
|
||||
|
||||
> **Note** Перед осуществлением перепрошивки Pixracer не должен быть подключен к компьютеру по USB.
|
||||
Для использования всех наиболее актуальных функций PX4 вы также можете использовать последнюю официальную версию прошивки (в экспериментальном режиме).
|
||||
|
||||
Для Клевера, в особенности для осуществления автономных полетов, рекомендуется использовать версию прошивки PX4 от Copter Express. Скачайте актуальную версию прошивки на GitHub — **<a class="latest-firmware v4" href="https://github.com/CopterExpress/Firmware/releases">скачать</a>**.
|
||||
1. Отключите полетный контроллер от компьютера (если он подключен).
|
||||
2. Запустите программу QGroundControl.
|
||||
3. Перейдите в панель *Vehicle Setup* (кликнув на логотип QGroundControl в левом верхнем углу) и выберите меню *Firmware*.
|
||||
4. Подключите полетный контроллер к компьютеру по USB.
|
||||
5. Выберите в появившемся меню справа *PX4 Flight Stack*.
|
||||
|
||||
> **Info** Для квадрокоптеров с Pixhawk (Клевер 2) существует отдельная версия прошивки. Подробности смотрите в статье "[Прошивка полетного контроллера](firmware.md)".
|
||||
<img src="../assets/qgc-firmware.png" alt="QGroundControl firmware upload" class="zoom">
|
||||
|
||||
Загрузите прошивку в полетный контролер:
|
||||
6. Для загрузки **прошивки COEX**:
|
||||
|
||||
<img src="../assets/qgc-firmware.png" alt="QGroundControl firmware upload" class="zoom">
|
||||
* Выберите *Advanced settings*.
|
||||
* В выпадающем меню выберите *Custom firmware file...*
|
||||
* Нажмите *OK* и выберите скаченный файл прошивки.
|
||||
|
||||
1. Запустите программу QGroundControl.
|
||||
2. Зайдите во вкладку *Vehicle Setup*.
|
||||
3. Выберите меню *Firmware*.
|
||||
4. Подключите Pixracer к компьютеру по USB.
|
||||
5. Дождитесь подключения Pixracer к QGroundControl.
|
||||
6. Выберите в меню справа *PX4 Flight Stack*.
|
||||
|
||||
Для загрузки прошивки от Copter Express (рекомендуется):
|
||||
|
||||
* Выберите *Advanced settings*.
|
||||
* В выпадающем меню выберите *Custom firmware file...*
|
||||
* Нажмите *OK* и выберите скаченный файл прошивки.
|
||||
|
||||
Для загрузки последней версии стандартной прошивки сразу нажмите *OK*.
|
||||
Для загрузки последней версии **стандартной прошивки** сразу нажмите *OK*.
|
||||
|
||||
Дождитесь, пока QGroundControl загрузит прошивку и выполнит перезагрузку полетного контроллера.
|
||||
|
||||
@@ -82,7 +75,7 @@
|
||||
|
||||
### Параметры
|
||||
|
||||
Для настройки параметров полетного контроллера войдите во вкладку *Vehicle Setup* и выберите меню *Parameters*. Вы можете использовать поле *Search* для поиска параметров по имени.
|
||||
Для настройки параметров полетного контроллера войдите во вкладку *Vehicle Setup* и выберите меню *Parameters*. Вы можете использовать поле *Search* для поиска параметров по имени. Рекомендуемые параметры для Клевера приведены в дальнейшей документации а также в соответствующей [сводной статье](parameters.md).
|
||||
|
||||
<img src="../assets/qgc-parameters.png" alt="QGroundControl parameters" class="zoom">
|
||||
|
||||
@@ -123,5 +116,3 @@
|
||||
|
||||
1. Чтобы коптер мог летать с подключением по USB, установите параметр `CBRK_USB_CHK` в 197848.
|
||||
2. Отключите проверку Safety Switch: `CBRK_IO_SAFETY` = 22027.
|
||||
|
||||
**Далее**: [Калибровка датчиков](calibration.md).
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
Автономный полет (OFFBOARD)
|
||||
===
|
||||
|
||||
> **Note** В версии образа **0.20** пакет `clever` был переименован в `clover`. Для более ранних версий см. документацию для версии [**0.19**](https://github.com/CopterExpress/clover/blob/v0.19/docs/ru/simple_offboard.md).
|
||||
|
||||
<!-- -->
|
||||
|
||||
> **Hint** Для автономных полетов рекомендуется использование [специальной сборки PX4 для Клевера](firmware.md#прошивка-для-клевера).
|
||||
# Автономный полет
|
||||
|
||||
Модуль `simple_offboard` пакета `clover` предназначен для упрощенного программирования автономного полета дрона ([режим](modes.md) `OFFBOARD`). Он позволяет устанавливать желаемые полетные задачи и автоматически трансформирует [систему координат](frames.md).
|
||||
|
||||
@@ -13,8 +6,7 @@
|
||||
|
||||
Основные сервисы – [`get_telemetry`](#gettelemetry) (получение телеметрии), [`navigate`](#navigate) (полет в заданную точку по прямой), [`navigate_global`](#navigateglobal) (полет в глобальную точку по прямой), [`land`](#land) (переход в режим посадки).
|
||||
|
||||
Использование из языка Python
|
||||
---
|
||||
## Использование из языка Python
|
||||
|
||||
Для использования сервисов, необходимо создать объекты-прокси к ним. Используйте этот шаблон для вашей программы:
|
||||
|
||||
@@ -37,8 +29,7 @@ land = rospy.ServiceProxy('land', Trigger)
|
||||
|
||||
Неиспользуемые функции-прокси можно удалить из кода.
|
||||
|
||||
Описание API
|
||||
---
|
||||
## Описание API
|
||||
|
||||
> **Note** Незаполненные числовые параметры устанавливаются в значение 0.
|
||||
|
||||
@@ -114,7 +105,7 @@ rosservice call /get_telemetry "{frame_id: ''}"
|
||||
* `auto_arm` – перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
|
||||
* `frame_id` – [система координат](frames.md), в которой заданы `x`, `y`, `z` и `yaw` (по умолчанию: `map`).
|
||||
|
||||
> **Note** Для полета без изменения угла по рысканью достаточно установить `yaw` в `NaN` (значение угловой скорости по-умолчанию – 0).
|
||||
> **Note** Для полета без изменения угла по рысканью достаточно установить `yaw` в `NaN` (значение угловой скорости по умолчанию – 0).
|
||||
|
||||
Взлет на высоту 1.5 м со скоростью взлета 0.5 м/с:
|
||||
|
||||
@@ -192,7 +183,7 @@ rosservice call /navigate "{x: 0.0, y: 0.0, z: 2, yaw: 0.0, yaw_rate: 0.0, speed
|
||||
* `auto_arm` – перевести коптер в `OFFBOARD` и заармить автоматически (**коптер взлетит**);
|
||||
* `frame_id` – [система координат](frames.md), в которой заданы `z` и `yaw` (по умолчанию: `map`).
|
||||
|
||||
> **Note** Для полета без изменения угла по рысканью достаточно установить `yaw` в `NaN` (значение угловой скорости по-умолчанию – 0).
|
||||
> **Note** Для полета без изменения угла по рысканью достаточно установить `yaw` в `NaN` (значение угловой скорости по умолчанию – 0).
|
||||
|
||||
Полет в глобальную точку со скоростью 5 м/с, оставаясь на текущей высоте (`yaw` установится в 0, коптер сориентируется передом на восток):
|
||||
|
||||
@@ -312,14 +303,9 @@ if res.success:
|
||||
rosservice call /land "{}"
|
||||
```
|
||||
|
||||
<!--
|
||||
### release
|
||||
> **Caution** В более новых версиях PX4 коптер выйдет из режима LAND в ручной режим, если сильно перемещать стики.
|
||||
|
||||
Перестать публиковать setpoint'ы коптеру (отпустить управление). Необходим для продолжения контроля средствами [MAVROS](mavros.md).
|
||||
-->
|
||||
|
||||
Дополнительные материалы
|
||||
------------------------
|
||||
## Дополнительные материалы
|
||||
|
||||
* [Полеты в поле ArUco-маркеров](aruco.md).
|
||||
* [Примеры программ и сниппеты](snippets.md).
|
||||
|
||||
56
docs/ru/simulation_m1.md
Normal file
56
docs/ru/simulation_m1.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Симулятор на компьютерах с чипом M1
|
||||
|
||||
Для архитектуры ARM64, которую используют компьютеры с чипом M1 (Apple Silicon), [готовый образ с симулятором](simulation_vm.md) не выпускается, поэтому возможна только ручная установка симулятора.
|
||||
|
||||
В качестве виртуальной машины рекомендуется использовать бесплатное приложение [**UTM**](https://mac.getutm.app/). Также возможно использование **VMware Fusion Public Tech Preview** с поддержкой M1.
|
||||
|
||||
## Установка симулятора с UTM
|
||||
|
||||
<img src="../assets/simulation_utm.png" width=500 class="center zoom">
|
||||
|
||||
1. Скачайте UTM с официального сайта [mac.getutm.app](https://mac.getutm.app/) и установите его.
|
||||
2. Скачайте исходный образ установщика Ubuntu 20.04 для архитектуры ARM64 по ссылке: https://cdimage.ubuntu.com/focal/daily-live/current/focal-desktop-arm64.iso.
|
||||
3. Создайте новую виртуальную машину в UTM, выбирая следующие настройки:
|
||||
|
||||
* **Тип**: Virtualize.
|
||||
* **Operating System** (ОС): Linux.
|
||||
* **Boot ISO Image** (образ для загрузки): выберите скаченный образ `focal-desktop-arm64.iso`.
|
||||
* **Memory** (память): 4096 MB или более.
|
||||
* **CPU Cores** (ядра процессора): 4 или более.
|
||||
* Включите поддержку OpenGL: *Enable hardware OpenGL acceleration*.
|
||||
* **Storage** (размер хранилища): 20 GB или более.
|
||||
|
||||
4. Запустите созданную виртуальную машину.
|
||||
5. Выберите пункт *Install Ubuntu* и установите Ubuntu с помощью мастера установки.
|
||||
|
||||
* Рекомендуемый набор ПО: *Minimal installation*.
|
||||
* Тип установки: *Erase disk and install Ubuntu*.
|
||||
* Введите параметры учетной записи по желанию, например:
|
||||
|
||||
<img src="../assets/simulation_ubuntu_account.png" width=400 class="center zoom">
|
||||
|
||||
6. Завершите установку и запустите установленную систему.
|
||||
7. Установите симулятор согласно [инструкции по сборке симулятора на собственной машине](simulation_native.md).
|
||||
|
||||
### Возможные проблемы при установке
|
||||
|
||||
#### Отсутствие картинки
|
||||
|
||||
Если при запуске виртуальной машины вместо изображения вы видите черный фон, попробуйте запустить машину с отключенной поддержкой GPU.
|
||||
|
||||
В настройках виртуальной машины выберите *Display*, в пункте *Emulated Display Card* выберите *virtio-ramfb*. Запустите машину. При успешном запуске поменяйте настройку обратно на *virtio-ramfb-gl (GPU Supported)* и снова запустите машину.
|
||||
|
||||
#### Проблема с `git clone`
|
||||
|
||||
При осуществлении команды `git clone` может возникнуть подобная ошибка:
|
||||
|
||||
```txt
|
||||
on git clone if error: RPC failed; curl 56 GnuTLS recv error (-54): Error in the pull function.
|
||||
fatal: the remote end hung up unexpectedly
|
||||
fatal: early EOF
|
||||
fatal: index-pack failed
|
||||
```
|
||||
|
||||
В этом случае поменяйте типа сетевой карты на Bridged. В настройках виртуальной машины выберите *Network*, в пункте *Network Mode* выберите *Bridged (Advanced)*.
|
||||
|
||||
В дальнейшем, при возникновении проблем с сетью измените тип сети обратно на *Shared Network*.
|
||||
@@ -144,10 +144,10 @@ sudo systemctl start roscore
|
||||
Установите любой веб-сервер, чтобы раздавать веб-инструменты Клевера (директория `~/.ros/www`), например, Monkey:
|
||||
|
||||
```bash
|
||||
wget https://github.com/CopterExpress/clover_vm/raw/master/assets/packages/monkey_1.6.9-1_amd64.deb -O /tmp/monkey_1.6.9-1_amd64.deb
|
||||
sudo apt-get install -y /tmp/monkey_1.6.9-1_amd64.deb
|
||||
wget https://github.com/CopterExpress/clover_vm/raw/master/assets/packages/monkey_1.6.9-1_$(dpkg --print-architecture).deb -P /tmp
|
||||
sudo dpkg -i /tmp/monkey_*.deb
|
||||
sed "s/pi/$USER/g" ~/catkin_ws/src/clover/builder/assets/monkey | sudo tee /etc/monkey/sites/default
|
||||
sudo -E sh -c "sed -i 's/SymLink Off/SymLink On/' /etc/monkey/monkey.conf"
|
||||
sudo sed -i 's/SymLink Off/SymLink On/' /etc/monkey/monkey.conf
|
||||
sudo cp ~/catkin_ws/src/clover/builder/assets/monkey.service /etc/systemd/system/monkey.service
|
||||
sudo systemctl enable monkey
|
||||
sudo systemctl start monkey
|
||||
|
||||
@@ -21,5 +21,3 @@ ssh pi@192.168.11.1
|
||||
Начиная с версии 0.11.4 [образа](image.md) доступ к шеллу также доступен через веб-браузер (с использованием [Butterfly](https://github.com/paradoxxxzero/butterfly)). Для доступа откройте страницу http://192.168.11.1 и выберите на ней ссылку *Open web terminal*:
|
||||
|
||||
<img src="../assets/butterfly.png">
|
||||
|
||||
**Далее**: [Командная строка](cli.md).
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* Проверить работу мультиметра путем замыкания щупов между собой. При корректной работе прибор издаст характерный звук.
|
||||
* Попарно красный щуп прикладывается к “+ ”контакту, черный к “-” / ”GND”. Если в цепи есть короткое замыкание, издается звук.
|
||||
|
||||

|
||||

|
||||
|
||||
1\. Прозвонить следующие цепи на НЕЗАМКНУТОСТЬ (отсутствие звукового сигнала мультиметра):
|
||||
|
||||
|
||||
@@ -18,5 +18,3 @@
|
||||
После подключения к Клеверу по адресу http://192.168.11.1 будет доступен веб-интерфейс. В нем доступны основные веб-инструменты Клевера: просмотр топиков с изображениями, веб-терминал (Butterfly) а также полная копия данной документации.
|
||||
|
||||
<img src="../assets/web.png" alt="Веб-интерфейс Клевера" class="zoom">
|
||||
|
||||
**Далее**: [Подключение Raspberry Pi к полетному контроллеру](connection.md).
|
||||
|
||||
Reference in New Issue
Block a user