Compare commits

..

12 Commits

Author SHA1 Message Date
Oleg Kalachev
d383a1c858 Minor fix 2020-10-06 02:38:29 +03:00
Oleg Kalachev
d15eb7785e Merge branch 'master' into ros-book 2020-10-06 02:31:40 +03:00
Oleg Kalachev
bb9d8edb78 Merge branch 'master' into ros-book 2020-10-06 02:23:01 +03:00
Oleg Kalachev
852b854676 Add REP abbreviation expansion 2020-08-10 21:26:13 +03:00
Oleg Kalachev
72491ade0e Update docs/ru/ros.md
Co-authored-by: Alexey Rogachevskiy <sfalexrog@gmail.com>
2020-08-07 00:41:42 +03:00
Oleg Kalachev
f5ee72940c Add timeout for wait_for_message 2020-08-06 15:36:09 +03:00
Oleg Kalachev
b6cedecdf0 Add wait_for_message info 2020-08-06 15:33:55 +03:00
Oleg Kalachev
8b1dddce67 Move working with multiple machines to ROS advanced article 2020-08-05 23:04:41 +03:00
Oleg Kalachev
a89bc82f2b Merge branch 'master' into ros-book 2020-08-05 13:48:06 +03:00
Oleg Kalachev
156527641a Continue working on ROS book 2020-08-05 13:44:32 +03:00
Oleg Kalachev
4f9e4b1a28 Merge branch 'master' into ros-book 2020-08-05 11:21:05 +03:00
Oleg Kalachev
46f8f6eb89 docs: add ROS book draft 2020-05-10 12:09:43 +03:00
603 changed files with 752 additions and 154476 deletions

View File

@@ -22,7 +22,6 @@
"ROS Kinetic", "ROS Kinetic",
"ROS Melodic", "ROS Melodic",
"OpenCV", "OpenCV",
"OpenVPN",
"Gazebo", "Gazebo",
"GitHub", "GitHub",
"FPV", "FPV",
@@ -107,9 +106,7 @@
"UDP", "UDP",
"QR", "QR",
"Li-ion", "Li-ion",
"Nvidia", "Nvidia"
"VirtualBox",
"VMware"
], ],
"code_blocks": false "code_blocks": false
}, },

View File

