mirror of
https://github.com/CopterExpress/clover.git
synced 2026-05-27 05:29:32 +00:00
Merge remote-tracking branch 'origin/master' into buster-python3
This commit is contained in:
@@ -51,6 +51,9 @@ network={
|
||||
}
|
||||
EOF
|
||||
|
||||
echo_stamp "Unblocking wireless interface"
|
||||
rfkill unblock wifi
|
||||
|
||||
NEW_HOSTNAME=$(echo ${NEW_SSID} | tr '[:upper:]' '[:lower:]')
|
||||
echo_stamp "Setting hostname to $NEW_HOSTNAME"
|
||||
hostnamectl set-hostname $NEW_HOSTNAME
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
set -e # Exit immidiately on non-zero result
|
||||
|
||||
SOURCE_IMAGE="https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2019-09-30/2019-09-26-raspbian-buster-lite.zip"
|
||||
SOURCE_IMAGE="https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2020-02-14/2020-02-13-raspbian-buster-lite.zip"
|
||||
|
||||
export DEBIAN_FRONTEND=${DEBIAN_FRONTEND:='noninteractive'}
|
||||
export LANG=${LANG:='C.UTF-8'}
|
||||
|
||||
@@ -41,7 +41,13 @@ interface wlan0
|
||||
static ip_address=192.168.11.1/24
|
||||
EOF
|
||||
|
||||
echo_stamp "#2 Write dhcp-config to /etc/dnsmasq.conf"
|
||||
echo_stamp "#2 Set wpa_supplicant country"
|
||||
|
||||
cat << EOF >> /etc/wpa_supplicant/wpa_supplicant.conf
|
||||
country=GB
|
||||
EOF
|
||||
|
||||
echo_stamp "#3 Write dhcp-config to /etc/dnsmasq.conf"
|
||||
|
||||
cat << EOF >> /etc/dnsmasq.conf
|
||||
interface=wlan0
|
||||
@@ -54,4 +60,4 @@ domain-needed
|
||||
quiet-dhcp6
|
||||
EOF
|
||||
|
||||
echo_stamp "#3 End of network installation"
|
||||
echo_stamp "#4 End of network installation"
|
||||
|
||||
@@ -155,6 +155,10 @@ cp -R node-v10.15.0-linux-armv6l/* /usr/local/
|
||||
rm -rf node-v10.15.0-linux-armv6l/
|
||||
rm node-v10.15.0-linux-armv6l.tar.gz
|
||||
|
||||
echo_stamp "Installing ptvsd"
|
||||
my_travis_retry pip install ptvsd
|
||||
my_travis_retry pip3 install ptvsd
|
||||
|
||||
echo_stamp "Add .vimrc"
|
||||
cat << EOF > /home/pi/.vimrc
|
||||
set mouse-=a
|
||||
|
||||
@@ -12,6 +12,10 @@ python3 --version
|
||||
ipython --version
|
||||
ipython3 --version
|
||||
|
||||
# ptvsd does not have a stand-alone binary
|
||||
python -m ptvsd --version
|
||||
python3 -m ptvsd --version
|
||||
|
||||
node -v
|
||||
npm -v
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<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" if="$(arg aruco_map)"/>
|
||||
<param name="cornerRefinementMethod" value="2"/>
|
||||
<param name="estimate_poses" value="true"/>
|
||||
<param name="send_tf" value="true"/>
|
||||
<param name="known_tilt" value="map"/>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<arg name="web_video_server" default="true"/>
|
||||
<arg name="rosbridge" default="true"/>
|
||||
<arg name="main_camera" default="true"/>
|
||||
<arg name="optical_flow" default="false"/>
|
||||
<arg name="optical_flow" default="true"/>
|
||||
<arg name="aruco" default="false"/>
|
||||
<arg name="rangefinder_vl53l1x" default="true"/>
|
||||
<arg name="led" default="true"/>
|
||||
@@ -35,6 +35,7 @@
|
||||
<remap from="image_raw" to="main_camera/image_raw"/>
|
||||
<remap from="camera_info" to="main_camera/camera_info"/>
|
||||
<param name="calc_flow_gyro" value="true"/>
|
||||
<param name="roi_rad" value="0.8"/>
|
||||
</node>
|
||||
|
||||
<!-- main nodelet manager -->
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<launch>
|
||||
<arg name="device" default="/dev/video1"/>
|
||||
<arg name="port" default="9999"/>
|
||||
|
||||
<node name="fpv_camera" pkg="clover" type="fpv_camera" args="$(arg device) $(arg port)" output="screen"/>
|
||||
</launch>
|
||||
@@ -1,20 +1,18 @@
|
||||
<launch>
|
||||
<!-- article about camera setup: https://clever.coex.tech/camera_frame -->
|
||||
|
||||
<arg name="direction_z" default="down"/> <!-- direction the camera points: down, up -->
|
||||
<arg name="direction_y" default="backward"/> <!-- direction the camera cable points: backward, forward -->
|
||||
|
||||
<node if="$(eval direction_z == 'down' and direction_y == 'backward')" pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 -1.5707963 0 3.1415926 base_link main_camera_optical"/>
|
||||
<node if="$(eval direction_z == 'down' and direction_y == 'forward')" pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 1.5707963 0 3.1415926 base_link main_camera_optical"/>
|
||||
<node if="$(eval direction_z == 'up' and direction_y == 'backward')" pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 0.07 1.5707963 0 0 base_link main_camera_optical"/>
|
||||
<node if="$(eval direction_z == 'up' and direction_y == 'forward')" pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 0.07 -1.5707963 0 0 base_link main_camera_optical"/>
|
||||
|
||||
<!-- Template for custom camera orientation -->
|
||||
<!-- Camera position and orientation are represented by base_link -> main_camera_optical transform -->
|
||||
<!-- static_transform_publisher arguments: x y z yaw pitch roll frame_id child_frame_id -->
|
||||
|
||||
<!-- article about camera setup: https://clover.coex.tech/camera_frame -->
|
||||
|
||||
<!-- camera is oriented downward, camera cable goes backward [option 1] -->
|
||||
<node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 -1.5707963 0 3.1415926 base_link main_camera_optical"/>
|
||||
|
||||
<!-- camera is oriented downward, camera cable goes forward [option 2] -->
|
||||
<!--<node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 1.5707963 0 3.1415926 base_link main_camera_optical"/>-->
|
||||
|
||||
<!-- camera is oriented upward, camera cable goes backward [option 3] -->
|
||||
<!--<node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 0.07 1.5707963 0 0 base_link main_camera_optical"/>-->
|
||||
|
||||
<!-- camera is oriented upward, camera cable goes forward [option 4] -->
|
||||
<!--<node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 0.07 -1.5707963 0 0 base_link main_camera_optical"/>-->
|
||||
<!-- <node pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.05 0 -0.07 -1.5707963 0 3.1415926 base_link main_camera_optical"/> -->
|
||||
|
||||
<!-- camera node -->
|
||||
<node pkg="nodelet" type="nodelet" name="main_camera" args="load cv_camera/CvCameraNodelet nodelet_manager" clear_params="true">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Usage
|
||||
# fpv_camera <video_device> <http port>
|
||||
# camera_stream <video_device> <http port>
|
||||
|
||||
echo "Starting FPV camera $1 on :$2"
|
||||
echo "Starting camera stream $1 on :$2"
|
||||
mjpg_streamer -i "/usr/lib/input_uvc.so -d $1 -r 320x240 -f 30" -o "/usr/lib/output_http.so -w /usr/share/mjpg_streamer/www -p $2"
|
||||
@@ -46,7 +46,9 @@ private:
|
||||
image_transport::CameraSubscriber img_sub_;
|
||||
image_transport::Publisher img_pub_;
|
||||
mavros_msgs::OpticalFlowRad flow_;
|
||||
int roi_, roi_2_;
|
||||
int roi_px_;
|
||||
double roi_rad_;
|
||||
cv::Rect roi_;
|
||||
Mat hann_;
|
||||
Mat prev_, curr_;
|
||||
Mat camera_matrix_, dist_coeffs_;
|
||||
@@ -63,8 +65,8 @@ private:
|
||||
|
||||
nh.param<std::string>("mavros/local_position/tf/frame_id", local_frame_id_, "map");
|
||||
nh.param<std::string>("mavros/local_position/tf/child_frame_id", fcu_frame_id_, "base_link");
|
||||
nh_priv.param("roi", roi_, 128);
|
||||
roi_2_ = roi_ / 2;
|
||||
nh_priv.param("roi", roi_px_, 128);
|
||||
nh_priv.param("roi_rad", roi_rad_, 0.0);
|
||||
nh_priv.param("calc_flow_gyro", calc_flow_gyro_, false);
|
||||
|
||||
img_sub_ = it.subscribeCamera("image_raw", 1, &OpticalFlow::flow, this);
|
||||
@@ -112,9 +114,31 @@ private:
|
||||
|
||||
auto img = cv_bridge::toCvShare(msg, "mono8")->image;
|
||||
|
||||
// Apply ROI
|
||||
if (roi_ != 0) {
|
||||
img = img(cv::Rect((msg->width / 2 - roi_2_), (msg->height / 2 - roi_2_), roi_, roi_));
|
||||
if (roi_.width == 0) { // ROI is not calculated
|
||||
// Calculate ROI
|
||||
if (roi_rad_ != 0) {
|
||||
std::vector<cv::Point3f> object_points = {
|
||||
cv::Point3f(-sin(roi_rad_ / 2), -sin(roi_rad_ / 2), cos(roi_rad_ / 2)),
|
||||
cv::Point3f(sin(roi_rad_ / 2), sin(roi_rad_ / 2), cos(roi_rad_ / 2)),
|
||||
};
|
||||
|
||||
std::vector<double> vec { 0, 0, 0 };
|
||||
std::vector<cv::Point2f> img_points;
|
||||
cv::projectPoints(object_points, vec, vec, camera_matrix_, dist_coeffs_, img_points);
|
||||
|
||||
roi_ = cv::Rect(cv::Point2i(round(img_points[0].x), round(img_points[0].y)),
|
||||
cv::Point2i(round(img_points[1].x), round(img_points[1].y)));
|
||||
|
||||
ROS_INFO("ROI: %d %d - %d %d ", roi_.tl().x, roi_.tl().y, roi_.br().x, roi_.br().y);
|
||||
|
||||
} else if (roi_px_ != 0) {
|
||||
roi_ = cv::Rect((msg->width / 2 - roi_px_ / 2), (msg->height / 2 - roi_px_ / 2), roi_px_, roi_px_);
|
||||
}
|
||||
}
|
||||
|
||||
if (roi_.width != 0) { // ROI is set
|
||||
// Apply ROI
|
||||
img = img(roi_);
|
||||
}
|
||||
|
||||
img.convertTo(curr_, CV_32F);
|
||||
|
||||
57892
clover/www/js/ros3d.js
vendored
57892
clover/www/js/ros3d.js
vendored
File diff suppressed because one or more lines are too long
1071
clover/www/js/roslib.js
vendored
1071
clover/www/js/roslib.js
vendored
File diff suppressed because it is too large
Load Diff
BIN
docs/assets/qgc-failsafe.png
Normal file
BIN
docs/assets/qgc-failsafe.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 602 KiB |
@@ -8,17 +8,17 @@
|
||||
|
||||
[**Lesson # 4** "Aerodynamics of the flight. Propeller"](https://github.com/CopterExpress/clever/blob/master/docs/en/lesson4.md)
|
||||
|
||||
[**Lesson # 5** "Brushless motors and controllers"](https://github.com/CopterExpress/clever/blob/master/docs/en/lesson5.md)
|
||||
<!--[**Lesson # 5** "Brushless motors and controllers"](https://github.com/CopterExpress/clever/blob/master/docs/en/lesson5.md)-->
|
||||
|
||||
[**Lesson 6** "Fundamentals of electromagnetism. Types of motors"](https://github.com/CopterExpress/clever/blob/master/docs/en/lesson6.md)
|
||||
|
||||
[**Lesson # 7** "Operating principle, types and design of batteries"](https://github.com/CopterExpress/clever/blob/master/docs/en/lesson7.md)
|
||||
<!--[**Lesson # 7** "Operating principle, types and design of batteries"](https://github.com/CopterExpress/clever/blob/master/docs/en/lesson7.md)
|
||||
|
||||
[**Lesson # 8** "Controlling the flight of the multicopter. The flight controller operating principle. PID ESCs"](https://github.com/CopterExpress/clever/blob/master/docs/en/lesson8.md)
|
||||
|
||||
[**Lesson # 9** "Fundamentals of radio communication. Operation principle of radio control equipment"](https://github.com/CopterExpress/clever/blob/master/docs/en/lesson9.md)
|
||||
|
||||
[**Lesson # 10** "Analog and digital video streaming. Cameras, transmitters and receivers used"](https://github.com/CopterExpress/clever/blob/master/docs/en/lesson10.md)
|
||||
[**Lesson # 10** "Analog and digital video streaming. Cameras, transmitters and receivers used"](https://github.com/CopterExpress/clever/blob/master/docs/en/lesson10.md)-->
|
||||
|
||||
## Video lessons
|
||||
|
||||
|
||||
@@ -73,8 +73,8 @@ def read_distance():
|
||||
global low
|
||||
done.clear()
|
||||
pi.gpio_trigger(TRIG, 50, 1)
|
||||
done.wait(timeout=5)
|
||||
return low / 58.0 / 100.0
|
||||
if done.wait(timeout=5):
|
||||
return low / 58.0 / 100.0
|
||||
|
||||
pi.set_mode(TRIG, pigpio.OUTPUT)
|
||||
pi.set_mode(ECHO, pigpio.INPUT)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* [Настройка пульта](radio.md)
|
||||
* [Полетные режимы](modes.md)
|
||||
* [Настройка питания](power.md)
|
||||
* [Настройка failsafe](failsafe.md)
|
||||
* Работа с Raspberry Pi
|
||||
* [Raspberry Pi](raspberry.md)
|
||||
* [Образ для RPi](image.md)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
<!-- TODO схема подключения -->
|
||||
|
||||
Дополнительным способом подключения является подключение подключение по интерйсу UART.
|
||||
Дополнительным способом подключения является подключение подключение по интерфейсу UART.
|
||||
|
||||
1. Подключите Raspberry Pi к полетному контроллеру по UART.
|
||||
2. [Подключитесь в Raspberry Pi по SSH](ssh.md).
|
||||
|
||||
13
docs/ru/failsafe.md
Normal file
13
docs/ru/failsafe.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Настройка failsafe
|
||||
|
||||
Основная статья: https://docs.px4.io/master/en/config/safety.html.
|
||||
|
||||
Во вкладке *Safety* настраиваются реакции квадрокоптера на различные нештатные ситуации. Рекомендуется включить как минимум реакцию на потерю связи с пультом управления:
|
||||
|
||||
1. Откройте вкладку *Safety*.
|
||||
2. В блоке *RC Loss Failsafe Trigger* выберите один из рекомендуемых вариантов реакции на потерю связи с пультом:
|
||||
* *Land mode* – переход в режим посадки;
|
||||
* *Terminate* – аварийное отключение моторов.
|
||||
3. В поле *RC Loss Timeout* выберите значение таймаута, по истечении которого связь с пультом считается потерянной. Рекомендуемое значение – 0.5 s.
|
||||
|
||||
<img src="../assets/qgc-failsafe.png" alt="QGroundControl failsafe" class="zoom">
|
||||
@@ -31,3 +31,5 @@
|
||||
<img src="../assets/qgc-esc.png" class="zoom">
|
||||
|
||||
Дополнительная информация: https://docs.px4.io/v1.9.0/en/advanced_config/esc_calibration.html.
|
||||
|
||||
**Далее**: [настройка Failsafe](failsafe.md).
|
||||
|
||||
@@ -73,8 +73,8 @@ def read_distance():
|
||||
global low
|
||||
done.clear()
|
||||
pi.gpio_trigger(TRIG, 50, 1)
|
||||
done.wait(timeout=5)
|
||||
return low / 58.0 / 100.0
|
||||
if done.wait(timeout=5):
|
||||
return low / 58.0 / 100.0
|
||||
|
||||
pi.set_mode(TRIG, pigpio.OUTPUT)
|
||||
pi.set_mode(ECHO, pigpio.INPUT)
|
||||
|
||||
Reference in New Issue
Block a user