@@ -10,7 +10,7 @@ env:
- IMAGE_VERSION=${TRAVIS_TAG:-${TRAVIS_COMMIT:0:7}} - IMAGE_VERSION=${TRAVIS_TAG:-${TRAVIS_COMMIT:0:7}}
- IMAGE_NAME="$(basename -s '.git' ${TARGET_REPO})_${IMAGE_VERSION}.img" - IMAGE_NAME="$(basename -s '.git' ${TARGET_REPO})_${IMAGE_VERSION}.img"
git: git:
depth: 1 depth: 50
jobs: jobs:
fast_finish: true fast_finish: true
include: include:
@@ -38,7 +38,7 @@ jobs:
- cp images/*.zip imgcache - cp images/*.zip imgcache
after_success: after_success:
- sudo chmod -R 777 * - sudo chmod -R 777 *
- cd images && zip -9 ${IMAGE_NAME}.zip ${IMAGE_NAME} && stat --printf="Compressed image size:%s\n" ${IMAGE_NAME}.zip - cd images && zip ${IMAGE_NAME}.zip ${IMAGE_NAME} && stat --printf="Compressed image size:%s\n" ${IMAGE_NAME}.zip
before_deploy: before_deploy:
# Set up git user name and tag this commit # Set up git user name and tag this commit
- git config --local user.name "goldarte" - git config --local user.name "goldarte"
@@ -77,7 +77,6 @@ jobs:
- sudo sh -c "echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | debconf-set-selections" - sudo sh -c "echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | debconf-set-selections"
- sudo apt update && sudo apt install -y calibre msttcorefonts - sudo apt update && sudo apt install -y calibre msttcorefonts
- npm install gitbook-cli -g - npm install gitbook-cli -g
- gitbook fetch 3.2.3 && npm i npm@3.10.10 --prefix=~/.gitbook/versions/3.2.3/ # fixing https://travis-ci.org/github/CopterExpress/clover/jobs/766541125#L932
- npm install markdownlint-cli -g - npm install markdownlint-cli -g
- npm install svgexport -g - npm install svgexport -g
- gitbook -V - gitbook -V
@@ -88,13 +87,7 @@ jobs:
- ./check_unused_assets.py - ./check_unused_assets.py
- gitbook install - gitbook install
- gitbook build - gitbook build
- for i in 1 2 3 4; do gitbook pdf ./ _book/clover.pdf && break || sleep 1; done - gitbook pdf ./ _book/clover.pdf
- sudo apt-get install ghostscript
- gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/default -dNOPAUSE -dQUIET -dBATCH -dDetectDuplicateImages -dCompressFonts=true -r150 -sOutputFile=_book/clover_ru_compressed.pdf _book/clover_ru.pdf
- gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/default -dNOPAUSE -dQUIET -dBATCH -dDetectDuplicateImages -dCompressFonts=true -r150 -sOutputFile=_book/clover_en_compressed.pdf _book/clover_en.pdf
- 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
deploy: deploy:
provider: pages provider: pages
local_dir: _book local_dir: _book

View File

@@ -1,14 +1,12 @@
# clover🍀: create autonomous drones easily # COEX Clover Drone Kit
<img src="docs/assets/clover42-main.png" align="right" width="400px" alt="COEX Clover Drone"> <img src="docs/assets/clever4-front-white.png" align="right" width="400px" alt="Clover Drone">
Clover is an open source [ROS](https://www.ros.org)-based framework, providing user-friendly tools to control [PX4](https://px4.io)-powered drones. Clover is available as a ROS package, but is shipped mainly as a preconfigured image for Raspberry Pi. Once you've installed Raspberry Pi on your drone and flashed the image to its microSD card, taking the drone up in the air is a matter of minutes. Clover is an educational programmable drone kit consisting of an unassembled quadcopter, open source software and documentation. The kit includes Pixracer-compatible autopilot running PX4 firmware, Raspberry Pi 4 as companion computer, a camera for computer vision navigation as well as additional sensors and peripheral devices.
COEX Clover Drone is an educational programmable drone kit, suited perfectly for running clover software. The kit is shipped unassembled and includes Pixracer-compatible autopilot running PX4 firmware, Raspberry Pi 4 as a companion computer, a camera for computer vision navigation as well as additional sensors and peripheral devices. Batteries included. The main documentation is available [on Gitbook](https://clover.coex.tech/).
The main documentation is available at [https://clover.coex.tech](https://clover.coex.tech/). Official website: [coex.tech/clover](https://coex.tech/clover). Official website: <a href="https://coex.tech/clover">coex.tech/clover</a>.
[__Support us on Kickstarter!__](https://www.kickstarter.com/projects/copterexpress/cloverdrone)
## Video compilation ## Video compilation
@@ -21,7 +19,6 @@ Clover drone is used on a wide range of educational events, including [Copter Ha
Preconfigured image for Raspberry Pi with installed and configured software, ready to fly, is available [in the Releases section](https://github.com/CopterExpress/clover/releases). Preconfigured image for Raspberry Pi with installed and configured software, ready to fly, is available [in the Releases section](https://github.com/CopterExpress/clover/releases).
[![Build Status](https://travis-ci.org/CopterExpress/clover.svg?branch=master)](https://travis-ci.org/CopterExpress/clover) [![Build Status](https://travis-ci.org/CopterExpress/clover.svg?branch=master)](https://travis-ci.org/CopterExpress/clover)
![GitHub all releases](https://img.shields.io/github/downloads/CopterExpress/clover/total)
Image features: Image features:

View File

@@ -1,8 +0,0 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Changelog for package aruco_pose
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0.21.1 (2020-11-17)
-------------------
* First release of aruco_pose package to ROS
* Contributors: Alamoris, Alexey Rogachevskiy, Arthur Golubtsov, Ilya Petrov, Oleg Kalachev

View File

@@ -111,7 +111,7 @@ generate_messages(
## Generate dynamic reconfigure parameters in the 'cfg' folder ## Generate dynamic reconfigure parameters in the 'cfg' folder
generate_dynamic_reconfigure_options( generate_dynamic_reconfigure_options(
cfg/Detector.cfg cfg/DetectorParams.cfg
) )
################################### ###################################

View File

@@ -8,8 +8,6 @@ p = cv2.aruco.DetectorParameters_create()
gen = ParameterGenerator() gen = ParameterGenerator()
gen.add("enabled", bool_t, 0, "if detection enabled", True)
gen.add("adaptiveThreshConstant", double_t, 0, gen.add("adaptiveThreshConstant", double_t, 0,
"Constant for adaptive thresholding before finding contours", "Constant for adaptive thresholding before finding contours",
p.adaptiveThreshConstant, 0, 100) p.adaptiveThreshConstant, 0, 100)

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<package format="2"> <package format="2">
<name>aruco_pose</name> <name>aruco_pose</name>
<version>0.21.1</version> <version>0.0.1</version>
<description>Positioning with ArUco markers</description> <description>Positioning with ArUco markers</description>
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer> <maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>

View File

@@ -62,7 +62,6 @@ private:
std::unique_ptr<tf2_ros::Buffer> tf_buffer_; std::unique_ptr<tf2_ros::Buffer> tf_buffer_;
std::unique_ptr<tf2_ros::TransformListener> tf_listener_; std::unique_ptr<tf2_ros::TransformListener> tf_listener_;
std::shared_ptr<dynamic_reconfigure::Server<aruco_pose::DetectorConfig>> dyn_srv_; std::shared_ptr<dynamic_reconfigure::Server<aruco_pose::DetectorConfig>> dyn_srv_;
bool enabled_ = true;
cv::Ptr<cv::aruco::Dictionary> dictionary_; cv::Ptr<cv::aruco::Dictionary> dictionary_;
cv::Ptr<cv::aruco::DetectorParameters> parameters_; cv::Ptr<cv::aruco::DetectorParameters> parameters_;
image_transport::Publisher debug_pub_; image_transport::Publisher debug_pub_;
@@ -129,8 +128,6 @@ public:
private: private:
void imageCallback(const sensor_msgs::ImageConstPtr& msg, const sensor_msgs::CameraInfoConstPtr &cinfo) void imageCallback(const sensor_msgs::ImageConstPtr& msg, const sensor_msgs::CameraInfoConstPtr &cinfo)
{ {
if (!enabled_) return;
Mat image = cv_bridge::toCvShare(msg, "bgr8")->image; Mat image = cv_bridge::toCvShare(msg, "bgr8")->image;
vector<int> ids; vector<int> ids;
@@ -359,7 +356,6 @@ private:
void paramCallback(aruco_pose::DetectorConfig &config, uint32_t level) void paramCallback(aruco_pose::DetectorConfig &config, uint32_t level)
{ {
enabled_ = config.enabled;
parameters_->adaptiveThreshConstant = config.adaptiveThreshConstant; parameters_->adaptiveThreshConstant = config.adaptiveThreshConstant;
parameters_->adaptiveThreshWinSizeMin = config.adaptiveThreshWinSizeMin; parameters_->adaptiveThreshWinSizeMin = config.adaptiveThreshWinSizeMin;
parameters_->adaptiveThreshWinSizeMax = config.adaptiveThreshWinSizeMax; parameters_->adaptiveThreshWinSizeMax = config.adaptiveThreshWinSizeMax;

View File

@@ -1,4 +1,4 @@
# Information: https://clover.coex.tech/aruco # Information: https://clover.coex.tech/en/aruco.html
import rospy import rospy
from clover import srv from clover import srv

View File

@@ -1,11 +0,0 @@
# Information: https://clover.coex.tech/en/simple_offboard.html#gettelemetry
import rospy
from clover import srv
rospy.init_node('flight')
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)
# Print drone's state
print(get_telemetry())

View File

@@ -1,4 +1,4 @@
# Information: https://clover.coex.tech/led # Information: https://clover.coex.tech/en/leds.html
import rospy import rospy
from clover.srv import SetLEDEffect from clover.srv import SetLEDEffect
@@ -7,25 +7,19 @@ rospy.init_node('leds')
set_effect = rospy.ServiceProxy('led/set_effect', SetLEDEffect) # define proxy to ROS-service set_effect = rospy.ServiceProxy('led/set_effect', SetLEDEffect) # define proxy to ROS-service
print('Fill red')
set_effect(r=255, g=0, b=0) # fill strip with red color set_effect(r=255, g=0, b=0) # fill strip with red color
rospy.sleep(2) rospy.sleep(2)
print('Fill green')
set_effect(r=0, g=100, b=0) # fill strip with green color set_effect(r=0, g=100, b=0) # fill strip with green color
rospy.sleep(2) rospy.sleep(2)
print('Fade to blue')
set_effect(effect='fade', r=0, g=0, b=255) # fade to blue color set_effect(effect='fade', r=0, g=0, b=255) # fade to blue color
rospy.sleep(2) rospy.sleep(2)
print('Flash red')
set_effect(effect='flash', r=255, g=0, b=0) # flash twice with red color set_effect(effect='flash', r=255, g=0, b=0) # flash twice with red color
rospy.sleep(2) rospy.sleep(5)
print('Blink white')
set_effect(effect='blink', r=255, g=255, b=255) # blink with white color set_effect(effect='blink', r=255, g=255, b=255) # blink with white color
rospy.sleep(5) rospy.sleep(5)
print('Rainbow')
set_effect(effect='rainbow') # show rainbow set_effect(effect='rainbow') # show rainbow

View File

@@ -65,7 +65,7 @@ echo_stamp "#6 Turn on UART"
# https://github.com/RPi-Distro/raspi-config/pull/75 # https://github.com/RPi-Distro/raspi-config/pull/75
/usr/bin/raspi-config nonint do_serial 1 /usr/bin/raspi-config nonint do_serial 1
/usr/bin/raspi-config nonint set_config_var enable_uart 1 /boot/config.txt /usr/bin/raspi-config nonint set_config_var enable_uart 1 /boot/config.txt
echo dtoverlay=pi3-disable-bt >> /boot/config.txt /usr/bin/raspi-config nonint set_config_var dtoverlay pi3-disable-bt /boot/config.txt
systemctl disable hciuart.service systemctl disable hciuart.service
# After adding to Raspbian OS # After adding to Raspbian OS
@@ -79,14 +79,4 @@ if ! grep -q "^bcm2835-v4l2" /etc/modules;
then printf "bcm2835-v4l2\n" >> /etc/modules then printf "bcm2835-v4l2\n" >> /etc/modules
fi fi
echo_stamp "#8 Check if Compute Module 4" echo_stamp "#8 End of configure hardware interfaces"
if grep -q "Compute Module 4" "/proc/device-tree/model"; then
echo_stamp "Enable USB on Compute Module 4"
echo "dtoverlay=dwc2,dr_mode=host" >> /boot/config.txt
echo_stamp "Enable OV7251 camera overlay"
echo "#dtoverlay=ov7251 # OV7251 camera on CAM1" >> /boot/config.txt
echo "dtoverlay=ov7251cam0 # OV7251 camera on CAM0" >> /boot/config.txt
fi
echo_stamp "#9 End of configure hardware interfaces"

View File

@@ -1,111 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
// Definitions for OV7251 camera module on VC I2C bus
/dts-v1/;
/plugin/;
//#include <dt-bindings/gpio/gpio.h>
/{
compatible = "brcm,bcm2835";
fragment@0 {
target = <&i2c_vc>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
ov7251: ov7251@60 {
compatible = "ovti,ov7251";
reg = <0x60>;
status = "okay";
clocks = <&ov7251_clk>;
clock-names = "xclk";
clock-frequency = <24000000>;
vdddo-supply = <&ov7251_dovdd>;
vdda-supply = <&ov7251_avdd>;
vddd-supply = <&ov7251_dvdd>;
enable-gpios = <&gpio 41 0>;
port {
ov7251_0: endpoint {
remote-endpoint = <&csi0_ep>;
clock-lanes = <0>;
data-lanes = <1>;
clock-noncontinuous;
link-frequencies =
/bits/ 64 <456000000>;
};
};
};
};
};
fragment@1 {
target = <&csi0>;
__overlay__ {
status = "okay";
port {
csi0_ep: endpoint {
remote-endpoint = <&ov7251_0>;
data-lanes = <1>;
};
};
};
};
fragment@2 {
target = <&i2c0if>;
__overlay__ {
status = "okay";
};
};
fragment@3 {
target-path="/";
__overlay__ {
ov7251_avdd: fixedregulator@0 {
compatible = "regulator-fixed";
regulator-name = "ov7251_avdd";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
};
ov7251_dovdd: fixedregulator@1 {
compatible = "regulator-fixed";
regulator-name = "ov7251_dovdd";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
ov7251_dvdd: fixedregulator@2 {
compatible = "regulator-fixed";
regulator-name = "ov7251_dvdd";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
};
ov7251_clk: ov7251-clk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24000000>;
};
};
};
fragment@4 {
target = <&i2c0mux>;
__overlay__ {
status = "okay";
};
};
fragment@5 {
target-path="/__overrides__";
__overlay__ {
cam0-pwdn-ctrl = <&ov7251>,"enable-gpios:0";
cam0-pwdn = <&ov7251>,"enable-gpios:4";
};
};
};

View File

@@ -15,8 +15,7 @@
set -e # Exit immidiately on non-zero result set -e # Exit immidiately on non-zero result
# https://www.raspberrypi.org/software/operating-systems/#raspberry-pi-os-32-bit SOURCE_IMAGE="https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2020-02-14/2020-02-13-raspbian-buster-lite.zip"
SOURCE_IMAGE="https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2021-03-25/2021-03-04-raspios-buster-armhf-lite.zip"
export DEBIAN_FRONTEND=${DEBIAN_FRONTEND:='noninteractive'} export DEBIAN_FRONTEND=${DEBIAN_FRONTEND:='noninteractive'}
export LANG=${LANG:='C.UTF-8'} export LANG=${LANG:='C.UTF-8'}
@@ -103,12 +102,10 @@ ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/rsysrot
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/butterfly.service' '/lib/systemd/system/' ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/butterfly.service' '/lib/systemd/system/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/butterfly.socket' '/lib/systemd/system/' ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/butterfly.socket' '/lib/systemd/system/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/monkey.service' '/lib/systemd/system/' ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/monkey.service' '/lib/systemd/system/'
# build hardware drivers
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-hardware.sh'
# software install # software install
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-software.sh' ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-software.sh'
# examples # examples
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/examples' '/home/pi/' # TODO: symlink? ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/examples' '/home/pi/'
# network setup # network setup
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-network.sh' ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-network.sh'
# avahi setup # avahi setup

View File

@@ -1,9 +0,0 @@
#! /usr/bin/env bash
set -ex
echo "Build overlay for OV7251 camera on CAM0"
# TODO: check Raspberry Pi OS version /boot/issue.txt
dtc -I dts -O dtb -o /boot/overlays/ov7251cam0.dtbo /home/pi/catkin_ws/src/clover/builder/assets/ov7251cam0-overlay.dts

View File

@@ -60,24 +60,4 @@ domain-needed
quiet-dhcp6 quiet-dhcp6
EOF EOF
echo_stamp "#4 Build the RTL8814AU Wi-Fi adapter driver" echo_stamp "#4 End of network installation"
cd /home/pi
git clone https://github.com/aircrack-ng/rtl8812au.git --depth=1
cd rtl8812au
echo kernel version: $(uname -r)
echo kernel version from procfs: $(cat /proc/version)
echo version: $(git describe --tags --always)
sed -i 's/CONFIG_PLATFORM_I386_PC = y/CONFIG_PLATFORM_I386_PC = n/g' Makefile # https://github.com/aircrack-ng/rtl8812au#for-raspberry-rpi
sed -i 's/CONFIG_PLATFORM_ARM_RPI = n/CONFIG_PLATFORM_ARM_RPI = y/g' Makefile
# sed -i 's/CONFIG_PLATFORM_ARM64_RPI = n/CONFIG_PLATFORM_ARM64_RPI = y/g' Makefile
apt-cache policy raspberrypi-kernel-headers
apt-get install -y raspberrypi-kernel-headers dkms
ls /lib/modules
KERNEL_VERSION=$(cd /lib/modules && echo *-v7l+) # can't use `uname` as it gives incorrect value in emulated environment
echo make
make KERNEL_VER=$KERNEL_VERSION KVER=$KERNEL_VERSION
echo make install
make install KERNEL_VER=$KERNEL_VERSION KVER=$KERNEL_VERSION
# TODO: rm -rf /home/pi/rtl8812au
echo_stamp "#5 End of network installation"

View File

@@ -76,11 +76,9 @@ my_travis_retry sudo -u pi rosdep update
export ROS_IP='127.0.0.1' # needed for running tests export ROS_IP='127.0.0.1' # needed for running tests
# echo_stamp "Reconfiguring Clover repository for simplier unshallowing" # TODO: bring back echo_stamp "Reconfiguring Clover repository for simplier unshallowing"
# cd /home/pi/catkin_ws/src/clover cd /home/pi/catkin_ws/src/clover
# git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
echo_stamp "Remove .git from Clover to reduce the size"
rm -rf /home/pi/catkin_ws/src/clover/.git # TODO: remove
echo_stamp "Build and install Clover" echo_stamp "Build and install Clover"
cd /home/pi/catkin_ws cd /home/pi/catkin_ws
@@ -101,7 +99,6 @@ rm -rf build # remove build artifacts
echo_stamp "Build Clover documentation" echo_stamp "Build Clover documentation"
cd /home/pi/catkin_ws/src/clover cd /home/pi/catkin_ws/src/clover
NPM_CONFIG_UNSAFE_PERM=true npm install gitbook-cli -g NPM_CONFIG_UNSAFE_PERM=true npm install gitbook-cli -g
NPM_CONFIG_UNSAFE_PERM=true gitbook fetch 3.2.3 && npm i npm@3.10.10 --prefix=~/.gitbook/versions/3.2.3/ # fixing https://travis-ci.org/github/CopterExpress/clover/jobs/766541125#L932
NPM_CONFIG_UNSAFE_PERM=true gitbook install NPM_CONFIG_UNSAFE_PERM=true gitbook install
gitbook build gitbook build
touch node_modules/CATKIN_IGNORE docs/CATKIN_IGNORE _book/CATKIN_IGNORE clover/www/CATKIN_IGNORE apps/CATKIN_IGNORE # ignore documentation files by catkin touch node_modules/CATKIN_IGNORE docs/CATKIN_IGNORE _book/CATKIN_IGNORE clover/www/CATKIN_IGNORE apps/CATKIN_IGNORE # ignore documentation files by catkin
@@ -133,9 +130,6 @@ catkin_make run_tests #&& catkin_test_results
echo_stamp "Change permissions for catkin_ws" echo_stamp "Change permissions for catkin_ws"
chown -Rf pi:pi /home/pi/catkin_ws chown -Rf pi:pi /home/pi/catkin_ws
echo_stamp "Change permissions for examples"
chown -Rf pi:pi /home/pi/examples
echo_stamp "Setup ROS environment" echo_stamp "Setup ROS environment"
cat << EOF >> /home/pi/.bashrc cat << EOF >> /home/pi/.bashrc
LANG='C.UTF-8' LANG='C.UTF-8'

View File

@@ -82,7 +82,6 @@ apt-get update
# Let's retry fetching those packages several times, just in case # Let's retry fetching those packages several times, just in case
echo_stamp "Software installing" echo_stamp "Software installing"
my_travis_retry apt-get install --no-install-recommends -y cmake-data=3.13.4-1 cmake=3.13.4-1 # FIXME: using older CMake due to https://travis-ci.org/github/CopterExpress/clover/jobs/764367665#L6984
my_travis_retry apt-get install --no-install-recommends -y \ my_travis_retry apt-get install --no-install-recommends -y \
unzip \ unzip \
zip \ zip \
@@ -95,8 +94,8 @@ lsof \
git \ git \
dnsmasq \ dnsmasq \
tmux \ tmux \
tree \
vim \ vim \
cmake \
libjpeg8 \ libjpeg8 \
tcpdump \ tcpdump \
ltrace \ ltrace \
@@ -111,6 +110,7 @@ libffi-dev \
monkey \ monkey \
pigpio python-pigpio python3-pigpio \ pigpio python-pigpio python3-pigpio \
i2c-tools \ i2c-tools \
espeak espeak-data python-espeak \
ntpdate \ ntpdate \
python-dev \ python-dev \
python3-dev \ python3-dev \
@@ -124,10 +124,9 @@ sed -i "s/updates_available//" /usr/share/byobu/status/status
echo_stamp "Installing pip" echo_stamp "Installing pip"
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip2.py
python3 get-pip.py python3 get-pip.py
python get-pip2.py python get-pip.py
rm get-pip.py get-pip2.py rm get-pip.py
#my_travis_retry pip install --upgrade pip #my_travis_retry pip install --upgrade pip
#my_travis_retry pip3 install --upgrade pip #my_travis_retry pip3 install --upgrade pip
@@ -137,7 +136,6 @@ pip3 --version
echo_stamp "Install and enable Butterfly (web terminal)" echo_stamp "Install and enable Butterfly (web terminal)"
echo_stamp "Workaround for tornado >= 6.0 breaking butterfly" echo_stamp "Workaround for tornado >= 6.0 breaking butterfly"
export CRYPTOGRAPHY_DONT_BUILD_RUST=1
my_travis_retry pip3 install tornado==5.1.1 my_travis_retry pip3 install tornado==5.1.1
my_travis_retry pip3 install butterfly my_travis_retry pip3 install butterfly
my_travis_retry pip3 install butterfly[systemd] my_travis_retry pip3 install butterfly[systemd]
@@ -149,7 +147,6 @@ my_travis_retry pip install --prefer-binary rpi_ws281x
echo_stamp "Setup Monkey" echo_stamp "Setup Monkey"
mv /etc/monkey/sites/default /etc/monkey/sites/default.orig mv /etc/monkey/sites/default /etc/monkey/sites/default.orig
mv /root/monkey /etc/monkey/sites/default mv /root/monkey /etc/monkey/sites/default
sed -i 's/SymLink Off/SymLink On/' /etc/monkey/monkey.conf
systemctl enable monkey.service systemctl enable monkey.service
echo_stamp "Install Node.js" echo_stamp "Install Node.js"

View File

@@ -5,7 +5,7 @@ set -e
# Step 1: Install pip # Step 1: Install pip
apt update apt update
apt install -y curl apt install -y curl
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python ./get-pip.py python ./get-pip.py
# Step 1.5: Add deb.coex.tech to apt # Step 1.5: Add deb.coex.tech to apt
@@ -41,6 +41,3 @@ pip install --upgrade pytest
cd /root/catkin_ws cd /root/catkin_ws
source devel/setup.bash source devel/setup.bash
catkin_make run_tests && catkin_test_results catkin_make run_tests && catkin_test_results
# Step 5: Install packages
catkin_make install

View File

@@ -25,7 +25,7 @@ import pymavlink
from pymavlink import mavutil from pymavlink import mavutil
import rpi_ws281x import rpi_ws281x
import pigpio import pigpio
# from espeak import espeak from espeak import espeak
from pyzbar import pyzbar from pyzbar import pyzbar
print cv2.getBuildInformation() print cv2.getBuildInformation()

View File

@@ -32,7 +32,7 @@ monkey --version
pigpiod -v pigpiod -v
i2cdetect -V i2cdetect -V
butterfly -h butterfly -h
# espeak --version espeak --version
mjpg_streamer --version mjpg_streamer --version
# ros stuff # ros stuff
@@ -43,8 +43,6 @@ rosversion aruco_pose
rosversion vl53l1x rosversion vl53l1x
rosversion mavros rosversion mavros
rosversion mavros_extras rosversion mavros_extras
rosversion ws281x
rosversion led_msgs
rosversion dynamic_reconfigure rosversion dynamic_reconfigure
rosversion tf2_web_republisher rosversion tf2_web_republisher
rosversion compressed_image_transport rosversion compressed_image_transport

View File

@@ -4,9 +4,7 @@ import os
import sys import sys
import subprocess import subprocess
EXCLUDE = ('clever4-front-white.png', 'clever4-front-white-large.png', '.DS_Store', EXCLUDE = ('clever4-front-white.png', '.DS_Store', 'clever4-front-black-large.png')
'clever4-front-black-large.png','clover42-black.png')
code = 0 code = 0
os.chdir('./docs') os.chdir('./docs')

View File

@@ -1,8 +0,0 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Changelog for package clover
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0.21.1 (2020-11-17)
-------------------
* First release of clover package to ROS
* Contributors: Alexey Rogachevskiy, Arthur Golubtsov, Oleg Kalachev

View File

@@ -44,12 +44,16 @@ Alternatively you may change the `fcu_url` property in `mavros.launch` file to p
## Running ## Running
To start connection to SITL, use:
```bash
roslaunch clover sitl.launch
```
To start connection to the flight controller, use: To start connection to the flight controller, use:
```bash ```bash
roslaunch clover clover.launch roslaunch clover clover.launch
``` ```
For the simulation information see the [corresponding article](https://clover.coex.tech/en/simulation.html).
> Note that the package is configured to connect to `/dev/px4fmu` by default (see [previous section](#manual-installation)). Install udev rules or specify path to your FCU device in `mavros.launch`. > Note that the package is configured to connect to `/dev/px4fmu` by default (see [previous section](#manual-installation)). Install udev rules or specify path to your FCU device in `mavros.launch`.

View File

@@ -1,20 +0,0 @@
image_width: 640
image_height: 480
distortion_model: rational_polynomial
camera_name: main_camera_optical
camera_matrix:
rows: 3
cols: 3
data: [ 279.33, 0, 304.288, 0, 280.417, 268.697, 0, 0, 1, ]
distortion_coefficients:
rows: 1
cols: 14
data: [ 0.155023, -0.0432218, 0.00152622, 6.48563e-05, 0.00390709, 0.495321, -0.0748121, 0.00553976, 0, 0, 0, 0, 0, 0, ]
rectification_matrix:
rows: 3
cols: 3
data: [ 1, 0, 0, 0, 1, 0, 0, 0, 1, ]
projection_matrix:
rows: 3
cols: 4
data: [ 279.33, 0, 304.288, 0, 0, 280.417, 268.697, 0, 0, 0, 1, 0, ]

View File

@@ -12,6 +12,7 @@
<arg name="led" default="true"/> <arg name="led" default="true"/>
<arg name="blocks" default="false"/> <arg name="blocks" default="false"/>
<arg name="rc" default="true"/> <arg name="rc" default="true"/>
<arg name="shell" default="true"/>
<arg name="simulator" default="false"/> <!-- flag that we are operating on a simulated drone --> <arg name="simulator" default="false"/> <!-- flag that we are operating on a simulated drone -->
@@ -90,6 +91,9 @@
<param name="use_fake_gcs" value="false"/> <param name="use_fake_gcs" value="false"/>
</node> </node>
<!-- Shell access through ROS service -->
<node name="shell" pkg="clover" type="shell" output="screen" if="$(arg shell)"/>
<!-- Update static directory --> <!-- Update static directory -->
<node pkg="roswww_static" name="roswww_static" type="main.py" clear_params="true"> <node pkg="roswww_static" name="roswww_static" type="main.py" clear_params="true">
<param name="default_package" value="clover"/> <param name="default_package" value="clover"/>

View File

@@ -2,17 +2,14 @@
<arg name="ws281x" default="true"/> <arg name="ws281x" default="true"/>
<arg name="led_effect" default="true"/> <arg name="led_effect" default="true"/>
<arg name="led_notify" default="true"/> <arg name="led_notify" default="true"/>
<arg name="led_count" default="72"/>
<arg name="gpio_pin" default="21"/>
<arg name="simulator" default="false"/> <arg name="simulator" default="false"/>
<!-- For additional help go to https://clover.coex.tech/led --> <!-- For additional help go to https://clover.coex.tech/led -->
<!-- ws281x led strip driver --> <!-- ws281x led strip driver -->
<node pkg="ws281x" name="led" type="ws281x_node" clear_params="true" output="screen" if="$(eval ws281x and not simulator)"> <node pkg="ws281x" name="led" type="ws281x_node" clear_params="true" output="screen" if="$(eval ws281x and not simulator)">
<param name="led_count" value="$(arg led_count)"/> <param name="led_count" value="58"/>
<param name="gpio_pin" value="$(arg gpio_pin)"/> <param name="gpio_pin" value="21"/>
<param name="brightness" value="64"/> <param name="brightness" value="64"/>
<param name="strip_type" value="WS2811_STRIP_GRB"/> <param name="strip_type" value="WS2811_STRIP_GRB"/>
<param name="target_frequency" value="800000"/> <param name="target_frequency" value="800000"/>
@@ -35,7 +32,7 @@
altctl: { r: 255, g: 255, b: 40 } altctl: { r: 255, g: 255, b: 40 }
posctl: { r: 50, g: 100, b: 220 } posctl: { r: 50, g: 100, b: 220 }
offboard: { r: 220, g: 20, b: 250 } offboard: { r: 220, g: 20, b: 250 }
low_battery: { threshold: 3.6, effect: blink_fast, r: 255, g: 0, b: 0 } low_battery: { threshold: 3.7, effect: blink_fast, r: 255, g: 0, b: 0 }
error: { effect: flash, r: 255, g: 0, b: 0 } error: { effect: flash, r: 255, g: 0, b: 0 }
</rosparam> </rosparam>
</node> </node>

View File

@@ -9,8 +9,6 @@
<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 == '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 == '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"/> <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"/>
<node if="$(eval direction_z == 'forward')" pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="0.03 0 0.05 -1.5707963 0 -1.5707963 base_link main_camera_optical"/>
<node if="$(eval direction_z == 'backward')" pkg="tf2_ros" type="static_transform_publisher" name="main_camera_frame" args="-0.03 0 0.05 1.5707963 0 -1.5707963 base_link main_camera_optical"/>
<!-- Template for custom camera orientation --> <!-- Template for custom camera orientation -->
<!-- Camera position and orientation are represented by base_link -> main_camera_optical transform --> <!-- Camera position and orientation are represented by base_link -> main_camera_optical transform -->

View File

@@ -6,15 +6,13 @@
<arg name="viz" default="true"/> <arg name="viz" default="true"/>
<arg name="respawn" default="true"/> <arg name="respawn" default="true"/>
<arg name="distance_sensor_remap" default="rangefinder/range"/> <arg name="distance_sensor_remap" default="rangefinder/range"/>
<arg name="usb_device" default="/dev/px4fmu"/>
<arg name="prefix" default="bash -c 'while [ ! -e $(arg usb_device) ]; do sleep 1; done; $0 $@'" if="$(eval fcu_conn == 'usb')"/>
<node pkg="mavros" type="mavros_node" name="mavros" launch-prefix="$(arg prefix)" required="false" clear_params="true" respawn="$(arg respawn)" unless="$(eval fcu_conn == 'none')" respawn_delay="1" output="screen"> <node pkg="mavros" type="mavros_node" name="mavros" required="false" clear_params="true" respawn="$(arg respawn)" unless="$(eval fcu_conn == 'none')" respawn_delay="1" output="screen">
<!-- UART connection --> <!-- UART connection -->
<param name="fcu_url" value="/dev/ttyAMA0:921600" if="$(eval fcu_conn is None or fcu_conn == 'uart')"/> <param name="fcu_url" value="/dev/ttyAMA0:921600" if="$(eval fcu_conn is None or fcu_conn == 'uart')"/>
<!-- USB connection --> <!-- USB connection -->
<param name="fcu_url" value="$(arg usb_device)" if="$(eval fcu_conn == 'usb')"/> <param name="fcu_url" value="/dev/px4fmu" if="$(eval fcu_conn == 'usb')"/>
<!-- sitl before PX4 1.9.0 --> <!-- sitl before PX4 1.9.0 -->
<param name="fcu_url" value="udp://@$(arg fcu_ip):14557" if="$(eval fcu_conn == 'udp')"/> <param name="fcu_url" value="udp://@$(arg fcu_ip):14557" if="$(eval fcu_conn == 'udp')"/>

19
clover/launch/sitl.launch Normal file
View File

@@ -0,0 +1,19 @@
<launch>
<!-- clover configuration for testing in sitl -->
<arg name="ip" default="127.0.0.1"/>
<arg name="rosbridge" default="false"/>
<include file="$(find clover)/launch/clover.launch">
<arg name="fcu_conn" value="udp"/>
<arg name="fcu_ip" value="$(arg ip)"/>
<arg name="gcs_bridge" value="false"/>
<arg name="optical_flow" value="false"/>
<arg name="web_video_server" default="false"/>
<arg name="main_camera" default="false"/>
<arg name="rosbridge" value="$(arg rosbridge)"/>
<arg name="aruco" default="false"/>
<arg name="rangefinder_vl53l1x" default="false"/>
<arg name="led" default="false"/>
<arg name="rc" default="false"/>
</include>
</launch>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<package format="2"> <package format="2">
<name>clover</name> <name>clover</name>
<version>0.21.1</version> <version>0.0.1</version>
<description>The Clover package</description> <description>The Clover package</description>
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer> <maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>

View File

@@ -36,7 +36,6 @@
#include <mavros_msgs/Thrust.h> #include <mavros_msgs/Thrust.h>
#include <mavros_msgs/State.h> #include <mavros_msgs/State.h>
#include <mavros_msgs/StatusText.h> #include <mavros_msgs/StatusText.h>
#include <mavros_msgs/ManualControl.h>
#include <clover/GetTelemetry.h> #include <clover/GetTelemetry.h>
#include <clover/Navigate.h> #include <clover/Navigate.h>
@@ -73,10 +72,9 @@ ros::Duration state_timeout;
ros::Duration velocity_timeout; ros::Duration velocity_timeout;
ros::Duration global_position_timeout; ros::Duration global_position_timeout;
ros::Duration battery_timeout; ros::Duration battery_timeout;
ros::Duration manual_control_timeout;
float default_speed; float default_speed;
bool auto_release; bool auto_release;
bool land_only_in_offboard, nav_from_sp, check_kill_switch; bool land_only_in_offboard, nav_from_sp;
std::map<string, string> reference_frames; std::map<string, string> reference_frames;
// Publishers // Publishers
@@ -124,7 +122,6 @@ enum { YAW, YAW_RATE, TOWARDS } setpoint_yaw_type;
// Last received telemetry messages // Last received telemetry messages
mavros_msgs::State state; mavros_msgs::State state;
mavros_msgs::StatusText statustext; mavros_msgs::StatusText statustext;
mavros_msgs::ManualControl manual_control;
PoseStamped local_position; PoseStamped local_position;
TwistStamped velocity; TwistStamped velocity;
NavSatFix global_position; NavSatFix global_position;
@@ -489,27 +486,6 @@ void publishSetpoint(const ros::TimerEvent& event)
publish(event.current_real); publish(event.current_real);
} }
inline void checkManualControl()
{
if (!manual_control_timeout.isZero() && TIMEOUT(manual_control, manual_control_timeout)) {
throw std::runtime_error("Manual control timeout, RC is switched off?");
}
if (check_kill_switch) {
// switch values: https://github.com/PX4/PX4-Autopilot/blob/c302514a0809b1765fafd13c014d705446ae1113/msg/manual_control_setpoint.msg#L3
const uint8_t SWITCH_POS_NONE = 0; // switch is not mapped
const uint8_t SWITCH_POS_ON = 1; // switch activated
const uint8_t SWITCH_POS_MIDDLE = 2; // middle position
const uint8_t SWITCH_POS_OFF = 3; // switch not activated
const int KILL_SWITCH_BIT = 12; // https://github.com/PX4/Firmware/blob/c302514a0809b1765fafd13c014d705446ae1113/src/modules/mavlink/mavlink_messages.cpp#L3975
uint8_t kill_switch = (manual_control.buttons & (0b11 << KILL_SWITCH_BIT)) >> KILL_SWITCH_BIT;
if (kill_switch == SWITCH_POS_ON)
throw std::runtime_error("Kill switch is on");
}
}
inline void checkState() inline void checkState()
{ {
if (TIMEOUT(state, state_timeout)) if (TIMEOUT(state, state_timeout))
@@ -537,10 +513,6 @@ bool serve(enum setpoint_type_t sp_type, float x, float y, float z, float vx, fl
// Checks // Checks
checkState(); checkState();
if (auto_arm) {
checkManualControl();
}
// default frame is local frame // default frame is local frame
if (frame_id.empty()) if (frame_id.empty())
frame_id = local_frame; frame_id = local_frame;
@@ -862,7 +834,6 @@ int main(int argc, char **argv)
nh_priv.param("auto_release", auto_release, true); nh_priv.param("auto_release", auto_release, true);
nh_priv.param("land_only_in_offboard", land_only_in_offboard, true); nh_priv.param("land_only_in_offboard", land_only_in_offboard, true);
nh_priv.param("nav_from_sp", nav_from_sp, true); nh_priv.param("nav_from_sp", nav_from_sp, true);
nh_priv.param("check_kill_switch", check_kill_switch, true);
nh_priv.param("default_speed", default_speed, 0.5f); nh_priv.param("default_speed", default_speed, 0.5f);
nh_priv.param<string>("body_frame", body.child_frame_id, "body"); nh_priv.param<string>("body_frame", body.child_frame_id, "body");
nh_priv.getParam("reference_frames", reference_frames); nh_priv.getParam("reference_frames", reference_frames);
@@ -872,7 +843,6 @@ int main(int argc, char **argv)
velocity_timeout = ros::Duration(nh_priv.param("velocity_timeout", 2.0)); velocity_timeout = ros::Duration(nh_priv.param("velocity_timeout", 2.0));
global_position_timeout = ros::Duration(nh_priv.param("global_position_timeout", 10.0)); global_position_timeout = ros::Duration(nh_priv.param("global_position_timeout", 10.0));
battery_timeout = ros::Duration(nh_priv.param("battery_timeout", 2.0)); battery_timeout = ros::Duration(nh_priv.param("battery_timeout", 2.0));
manual_control_timeout = ros::Duration(nh_priv.param("manual_control_timeout", 0.0));
transform_timeout = ros::Duration(nh_priv.param("transform_timeout", 0.5)); transform_timeout = ros::Duration(nh_priv.param("transform_timeout", 0.5));
telemetry_transform_timeout = ros::Duration(nh_priv.param("telemetry_transform_timeout", 0.5)); telemetry_transform_timeout = ros::Duration(nh_priv.param("telemetry_transform_timeout", 0.5));
@@ -890,7 +860,6 @@ int main(int argc, char **argv)
auto global_position_sub = nh.subscribe("mavros/global_position/global", 1, &handleMessage<NavSatFix, global_position>); auto global_position_sub = nh.subscribe("mavros/global_position/global", 1, &handleMessage<NavSatFix, global_position>);
auto battery_sub = nh.subscribe("mavros/battery", 1, &handleMessage<BatteryState, battery>); auto battery_sub = nh.subscribe("mavros/battery", 1, &handleMessage<BatteryState, battery>);
auto statustext_sub = nh.subscribe("mavros/statustext/recv", 1, &handleMessage<mavros_msgs::StatusText, statustext>); auto statustext_sub = nh.subscribe("mavros/statustext/recv", 1, &handleMessage<mavros_msgs::StatusText, statustext>);
auto manual_control_sub = nh.subscribe("mavros/manual_control/control", 1, &handleMessage<mavros_msgs::ManualControl, manual_control>);
auto local_position_sub = nh.subscribe("mavros/local_position/pose", 1, &handleLocalPosition); auto local_position_sub = nh.subscribe("mavros/local_position/pose", 1, &handleLocalPosition);
// Setpoint publishers // Setpoint publishers

View File

@@ -28,3 +28,19 @@ def test_simple_offboard_services_available():
def test_web_video_server(node): def test_web_video_server(node):
import urllib2 import urllib2
urllib2.urlopen("http://localhost:8080").read() urllib2.urlopen("http://localhost:8080").read()
def test_shell(node):
execute = rospy.ServiceProxy('exec', srv.Execute)
execute.wait_for_service(5)
res = execute(cmd='echo foo')
assert res.code == 0
assert res.output == 'foo\n'
res = execute(cmd='foo')
assert res.code == 32512
assert res.output == ''
res = execute(cmd='ls foo')
assert res.code == 512
assert res.output == ''

View File

@@ -1 +0,0 @@
/etc/clover_version

View File

@@ -1,5 +1,3 @@
<title>Clover Drone Kit Tools</title>
<h1>Clover Drone Kit Tools</h1> <h1>Clover Drone Kit Tools</h1>
<ul> <ul>
@@ -13,15 +11,15 @@
<div class="version"></div> <div class="version"></div>
<script src="js/roslib.js"></script>
<script type="text/javascript"> <script type="text/javascript">
document.querySelector("#wvs").href = location.protocol + '//' + location.hostname + ':8080'; document.querySelector("#wvs").href = location.protocol + '//' + location.hostname + ':8080';
document.querySelector("#butterfly").href = location.protocol + '//' + location.hostname + ':57575'; document.querySelector("#butterfly").href = location.protocol + '//' + location.hostname + ':57575';
// Determine image version // Determine image version
fetch('clover_version').then(function(response) { var ros = new ROSLIB.Ros({ url: 'ws://' + location.hostname + ':9090' });
if (response.status !== 200) return; var exec = new ROSLIB.Service({ ros: ros, name : '/exec', serviceType : 'clover/Execute' });
response.text().then(function(text) { exec.callService(new ROSLIB.ServiceRequest({ cmd: 'cat /etc/clover_version' }), function(result) {
document.querySelector('.version').innerHTML = 'Version: ' + text; document.querySelector('.version').innerHTML = 'Version: ' + result.output;
});
}); });
</script> </script>

View File

@@ -1,8 +0,0 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Changelog for package clover_blocks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0.21.1 (2020-11-17)
-------------------
* First release of clover_blocks package to ROS
* Contributors: Oleg Kalachev

View File

@@ -30,9 +30,7 @@ The frontend files are located in [`www`](./www/) subdirectory. The frontend app
Parameters read by frontend: Parameters read by frontend:
* `~navigate_tolerance` (*float*) distance tolerance in meters, used for navigate-like blocks (default: 0.2). * `~navigate_tolerance` (*float*) distance tolerance in meters, used for navigate-like blocks (default: 0.2).
* `~yaw_tolerance` (*float*) yaw angle tolerance in degrees, used in set_yaw block (default: 20).
* `~sleep_time` (*float*) duration of sleep in loop cycles, used for navigate-like blocks (default: 0.2). * `~sleep_time` (*float*) duration of sleep in loop cycles, used for navigate-like blocks (default: 0.2).
* `~confirm_run` (*bool*) enable confirmation to run the program (default: true).
These parameters also can be set as URL GET-parameters, for example: These parameters also can be set as URL GET-parameters, for example:

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<package format="2"> <package format="2">
<name>clover_blocks</name> <name>clover_blocks</name>
<version>0.21.1</version> <version>0.0.0</version>
<description>Blockly programming support for Clover</description> <description>Blockly programming support for Clover</description>
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer> <maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
<license>MIT</license> <license>MIT</license>

View File

@@ -29,7 +29,7 @@
</value> </value>
<value name="Z"> <value name="Z">
<shadow type="math_number" id="n0ULZn64%k.:,l(,D?TZ"> <shadow type="math_number" id="n0ULZn64%k.:,l(,D?TZ">
<field name="NUM">1</field> <field name="NUM">0</field>
</shadow> </shadow>
</value> </value>
<value name="ID"> <value name="ID">

View File

@@ -1,91 +1,106 @@
<xml xmlns="https://developers.google.com/blockly/xml"> <xml xmlns="https://developers.google.com/blockly/xml">
<block type="controls_whileUntil" id="U1it{GcGuSS:=[xiwZr1" x="113" y="113"> <variables>
<field name="MODE">WHILE</field> <variable id="_{V-S5HPBUl]CcJkL1Jw">led_count</variable>
<value name="BOOL"> </variables>
<block type="logic_boolean" id="]7ZDRwde}/RqjQCX}aVW"> <block type="variables_set" id="{)^J~:UMX%D;RWvztWLN" x="113" y="87">
<field name="BOOL">TRUE</field> <field name="VAR" id="_{V-S5HPBUl]CcJkL1Jw">led_count</field>
<value name="VALUE">
<block type="math_number" id="V_W$3,VFwZjcc|?|1o`l">
<field name="NUM">58</field>
</block> </block>
</value> </value>
<statement name="DO"> <next>
<block type="set_effect" id="WI0zqOz/z3].cR/6UWHn"> <block type="controls_whileUntil" id="U1it{GcGuSS:=[xiwZr1">
<field name="EFFECT">FILL</field> <field name="MODE">WHILE</field>
<value name="COLOR"> <value name="BOOL">
<shadow type="colour_picker" id="B`6;Xv{s2TFp8Yd=ZpSD"> <block type="logic_boolean" id="]7ZDRwde}/RqjQCX}aVW">
<field name="COLOUR">#000000</field> <field name="BOOL">TRUE</field>
</shadow> </block>
</value> </value>
<next> <statement name="DO">
<block type="set_led" id="^Vcs}ki?#ctf7rAchix$"> <block type="set_effect" id="WI0zqOz/z3].cR/6UWHn">
<value name="INDEX"> <field name="EFFECT">FILL</field>
<shadow type="math_number" id="U;VWW$[*LOF7Gf,~?YR7"> <value name="COLOR">
<field name="NUM">0</field> <shadow type="colour_picker" id="B`6;Xv{s2TFp8Yd=ZpSD">
<field name="COLOUR">#000000</field>
</shadow> </shadow>
<block type="math_arithmetic" id="AI6PZBd`]_Z%_~4c-%dB"> </value>
<field name="OP">MULTIPLY</field> <next>
<value name="A"> <block type="set_led" id="^Vcs}ki?#ctf7rAchix$">
<shadow type="math_number" id="|p}X]`SedK3).F/;}NlB"> <value name="INDEX">
<field name="NUM">1</field> <shadow type="math_number" id="U;VWW$[*LOF7Gf,~?YR7">
<field name="NUM">0</field>
</shadow> </shadow>
<block type="math_arithmetic" id="-haE#:,cg{-J=NZERA;F"> <block type="math_arithmetic" id="AI6PZBd`]_Z%_~4c-%dB">
<field name="OP">DIVIDE</field> <field name="OP">MULTIPLY</field>
<value name="A"> <value name="A">
<shadow type="math_number" id="::st;ot}[r]csqceURu*"> <shadow type="math_number" id="|p}X]`SedK3).F/;}NlB">
<field name="NUM">1</field> <field name="NUM">1</field>
</shadow> </shadow>
<block type="math_arithmetic" id="a%+LN)F~=Igg+,p02[qo"> <block type="math_arithmetic" id="-haE#:,cg{-J=NZERA;F">
<field name="OP">ADD</field> <field name="OP">DIVIDE</field>
<value name="A"> <value name="A">
<shadow type="math_number" id="*yIGN((y)/^z0:f5:VDw"> <shadow type="math_number" id="::st;ot}[r]csqceURu*">
<field name="NUM">1</field> <field name="NUM">1</field>
</shadow> </shadow>
<block type="get_yaw" id="mf%77q30bEqNfc/3`Mtb"> <block type="math_arithmetic" id="a%+LN)F~=Igg+,p02[qo">
<field name="FRAME_ID">MAP</field> <field name="OP">ADD</field>
<value name="ID"> <value name="A">
<shadow type="math_number" id="xb32G.N#ip`|^Xv*MOmY"> <shadow type="math_number" id="*yIGN((y)/^z0:f5:VDw">
<field name="NUM">0</field> <field name="NUM">1</field>
</shadow>
<block type="get_yaw" id="mf%77q30bEqNfc/3`Mtb">
<field name="FRAME_ID">MAP</field>
<value name="ID">
<shadow type="math_number" id="xb32G.N#ip`|^Xv*MOmY">
<field name="NUM">0</field>
</shadow>
</value>
</block>
</value>
<value name="B">
<shadow type="math_number" id="T/fTrm;j2Azgav;gI{ZW">
<field name="NUM">180</field>
</shadow> </shadow>
</value> </value>
</block> </block>
</value> </value>
<value name="B"> <value name="B">
<shadow type="math_number" id="T/fTrm;j2Azgav;gI{ZW"> <shadow type="math_number" id="Wo1/ZCeir,u6/.e1H+BB">
<field name="NUM">180</field> <field name="NUM">360</field>
</shadow> </shadow>
</value> </value>
</block> </block>
</value> </value>
<value name="B"> <value name="B">
<shadow type="math_number" id="Wo1/ZCeir,u6/.e1H+BB"> <shadow type="math_number" id="jENTcXz0C5/=)Xpd!}LL">
<field name="NUM">360</field> <field name="NUM">1</field>
</shadow> </shadow>
<block type="variables_get" id="Ko,`n=i88FY~`YbQLA?[">
<field name="VAR" id="_{V-S5HPBUl]CcJkL1Jw">led_count</field>
</block>
</value> </value>
</block> </block>
</value> </value>
<value name="B"> <value name="COLOR">
<shadow type="math_number" id="jENTcXz0C5/=)Xpd!}LL"> <shadow type="colour_picker" id="+vw3bff.5c[=_w,Xm^C(">
<field name="NUM">1</field> <field name="COLOUR">#3366ff</field>
</shadow>
<block type="led_count" id="vM@X8s!xa]v}AaK6PWF5"></block>
</value>
</block>
</value>
<value name="COLOR">
<shadow type="colour_picker" id="+vw3bff.5c[=_w,Xm^C(">
<field name="COLOUR">#3366ff</field>
</shadow>
</value>
<next>
<block type="wait" id="DT%f$bn1*1El5zsgUW8Y">
<value name="TIME">
<shadow type="math_number" id="~Y0hNY[_^#v@aZkE-TH[">
<field name="NUM">0.1</field>
</shadow> </shadow>
</value> </value>
<next>
<block type="wait" id="DT%f$bn1*1El5zsgUW8Y">
<value name="TIME">
<shadow type="math_number" id="~Y0hNY[_^#v@aZkE-TH[">
<field name="NUM">0.1</field>
</shadow>
</value>
</block>
</next>
</block> </block>
</next> </next>
</block> </block>
</next> </statement>
</block> </block>
</statement> </next>
</block> </block>
</xml> </xml>

View File

@@ -1,13 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
# Copyright (C) 2020 Copter Express Technologies
#
# Author: Oleg Kalachev <okalachev@gmail.com>
#
# Distributed under MIT License (available at https://opensource.org/licenses/MIT).
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
from __future__ import print_function from __future__ import print_function
import rospy import rospy

View File

@@ -1,13 +1,3 @@
/*
* Copyright (C) 2020 Copter Express Technologies
*
* Author: Oleg Kalachev <okalachev@gmail.com>
*
* Distributed under MIT License (available at https://opensource.org/licenses/MIT).
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*/
const COLOR_FLIGHT = 293; const COLOR_FLIGHT = 293;
const COLOR_STATE = 36; const COLOR_STATE = 36;
const COLOR_LED = 143; const COLOR_LED = 143;
@@ -353,17 +343,6 @@ Blockly.Blocks['set_effect'] = {
} }
}; };
Blockly.Blocks['led_count'] = {
init: function () {
this.appendDummyInput()
.appendField("LED count");
this.setOutput(true, "Number");
this.setColour(COLOR_LED);
this.setTooltip("Returns the number of LEDs (configured in led.launch).");
this.setHelpUrl(DOCS_URL + '#' + this.type);
}
};
Blockly.Blocks['take_off'] = { Blockly.Blocks['take_off'] = {
init: function () { init: function () {
this.appendValueInput("ALT") this.appendValueInput("ALT")
@@ -546,7 +525,7 @@ Blockly.Blocks['gpio_read'] = {
this.setOutput(true, "Boolean"); this.setOutput(true, "Boolean");
this.setColour(COLOR_GPIO); this.setColour(COLOR_GPIO);
this.setTooltip("Returns if there is voltage on a GPIO pin."); this.setTooltip("Returns if there is voltage on a GPIO pin.");
this.setHelpUrl(DOCS_URL + '#GPIO'); this.setHelpUrl(DOCS_URL + '#' + this.type);
} }
}; };
@@ -563,7 +542,7 @@ Blockly.Blocks['gpio_write'] = {
this.setPreviousStatement(true, null); this.setPreviousStatement(true, null);
this.setNextStatement(true, null); this.setNextStatement(true, null);
this.setTooltip("Set GPIO pin level."); this.setTooltip("Set GPIO pin level.");
this.setHelpUrl(DOCS_URL + '#GPIO'); this.setHelpUrl(DOCS_URL + '#' + this.type);
} }
}; };
@@ -579,24 +558,7 @@ Blockly.Blocks['set_servo'] = {
this.setColour(COLOR_GPIO); this.setColour(COLOR_GPIO);
this.setPreviousStatement(true, null); this.setPreviousStatement(true, null);
this.setNextStatement(true, null); this.setNextStatement(true, null);
this.setTooltip("Set PWM on a GPIO pin to control servo. PWM is specified in range of 5002500 μs."); this.setTooltip("Set PWM on a GPIO pin to control servo. PWM is specified in range of 5002500 ms.");
this.setHelpUrl(DOCS_URL + '#GPIO'); this.setHelpUrl(DOCS_URL + '#' + this.type);
}
};
Blockly.Blocks['set_duty_cycle'] = {
init: function () {
this.appendValueInput("PIN")
.setCheck("Number")
.appendField("set GPIO pin");
this.appendValueInput("DUTY_CYCLE")
.setCheck("Number")
.appendField("to duty cycle");
this.setInputsInline(true);
this.setColour(COLOR_GPIO);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("Set PWM duty cycle on a GPIO pin (better to control LEDs, etc). Duty cycle is set in range of 01.");
this.setHelpUrl(DOCS_URL + '#GPIO');
} }
}; };

View File

@@ -106,7 +106,6 @@
<value name="INDEX"><shadow type="math_number"><field name="NUM">0</field></shadow></value> <value name="INDEX"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
<value name="COLOR"><shadow type="colour_picker"></shadow></value> <value name="COLOR"><shadow type="colour_picker"></shadow></value>
</block> </block>
<block type="led_count"></block>
</category> </category>
<category name="GPIO" colour="#5b97cc"> <category name="GPIO" colour="#5b97cc">
<block type="gpio_read"> <block type="gpio_read">
@@ -120,10 +119,6 @@
<value name="PIN"><shadow type="math_number"><field name="NUM">1</field></shadow></value> <value name="PIN"><shadow type="math_number"><field name="NUM">1</field></shadow></value>
<value name="PWM"><shadow type="math_number"><field name="NUM">1500</field></shadow></value> <value name="PWM"><shadow type="math_number"><field name="NUM">1500</field></shadow></value>
</block> </block>
<block type="set_duty_cycle">
<value name="PIN"><shadow type="math_number"><field name="NUM">1</field></shadow></value>
<value name="DUTY_CYCLE"><shadow type="math_number"><field name="NUM">0.5</field></shadow></value>
</block>
</category> </category>
<sep></sep> <sep></sep>
<category name="Logic" colour="#5b80a5"> <category name="Logic" colour="#5b80a5">

View File

@@ -1,13 +1,3 @@
/*
* Copyright (C) 2020 Copter Express Technologies
*
* Author: Oleg Kalachev <okalachev@gmail.com>
*
* Distributed under MIT License (available at https://opensource.org/licenses/MIT).
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*/
import * as ros from './ros.js'; import * as ros from './ros.js';
import './blocks.js'; import './blocks.js';
import {generateCode, generateUserCode} from './python.js'; import {generateCode, generateUserCode} from './python.js';
@@ -39,9 +29,7 @@ var workspace = Blockly.inject('blockly', {
function readParams() { function readParams() {
return Promise.all([ return Promise.all([
ros.readParam('navigate_tolerance', true, 0.2), ros.readParam('navigate_tolerance', true, 0.2),
ros.readParam('yaw_tolerance', true, 20), ros.readParam('sleep_time', true, 0.2)
ros.readParam('sleep_time', true, 0.2),
ros.readParam('confirm_run', true, true),
]); ]);
} }
@@ -109,7 +97,7 @@ new ROSLIB.Topic({ ros: ros.ros, name: ros.priv + 'prompt', messageType: 'clover
name: ros.priv + 'input/' + msg.id, name: ros.priv + 'input/' + msg.id,
messageType: 'std_msgs/String', messageType: 'std_msgs/String',
latch: true latch: true
}).publish(new ROSLIB.Message({ data: response || '' })); }).publish(new ROSLIB.Message({ data: response }));
}); });
window.stopProgram = function() { window.stopProgram = function() {
@@ -125,7 +113,7 @@ ros.ros.on('close', update);
ready.then(() => runButton.disabled = false); ready.then(() => runButton.disabled = false);
window.runProgram = function() { window.runProgram = function() {
if (ros.params.confirm_run && !confirm('Run program?')) return; if (!confirm('Run program?')) return;
runRequest = true; runRequest = true;
update(); update();

View File

@@ -1,13 +1,3 @@
/*
* Copyright (C) 2020 Copter Express Technologies
*
* Author: Oleg Kalachev <okalachev@gmail.com>
*
* Distributed under MIT License (available at https://opensource.org/licenses/MIT).
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*/
import {params} from './ros.js'; import {params} from './ros.js';
// If any new block imports any library, add that library name here. // If any new block imports any library, add that library name here.
@@ -15,12 +5,17 @@ Blockly.Python.addReservedWords('_b,_print');
Blockly.Python.addReservedWords('rospy,srv,Trigger,get_telemetry,navigate,set_velocity,land'); Blockly.Python.addReservedWords('rospy,srv,Trigger,get_telemetry,navigate,set_velocity,land');
Blockly.Python.addReservedWords('navigate_wait,land_wait,wait_arrival,wait_yaw,get_distance'); Blockly.Python.addReservedWords('navigate_wait,land_wait,wait_arrival,wait_yaw,get_distance');
Blockly.Python.addReservedWords('pigpio,pi,Range'); Blockly.Python.addReservedWords('pigpio,pi,Range');
Blockly.Python.addReservedWords('SetLEDEffect,set_effect,led_count,get_led_count'); Blockly.Python.addReservedWords('SetLEDEffect,set_effect');
Blockly.Python.addReservedWords('SetLEDs,LEDState,set_leds'); Blockly.Python.addReservedWords('SetLEDs,LEDState,set_leds');
// TODO: parametrize
const navigate_tolerance = 0.2;
const sleep_time = 0.2;
const IMPORT_SRV = `from clover import srv const IMPORT_SRV = `from clover import srv
from std_srvs.srv import Trigger`; from std_srvs.srv import Trigger`;
// TODO: tolerance to parameters
const NAVIGATE_WAIT = () => `\ndef navigate_wait(x=0, y=0, z=0, speed=0.5, frame_id='body', auto_arm=False): const NAVIGATE_WAIT = () => `\ndef navigate_wait(x=0, y=0, z=0, speed=0.5, frame_id='body', auto_arm=False):
res = navigate(x=x, y=y, z=z, yaw=float('nan'), speed=speed, frame_id=frame_id, auto_arm=auto_arm) res = navigate(x=x, y=y, z=z, yaw=float('nan'), speed=speed, frame_id=frame_id, auto_arm=auto_arm)
@@ -38,13 +33,15 @@ const LAND_WAIT = () => `\ndef land_wait():
while get_telemetry().armed: while get_telemetry().armed:
rospy.sleep(${params.sleep_time})\n`; rospy.sleep(${params.sleep_time})\n`;
// TODO: tolerance to parameters
const WAIT_YAW = () => `\ndef wait_yaw(): const WAIT_YAW = () => `\ndef wait_yaw():
while not rospy.is_shutdown(): while not rospy.is_shutdown():
telem = get_telemetry(frame_id='navigate_target') telem = get_telemetry(frame_id='navigate_target')
if abs(telem.yaw) < math.radians(${params.yaw_tolerance}): if abs(telem.yaw) < math.radians(20):
return return
rospy.sleep(${params.sleep_time})\n`; rospy.sleep(${params.sleep_time})\n`;
// TODO: tolerance to parameters
const WAIT_ARRIVAL = () => `\ndef wait_arrival(): const WAIT_ARRIVAL = () => `\ndef wait_arrival():
while not rospy.is_shutdown(): while not rospy.is_shutdown():
telem = get_telemetry(frame_id='navigate_target') telem = get_telemetry(frame_id='navigate_target')
@@ -52,6 +49,7 @@ const WAIT_ARRIVAL = () => `\ndef wait_arrival():
return return
rospy.sleep(${params.sleep_time})\n`; rospy.sleep(${params.sleep_time})\n`;
// TODO: tolerance to parameters
const ARRIVED = () => `\ndef arrived(): const ARRIVED = () => `\ndef arrived():
telem = get_telemetry(frame_id='navigate_target') telem = get_telemetry(frame_id='navigate_target')
return math.sqrt(telem.x ** 2 + telem.y ** 2 + telem.z ** 2) < ${params.navigate_tolerance}\n` return math.sqrt(telem.x ** 2 + telem.y ** 2 + telem.z ** 2) < ${params.navigate_tolerance}\n`
@@ -87,9 +85,6 @@ function generateROSDefinitions() {
Blockly.Python.definitions_['import_set_led'] = 'from led_msgs.srv import SetLEDs\nfrom led_msgs.msg import LEDState'; Blockly.Python.definitions_['import_set_led'] = 'from led_msgs.srv import SetLEDs\nfrom led_msgs.msg import LEDState';
code += `set_leds = rospy.ServiceProxy('led/set_leds', SetLEDs, persistent=True)\n`; code += `set_leds = rospy.ServiceProxy('led/set_leds', SetLEDs, persistent=True)\n`;
} }
if (rosDefinitions.ledStateArray) {
Blockly.Python.definitions_['import_led_state_array'] = 'from led_msgs.msg import LEDStateArray';
}
if (rosDefinitions.navigateWait) { if (rosDefinitions.navigateWait) {
Blockly.Python.definitions_['import_math'] = 'import math'; Blockly.Python.definitions_['import_math'] = 'import math';
code += NAVIGATE_WAIT(); code += NAVIGATE_WAIT();
@@ -394,45 +389,26 @@ Blockly.Python.set_led = function(block) {
return `set_leds([LEDState(index=${index}, r=${color.r}, g=${color.g}, b=${color.b})])\n`; return `set_leds([LEDState(index=${index}, r=${color.r}, g=${color.g}, b=${color.b})])\n`;
} else { } else {
let parseColor = Blockly.Python.provideFunction_('parse_color', [PARSE_COLOR]); let parseColor = Blockly.Python.provideFunction_('parse_color', [PARSE_COLOR]);
return `set_leds([LEDState(index=${index}, **${parseColor}(${colorCode}))])\n`; return `set_leds([LEDState(index=${index}, **${parseColor}(${colorCode})])\n`;
} }
} }
const GET_LED_COUNT = `led_count = None
def get_led_count():
global led_count
if led_count is None:
led_count = len(rospy.wait_for_message('led/state', LEDStateArray, timeout=10).leds)
return led_count\n`;
Blockly.Python.led_count = function(block) {
rosDefinitions.ledStateArray = true;
initNode();
Blockly.Python.definitions_['get_led_count'] = GET_LED_COUNT;
return [`get_led_count()`, Blockly.Python.ORDER_FUNCTION_CALL]
}
function pigpio() { function pigpio() {
Blockly.Python.definitions_['import_pigpio'] = 'import pigpio'; Blockly.Python.definitions_['import_pigpio'] = 'import pigpio';
Blockly.Python.definitions_['init_pigpio'] = 'pi = pigpio.pi()'; Blockly.Python.definitions_['init_pigpio'] = 'pi = pigpio.pi()';
} }
const GPIO_READ = `\ndef gpio_read(pin): const GPIO_READ = `\ndef gpio_read(pin):
pi.set_mode(pin, pigpio.INPUT) pi.set_mode(pin, pigpio.INPUT)
return pi.read(pin)\n`; return pi.read(pin)\n`;
const GPIO_WRITE = `\ndef gpio_write(pin, level): const GPIO_WRITE = `\ndef gpio_write(pin, level):
pi.set_mode(pin, pigpio.OUTPUT) pi.set_mode(pin, pigpio.OUTPUT)
pi.write(pin, level)\n`; pi.write(pin, level)\n`;
const SET_SERVO = `\ndef set_servo(pin, pwm): const SET_SERVO = `\ndef set_servo(pin, pwm):
pi.set_mode(pin, pigpio.OUTPUT) pi.set_mode(pin, pigpio.OUTPUT)
pi.set_servo_pulsewidth(pin, pwm)\n`; pi.set_servo_pulsewidth(pin, pwm)\n`;
const SET_DUTY_CYCLE = `\ndef set_duty_cycle(pin, duty_cycle):
pi.set_mode(pin, pigpio.OUTPUT)
pi.set_PWM_dutycycle(pin, duty_cycle * 255)\n`;
Blockly.Python.gpio_read = function(block) { Blockly.Python.gpio_read = function(block) {
pigpio(); pigpio();
@@ -456,11 +432,3 @@ Blockly.Python.set_servo = function(block) {
var pwm = Blockly.Python.valueToCode(block, 'PWM', Blockly.Python.ORDER_NONE); var pwm = Blockly.Python.valueToCode(block, 'PWM', Blockly.Python.ORDER_NONE);
return `set_servo(${pin}, ${pwm})\n`; return `set_servo(${pin}, ${pwm})\n`;
} }
Blockly.Python.set_duty_cycle = function(block) {
pigpio();
Blockly.Python.definitions_['set_duty_cycle'] = SET_DUTY_CYCLE;
var pin = Blockly.Python.valueToCode(block, 'PIN', Blockly.Python.ORDER_NONE);
var dutyCycle = Blockly.Python.valueToCode(block, 'DUTY_CYCLE', Blockly.Python.ORDER_NONE);
return `set_duty_cycle(${pin}, ${dutyCycle})\n`;
}

View File

@@ -1,13 +1,3 @@
/*
* Copyright (C) 2020 Copter Express Technologies
*
* Author: Oleg Kalachev <okalachev@gmail.com>
*
* Distributed under MIT License (available at https://opensource.org/licenses/MIT).
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*/
var url = 'ws://' + location.hostname + ':9090'; var url = 'ws://' + location.hostname + ':9090';
export var ros = new ROSLIB.Ros({ url }); export var ros = new ROSLIB.Ros({ url });

View File

@@ -1,9 +0,0 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Changelog for package clover_description
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0.21.1 (2020-11-17)
-------------------
* First release of clover_description package to ROS
* Contributors: Alexey Rogachevskiy

View File

@@ -1,6 +1,6 @@
<package format="2"> <package format="2">
<name>clover_description</name> <name>clover_description</name>
<version>0.21.1</version> <version>0.0.1</version>
<description>The clover_description package provides URDF models of the Clover series of quadcopters.</description> <description>The clover_description package provides URDF models of the Clover series of quadcopters.</description>
<maintainer email="sfalexrog@gmail.com">Alexey Rogachevskiy</maintainer> <maintainer email="sfalexrog@gmail.com">Alexey Rogachevskiy</maintainer>

View File

@@ -1,8 +0,0 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Changelog for package clover_simulation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0.21.1 (2020-11-17)
-------------------
* First release of clover_simulation package to ROS
* Contributors: Alexey Rogachevskiy

View File

@@ -52,7 +52,7 @@ target_compile_options(throttling_camera PRIVATE -std=c++11)
add_dependencies(throttling_camera ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) add_dependencies(throttling_camera ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
install(DIRECTORY launch DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) install(DIRECTORY launch DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
install(DIRECTORY models DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) install(DIRECTORY meshes DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
install(DIRECTORY resources DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) install(DIRECTORY resources DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
catkin_install_python(PROGRAMS scripts/aruco_gen catkin_install_python(PROGRAMS scripts/aruco_gen

View File

@@ -1,5 +1,4 @@
<launch> <launch>
<arg name="type" default="gazebo"/> <!-- gazebo, jmavsim, none (only clover packages) -->
<arg name="mav_id" default="0"/> <arg name="mav_id" default="0"/>
<arg name="est" default="ekf2"/> <!-- PX4 estimator: lpe, ekf2 --> <arg name="est" default="ekf2"/> <!-- PX4 estimator: lpe, ekf2 -->
<arg name="vehicle" default="clover"/> <!-- PX4 vehicle configuration: clover, clover_vpe --> <arg name="vehicle" default="clover"/> <!-- PX4 vehicle configuration: clover, clover_vpe -->
@@ -10,22 +9,22 @@
<arg name="use_clover_physics" default="false"/> <!-- Use inertial parameters from CAD models --> <arg name="use_clover_physics" default="false"/> <!-- Use inertial parameters from CAD models -->
<!-- Gazebo instance --> <!-- Gazebo instance -->
<include file="$(find gazebo_ros)/launch/empty_world.launch" if="$(eval type == 'gazebo')"> <include file="$(find gazebo_ros)/launch/empty_world.launch">
<!-- Workaround for crashes in VMware --> <!-- Workaround for crashes in VMware -->
<env name="SVGA_VGPU10" value="0"/> <env name="SVGA_VGPU10" value="0"/>
<arg name="gui" value="true"/> <arg name="gui" value="true"/>
<arg name="world_name" value="$(find clover_simulation)/resources/worlds/clover_aruco.world"/> <arg name="world_name" value="$(find clover_simulation)/resources/worlds/clover.world"/>
<arg name="verbose" value="true"/> <arg name="verbose" value="true"/>
</include> </include>
<!-- PX4 instance --> <!-- PX4 instance -->
<node name="sitl_$(arg mav_id)" pkg="px4" type="px4" output="screen" args="$(find px4)/ROMFS/px4fmu_common -s etc/init.d-posix/rcS -i $(arg mav_id)" unless="$(eval type == 'none')"> <node name="sitl_$(arg mav_id)" pkg="px4" type="px4" output="screen" args="$(find px4)/ROMFS/px4fmu_common -s etc/init.d-posix/rcS -i $(arg mav_id)">
<env name="PX4_SIM_MODEL" value="$(arg vehicle)"/> <env name="PX4_SIM_MODEL" value="$(arg vehicle)"/>
<env name="PX4_ESTIMATOR" value="$(arg est)"/> <env name="PX4_ESTIMATOR" value="$(arg est)"/>
</node> </node>
<!-- Clover model --> <!-- Clover model -->
<include file="$(find clover_description)/launch/spawn_drone.launch" if="$(eval type == 'gazebo')"> <include file="$(find clover_description)/launch/spawn_drone.launch">
<arg name="main_camera" value="$(arg main_camera)"/> <arg name="main_camera" value="$(arg main_camera)"/>
<arg name="rangefinder" value="$(arg rangefinder)"/> <arg name="rangefinder" value="$(arg rangefinder)"/>
<arg name="led" value="$(arg led)"/> <arg name="led" value="$(arg led)"/>
@@ -33,20 +32,10 @@
<arg name="use_clover_physics" value="$(arg use_clover_physics)"/> <arg name="use_clover_physics" value="$(arg use_clover_physics)"/>
</include> </include>
<node name="jmavsim" pkg="px4" type="jmavsim_run.sh" output="screen" if="$(eval type == 'jmavsim')"/>
<param name="use_sim_time" value="false" if="$(eval type == 'jmavsim')"/>
<!-- Clover services --> <!-- Clover services -->
<include file="$(find clover)/launch/clover.launch"> <include file="$(find clover)/launch/clover.launch">
<arg name="simulator" value="true"/> <arg name="simulator" value="true"/>
<arg name="fcu_conn" value="sitl"/> <arg name="fcu_conn" value="sitl"/>
<arg name="fcu_ip" value="127.0.0.1"/> <arg name="fcu_ip" value="127.0.0.1"/>
<arg name="gcs_bridge" value=""/>
<arg name="rc" default="false"/>
<arg name="web_video_server" default="false" if="$(eval type == 'jmavsim')"/>
<arg name="main_camera" default="false" if="$(eval type == 'jmavsim')"/>
<arg name="aruco" default="false" if="$(eval type == 'jmavsim')"/>
<arg name="led" default="false" if="$(eval type == 'jmavsim')"/>
</include> </include>
</launch> </launch>

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Some files were not shown because too many files have changed in this diff Show More