Compare commits

..

43 Commits

Author SHA1 Message Date
Alexey Rogachevskiy
ba6feec32e builder: Don't test for what's not there
(we don't install pip2 anymore, but this may be reverted eventually)
2019-11-08 21:03:32 +03:00
Alexey Rogachevskiy
e3e92d0b57 builder: Use python3 for rosdep 2019-11-08 19:38:05 +03:00
Alexey Rogachevskiy
ff632ef1ba builder, aruco_pose, clever: Use python3 wherever possible 2019-11-08 19:04:39 +03:00
Alexey Rogachevskiy
a1577eeea0 builder: Use venv for butterfly validation 2019-11-08 17:25:19 +03:00
Alexey Rogachevskiy
53caa9771c clever: Update Python deps in requirements.txt 2019-11-08 16:18:16 +03:00
Alexey Rogachevskiy
c720c9d02d builder: Use Melodic+Python3 2019-11-08 12:23:56 +03:00
Alexey Rogachevskiy
9ff7e4a64d Merge remote-tracking branch 'origin/master' into buster 2019-10-12 04:10:39 +03:00
Alexey Rogachevskiy
b5ff8388b2 selfcheck: Update systemd-analyze regex 2019-10-12 04:09:32 +03:00
Alexey Rogachevskiy
e3fc40f2b7 Merge remote-tracking branch 'origin' into buster 2019-10-10 23:32:37 +03:00
Alexey Rogachevskiy
3640f09d82 aruco_pose: Remove unused vendored code 2019-10-09 19:15:53 +03:00
Alexey Rogachevskiy
31c6944b52 builder: Disable catkin tests
These tests fail on a remote machine but seem to pass just fine on real hardware. Something must have changed between Kinetic and Melodic, and we must investigate more, but for now we just need a working image.
2019-10-07 14:40:06 +03:00
Alexey Rogachevskiy
70684d952f Merge remote-tracking branch 'origin' into buster 2019-10-07 14:26:06 +03:00
Alexey Rogachevskiy
6457dffb73 builder: Move ld.so.preload back after tests 2019-10-07 14:23:49 +03:00
sfalexrog
7b0b3c751b builder: Use default kernel 2019-10-06 21:05:51 +03:00
sfalexrog
d833151963 builder: Use more recent base image 2019-10-06 19:23:00 +03:00
sfalexrog
25fe4397ee builder: Install tornado==4.2.1 for rosbridge_suite 2019-09-24 16:42:40 +03:00
Alexey Rogachevskiy
35ac2396f0 Merge branch 'master' into buster 2019-09-13 00:57:34 +03:00
Alexey Rogachevskiy
99f305cdd2 builder: Re-add mjpgstreamer 2019-09-12 21:39:13 +03:00
Alexey Rogachevskiy
a0b67f51c3 aruco_pose: Allow rgb8 map images (again) 2019-09-11 21:33:46 +03:00
Alexey Rogachevskiy
915fbdfcc0 builder: Disable mjpg_streamer test 2019-09-11 21:09:21 +03:00
Alexey Rogachevskiy
239eaf715d aruco_pose: Accept rgb8 map images 2019-09-11 21:07:40 +03:00
Alexey Rogachevskiy
22e1bd6b92 builder: Use correct file types for standalone install 2019-09-11 20:55:08 +03:00
Alexey Rogachevskiy
540428aefc builder: Add repo for standalone build 2019-09-11 20:45:57 +03:00
Alexey Rogachevskiy
2ea0eb0783 builder: Use -y for package installation 2019-09-11 18:55:01 +03:00
sfalexrog
24b1cd12ba builder: Set permissions for standalone-install 2019-09-11 18:50:06 +03:00
sfalexrog
06df5cc31a travis: Add native tests 2019-09-11 18:17:19 +03:00
sfalexrog
0a945cc6bf builder: Remove unused builder code 2019-09-11 18:10:07 +03:00
sfalexrog
78603f5f9c builder: Add led packages 2019-09-11 18:09:05 +03:00
sfalexrog
cdc3a1bbc9 aruco_pose: Vendor opencv_contrib/aruco again 2019-09-11 18:03:55 +03:00
sfalexrog
8a6f6ab147 Revert "aruco_pose: Vendor in aruco library from OpenCV 3.4.6"
This reverts commit 9c14a8c002bb3396f9a7d9b2ba39969207f066ba.
2019-09-11 18:03:55 +03:00
sfalexrog
3b19e60111 roscore: Use melodic distribution 2019-09-11 18:03:55 +03:00
sfalexrog
eff5a535e3 tests: Don't try to locate opencv in ros 2019-09-11 18:03:55 +03:00
sfalexrog
fc9ab73640 travis: Disable eclint for vendored aruco library 2019-09-11 18:03:55 +03:00
sfalexrog
512a389670 aruco_pose: Vendor in aruco library from OpenCV 3.4.6 2019-09-11 18:03:55 +03:00
sfalexrog
077ccf0954 builder: Update rosdep 2019-09-11 18:03:55 +03:00
sfalexrog
04d10ed337 aruco_pose, clever: Remove opencv3 ROS dependency 2019-09-11 18:03:55 +03:00
sfalexrog
ae07f2fb01 builder: Update kernel version 2019-09-11 18:03:55 +03:00
sfalexrog
a83ef3a9ad builder: Move to ROS Melodic 2019-09-11 18:03:55 +03:00
sfalexrog
84106ec919 builder: Search for buster ROS packages 2019-09-11 17:58:48 +03:00
sfalexrog
72dfa64678 builder: Use coex repo to install Monkey 2019-09-11 17:58:48 +03:00
sfalexrog
bdcf383408 builder: Move ld.so.preload to have less errors 2019-09-11 17:58:48 +03:00
sfalexrog
b08d2859e1 builder: Use correct repository specifications 2019-09-11 17:58:48 +03:00
sfalexrog
851a978859 builder: Build against Buster 2019-09-11 17:57:14 +03:00
443 changed files with 7150 additions and 194435 deletions

View File

@@ -20,7 +20,6 @@
"MAVLink",
"ROS",
"ROS Kinetic",
"ROS Melodic",
"OpenCV",
"Gazebo",
"GitHub",
@@ -105,8 +104,7 @@
"TCP",
"UDP",
"QR",
"Li-ion",
"Nvidia"
"Li-ion"
],
"code_blocks": false
},

View File

@@ -1,5 +1,4 @@
os: linux
dist: xenial
sudo: required
language: generic
services:
- docker
@@ -44,7 +43,7 @@ jobs:
- cd images && zip ${IMAGE_NAME}.zip ${IMAGE_NAME}
deploy:
provider: releases
token: ${GITHUB_OAUTH_TOKEN}
api_key: ${GITHUB_OAUTH_TOKEN}
file: ${IMAGE_NAME}.zip
skip_cleanup: true
on:
@@ -58,7 +57,7 @@ jobs:
before_script:
- docker pull ${NATIVE_DOCKER}
script:
- docker run --rm -v $(pwd):/root/catkin_ws/src/clover ${NATIVE_DOCKER} /root/catkin_ws/src/clover/builder/standalone-install.sh
- docker run --rm -v $(pwd):/root/catkin_ws/src/clever ${NATIVE_DOCKER} /root/catkin_ws/src/clever/builder/standalone-install.sh
- stage: Build
name: "Native Melodic build"
env:
@@ -66,7 +65,7 @@ jobs:
before_script:
- docker pull ${NATIVE_DOCKER}
script:
- docker run --rm -v $(pwd):/root/catkin_ws/src/clover ${NATIVE_DOCKER} /root/catkin_ws/src/clover/builder/standalone-install.sh
- docker run --rm -v $(pwd):/root/catkin_ws/src/clever ${NATIVE_DOCKER} /root/catkin_ws/src/clever/builder/standalone-install.sh
- stage: Build
name: "Documentation"
language: node_js
@@ -85,13 +84,13 @@ jobs:
- gitbook build
deploy:
provider: pages
local_dir: _book
skip_cleanup: true
token: ${GITHUB_OAUTH_TOKEN}
keep_history: true
target_branch: master
repo: CopterExpress/clover.coex.tech
fqdn: clover.coex.tech
local-dir: _book
skip-cleanup: true
github-token: ${GITHUB_OAUTH_TOKEN}
keep-history: true
target-branch: master
repo: CopterExpress/clever.coex.tech
fqdn: clever.coex.tech
verbose: true
on:
branch: master
@@ -110,7 +109,7 @@ jobs:
- wget https://github.com/okalachev/editorconfig-checker/releases/download/1.2.1-disable-spaces-amount/ec-linux-amd64
- chmod +x ec-linux-amd64
script:
- ./ec-linux-amd64 -spaces-after-tabs -e "roslib.js|ros3d.js|eventemitter2.js|draw.cpp|BinUtils.swift|\.idea|apps/android/app|Assets.xcassets|test_parser_pass.txt|test_node_failure.txt|aruco_pose/vendor|\.stl|\.dxf"
- ./ec-linux-amd64 -spaces-after-tabs -e "roslib.js|ros3d.js|eventemitter2.js|draw.cpp|BinUtils.swift|\.idea|apps/android/app|Assets.xcassets|test_parser_pass.txt|test_node_failure.txt|aruco_pose/vendor"
stages:
- Build
- Annotate

234
README.md
View File

@@ -1,173 +1,103 @@
# COEX Clover Drone Kit
# CLEVER
<table align=center>
<tr>
<td align=center><a href="https://px4.io"><img src="docs/assets/px4.svg" height=60></a></td>
<td align=center><a href="https://www.raspberrypi.org"><img src="docs/assets/rpi.svg" height=60></a></td>
<td align=center><a href="https://www.ros.org"><img src="docs/assets/ros.svg" height=60></a></td>
</tr>
</table>
<img src="docs/assets/clever4-front-white.png" align="right" width="400px" alt="CLEVER drone">
This repository contains documentation, software platform source code and RPi image builder for COEX Clover drone kit.
CLEVER (Russian: *"Клевер"*, meaning *"Clover"*) is an educational programmable drone kit consisting of an unassembled quadcopter, open source software and documentation. The kit includes Pixhawk/Pixracer autopilot running PX4 firmware, Raspberry Pi 3 as companion computer, a camera for computer vision navigation as well as additional sensors and peripheral devices.
<img src="docs/assets/clover42.png" align="right" width="400px" alt="COEX Clover">
Copter Express has implemented a large number of different autonomous drone projects using exactly the same platform: [automated pizza delivery](https://www.youtube.com/watch?v=hmkAoZOtF58) in Samara and Kazan, coffee delivery in Skolkovo Innovation Center, [autonomous quadcopter with charging station](https://www.youtube.com/watch?v=RjX6nUqw1mI) for site monitoring and security, winning drones on [Robocross-2016](https://www.youtube.com/watch?v=dGbDaz_VmYU) and [Robocross-2017](https://youtu.be/AQnd2CRczbQ) competitions and many others.
Clover is a [PX4](https://px4.io)- and [ROS](https://www.ros.org)-powered educational programmable drone kit consisting of an unassembled quadcopter, open source software and documentation. The kit includes Pixracer-compatible autopilot, Raspberry Pi 4 as companion computer, a camera for computer vision navigation as well as additional sensors and peripheral devices.
**The main documentation is available [on Gitbook](https://clever.coex.tech/).**
The main documentation is available at [https://clover.coex.tech](https://clover.coex.tech/). Official website: <a href="https://coex.tech/clover">coex.tech/clover</a>.
Use it to learn how to assemble, configure, pilot and program autonomous CLEVER drone.
## Autonomous flights video
## Raspberry Pi image
[![Clover Drone Kit autonomy compilation](http://img.youtube.com/vi/u3omgsYC4Fk/hqdefault.jpg)](https://youtu.be/u3omgsYC4Fk)
**Preconfigured image for Raspberry Pi 3 with installed and configured software, ready to fly, is available [in the Releases section](https://github.com/CopterExpress/clever/releases).**
Clover drone is used on a wide range of educational events, including [Copter Hack](https://www.youtube.com/watch?v=xgXheg3TTs4), WorldSkills Drone Operation competition, [Autonomous Vehicles Track of NTI Olympics 20162020](https://www.youtube.com/watch?v=E1_ehvJRKxg), Quadro Hack 2019 (National University of Science and Technology MISiS), Russian Robot Olympiad (autonomous flights), and others.
[![Build Status](https://travis-ci.org/CopterExpress/clever.svg?branch=master)](https://travis-ci.org/CopterExpress/clever)
## Features
Image includes:
### Prebuilt RPi image
* Raspbian Buster
* ROS Melodic
* Configured networking
* OpenCV
* mavros
* Periphery drivers (`pigpiod`, `rpi_ws281x`, etc)
* CLEVER software bundle for autonomous drone control
...
### Common robotics software
Prebuilt image for Raspberry Pi includes:
|Software|Description|
|-|-|
|Raspbian Buster||
|[ROS Melodic](http://wiki.ros.org/melodic)|Common robotics framework|
|[OpenCV](https://opencv.org)|Computer vision library|
|[`mavros`](http://wiki.ros.org/mavros)|ROS package for communication with the flight controller|
|Configured networking||
|Periphery drivers for ROS ([GPIO](https://clover.coex.tech/en/gpio.html), [LED strip](https://clover.coex.tech/en/leds.html), etc)||
|`clover`|package for autonomous drone control|
|`aruco_pose`|Package for marker-assisted navigation|
### QGroundControl Wi-Fi bridge
...
### Easy autonomous flights programming
By using `clover` package, taking off, navigating and landing is just:
```python
navigate(x=0, y=0, z=1, frame_id='body', auto_arm=True) # takeoff and hover 1 m above the ground
```
```python
navigate(x=1, y=0, z=0, frame_id='body') # fly forward 1 m
```
```
land()
```
See [programming documentation](https://clover.coex.tech) for further information.
### Optical flow positioning
<img src="docs/assets/optical-flow.gif">
RPi based optical flow....
See [details](https://clover.coex.tech/en/optical_flow.html) in the documentation.
### ArUco markers recognizing
<img src="docs/assets/aruco.gif">
...
See [details](https://clover.coex.tech/en/aruco.html) in the documentation.
### Easy working with peripheral devices
Preinstalled package for the [LED strip](https://clover.coex.tech/en/leds.html) allows high-level control (such as rainbow effect or color fade) as well as individual LED low-level control:
```python
set_effect(r=0, g=100, b=0) # fill strip with green color
```
```python
set_effect(effect='fade', r=0, g=0, b=255) # fade to blue color
```
```python
set_effect(effect='rainbow') # show rainbow
```
Preinstalled [VL53L1X rangefinder driver](https://clover.coex.tech/en/laser.html) passes data to the flight controller automatically and allows the user to get its data:
```python
data = rospy.wait_for_message('rangefinder/range', Range) # get data from the rangefinder
```
Preinstalled fast Python [GPIO library](https://clover.coex.tech/en/gpio.html).
```python
pi.write(11, 1) # set signal of pin 11 to high
```
```python
level = pi.read(12) # read the state of pin 12
```
### Simulator
<img src="docs/assets/simulator.jpg" width=400 align=center>
Clover repository includes three simulation-related repository for Gazebo-based simulation.
Screenshot...
See details in the [documentation](https://clover.coex.tech/en/simulation.html). The simulation environment also available as a virtual machine image.
### Remote control apps
<table>
<tr>
<td>
<a href="https://itunes.apple.com/ru/app/clever-rc/id1396166572?mt=8">
<img src="docs/assets/appstore.svg" height=40>
</a>
</td>
<td>
<a href="https://play.google.com/store/apps/details?id=express.copter.cleverrc">
<img src="docs/assets/google_play.png" height=40>
</a>
</td>
</tr>
</table>
<!-- <a href="https://itunes.apple.com/ru/app/clever-rc/id1396166572?mt=8"><img src="docs/assets/appstore.svg"></a><a href="https://play.google.com/store/apps/details?id=express.copter.cleverrc"><img src="docs/assets/google_play.png" width="15%"></a> -->
### Community
<img src="docs/assets/community/collage.jpg" width=400 align=center>
Clover is widely used ...
[Telegram chat](tg://resolve?domain=COEXHelpdesk)...
### Free and open source
The Clover software bundle is free, open source, and compatible with any PX4/ROS-based drone.
API description (in Russian) for autonomous flights is available [on GitBook](https://clever.coex.tech/simple_offboard.html).
## Manual installation
For manual package installation and running see [`clover` package documentation](clover/README.md).
Install ROS Melodic according to the [documentation](http://wiki.ros.org/melodic/Installation), then [create a Catkin workspace](http://wiki.ros.org/catkin/Tutorials/create_a_workspace).
## PX4 Dev Summit 2019 talk
Clone this repo to directory `~/catkin_ws/src/clever`:
[![](http://img.youtube.com/vi/CTG9E9PbJQ8/0.jpg)](http://www.youtube.com/watch?v=CTG9E9PbJQ8)
```bash
cd ~/catkin_ws/src
git clone https://github.com/CopterExpress/clever.git clever
```
## Other resources
All the required ROS packages (including `mavros` and `opencv`) can be installed using `rosdep`:
* Official documentation: [https://clover.coex.tech](https://clover.coex.tech).
* ROS Wiki page: [https://wiki.ros.org/Robots/clover](https://wiki.ros.org/Robots/clover).
* ROS Robots page: [https://robots.ros.org/clover](https://robots.ros.org/clover).
```bash
cd ~/catkin_ws/
rosdep install -y --from-paths src --ignore-src
```
Build ROS packages (on memory constrained platforms you might be going to need to use `-j1` key):
```bash
cd ~/catkin_ws
catkin_make -j1
```
To complete `mavros` install you'll need to install `geographiclib` datasets:
```bash
curl https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts/install_geographiclib_datasets.sh | sudo bash
```
You may optionally install udev rules to provide `/dev/px4fmu` symlink to your PX4-based flight controller connected over USB. Copy `99-px4fmu.rules` to your `/lib/udev/rules.d` folder:
```bash
cd ~/catkin_ws/src/clever/clever/config
sudo cp 99-px4fmu.rules /lib/udev/rules.d
```
Alternatively you may change the `fcu_url` property in `mavros.launch` file to point to your flight controller device.
## Running
Enable systemd service `roscore` (if not running):
```bash
sudo systemctl enable /home/<username>/catkin_ws/src/clever/builder/assets/roscore.service
sudo systemctl start roscore
```
To start connection to SITL, use:
```bash
roslaunch clever sitl.launch
```
To start connection to the flight controller, use:
```bash
roslaunch clever clever.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`.
Also, you can enable and start the systemd service:
```bash
sudo systemctl enable /home/<username>/catkin_ws/src/clever/deploy/clever.service
sudo systemctl start clever
```
## License
While the Clover platform source code is available under the MIT License, note, that the [documentation](docs/) is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
While the Clever platform source code is available under the MIT License, note, that the [documentation](docs/) is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

View File

View File

@@ -1,6 +1,8 @@
cmake_minimum_required(VERSION 3.0)
project(aruco_pose)
add_definitions(-std=c++11 -Wall -g)
## Compile as C++11, supported in ROS Kinetic and newer
add_compile_options(-std=c++11)
@@ -19,11 +21,10 @@ find_package(catkin REQUIRED COMPONENTS
tf2_geometry_msgs
sensor_msgs
message_generation
dynamic_reconfigure
)
find_package(OpenCV 3 REQUIRED COMPONENTS core imgproc calib3d)
if ("${OpenCV_VERSION_MINOR}" LESS "9")
if ("${OpenCV_VERSION_MINOR}" LESS "3")
message(STATUS "OpenCV version too low, using vendored ArUco package")
include(vendor/VendorOpenCV.cmake)
else()
@@ -110,9 +111,10 @@ generate_messages(
## and list every .cfg file to be processed
## Generate dynamic reconfigure parameters in the 'cfg' folder
generate_dynamic_reconfigure_options(
cfg/DetectorParams.cfg
)
# generate_dynamic_reconfigure_options(
# cfg/DynReconf1.cfg
# cfg/DynReconf2.cfg
# )
###################################
## catkin specific configuration ##
@@ -149,7 +151,7 @@ add_library(aruco_pose
src/draw.cpp
)
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}_generate_messages_cpp ${PROJECT_NAME}_gencfg)
add_dependencies(${PROJECT_NAME} aruco_pose_generate_messages_cpp)
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
@@ -227,5 +229,4 @@ if (CATKIN_ENABLE_TESTING)
add_rostest(test/test_parser_empty_map.test)
add_rostest(test/test_node_failure.test)
add_rostest(test/largemap.test)
add_rostest(test/crash_opencv.test)
endif()

View File

@@ -1,107 +0,0 @@
#!/usr/bin/env python
PACKAGE = "aruco_pose"
from dynamic_reconfigure.parameter_generator_catkin import *
import cv2.aruco
p = cv2.aruco.DetectorParameters_create()
gen = ParameterGenerator()
gen.add("adaptiveThreshConstant", double_t, 0,
"Constant for adaptive thresholding before finding contours",
p.adaptiveThreshConstant, 0, 100)
gen.add("adaptiveThreshWinSizeMin", int_t, 0,
"Minimum window size for adaptive thresholding before finding contours",
p.adaptiveThreshWinSizeMin, 1, 100)
gen.add("adaptiveThreshWinSizeMax", int_t, 0,
"Maximum window size for adaptive thresholding before finding contours",
p.adaptiveThreshWinSizeMax, 1, 100)
gen.add("adaptiveThreshWinSizeStep", int_t, 0,
"Increments from adaptiveThreshWinSizeMin to adaptiveThreshWinSizeMax during the thresholding",
p.adaptiveThreshWinSizeStep, 1, 100)
gen.add("cornerRefinementMaxIterations", int_t, 0,
"Maximum number of iterations for stop criteria of the corner refinement process",
p.cornerRefinementMaxIterations, 1, 1000)
corner_refine_enum = gen.enum([ gen.const("CORNER_REFINE_NONE", int_t, 0, "No refinement"),
gen.const("CORNER_REFINE_SUBPIX", int_t, 1, "Do subpixel refinement"),
gen.const("CORNER_REFINE_CONTOUR", int_t, 2, "Use contour-Points"),
gen.const("CORNER_REFINE_APRILTAG", int_t, 3, "Use the AprilTag2 approach")],
"An enum to set corner refinement method")
gen.add("cornerRefinementMethod", int_t, 0, "Corner refinement method", 0, 0, 3, edit_method=corner_refine_enum)
gen.add("cornerRefinementMinAccuracy", double_t, 0,
"Minimum error for the stop criteria of the corner refinement process",
p.cornerRefinementMinAccuracy, 0, 1)
gen.add("cornerRefinementWinSize", int_t, 0,
"Window size for the corner refinement process (in pixels)",
p.cornerRefinementWinSize, 1, 100)
gen.add("detectInvertedMarker", bool_t, 0,
"check if there is a white marker. In order to generate a 'white' marker just invert a normal marker by using a tilde",
False)
gen.add("errorCorrectionRate", double_t, 0,
"Error correction rate respect to the maximum error correction capability for each dictionary",
p.errorCorrectionRate, 0, 1)
gen.add("minCornerDistanceRate", double_t, 0,
"Minimum distance between corners for detected markers relative to its perimeter",
p.minCornerDistanceRate, 0, 0.25)
gen.add("markerBorderBits", int_t, 0,
"Number of bits of the marker border, i.e. marker border width",
p.markerBorderBits, 1, 10)
gen.add("maxErroneousBitsInBorderRate", double_t, 0,
"Maximum number of accepted erroneous bits in the border (i.e. number of allowed white bits in the border)",
p.maxErroneousBitsInBorderRate, 0, 1)
gen.add("minDistanceToBorder", int_t, 0,
"Minimum distance of any corner to the image border for detected markers (in pixels)",
p.minDistanceToBorder, 0, 1000)
gen.add("minMarkerDistanceRate", double_t, 0,
"minimum mean distance beetween two marker corners to be considered similar, so that the smaller one is removed. The rate is relative to the smaller perimeter of the two markers",
p.minMarkerDistanceRate, 0, 1)
gen.add("minMarkerPerimeterRate", double_t, 0,
"Determine minimum perimeter for marker contour to be detected. This is defined as a rate respect to the maximum dimension of the input image",
p.minMarkerPerimeterRate, 0, 4)
gen.add("maxMarkerPerimeterRate", double_t, 0,
"Determine maximum perimeter for marker contour to be detected. This is defined as a rate respect to the maximum dimension of the input image",
p.maxMarkerPerimeterRate, 0, 4)
gen.add("minOtsuStdDev", double_t, 0,
"Minimun standard deviation in pixels values during the decodification step to apply Otsu thresholding (otherwise, all the bits are set to 0 or 1 depending on mean higher than 128 or not)",
p.minOtsuStdDev, 0, 100)
gen.add("perspectiveRemoveIgnoredMarginPerCell", double_t, 0,
"Width of the margin of pixels on each cell not considered for the determination of the cell bit. Represents the rate respect to the total size of the cell, i.e. perpectiveRemovePixelPerCell",
p.perspectiveRemoveIgnoredMarginPerCell, 0, 1)
gen.add("perspectiveRemovePixelPerCell", int_t, 0,
"Number of bits (per dimension) for each cell of the marker when removing the perspective",
p.perspectiveRemovePixelPerCell, 1, 100)
gen.add("polygonalApproxAccuracyRate", double_t, 0,
"Minimum accuracy during the polygonal approximation process to determine which contours are squares",
p.polygonalApproxAccuracyRate, 0, 1)
gen.add("aprilTagQuadDecimate", double_t, 0,
"Detection of quads can be done on a lower-resolution image, improving speed at a cost of pose accuracy and a slight decrease in detection rate. Decoding the binary payload is still done at full resolution",
0, 0, 1000)
gen.add("aprilTagQuadSigma", double_t, 0,
"What Gaussian blur should be applied to the segmented image (used for quad detection?) Parameter is the standard deviation in pixels. Very noisy images benefit from non-zero values",
0, 0, 1000)
exit(gen.generate(PACKAGE, "aruco_pose", "Detector"))

View File

@@ -1,4 +1,3 @@
# id length x y z rot_z rot_y rot_x
1 0.33 0 0 0 0 0 0
2 0.33 1 0 0 0 0 0
3 0.33 0 1 0 0 0 0

View File

@@ -18,6 +18,8 @@
<depend>tf2</depend>
<depend>tf2_ros</depend>
<depend>tf2_geometry_msgs</depend>
<!-- FIXME: OpenCV3 is not in Melodic -->
<!-- <depend>opencv3</depend> -->
<depend>cv_bridge</depend>
<depend>image_transport</depend>
<depend>message_generation</depend>
@@ -27,7 +29,6 @@
<depend>visualization_msgs</depend>
<depend>sensor_msgs</depend>
<depend>rostest</depend>
<depend>dynamic_reconfigure</depend>
<test_depend>image_publisher</test_depend>
<test_depend>ros_pytest</test_depend>

View File

@@ -30,7 +30,6 @@
#include <tf2_geometry_msgs/tf2_geometry_msgs.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <dynamic_reconfigure/server.h>
#include <geometry_msgs/Vector3.h>
#include <geometry_msgs/Pose.h>
#include <geometry_msgs/PoseStamped.h>
@@ -47,21 +46,18 @@
#include <aruco_pose/Marker.h>
#include <aruco_pose/MarkerArray.h>
#include <aruco_pose/DetectorConfig.h>
#include "utils.h"
#include <memory>
#include <functional>
using std::vector;
using cv::Mat;
class ArucoDetect : public nodelet::Nodelet {
private:
std::unique_ptr<tf2_ros::TransformBroadcaster> br_;
std::unique_ptr<tf2_ros::Buffer> tf_buffer_;
std::unique_ptr<tf2_ros::TransformListener> tf_listener_;
std::shared_ptr<dynamic_reconfigure::Server<aruco_pose::DetectorConfig>> dyn_srv_;
ros::NodeHandle nh_, nh_priv_;
tf2_ros::TransformBroadcaster br_;
tf2_ros::Buffer tf_buffer_;
tf2_ros::TransformListener tf_listener_{tf_buffer_};
cv::Ptr<cv::aruco::Dictionary> dictionary_;
cv::Ptr<cv::aruco::DetectorParameters> parameters_;
image_transport::Publisher debug_pub_;
@@ -80,32 +76,30 @@ private:
public:
virtual void onInit()
{
ros::NodeHandle& nh_ = getNodeHandle();
ros::NodeHandle& nh_priv_ = getPrivateNodeHandle();
br_.reset(new tf2_ros::TransformBroadcaster());
tf_buffer_.reset(new tf2_ros::Buffer());
tf_listener_.reset(new tf2_ros::TransformListener(*tf_buffer_, nh_));
nh_ = getNodeHandle();
nh_priv_ = getPrivateNodeHandle();
int dictionary;
dictionary = nh_priv_.param("dictionary", 2);
estimate_poses_ = nh_priv_.param("estimate_poses", true);
send_tf_ = nh_priv_.param("send_tf", true);
nh_priv_.param("dictionary", dictionary, 2);
nh_priv_.param("estimate_poses", estimate_poses_, true);
nh_priv_.param("send_tf", send_tf_, true);
if (estimate_poses_ && !nh_priv_.getParam("length", length_)) {
NODELET_FATAL("can't estimate marker's poses as ~length parameter is not defined");
ros::shutdown();
}
readLengthOverride(nh_priv_);
readLengthOverride();
known_tilt_ = nh_priv_.param<std::string>("known_tilt", "");
auto_flip_ = nh_priv_.param("auto_flip", false);
nh_priv_.param<std::string>("known_tilt", known_tilt_, "");
nh_priv_.param("auto_flip", auto_flip_, false);
frame_id_prefix_ = nh_priv_.param<std::string>("frame_id_prefix", "aruco_");
nh_priv_.param<std::string>("frame_id_prefix", frame_id_prefix_, "aruco_");
camera_matrix_ = cv::Mat::zeros(3, 3, CV_64F);
dist_coeffs_ = cv::Mat::zeros(8, 1, CV_64F);
dictionary_ = cv::aruco::getPredefinedDictionary(static_cast<cv::aruco::PREDEFINED_DICTIONARY_NAME>(dictionary));
parameters_ = cv::aruco::DetectorParameters::create();
parameters_->cornerRefinementMethod = cv::aruco::CORNER_REFINE_SUBPIX;
image_transport::ImageTransport it(nh_);
image_transport::ImageTransport it_priv(nh_priv_);
@@ -116,12 +110,6 @@ public:
vis_markers_pub_ = nh_priv_.advertise<visualization_msgs::MarkerArray>("visualization", 1);
img_sub_ = it.subscribeCamera("image_raw", 1, &ArucoDetect::imageCallback, this);
dyn_srv_ = std::make_shared<dynamic_reconfigure::Server<aruco_pose::DetectorConfig>>(nh_priv_);
dynamic_reconfigure::Server<aruco_pose::DetectorConfig>::CallbackType cb;
cb = std::bind(&ArucoDetect::paramCallback, this, std::placeholders::_1, std::placeholders::_2);
dyn_srv_->setCallback(cb);
NODELET_INFO("ready");
}
@@ -171,8 +159,8 @@ private:
if (!known_tilt_.empty()) {
try {
snap_to = tf_buffer_->lookupTransform(msg->header.frame_id, known_tilt_,
msg->header.stamp, ros::Duration(0.02));
snap_to = tf_buffer_.lookupTransform(msg->header.frame_id, known_tilt_,
msg->header.stamp, ros::Duration(0.02));
} catch (const tf2::TransformException& e) {
NODELET_WARN_THROTTLE(5, "can't snap: %s", e.what());
}
@@ -206,7 +194,7 @@ private:
if (map_markers_ids_.find(ids[i]) == map_markers_ids_.end()) {
transform.transform.rotation = marker.pose.orientation;
fillTranslation(transform.transform.translation, tvecs[i]);
br_->sendTransform(transform);
br_.sendTransform(transform);
}
}
}
@@ -327,10 +315,10 @@ private:
return frame_id_prefix_ + std::to_string(id);
}
void readLengthOverride(ros::NodeHandle& nh)
void readLengthOverride()
{
std::map<std::string, double> length_override;
nh.getParam("length_override", length_override);
nh_priv_.getParam("length_override", length_override);
for (auto const& item : length_override) {
length_override_[std::stoi(item.first)] = item.second;
}
@@ -353,37 +341,6 @@ private:
map_markers_ids_.insert(marker.id);
}
}
void paramCallback(aruco_pose::DetectorConfig &config, uint32_t level)
{
parameters_->adaptiveThreshConstant = config.adaptiveThreshConstant;
parameters_->adaptiveThreshWinSizeMin = config.adaptiveThreshWinSizeMin;
parameters_->adaptiveThreshWinSizeMax = config.adaptiveThreshWinSizeMax;
parameters_->adaptiveThreshWinSizeStep = config.adaptiveThreshWinSizeStep;
parameters_->cornerRefinementMaxIterations = config.cornerRefinementMaxIterations;
parameters_->cornerRefinementMethod = config.cornerRefinementMethod;
parameters_->cornerRefinementMinAccuracy = config.cornerRefinementMinAccuracy;
parameters_->cornerRefinementWinSize = config.cornerRefinementWinSize;
#if ((CV_VERSION_MAJOR == 3) && (CV_VERSION_MINOR >= 4) && (CV_VERSION_REVISION >= 7)) || (CV_VERSION_MAJOR > 3)
parameters_->detectInvertedMarker = config.detectInvertedMarker;
#endif
parameters_->errorCorrectionRate = config.errorCorrectionRate;
parameters_->minCornerDistanceRate = config.minCornerDistanceRate;
parameters_->markerBorderBits = config.markerBorderBits;
parameters_->maxErroneousBitsInBorderRate = config.maxErroneousBitsInBorderRate;
parameters_->minDistanceToBorder = config.minDistanceToBorder;
parameters_->minMarkerDistanceRate = config.minMarkerDistanceRate;
parameters_->minMarkerPerimeterRate = config.minMarkerPerimeterRate;
parameters_->maxMarkerPerimeterRate = config.maxMarkerPerimeterRate;
parameters_->minOtsuStdDev = config.minOtsuStdDev;
parameters_->perspectiveRemoveIgnoredMarginPerCell = config.perspectiveRemoveIgnoredMarginPerCell;
parameters_->perspectiveRemovePixelPerCell = config.perspectiveRemovePixelPerCell;
parameters_->polygonalApproxAccuracyRate = config.polygonalApproxAccuracyRate;
#if ((CV_VERSION_MAJOR == 3) && (CV_VERSION_MINOR >= 4) && (CV_VERSION_REVISION >= 2)) || (CV_VERSION_MAJOR > 3)
parameters_->aprilTagQuadDecimate = config.aprilTagQuadDecimate;
parameters_->aprilTagQuadSigma = config.aprilTagQuadSigma;
#endif
}
};
PLUGINLIB_EXPORT_CLASS(ArucoDetect, nodelet::Nodelet)

View File

@@ -58,6 +58,7 @@ typedef message_filters::sync_policies::ExactTime<Image, CameraInfo, MarkerArray
class ArucoMap : public nodelet::Nodelet {
private:
ros::NodeHandle nh_, nh_priv_;
ros::Publisher img_pub_, pose_pub_, markers_pub_, vis_markers_pub_;
image_transport::Publisher debug_pub_;
message_filters::Subscriber<Image> image_sub_;
@@ -82,8 +83,8 @@ private:
public:
virtual void onInit()
{
ros::NodeHandle &nh_ = getNodeHandle();
ros::NodeHandle &nh_priv_ = getPrivateNodeHandle();
nh_ = getNodeHandle();
nh_priv_ = getPrivateNodeHandle();
image_transport::ImageTransport it_priv(nh_priv_);
@@ -95,18 +96,19 @@ public:
board_->dictionary = cv::aruco::getPredefinedDictionary(
static_cast<cv::aruco::PREDEFINED_DICTIONARY_NAME>(nh_priv_.param("dictionary", 2)));
camera_matrix_ = cv::Mat::zeros(3, 3, CV_64F);
dist_coeffs_ = cv::Mat::zeros(8, 1, CV_64F);
std::string type, map;
type = nh_priv_.param<std::string>("type", "map");
transform_.child_frame_id = nh_priv_.param<std::string>("frame_id", "aruco_map");
known_tilt_ = nh_priv_.param<std::string>("known_tilt", "");
auto_flip_ = nh_priv_.param("auto_flip", false);
image_width_ = nh_priv_.param("image_width" , 2000);
image_height_ = nh_priv_.param("image_height", 2000);
image_margin_ = nh_priv_.param("image_margin", 200);
image_axis_ = nh_priv_.param("image_axis", true);
markers_parent_frame_ = nh_priv_.param<std::string>("markers/frame_id", transform_.child_frame_id);
markers_frame_ = nh_priv_.param<std::string>("markers/child_frame_id_prefix", "");
nh_priv_.param<std::string>("type", type, "map");
nh_priv_.param<std::string>("frame_id", transform_.child_frame_id, "aruco_map");
nh_priv_.param<std::string>("known_tilt", known_tilt_, "");
nh_priv_.param("auto_flip", auto_flip_, false);
nh_priv_.param("image_width", image_width_, 2000);
nh_priv_.param("image_height", image_height_, 2000);
nh_priv_.param("image_margin", image_margin_, 200);
nh_priv_.param("image_axis", image_axis_, true);
nh_priv_.param<std::string>("markers/frame_id", markers_parent_frame_, transform_.child_frame_id);
nh_priv_.param<std::string>("markers/child_frame_id_prefix", markers_frame_, "");
// createStripLine();
@@ -114,7 +116,7 @@ public:
param(nh_priv_, "map", map);
loadMap(map);
} else if (type == "gridboard") {
createGridBoard(nh_priv_);
createGridBoard();
} else {
NODELET_FATAL("unknown type: %s", type.c_str());
ros::shutdown();
@@ -329,7 +331,7 @@ publish_debug:
NODELET_INFO("loading %s complete (%d markers)", filename.c_str(), static_cast<int>(board_->ids.size()));
}
void createGridBoard(ros::NodeHandle& nh)
void createGridBoard()
{
NODELET_INFO("generate gridboard");
NODELET_WARN("gridboard maps are deprecated");
@@ -337,15 +339,15 @@ publish_debug:
int markers_x, markers_y, first_marker;
double markers_side, markers_sep_x, markers_sep_y;
std::vector<int> marker_ids;
markers_x = nh.param("markers_x", 10);
markers_y = nh.param("markers_y", 10);
first_marker = nh.param("first_marker", 0);
nh_priv_.param<int>("markers_x", markers_x, 10);
nh_priv_.param<int>("markers_y", markers_y, 10);
nh_priv_.param<int>("first_marker", first_marker, 0);
param(nh, "markers_side", markers_side);
param(nh, "markers_sep_x", markers_sep_x);
param(nh, "markers_sep_y", markers_sep_y);
param(nh_priv_, "markers_side", markers_side);
param(nh_priv_, "markers_sep_x", markers_sep_x);
param(nh_priv_, "markers_sep_y", markers_sep_y);
if (nh.getParam("marker_ids", marker_ids)) {
if (nh_priv_.getParam("marker_ids", marker_ids)) {
if ((unsigned int)(markers_x * markers_y) != marker_ids.size()) {
NODELET_FATAL("~marker_ids length should be equal to ~markers_x * ~markers_y");
ros::shutdown();
@@ -392,7 +394,7 @@ publish_debug:
int num_markers = board_->dictionary->bytesList.rows;
if (num_markers <= id) {
NODELET_ERROR("Marker id %d is not in dictionary; current dictionary contains %d markers. "
"Please see https://github.com/CopterExpress/clover/blob/master/aruco_pose/README.md#parameters for details",
"Please see https://github.com/CopterExpress/clever/blob/master/aruco_pose/README.md#parameters for details",
id, num_markers);
return;
}

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# Copyright (C) 2018 Copter Express Technologies
#
@@ -13,21 +13,17 @@
Generate map file for aruco_map nodelet.
Usage:
genmap.py <length> <x> <y> <dist_x> <dist_y> [<first>] [--top-left | --bottom-left]
genmap.py <length> <x> <y> <dist_x> <dist_y> <first> [--top-left]
genmap.py (-h | --help)
Options:
<length> Marker side length
<x> Marker count along X axis
<y> Marker count along Y axis
<dist_x> Distance between markers along X axis
<dist_y> Distance between markers along Y axis
<first> First marker ID [default: 0]
--top-left First marker is on top-left (default)
--bottom-left First marker is on bottom-left
Example:
rosrun aruco_pose genmap.py 0.33 2 4 1 1 0 > $(catkin_find aruco_pose map)/test_map.txt
<length> Marker side length
<x> Marker count along X axis
<y> Marker count along Y axis
<dist_x> Distance between markers along X axis
<dist_y> Distance between markers along Y axis
<first> First marker ID
--top-left First marker is on top-left (not bottom-left)
"""
from __future__ import print_function
@@ -38,21 +34,20 @@ from docopt import docopt
arguments = docopt(__doc__)
length = float(arguments['<length>'])
first = int(arguments['<first>'] if arguments['<first>'] is not None else 0)
first = int(arguments['<first>'])
markers_x = int(arguments['<x>'])
markers_y = int(arguments['<y>'])
dist_x = float(arguments['<dist_x>'])
dist_y = float(arguments['<dist_y>'])
bottom_left = arguments['--bottom-left']
top_left = arguments['--top-left']
max_y = (markers_y - 1) * dist_y
print('# id\tlength\tx\ty\tz\trot_z\trot_y\trot_x')
for y in range(markers_y):
for x in range(markers_x):
pos_x = x * dist_x
pos_y = y * dist_y
if not bottom_left:
if top_left:
pos_y = max_y - pos_y
print('{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t'.format(first, length, pos_x, pos_y, 0, 0, 0, 0))
first += 1

View File

@@ -35,7 +35,9 @@ static void parseCameraInfo(const sensor_msgs::CameraInfoConstPtr& cinfo, cv::Ma
for (unsigned int i = 0; i < 3; ++i)
for (unsigned int j = 0; j < 3; ++j)
matrix.at<double>(i, j) = cinfo->K[3 * i + j];
dist = cv::Mat(cinfo->D, true);
for (unsigned int k = 0; k < cinfo->D.size(); k++)
dist.at<double>(k) = cinfo->D[k];
}
inline void rotatePoint(cv::Point3f& p, cv::Point3f origin, float angle)

View File

@@ -14,7 +14,6 @@
<param name="length_override/3" value="0.1"/>
<param name="estimate_poses" value="true"/>
<param name="send_tf" value="true"/>
<param name="cornerRefinementMethod" value="1"/>
</node>
<node name="aruco_map" pkg="nodelet" type="nodelet" args="load aruco_pose/aruco_map nodelet_manager" clear_params="true" required="true">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 KiB

View File

@@ -1,18 +0,0 @@
import rospy
import pytest
from visualization_msgs.msg import MarkerArray as VisMarkerArray
@pytest.fixture
def node():
return rospy.init_node('aruco_pose_opencv_crash', anonymous=True)
def test_opencv_crashes_img01(node):
rospy.wait_for_message('aruco_detect_01/visualization', VisMarkerArray, timeout=5)
def test_opencv_crashes_img02(node):
rospy.wait_for_message('aruco_detect_02/visualization', VisMarkerArray, timeout=5)
def test_opencv_crashes_img03(node):
rospy.wait_for_message('aruco_detect_03/visualization', VisMarkerArray, timeout=5)

View File

@@ -1,51 +0,0 @@
<launch>
<arg name="corner_method" default="2"/>
<node pkg="image_publisher" type="image_publisher" name="imgpub_01" args="$(find aruco_pose)/test/crash_image_01.png">
<param name="frame_id" value="main_camera_optical"/>
<param name="publish_rate" value="10"/>
<param name="camera_info_url" value="file://$(find aruco_pose)/test/camera_info.yaml" />
</node>
<node pkg="image_publisher" type="image_publisher" name="imgpub_02" args="$(find aruco_pose)/test/crash_image_02.png">
<param name="frame_id" value="main_camera_optical"/>
<param name="publish_rate" value="10"/>
<param name="camera_info_url" value="file://$(find aruco_pose)/test/camera_info.yaml" />
</node>
<node pkg="image_publisher" type="image_publisher" name="imgpub_03" args="$(find aruco_pose)/test/crash_image_03.png">
<param name="frame_id" value="main_camera_optical"/>
<param name="publish_rate" value="10"/>
<param name="camera_info_url" value="file://$(find aruco_pose)/test/camera_info.yaml" />
</node>
<node pkg="nodelet" type="nodelet" name="nodelet_manager_01" args="manager"/>
<node pkg="nodelet" clear_params="true" type="nodelet" name="aruco_detect_01" args="load aruco_pose/aruco_detect nodelet_manager_01">
<remap from="image_raw" to="imgpub_01/image_raw"/>
<remap from="camera_info" to="imgpub_01/camera_info"/>
<param name="length" value="0.33"/>
<param name="cornerRefinementMethod" value="$(arg corner_method)"/>
</node>
<node pkg="nodelet" type="nodelet" name="nodelet_manager_02" args="manager"/>
<node pkg="nodelet" clear_params="true" type="nodelet" name="aruco_detect_02" args="load aruco_pose/aruco_detect nodelet_manager_02">
<remap from="image_raw" to="imgpub_02/image_raw"/>
<remap from="camera_info" to="imgpub_02/camera_info"/>
<param name="length" value="0.33"/>
<param name="cornerRefinementMethod" value="$(arg corner_method)"/>
</node>
<node pkg="nodelet" type="nodelet" name="nodelet_manager_03" args="manager"/>
<node pkg="nodelet" clear_params="true" type="nodelet" name="aruco_detect_03" args="load aruco_pose/aruco_detect nodelet_manager_03">
<remap from="image_raw" to="imgpub_03/image_raw"/>
<remap from="camera_info" to="imgpub_03/camera_info"/>
<param name="length" value="0.33"/>
<param name="cornerRefinementMethod" value="$(arg corner_method)"/>
</node>
<param name="test_module" value="$(find aruco_pose)/test/crash_opencv.py"/>
<test test-name="crash_opencv" pkg="ros_pytest" type="ros_pytest_runner"/>
</launch>

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import sys
import unittest
import json

View File

@@ -924,8 +924,6 @@ static void _refineCandidateLines(std::vector<Point>& nContours, std::vector<Poi
// calculate the line :: who passes through the grouped points
Point3f lines[4];
for(int i=0; i<4; i++){
// Don't try to "interpolate" single points
if (cntPts[i].size() < 2) return;
lines[i]=_interpolate2Dline(cntPts[i]);
}

View File

@@ -1,5 +1,5 @@
{
"title": "Clover",
"title": "Clever",
"description": "Конструктор квадрокоптера «Клевер»",
"author": "Copter Express",
"language": "en",
@@ -28,7 +28,7 @@
"blank": true
},
"sitemap": {
"hostname": "https://clover.coex.tech"
"hostname": "https://clever.coex.tech"
},
"toolbar": {
"buttons":
@@ -37,19 +37,19 @@
"label": "Edit page on github",
"icon": "fa fa-pencil-square-o",
"position" : "left",
"url": "https://github.com/CopterExpress/clover/edit/master/docs/{{filepath_lang}}"
"url": "https://github.com/CopterExpress/clever/edit/master/docs/{{filepath_lang}}"
},
{
"label": "GitHub",
"icon": "fa fa-github",
"position" : "left",
"url": "https://github.com/CopterExpress/clover"
"url": "https://github.com/CopterExpress/clever"
}
]
},
"addcssjs": {
"css": ["../clover.css"],
"js": ["../clover.js"]
"css": ["../clever.css"],
"js": ["../clever.js"]
},
"language-picker": {
"languages": [["ru", "Russian"], ["en", "English"]]

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<!--
This file is part of avahi.
avahi is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
avahi is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with avahi; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
-->
<!-- See avahi.service(5) for more information about this configuration file -->
<service-group>
<name replace-wildcards="yes">%h</name>
<service>
<type>_sftp-ssh._tcp</type>
<port>22</port>
</service>
</service-group>

View File

@@ -2,5 +2,5 @@
Description=Butterfly Terminal Server
[Service]
ExecStart=/usr/local/bin/butterfly.server.py --host="0.0.0.0" --unsecure
ExecStart=/bin/bash -c ". /root/butterfly_env/bin/activate; butterfly.server.py --host="0.0.0.0" --unsecure"
User=pi

View File

@@ -1,12 +1,13 @@
[Unit]
Description=Clover ROS package
Description=Clever ROS package
Requires=roscore.service
After=network.target
[Service]
User=pi
ExecStart=/bin/bash -c ". /home/pi/catkin_ws/devel/setup.sh; \
ROS_HOSTNAME=`hostname`.local exec stdbuf -o L roslaunch clover clover.launch --wait --screen --skip-log-check \
2> >(tee /tmp/clover.err)"
ROS_HOSTNAME=`hostname`.local exec stdbuf -o L roslaunch clever clever.launch --wait --screen --skip-log-check \
2> >(tee /tmp/clever.err)"
[Install]
WantedBy=multi-user.target

View File

@@ -1,3 +0,0 @@
print("Warning: clever package is renamed to clover")
from clover.srv import *

View File

@@ -1,10 +0,0 @@
#!/usr/bin/env python
from distutils.core import setup
setup(name='clever',
version='1.0',
description='Clever transitional package for backwards compatibility',
author='Oleg Kalachev',
packages=['clever'],
)

View File

@@ -1,31 +0,0 @@
# Information: https://clover.coex.tech/programming
import rospy
from clover import srv
from std_srvs.srv import Trigger
rospy.init_node('flight')
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)
navigate = rospy.ServiceProxy('navigate', srv.Navigate)
navigate_global = rospy.ServiceProxy('navigate_global', srv.NavigateGlobal)
set_position = rospy.ServiceProxy('set_position', srv.SetPosition)
set_velocity = rospy.ServiceProxy('set_velocity', srv.SetVelocity)
set_attitude = rospy.ServiceProxy('set_attitude', srv.SetAttitude)
set_rates = rospy.ServiceProxy('set_rates', srv.SetRates)
land = rospy.ServiceProxy('land', Trigger)
# Take off and hover 1 m above the ground
navigate(x=0, y=0, z=1, frame_id='body', auto_arm=True)
# Wait for 3 seconds
rospy.sleep(3)
# Fly forward 1 m
navigate(x=1, y=0, z=0, frame_id='body')
# Wait for 3 seconds
rospy.sleep(3)
# Perform landing
land()

View File

@@ -1,37 +0,0 @@
# Information: https://clover.coex.tech/en/aruco.html
import rospy
from clover import srv
from std_srvs.srv import Trigger
rospy.init_node('flight')
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)
navigate = rospy.ServiceProxy('navigate', srv.Navigate)
navigate_global = rospy.ServiceProxy('navigate_global', srv.NavigateGlobal)
set_position = rospy.ServiceProxy('set_position', srv.SetPosition)
set_velocity = rospy.ServiceProxy('set_velocity', srv.SetVelocity)
set_attitude = rospy.ServiceProxy('set_attitude', srv.SetAttitude)
set_rates = rospy.ServiceProxy('set_rates', srv.SetRates)
land = rospy.ServiceProxy('land', Trigger)
# Take off and hover 1 m above the ground
navigate(x=0, y=0, z=1, frame_id='body', auto_arm=True)
# Wait for 3 seconds
rospy.sleep(3)
# Fly 1 meter above ArUco marker 0
navigate(x=0, y=0, z=1, frame_id='aruco_0')
# Wait for 3 seconds
rospy.sleep(3)
# Fly to x=1 y=1 z=1 relative to ArUco markers map
navigate(x=1, y=1, z=1, frame_id='aruco_map')
# Wait for 3 seconds
rospy.sleep(3)
# Perform landing
land()

View File

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

View File

@@ -1,41 +0,0 @@
# Information: https://clover.coex.tech/en/snippets.html#block-nav
import math
import rospy
from clover import srv
from std_srvs.srv import Trigger
rospy.init_node('flight')
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)
navigate = rospy.ServiceProxy('navigate', srv.Navigate)
navigate_global = rospy.ServiceProxy('navigate_global', srv.NavigateGlobal)
set_position = rospy.ServiceProxy('set_position', srv.SetPosition)
set_velocity = rospy.ServiceProxy('set_velocity', srv.SetVelocity)
set_attitude = rospy.ServiceProxy('set_attitude', srv.SetAttitude)
set_rates = rospy.ServiceProxy('set_rates', srv.SetRates)
land = rospy.ServiceProxy('land', Trigger)
def navigate_wait(x=0, y=0, z=0, yaw=float('nan'), yaw_rate=0, speed=0.5, \
frame_id='body', tolerance=0.2, auto_arm=False):
res = navigate(x=x, y=y, z=z, yaw=yaw, yaw_rate=yaw_rate, speed=speed, \
frame_id=frame_id, auto_arm=auto_arm)
if not res.success:
return res
while not rospy.is_shutdown():
telem = get_telemetry(frame_id='navigate_target')
if math.sqrt(telem.x ** 2 + telem.y ** 2 + telem.z ** 2) < tolerance:
return res
rospy.sleep(0.2)
# Take off 1 meter
navigate_wait(z=1, frame_id='body', auto_arm=True)
# Fly forward 1 m
navigate_wait(x=1, frame_id='body')
# Land
land()

View File

@@ -35,26 +35,9 @@ echo_stamp() {
echo -e ${TEXT}
}
NEW_SSID='clover-'$(head -c 100 /dev/urandom | xxd -ps -c 100 | sed -e "s/[^0-9]//g" | cut -c 1-4)
NEW_SSID='CLEVER-'$(head -c 100 /dev/urandom | xxd -ps -c 100 | sed -e "s/[^0-9]//g" | cut -c 1-4)
echo_stamp "Setting SSID to ${NEW_SSID}"
# TODO: Use wpa_cli insted direct file edit
# FIXME: We rely on raspberrypi-net-mods to copy our file to /etc/wpa_supplicant.
# This is not very reliable, but seems to fix our rfkill problem.
cat << EOF >> /boot/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=GB
network={
ssid="${NEW_SSID}"
psk="cloverwifi"
mode=2
proto=WPA RSN
key_mgmt=WPA-PSK
pairwise=CCMP
group=CCMP
auth_alg=OPEN
}
EOF
sudo sed -i.OLD "s/CLEVER/${NEW_SSID}/" /etc/wpa_supplicant/wpa_supplicant.conf
NEW_HOSTNAME=$(echo ${NEW_SSID} | tr '[:upper:]' '[:lower:]')
echo_stamp "Setting hostname to $NEW_HOSTNAME"
@@ -62,10 +45,6 @@ hostnamectl set-hostname $NEW_HOSTNAME
sed -i 's/127\.0\.1\.1.*/127.0.1.1\t'${NEW_HOSTNAME}' '${NEW_HOSTNAME}'.local/g' /etc/hosts
# .local (mdns) hostname added to make it accesable when wlan and ethernet interfaces are down
echo_stamp "Enable ROS services"
systemctl enable roscore
systemctl enable clover
echo_stamp "Harware setup"
/root/hardware_setup.sh

View File

@@ -1,735 +1,723 @@
catkin:
debian:
buster: [ros-melodic-catkin]
buster: ros-melodic-catkin
genmsg:
debian:
buster: [ros-melodic-genmsg]
buster: ros-melodic-genmsg
gencpp:
debian:
buster: [ros-melodic-gencpp]
buster: ros-melodic-gencpp
geneus:
debian:
buster: [ros-melodic-geneus]
buster: ros-melodic-geneus
genlisp:
debian:
buster: [ros-melodic-genlisp]
buster: ros-melodic-genlisp
gennodejs:
debian:
buster: [ros-melodic-gennodejs]
buster: ros-melodic-gennodejs
genpy:
debian:
buster: [ros-melodic-genpy]
buster: ros-melodic-genpy
bond_core:
debian:
buster: [ros-melodic-bond-core]
buster: ros-melodic-bond-core
cmake_modules:
debian:
buster: [ros-melodic-cmake-modules]
buster: ros-melodic-cmake-modules
class_loader:
debian:
buster: [ros-melodic-class-loader]
buster: ros-melodic-class-loader
common_msgs:
debian:
buster: [ros-melodic-common-msgs]
buster: ros-melodic-common-msgs
common_tutorials:
debian:
buster: [ros-melodic-common-tutorials]
buster: ros-melodic-common-tutorials
cpp_common:
debian:
buster: [ros-melodic-cpp-common]
buster: ros-melodic-cpp-common
desktop:
debian:
buster: [ros-melodic-desktop]
buster: ros-melodic-desktop
diagnostics:
debian:
buster: [ros-melodic-diagnostics]
buster: ros-melodic-diagnostics
executive_smach:
debian:
buster: [ros-melodic-executive-smach]
buster: ros-melodic-executive-smach
geometry:
debian:
buster: [ros-melodic-geometry]
buster: ros-melodic-geometry
geometry_tutorials:
debian:
buster: [ros-melodic-geometry-tutorials]
buster: ros-melodic-geometry-tutorials
gl_dependency:
debian:
buster: [ros-melodic-gl-dependency]
buster: ros-melodic-gl-dependency
image_common:
debian:
buster: [ros-melodic-image-common]
buster: ros-melodic-image-common
image_pipeline:
debian:
buster: [ros-melodic-image-pipeline]
buster: ros-melodic-image-pipeline
image_transport_plugins:
debian:
buster: [ros-melodic-image-transport-plugins]
buster: ros-melodic-image-transport-plugins
laser_pipeline:
debian:
buster: [ros-melodic-laser-pipeline]
buster: ros-melodic-laser-pipeline
mavlink:
debian:
buster: [ros-melodic-mavlink]
buster: ros-melodic-mavlink
media_export:
debian:
buster: [ros-melodic-media-export]
buster: ros-melodic-media-export
message_generation:
debian:
buster: [ros-melodic-message-generation]
buster: ros-melodic-message-generation
message_runtime:
debian:
buster: [ros-melodic-message-runtime]
buster: ros-melodic-message-runtime
mk:
debian:
buster: [ros-melodic-mk]
buster: ros-melodic-mk
nodelet_core:
debian:
buster: [ros-melodic-nodelet-core]
buster: ros-melodic-nodelet-core
orocos_kdl:
debian:
buster: [ros-melodic-orocos-kdl]
buster: ros-melodic-orocos-kdl
perception:
debian:
buster: [ros-melodic-perception]
buster: ros-melodic-perception
perception_pcl:
debian:
buster: [ros-melodic-perception-pcl]
buster: ros-melodic-perception-pcl
python_orocos_kdl:
debian:
buster: [ros-melodic-python-orocos-kdl]
buster: ros-melodic-python-orocos-kdl
qt_dotgraph:
debian:
buster: [ros-melodic-qt-dotgraph]
buster: ros-melodic-qt-dotgraph
qt_gui:
debian:
buster: [ros-melodic-qt-gui]
buster: ros-melodic-qt-gui
qt_gui_py_common:
debian:
buster: [ros-melodic-qt-gui-py-common]
buster: ros-melodic-qt-gui-py-common
qwt_dependency:
debian:
buster: [ros-melodic-qwt-dependency]
buster: ros-melodic-qwt-dependency
robot:
debian:
buster: [ros-melodic-robot]
buster: ros-melodic-robot
ros:
debian:
buster: [ros-melodic-ros]
buster: ros-melodic-ros
ros_base:
debian:
buster: [ros-melodic-ros-base]
buster: ros-melodic-ros-base
ros_comm:
debian:
buster: [ros-melodic-ros-comm]
buster: ros-melodic-ros-comm
ros_core:
debian:
buster: [ros-melodic-ros-core]
buster: ros-melodic-ros-core
ros_environment:
debian:
buster: [ros-melodic-ros-environment]
buster: ros-melodic-ros-environment
ros_tutorials:
debian:
buster: [ros-melodic-ros-tutorials]
buster: ros-melodic-ros-tutorials
rosapi:
debian:
buster: [ros-melodic-rosapi]
buster: ros-melodic-rosapi
rosbag_migration_rule:
debian:
buster: [ros-melodic-rosbag-migration-rule]
buster: ros-melodic-rosbag-migration-rule
rosbash:
debian:
buster: [ros-melodic-rosbash]
buster: ros-melodic-rosbash
rosboost_cfg:
debian:
buster: [ros-melodic-rosboost-cfg]
buster: ros-melodic-rosboost-cfg
rosbridge_server:
debian:
buster: [ros-melodic-rosbridge-server]
buster: ros-melodic-rosbridge-server
rosbridge_suite:
debian:
buster: [ros-melodic-rosbridge-suite]
buster: ros-melodic-rosbridge-suite
rosbuild:
debian:
buster: [ros-melodic-rosbuild]
buster: ros-melodic-rosbuild
rosclean:
debian:
buster: [ros-melodic-rosclean]
buster: ros-melodic-rosclean
roscpp_core:
debian:
buster: [ros-melodic-roscpp-core]
buster: ros-melodic-roscpp-core
roscpp_traits:
debian:
buster: [ros-melodic-roscpp-traits]
buster: ros-melodic-roscpp-traits
roscreate:
debian:
buster: [ros-melodic-roscreate]
buster: ros-melodic-roscreate
rosgraph:
debian:
buster: [ros-melodic-rosgraph]
buster: ros-melodic-rosgraph
roslang:
debian:
buster: [ros-melodic-roslang]
buster: ros-melodic-roslang
roslint:
debian:
buster: [ros-melodic-roslint]
buster: ros-melodic-roslint
roslisp:
debian:
buster: [ros-melodic-roslisp]
buster: ros-melodic-roslisp
rosmake:
debian:
buster: [ros-melodic-rosmake]
buster: ros-melodic-rosmake
rosmaster:
debian:
buster: [ros-melodic-rosmaster]
buster: ros-melodic-rosmaster
rospack:
debian:
buster: [ros-melodic-rospack]
buster: ros-melodic-rospack
roslib:
debian:
buster: [ros-melodic-roslib]
buster: ros-melodic-roslib
rosparam:
debian:
buster: [ros-melodic-rosparam]
buster: ros-melodic-rosparam
rospy:
debian:
buster: [ros-melodic-rospy]
buster: ros-melodic-rospy
rosserial:
debian:
buster: [ros-melodic-rosserial]
buster: ros-melodic-rosserial
rosserial_msgs:
debian:
buster: [ros-melodic-rosserial-msgs]
buster: ros-melodic-rosserial-msgs
rosserial_python:
debian:
buster: [ros-melodic-rosserial-python]
buster: ros-melodic-rosserial-python
rosservice:
debian:
buster: [ros-melodic-rosservice]
buster: ros-melodic-rosservice
rostime:
debian:
buster: [ros-melodic-rostime]
buster: ros-melodic-rostime
roscpp_serialization:
debian:
buster: [ros-melodic-roscpp-serialization]
buster: ros-melodic-roscpp-serialization
python_qt_binding:
debian:
buster: [ros-melodic-python-qt-binding]
buster: ros-melodic-python-qt-binding
roslaunch:
debian:
buster: [ros-melodic-roslaunch]
buster: ros-melodic-roslaunch
rosunit:
debian:
buster: [ros-melodic-rosunit]
buster: ros-melodic-rosunit
angles:
debian:
buster: [ros-melodic-angles]
buster: ros-melodic-angles
libmavconn:
debian:
buster: [ros-melodic-libmavconn]
buster: ros-melodic-libmavconn
rosconsole:
debian:
buster: [ros-melodic-rosconsole]
buster: ros-melodic-rosconsole
pluginlib:
debian:
buster: [ros-melodic-pluginlib]
buster: ros-melodic-pluginlib
qt_gui_cpp:
debian:
buster: [ros-melodic-qt-gui-cpp]
buster: ros-melodic-qt-gui-cpp
resource_retriever:
debian:
buster: [ros-melodic-resource-retriever]
buster: ros-melodic-resource-retriever
rosconsole_bridge:
debian:
buster: [ros-melodic-rosconsole-bridge]
buster: ros-melodic-rosconsole-bridge
roslz4:
debian:
buster: [ros-melodic-roslz4]
buster: ros-melodic-roslz4
rosserial_client:
debian:
buster: [ros-melodic-rosserial-client]
buster: ros-melodic-rosserial-client
rostest:
debian:
buster: [ros-melodic-rostest]
buster: ros-melodic-rostest
rqt_action:
debian:
buster: [ros-melodic-rqt-action]
buster: ros-melodic-rqt-action
rqt_bag:
debian:
buster: [ros-melodic-rqt-bag]
buster: ros-melodic-rqt-bag
rqt_bag_plugins:
debian:
buster: [ros-melodic-rqt-bag-plugins]
buster: ros-melodic-rqt-bag-plugins
rqt_common_plugins:
debian:
buster: [ros-melodic-rqt-common-plugins]
buster: ros-melodic-rqt-common-plugins
rqt_console:
debian:
buster: [ros-melodic-rqt-console]
buster: ros-melodic-rqt-console
rqt_dep:
debian:
buster: [ros-melodic-rqt-dep]
buster: ros-melodic-rqt-dep
rqt_graph:
debian:
buster: [ros-melodic-rqt-graph]
buster: ros-melodic-rqt-graph
rqt_gui:
debian:
buster: [ros-melodic-rqt-gui]
buster: ros-melodic-rqt-gui
rqt_logger_level:
debian:
buster: [ros-melodic-rqt-logger-level]
buster: ros-melodic-rqt-logger-level
rqt_moveit:
debian:
buster: [ros-melodic-rqt-moveit]
buster: ros-melodic-rqt-moveit
rqt_msg:
debian:
buster: [ros-melodic-rqt-msg]
buster: ros-melodic-rqt-msg
rqt_nav_view:
debian:
buster: [ros-melodic-rqt-nav-view]
buster: ros-melodic-rqt-nav-view
rqt_plot:
debian:
buster: [ros-melodic-rqt-plot]
buster: ros-melodic-rqt-plot
rqt_pose_view:
debian:
buster: [ros-melodic-rqt-pose-view]
buster: ros-melodic-rqt-pose-view
rqt_publisher:
debian:
buster: [ros-melodic-rqt-publisher]
buster: ros-melodic-rqt-publisher
rqt_py_console:
debian:
buster: [ros-melodic-rqt-py-console]
buster: ros-melodic-rqt-py-console
rqt_reconfigure:
debian:
buster: [ros-melodic-rqt-reconfigure]
buster: ros-melodic-rqt-reconfigure
rqt_robot_dashboard:
debian:
buster: [ros-melodic-rqt-robot-dashboard]
buster: ros-melodic-rqt-robot-dashboard
rqt_robot_monitor:
debian:
buster: [ros-melodic-rqt-robot-monitor]
buster: ros-melodic-rqt-robot-monitor
rqt_robot_plugins:
debian:
buster: [ros-melodic-rqt-robot-plugins]
buster: ros-melodic-rqt-robot-plugins
rqt_robot_steering:
debian:
buster: [ros-melodic-rqt-robot-steering]
buster: ros-melodic-rqt-robot-steering
rqt_runtime_monitor:
debian:
buster: [ros-melodic-rqt-runtime-monitor]
buster: ros-melodic-rqt-runtime-monitor
rqt_service_caller:
debian:
buster: [ros-melodic-rqt-service-caller]
buster: ros-melodic-rqt-service-caller
rqt_shell:
debian:
buster: [ros-melodic-rqt-shell]
buster: ros-melodic-rqt-shell
rqt_srv:
debian:
buster: [ros-melodic-rqt-srv]
buster: ros-melodic-rqt-srv
rqt_tf_tree:
debian:
buster: [ros-melodic-rqt-tf-tree]
buster: ros-melodic-rqt-tf-tree
rqt_top:
debian:
buster: [ros-melodic-rqt-top]
buster: ros-melodic-rqt-top
rqt_topic:
debian:
buster: [ros-melodic-rqt-topic]
buster: ros-melodic-rqt-topic
rqt_web:
debian:
buster: [ros-melodic-rqt-web]
buster: ros-melodic-rqt-web
smach:
debian:
buster: [ros-melodic-smach]
buster: ros-melodic-smach
smclib:
debian:
buster: [ros-melodic-smclib]
buster: ros-melodic-smclib
std_msgs:
debian:
buster: [ros-melodic-std-msgs]
buster: ros-melodic-std-msgs
actionlib_msgs:
debian:
buster: [ros-melodic-actionlib-msgs]
buster: ros-melodic-actionlib-msgs
bond:
debian:
buster: [ros-melodic-bond]
buster: ros-melodic-bond
diagnostic_msgs:
debian:
buster: [ros-melodic-diagnostic-msgs]
buster: ros-melodic-diagnostic-msgs
geometry_msgs:
debian:
buster: [ros-melodic-geometry-msgs]
buster: ros-melodic-geometry-msgs
eigen_conversions:
debian:
buster: [ros-melodic-eigen-conversions]
buster: ros-melodic-eigen-conversions
kdl_conversions:
debian:
buster: [ros-melodic-kdl-conversions]
buster: ros-melodic-kdl-conversions
nav_msgs:
debian:
buster: [ros-melodic-nav-msgs]
buster: ros-melodic-nav-msgs
rosbridge_msgs:
debian:
buster: [ros-melodic-rosbridge-msgs]
buster: ros-melodic-rosbridge-msgs
rosgraph_msgs:
debian:
buster: [ros-melodic-rosgraph-msgs]
buster: ros-melodic-rosgraph-msgs
rosmsg:
debian:
buster: [ros-melodic-rosmsg]
buster: ros-melodic-rosmsg
rqt_py_common:
debian:
buster: [ros-melodic-rqt-py-common]
buster: ros-melodic-rqt-py-common
shape_msgs:
debian:
buster: [ros-melodic-shape-msgs]
buster: ros-melodic-shape-msgs
smach_msgs:
debian:
buster: [ros-melodic-smach-msgs]
buster: ros-melodic-smach-msgs
std_srvs:
debian:
buster: [ros-melodic-std-srvs]
buster: ros-melodic-std-srvs
tf2_msgs:
debian:
buster: [ros-melodic-tf2-msgs]
buster: ros-melodic-tf2-msgs
tf2:
debian:
buster: [ros-melodic-tf2]
buster: ros-melodic-tf2
tf2_eigen:
debian:
buster: [ros-melodic-tf2-eigen]
buster: ros-melodic-tf2-eigen
trajectory_msgs:
debian:
buster: [ros-melodic-trajectory-msgs]
buster: ros-melodic-trajectory-msgs
control_msgs:
debian:
buster: [ros-melodic-control-msgs]
buster: ros-melodic-control-msgs
urdf_parser_plugin:
debian:
buster: [ros-melodic-urdf-parser-plugin]
buster: ros-melodic-urdf-parser-plugin
urdfdom_py:
debian:
buster: [ros-melodic-urdfdom-py]
buster: ros-melodic-urdfdom-py
uuid_msgs:
debian:
buster: [ros-melodic-uuid-msgs]
buster: ros-melodic-uuid-msgs
geographic_msgs:
debian:
buster: [ros-melodic-geographic-msgs]
buster: ros-melodic-geographic-msgs
vision_opencv:
debian:
buster: [ros-melodic-vision-opencv]
buster: ros-melodic-vision-opencv
visualization_msgs:
debian:
buster: [ros-melodic-visualization-msgs]
buster: ros-melodic-visualization-msgs
visualization_tutorials:
debian:
buster: [ros-melodic-visualization-tutorials]
buster: ros-melodic-visualization-tutorials
viz:
debian:
buster: [ros-melodic-viz]
buster: ros-melodic-viz
webkit_dependency:
debian:
buster: [ros-melodic-webkit-dependency]
buster: ros-melodic-webkit-dependency
xmlrpcpp:
debian:
buster: [ros-melodic-xmlrpcpp]
buster: ros-melodic-xmlrpcpp
roscpp:
debian:
buster: [ros-melodic-roscpp]
buster: ros-melodic-roscpp
bondcpp:
debian:
buster: [ros-melodic-bondcpp]
buster: ros-melodic-bondcpp
bondpy:
debian:
buster: [ros-melodic-bondpy]
buster: ros-melodic-bondpy
nodelet:
debian:
buster: [ros-melodic-nodelet]
buster: ros-melodic-nodelet
nodelet_tutorial_math:
debian:
buster: [ros-melodic-nodelet-tutorial-math]
buster: ros-melodic-nodelet-tutorial-math
pluginlib_tutorials:
debian:
buster: [ros-melodic-pluginlib-tutorials]
buster: ros-melodic-pluginlib-tutorials
roscpp_tutorials:
debian:
buster: [ros-melodic-roscpp-tutorials]
buster: ros-melodic-roscpp-tutorials
rosout:
debian:
buster: [ros-melodic-rosout]
buster: ros-melodic-rosout
async_web_server_cpp:
debian:
buster: [ros-melodic-async-web-server-cpp]
buster: ros-melodic-async-web-server-cpp
camera_calibration:
debian:
buster: [ros-melodic-camera-calibration]
buster: ros-melodic-camera-calibration
diagnostic_aggregator:
debian:
buster: [ros-melodic-diagnostic-aggregator]
buster: ros-melodic-diagnostic-aggregator
diagnostic_updater:
debian:
buster: [ros-melodic-diagnostic-updater]
buster: ros-melodic-diagnostic-updater
diagnostic_common_diagnostics:
debian:
buster: [ros-melodic-diagnostic-common-diagnostics]
buster: ros-melodic-diagnostic-common-diagnostics
dynamic_reconfigure:
debian:
buster: [ros-melodic-dynamic-reconfigure]
buster: ros-melodic-dynamic-reconfigure
filters:
debian:
buster: [ros-melodic-filters]
buster: ros-melodic-filters
joint_state_publisher:
debian:
buster: [ros-melodic-joint-state-publisher]
buster: ros-melodic-joint-state-publisher
message_filters:
debian:
buster: [ros-melodic-message-filters]
buster: ros-melodic-message-filters
ros_pytest:
debian:
buster: [ros-melodic-ros-pytest]
buster: ros-melodic-ros-pytest
rosauth:
debian:
buster: [ros-melodic-rosauth]
buster: ros-melodic-rosauth
rosbag_storage:
debian:
buster: [ros-melodic-rosbag-storage]
buster: ros-melodic-rosbag-storage
rosnode:
debian:
buster: [ros-melodic-rosnode]
buster: ros-melodic-rosnode
rospy_tutorials:
debian:
buster: [ros-melodic-rospy-tutorials]
buster: ros-melodic-rospy-tutorials
rosshow:
debian:
buster: [ros-melodic-rosshow]
buster: ros-melodic-rosshow
rostopic:
debian:
buster: [ros-melodic-rostopic]
buster: ros-melodic-rostopic
rqt_gui_cpp:
debian:
buster: [ros-melodic-rqt-gui-cpp]
buster: ros-melodic-rqt-gui-cpp
rqt_gui_py:
debian:
buster: [ros-melodic-rqt-gui-py]
buster: ros-melodic-rqt-gui-py
self_test:
debian:
buster: [ros-melodic-self-test]
buster: ros-melodic-self-test
smach_ros:
debian:
buster: [ros-melodic-smach-ros]
buster: ros-melodic-smach-ros
tf2_py:
debian:
buster: [ros-melodic-tf2-py]
buster: ros-melodic-tf2-py
topic_tools:
debian:
buster: [ros-melodic-topic-tools]
buster: ros-melodic-topic-tools
rosbag:
debian:
buster: [ros-melodic-rosbag]
buster: ros-melodic-rosbag
actionlib:
debian:
buster: [ros-melodic-actionlib]
buster: ros-melodic-actionlib
actionlib_tutorials:
debian:
buster: [ros-melodic-actionlib-tutorials]
buster: ros-melodic-actionlib-tutorials
diagnostic_analysis:
debian:
buster: [ros-melodic-diagnostic-analysis]
buster: ros-melodic-diagnostic-analysis
nodelet_topic_tools:
debian:
buster: [ros-melodic-nodelet-topic-tools]
buster: ros-melodic-nodelet-topic-tools
roswtf:
debian:
buster: [ros-melodic-roswtf]
buster: ros-melodic-roswtf
rqt_launch:
debian:
buster: [ros-melodic-rqt-launch]
buster: ros-melodic-rqt-launch
sensor_msgs:
debian:
buster: [ros-melodic-sensor-msgs]
buster: ros-melodic-sensor-msgs
camera_calibration_parsers:
debian:
buster: [ros-melodic-camera-calibration-parsers]
buster: ros-melodic-camera-calibration-parsers
cv_bridge:
debian:
buster: [ros-melodic-cv-bridge]
buster: ros-melodic-cv-bridge
image_geometry:
debian:
buster: [ros-melodic-image-geometry]
buster: ros-melodic-image-geometry
image_transport:
debian:
buster: [ros-melodic-image-transport]
buster: ros-melodic-image-transport
camera_info_manager:
debian:
buster: [ros-melodic-camera-info-manager]
buster: ros-melodic-camera-info-manager
compressed_depth_image_transport:
debian:
buster: [ros-melodic-compressed-depth-image-transport]
buster: ros-melodic-compressed-depth-image-transport
compressed_image_transport:
debian:
buster: [ros-melodic-compressed-image-transport]
buster: ros-melodic-compressed-image-transport
cv_camera:
debian:
buster: [ros-melodic-cv-camera]
buster: ros-melodic-cv-camera
image_proc:
debian:
buster: [ros-melodic-image-proc]
buster: ros-melodic-image-proc
image_publisher:
debian:
buster: [ros-melodic-image-publisher]
buster: ros-melodic-image-publisher
map_msgs:
debian:
buster: [ros-melodic-map-msgs]
buster: ros-melodic-map-msgs
mavros_msgs:
debian:
buster: [ros-melodic-mavros-msgs]
buster: ros-melodic-mavros-msgs
pcl_msgs:
debian:
buster: [ros-melodic-pcl-msgs]
buster: ros-melodic-pcl-msgs
pcl_conversions:
debian:
buster: [ros-melodic-pcl-conversions]
buster: ros-melodic-pcl-conversions
polled_camera:
debian:
buster: [ros-melodic-polled-camera]
buster: ros-melodic-polled-camera
rqt_image_view:
debian:
buster: [ros-melodic-rqt-image-view]
buster: ros-melodic-rqt-image-view
stereo_msgs:
debian:
buster: [ros-melodic-stereo-msgs]
buster: ros-melodic-stereo-msgs
image_view:
debian:
buster: [ros-melodic-image-view]
buster: ros-melodic-image-view
rosbridge_library:
debian:
buster: [ros-melodic-rosbridge-library]
buster: ros-melodic-rosbridge-library
stereo_image_proc:
debian:
buster: [ros-melodic-stereo-image-proc]
buster: ros-melodic-stereo-image-proc
tf2_ros:
debian:
buster: [ros-melodic-tf2-ros]
buster: ros-melodic-tf2-ros
depth_image_proc:
debian:
buster: [ros-melodic-depth-image-proc]
buster: ros-melodic-depth-image-proc
mavros:
debian:
buster: [ros-melodic-mavros]
buster: ros-melodic-mavros
tf:
debian:
buster: [ros-melodic-tf]
buster: ros-melodic-tf
interactive_markers:
debian:
buster: [ros-melodic-interactive-markers]
buster: ros-melodic-interactive-markers
interactive_marker_tutorials:
debian:
buster: [ros-melodic-interactive-marker-tutorials]
buster: ros-melodic-interactive-marker-tutorials
laser_geometry:
debian:
buster: [ros-melodic-laser-geometry]
buster: ros-melodic-laser-geometry
laser_assembler:
debian:
buster: [ros-melodic-laser-assembler]
buster: ros-melodic-laser-assembler
laser_filters:
debian:
buster: [ros-melodic-laser-filters]
buster: ros-melodic-laser-filters
pcl_ros:
debian:
buster: [ros-melodic-pcl-ros]
buster: ros-melodic-pcl-ros
tf2_geometry_msgs:
debian:
buster: [ros-melodic-tf2-geometry-msgs]
buster: ros-melodic-tf2-geometry-msgs
image_rotate:
debian:
buster: [ros-melodic-image-rotate]
buster: ros-melodic-image-rotate
tf2_kdl:
debian:
buster: [ros-melodic-tf2-kdl]
buster: ros-melodic-tf2-kdl
tf2_web_republisher:
debian:
buster: [ros-melodic-tf2-web-republisher]
buster: ros-melodic-tf2-web-republisher
tf_conversions:
debian:
buster: [ros-melodic-tf-conversions]
buster: ros-melodic-tf-conversions
theora_image_transport:
debian:
buster: [ros-melodic-theora-image-transport]
buster: ros-melodic-theora-image-transport
turtlesim:
debian:
buster: [ros-melodic-turtlesim]
buster: ros-melodic-turtlesim
turtle_actionlib:
debian:
buster: [ros-melodic-turtle-actionlib]
buster: ros-melodic-turtle-actionlib
turtle_tf:
debian:
buster: [ros-melodic-turtle-tf]
buster: ros-melodic-turtle-tf
turtle_tf2:
debian:
buster: [ros-melodic-turtle-tf2]
buster: ros-melodic-turtle-tf2
urdf:
debian:
buster: [ros-melodic-urdf]
buster: ros-melodic-urdf
kdl_parser:
debian:
buster: [ros-melodic-kdl-parser]
buster: ros-melodic-kdl-parser
kdl_parser_py:
debian:
buster: [ros-melodic-kdl-parser-py]
buster: ros-melodic-kdl-parser-py
mavros_extras:
debian:
buster: [ros-melodic-mavros-extras]
buster: ros-melodic-mavros-extras
robot_state_publisher:
debian:
buster: [ros-melodic-robot-state-publisher]
buster: ros-melodic-robot-state-publisher
rviz:
debian:
buster: [ros-melodic-rviz]
buster: ros-melodic-rviz
librviz_tutorial:
debian:
buster: [ros-melodic-librviz-tutorial]
buster: ros-melodic-librviz-tutorial
rqt_rviz:
debian:
buster: [ros-melodic-rqt-rviz]
buster: ros-melodic-rqt-rviz
rviz_plugin_tutorials:
debian:
buster: [ros-melodic-rviz-plugin-tutorials]
buster: ros-melodic-rviz-plugin-tutorials
rviz_python_tutorial:
debian:
buster: [ros-melodic-rviz-python-tutorial]
buster: ros-melodic-rviz-python-tutorial
urdf_tutorial:
debian:
buster: [ros-melodic-urdf-tutorial]
buster: ros-melodic-urdf-tutorial
usb_cam:
debian:
buster: [ros-melodic-usb-cam]
buster: ros-melodic-usb-cam
visualization_marker_tutorials:
debian:
buster: [ros-melodic-visualization-marker-tutorials]
buster: ros-melodic-visualization-marker-tutorials
vl53l1x:
debian:
buster: [ros-melodic-vl53l1x]
buster: ros-melodic-vl53l1x
web_video_server:
debian:
buster: [ros-melodic-web-video-server]
buster: ros-melodic-web-video-server
xacro:
debian:
buster: [ros-melodic-xacro]
buster: ros-melodic-xacro
led_msgs:
debian:
buster: [ros-melodic-led-msgs]
buster: ros-melodic-led-msgs
ws281x:
debian:
buster: [ros-melodic-ws281x]
ddynamic_reconfigure:
debian:
buster: [ros-melodic-ddynamic-reconfigure]
librealsense2:
debian:
buster: [ros-melodic-librealsense2]
realsense2_camera:
debian:
buster: [ros-melodic-realsense2-camera]
realsense2_description:
debian:
buster: [ros-melodic-realsense2-description]
stretch: ros-melodic-ws281x

View File

@@ -1,735 +0,0 @@
catkin:
debian:
buster: [ros-melodic-catkin]
genmsg:
debian:
buster: [ros-melodic-genmsg]
gencpp:
debian:
buster: [ros-melodic-gencpp]
geneus:
debian:
buster: [ros-melodic-geneus]
genlisp:
debian:
buster: [ros-melodic-genlisp]
gennodejs:
debian:
buster: [ros-melodic-gennodejs]
genpy:
debian:
buster: [ros-melodic-genpy]
bond_core:
debian:
buster: [ros-melodic-bond-core]
cmake_modules:
debian:
buster: [ros-melodic-cmake-modules]
class_loader:
debian:
buster: [ros-melodic-class-loader]
common_msgs:
debian:
buster: [ros-melodic-common-msgs]
common_tutorials:
debian:
buster: [ros-melodic-common-tutorials]
cpp_common:
debian:
buster: [ros-melodic-cpp-common]
desktop:
debian:
buster: [ros-melodic-desktop]
diagnostics:
debian:
buster: [ros-melodic-diagnostics]
executive_smach:
debian:
buster: [ros-melodic-executive-smach]
geometry:
debian:
buster: [ros-melodic-geometry]
geometry_tutorials:
debian:
buster: [ros-melodic-geometry-tutorials]
gl_dependency:
debian:
buster: [ros-melodic-gl-dependency]
image_common:
debian:
buster: [ros-melodic-image-common]
image_pipeline:
debian:
buster: [ros-melodic-image-pipeline]
image_transport_plugins:
debian:
buster: [ros-melodic-image-transport-plugins]
laser_pipeline:
debian:
buster: [ros-melodic-laser-pipeline]
mavlink:
debian:
buster: [ros-melodic-mavlink]
media_export:
debian:
buster: [ros-melodic-media-export]
message_generation:
debian:
buster: [ros-melodic-message-generation]
message_runtime:
debian:
buster: [ros-melodic-message-runtime]
mk:
debian:
buster: [ros-melodic-mk]
nodelet_core:
debian:
buster: [ros-melodic-nodelet-core]
orocos_kdl:
debian:
buster: [ros-melodic-orocos-kdl]
perception:
debian:
buster: [ros-melodic-perception]
perception_pcl:
debian:
buster: [ros-melodic-perception-pcl]
python_orocos_kdl:
debian:
buster: [ros-melodic-python-orocos-kdl]
qt_dotgraph:
debian:
buster: [ros-melodic-qt-dotgraph]
qt_gui:
debian:
buster: [ros-melodic-qt-gui]
qt_gui_py_common:
debian:
buster: [ros-melodic-qt-gui-py-common]
qwt_dependency:
debian:
buster: [ros-melodic-qwt-dependency]
robot:
debian:
buster: [ros-melodic-robot]
ros:
debian:
buster: [ros-melodic-ros]
ros_base:
debian:
buster: [ros-melodic-ros-base]
ros_comm:
debian:
buster: [ros-melodic-ros-comm]
ros_core:
debian:
buster: [ros-melodic-ros-core]
ros_environment:
debian:
buster: [ros-melodic-ros-environment]
ros_tutorials:
debian:
buster: [ros-melodic-ros-tutorials]
rosapi:
debian:
buster: [ros-melodic-rosapi]
rosbag_migration_rule:
debian:
buster: [ros-melodic-rosbag-migration-rule]
rosbash:
debian:
buster: [ros-melodic-rosbash]
rosboost_cfg:
debian:
buster: [ros-melodic-rosboost-cfg]
rosbridge_server:
debian:
buster: [ros-melodic-rosbridge-server]
rosbridge_suite:
debian:
buster: [ros-melodic-rosbridge-suite]
rosbuild:
debian:
buster: [ros-melodic-rosbuild]
rosclean:
debian:
buster: [ros-melodic-rosclean]
roscpp_core:
debian:
buster: [ros-melodic-roscpp-core]
roscpp_traits:
debian:
buster: [ros-melodic-roscpp-traits]
roscreate:
debian:
buster: [ros-melodic-roscreate]
rosgraph:
debian:
buster: [ros-melodic-rosgraph]
roslang:
debian:
buster: [ros-melodic-roslang]
roslint:
debian:
buster: [ros-melodic-roslint]
roslisp:
debian:
buster: [ros-melodic-roslisp]
rosmake:
debian:
buster: [ros-melodic-rosmake]
rosmaster:
debian:
buster: [ros-melodic-rosmaster]
rospack:
debian:
buster: [ros-melodic-rospack]
roslib:
debian:
buster: [ros-melodic-roslib]
rosparam:
debian:
buster: [ros-melodic-rosparam]
rospy:
debian:
buster: [ros-melodic-rospy]
rosserial:
debian:
buster: [ros-melodic-rosserial]
rosserial_msgs:
debian:
buster: [ros-melodic-rosserial-msgs]
rosserial_python:
debian:
buster: [ros-melodic-rosserial-python]
rosservice:
debian:
buster: [ros-melodic-rosservice]
rostime:
debian:
buster: [ros-melodic-rostime]
roscpp_serialization:
debian:
buster: [ros-melodic-roscpp-serialization]
python_qt_binding:
debian:
buster: [ros-melodic-python-qt-binding]
roslaunch:
debian:
buster: [ros-melodic-roslaunch]
rosunit:
debian:
buster: [ros-melodic-rosunit]
angles:
debian:
buster: [ros-melodic-angles]
libmavconn:
debian:
buster: [ros-melodic-libmavconn]
rosconsole:
debian:
buster: [ros-melodic-rosconsole]
pluginlib:
debian:
buster: [ros-melodic-pluginlib]
qt_gui_cpp:
debian:
buster: [ros-melodic-qt-gui-cpp]
resource_retriever:
debian:
buster: [ros-melodic-resource-retriever]
rosconsole_bridge:
debian:
buster: [ros-melodic-rosconsole-bridge]
roslz4:
debian:
buster: [ros-melodic-roslz4]
rosserial_client:
debian:
buster: [ros-melodic-rosserial-client]
rostest:
debian:
buster: [ros-melodic-rostest]
rqt_action:
debian:
buster: [ros-melodic-rqt-action]
rqt_bag:
debian:
buster: [ros-melodic-rqt-bag]
rqt_bag_plugins:
debian:
buster: [ros-melodic-rqt-bag-plugins]
rqt_common_plugins:
debian:
buster: [ros-melodic-rqt-common-plugins]
rqt_console:
debian:
buster: [ros-melodic-rqt-console]
rqt_dep:
debian:
buster: [ros-melodic-rqt-dep]
rqt_graph:
debian:
buster: [ros-melodic-rqt-graph]
rqt_gui:
debian:
buster: [ros-melodic-rqt-gui]
rqt_logger_level:
debian:
buster: [ros-melodic-rqt-logger-level]
rqt_moveit:
debian:
buster: [ros-melodic-rqt-moveit]
rqt_msg:
debian:
buster: [ros-melodic-rqt-msg]
rqt_nav_view:
debian:
buster: [ros-melodic-rqt-nav-view]
rqt_plot:
debian:
buster: [ros-melodic-rqt-plot]
rqt_pose_view:
debian:
buster: [ros-melodic-rqt-pose-view]
rqt_publisher:
debian:
buster: [ros-melodic-rqt-publisher]
rqt_py_console:
debian:
buster: [ros-melodic-rqt-py-console]
rqt_reconfigure:
debian:
buster: [ros-melodic-rqt-reconfigure]
rqt_robot_dashboard:
debian:
buster: [ros-melodic-rqt-robot-dashboard]
rqt_robot_monitor:
debian:
buster: [ros-melodic-rqt-robot-monitor]
rqt_robot_plugins:
debian:
buster: [ros-melodic-rqt-robot-plugins]
rqt_robot_steering:
debian:
buster: [ros-melodic-rqt-robot-steering]
rqt_runtime_monitor:
debian:
buster: [ros-melodic-rqt-runtime-monitor]
rqt_service_caller:
debian:
buster: [ros-melodic-rqt-service-caller]
rqt_shell:
debian:
buster: [ros-melodic-rqt-shell]
rqt_srv:
debian:
buster: [ros-melodic-rqt-srv]
rqt_tf_tree:
debian:
buster: [ros-melodic-rqt-tf-tree]
rqt_top:
debian:
buster: [ros-melodic-rqt-top]
rqt_topic:
debian:
buster: [ros-melodic-rqt-topic]
rqt_web:
debian:
buster: [ros-melodic-rqt-web]
smach:
debian:
buster: [ros-melodic-smach]
smclib:
debian:
buster: [ros-melodic-smclib]
std_msgs:
debian:
buster: [ros-melodic-std-msgs]
actionlib_msgs:
debian:
buster: [ros-melodic-actionlib-msgs]
bond:
debian:
buster: [ros-melodic-bond]
diagnostic_msgs:
debian:
buster: [ros-melodic-diagnostic-msgs]
geometry_msgs:
debian:
buster: [ros-melodic-geometry-msgs]
eigen_conversions:
debian:
buster: [ros-melodic-eigen-conversions]
kdl_conversions:
debian:
buster: [ros-melodic-kdl-conversions]
nav_msgs:
debian:
buster: [ros-melodic-nav-msgs]
rosbridge_msgs:
debian:
buster: [ros-melodic-rosbridge-msgs]
rosgraph_msgs:
debian:
buster: [ros-melodic-rosgraph-msgs]
rosmsg:
debian:
buster: [ros-melodic-rosmsg]
rqt_py_common:
debian:
buster: [ros-melodic-rqt-py-common]
shape_msgs:
debian:
buster: [ros-melodic-shape-msgs]
smach_msgs:
debian:
buster: [ros-melodic-smach-msgs]
std_srvs:
debian:
buster: [ros-melodic-std-srvs]
tf2_msgs:
debian:
buster: [ros-melodic-tf2-msgs]
tf2:
debian:
buster: [ros-melodic-tf2]
tf2_eigen:
debian:
buster: [ros-melodic-tf2-eigen]
trajectory_msgs:
debian:
buster: [ros-melodic-trajectory-msgs]
control_msgs:
debian:
buster: [ros-melodic-control-msgs]
urdf_parser_plugin:
debian:
buster: [ros-melodic-urdf-parser-plugin]
urdfdom_py:
debian:
buster: [ros-melodic-urdfdom-py]
uuid_msgs:
debian:
buster: [ros-melodic-uuid-msgs]
geographic_msgs:
debian:
buster: [ros-melodic-geographic-msgs]
vision_opencv:
debian:
buster: [ros-melodic-vision-opencv]
visualization_msgs:
debian:
buster: [ros-melodic-visualization-msgs]
visualization_tutorials:
debian:
buster: [ros-melodic-visualization-tutorials]
viz:
debian:
buster: [ros-melodic-viz]
webkit_dependency:
debian:
buster: [ros-melodic-webkit-dependency]
xmlrpcpp:
debian:
buster: [ros-melodic-xmlrpcpp]
roscpp:
debian:
buster: [ros-melodic-roscpp]
bondcpp:
debian:
buster: [ros-melodic-bondcpp]
bondpy:
debian:
buster: [ros-melodic-bondpy]
nodelet:
debian:
buster: [ros-melodic-nodelet]
nodelet_tutorial_math:
debian:
buster: [ros-melodic-nodelet-tutorial-math]
pluginlib_tutorials:
debian:
buster: [ros-melodic-pluginlib-tutorials]
roscpp_tutorials:
debian:
buster: [ros-melodic-roscpp-tutorials]
rosout:
debian:
buster: [ros-melodic-rosout]
async_web_server_cpp:
debian:
buster: [ros-melodic-async-web-server-cpp]
camera_calibration:
debian:
buster: [ros-melodic-camera-calibration]
diagnostic_aggregator:
debian:
buster: [ros-melodic-diagnostic-aggregator]
diagnostic_updater:
debian:
buster: [ros-melodic-diagnostic-updater]
diagnostic_common_diagnostics:
debian:
buster: [ros-melodic-diagnostic-common-diagnostics]
dynamic_reconfigure:
debian:
buster: [ros-melodic-dynamic-reconfigure]
filters:
debian:
buster: [ros-melodic-filters]
joint_state_publisher:
debian:
buster: [ros-melodic-joint-state-publisher]
message_filters:
debian:
buster: [ros-melodic-message-filters]
ros_pytest:
debian:
buster: [ros-melodic-ros-pytest]
rosauth:
debian:
buster: [ros-melodic-rosauth]
rosbag_storage:
debian:
buster: [ros-melodic-rosbag-storage]
rosnode:
debian:
buster: [ros-melodic-rosnode]
rospy_tutorials:
debian:
buster: [ros-melodic-rospy-tutorials]
rosshow:
debian:
buster: [ros-melodic-rosshow]
rostopic:
debian:
buster: [ros-melodic-rostopic]
rqt_gui_cpp:
debian:
buster: [ros-melodic-rqt-gui-cpp]
rqt_gui_py:
debian:
buster: [ros-melodic-rqt-gui-py]
self_test:
debian:
buster: [ros-melodic-self-test]
smach_ros:
debian:
buster: [ros-melodic-smach-ros]
tf2_py:
debian:
buster: [ros-melodic-tf2-py]
topic_tools:
debian:
buster: [ros-melodic-topic-tools]
rosbag:
debian:
buster: [ros-melodic-rosbag]
actionlib:
debian:
buster: [ros-melodic-actionlib]
actionlib_tutorials:
debian:
buster: [ros-melodic-actionlib-tutorials]
diagnostic_analysis:
debian:
buster: [ros-melodic-diagnostic-analysis]
nodelet_topic_tools:
debian:
buster: [ros-melodic-nodelet-topic-tools]
roswtf:
debian:
buster: [ros-melodic-roswtf]
rqt_launch:
debian:
buster: [ros-melodic-rqt-launch]
sensor_msgs:
debian:
buster: [ros-melodic-sensor-msgs]
camera_calibration_parsers:
debian:
buster: [ros-melodic-camera-calibration-parsers]
cv_bridge:
debian:
buster: [ros-melodic-cv-bridge]
image_geometry:
debian:
buster: [ros-melodic-image-geometry]
image_transport:
debian:
buster: [ros-melodic-image-transport]
camera_info_manager:
debian:
buster: [ros-melodic-camera-info-manager]
compressed_depth_image_transport:
debian:
buster: [ros-melodic-compressed-depth-image-transport]
compressed_image_transport:
debian:
buster: [ros-melodic-compressed-image-transport]
cv_camera:
debian:
buster: [ros-melodic-cv-camera]
image_proc:
debian:
buster: [ros-melodic-image-proc]
image_publisher:
debian:
buster: [ros-melodic-image-publisher]
map_msgs:
debian:
buster: [ros-melodic-map-msgs]
mavros_msgs:
debian:
buster: [ros-melodic-mavros-msgs]
pcl_msgs:
debian:
buster: [ros-melodic-pcl-msgs]
pcl_conversions:
debian:
buster: [ros-melodic-pcl-conversions]
polled_camera:
debian:
buster: [ros-melodic-polled-camera]
rqt_image_view:
debian:
buster: [ros-melodic-rqt-image-view]
stereo_msgs:
debian:
buster: [ros-melodic-stereo-msgs]
image_view:
debian:
buster: [ros-melodic-image-view]
rosbridge_library:
debian:
buster: [ros-melodic-rosbridge-library]
stereo_image_proc:
debian:
buster: [ros-melodic-stereo-image-proc]
tf2_ros:
debian:
buster: [ros-melodic-tf2-ros]
depth_image_proc:
debian:
buster: [ros-melodic-depth-image-proc]
mavros:
debian:
buster: [ros-melodic-mavros]
tf:
debian:
buster: [ros-melodic-tf]
interactive_markers:
debian:
buster: [ros-melodic-interactive-markers]
interactive_marker_tutorials:
debian:
buster: [ros-melodic-interactive-marker-tutorials]
laser_geometry:
debian:
buster: [ros-melodic-laser-geometry]
laser_assembler:
debian:
buster: [ros-melodic-laser-assembler]
laser_filters:
debian:
buster: [ros-melodic-laser-filters]
pcl_ros:
debian:
buster: [ros-melodic-pcl-ros]
tf2_geometry_msgs:
debian:
buster: [ros-melodic-tf2-geometry-msgs]
image_rotate:
debian:
buster: [ros-melodic-image-rotate]
tf2_kdl:
debian:
buster: [ros-melodic-tf2-kdl]
tf2_web_republisher:
debian:
buster: [ros-melodic-tf2-web-republisher]
tf_conversions:
debian:
buster: [ros-melodic-tf-conversions]
theora_image_transport:
debian:
buster: [ros-melodic-theora-image-transport]
turtlesim:
debian:
buster: [ros-melodic-turtlesim]
turtle_actionlib:
debian:
buster: [ros-melodic-turtle-actionlib]
turtle_tf:
debian:
buster: [ros-melodic-turtle-tf]
turtle_tf2:
debian:
buster: [ros-melodic-turtle-tf2]
urdf:
debian:
buster: [ros-melodic-urdf]
kdl_parser:
debian:
buster: [ros-melodic-kdl-parser]
kdl_parser_py:
debian:
buster: [ros-melodic-kdl-parser-py]
mavros_extras:
debian:
buster: [ros-melodic-mavros-extras]
robot_state_publisher:
debian:
buster: [ros-melodic-robot-state-publisher]
rviz:
debian:
buster: [ros-melodic-rviz]
librviz_tutorial:
debian:
buster: [ros-melodic-librviz-tutorial]
rqt_rviz:
debian:
buster: [ros-melodic-rqt-rviz]
rviz_plugin_tutorials:
debian:
buster: [ros-melodic-rviz-plugin-tutorials]
rviz_python_tutorial:
debian:
buster: [ros-melodic-rviz-python-tutorial]
urdf_tutorial:
debian:
buster: [ros-melodic-urdf-tutorial]
usb_cam:
debian:
buster: [ros-melodic-usb-cam]
visualization_marker_tutorials:
debian:
buster: [ros-melodic-visualization-marker-tutorials]
vl53l1x:
debian:
buster: [ros-melodic-vl53l1x]
web_video_server:
debian:
buster: [ros-melodic-web-video-server]
xacro:
debian:
buster: [ros-melodic-xacro]
led_msgs:
debian:
buster: [ros-melodic-led-msgs]
ws281x:
debian:
buster: [ros-melodic-ws281x]
ddynamic_reconfigure:
debian:
buster: [ros-melodic-ddynamic-reconfigure]
librealsense2:
debian:
buster: [ros-melodic-librealsense2]
realsense2_camera:
debian:
buster: [ros-melodic-realsense2-camera]
realsense2_description:
debian:
buster: [ros-melodic-realsense2-description]

View File

@@ -20,7 +20,7 @@
# Example:
# DocumentRoot /home/krypton/htdocs
DocumentRoot /home/pi/.ros/www
DocumentRoot /home/pi/catkin_ws/src/clever/clever/www
# Redirect:
# ---------

View File

@@ -0,0 +1,22 @@
python3-crypto:
debian:
buster: [python3-crypto]
python3-imaging:
debian:
buster: [python3-pil]
python3-wxtools:
debian:
pip:
packages: [wxPython]
python3-future:
debian:
buster: [python3-future]
python3-twisted:
debian:
buster: [python3-twisted]
python3-serial:
debian:
buster: [python3-serial]
python3-requests:
debian:
buster: [python3-requests]

View File

@@ -1,5 +1,6 @@
[Unit]
Description=Launcher for the ROS master, parameter server and rosout logging node
After=network.target
[Service]
User=pi

View File

@@ -1,107 +0,0 @@
# /etc/rsyslog.conf configuration file for rsyslog
#
# For more information install rsyslog-doc and see
# /usr/share/doc/rsyslog-doc/html/configuration/index.html
#################
#### MODULES ####
#################
module(load="imuxsock") # provides support for local system logging
module(load="imklog") # provides kernel logging support
#module(load="immark") # provides --MARK-- message capability
# provides UDP syslog reception
#module(load="imudp")
#input(type="imudp" port="514")
# provides TCP syslog reception
#module(load="imtcp")
#input(type="imtcp" port="514")
###########################
#### GLOBAL DIRECTIVES ####
###########################
#
# Use traditional timestamp format.
# To enable high precision timestamps, comment out the following line.
#
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
#
# Set the default permissions for all log files.
#
$FileOwner root
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022
#
# Where to place spool and state files
#
$WorkDirectory /var/spool/rsyslog
#
# Include all config files in /etc/rsyslog.d/
#
$IncludeConfig /etc/rsyslog.d/*.conf
#
# Enable custom output channels to limit file sizes
#
$outchannel limauth,/var/log/auth.log,10485760,/etc/rsyslog.d/rsysrot.sh /var/log/auth.log
$outchannel limsyslog,/var/log/syslog,10485760,/etc/rsyslog.d/rsysrot.sh /var/log/syslog
$outchannel limdaemon,/var/log/daemon.log,10485760,/etc/rsyslog.d/rsysrot.sh /var/log/daemon.log
$outchannel limkern,/var/log/kern.log,10485760,/etc/rsyslog.d/rsysrot.sh /var/log/kern.log
$outchannel limlpr,/var/log/lpr.log,10485760,/etc/rsyslog.d/rsysrot.sh /var/log/lpr.log
$outchannel limmail,/var/log/mail.log,10485760,/etc/rsyslog.d/rsysrot.sh /var/log/mail.log
$outchannel limmailinfo,/var/log/mail.info,10485760,/etc/rsyslog.d/rsysrot.sh /var/log/mail.info
$outchannel limmailwarn,/var/log/mail.warn,10485760,/etc/rsyslog.d/rsysrot.sh /var/log/mail.warn
$outchannel limmailerr,/var/log/mail.err,10485760,/etc/rsyslog.d/rsysrot.sh /var/log/mail.err
$outchannel limuser,/var/log/user.log,10485760,/etc/rsyslog.d/rsysrot.sh /var/log/user.log
$outchannel limdebug,/var/log/debug,10485760,/etc/rsyslog.d/rsysrot.sh /var/log/debug
$outchannel limmsgs,/var/log/messages,10485760,/etc/rsyslog.d/rsysrot.sh /var/log/messages
###############
#### RULES ####
###############
#
# First some standard log files. Log by facility.
#
auth,authpriv.* :omfile:$limauth
*.*;auth,authpriv.none :omfile:$limsyslog
#cron.* /var/log/cron.log
daemon.* :omfile:$limdaemon
kern.* :omfile:$limkern
lpr.* :omfile:$limlpr
mail.* :omfile:$limmail
user.* :omfile:$limuser
#
# Logging for the mail system. Split it up so that
# it is easy to write scripts to parse these files.
#
mail.info :omfile:$limmailinfo
mail.warn :omfile:$limmailwarn
mail.err :omfile:$limmailerr
#
# Some "catch-all" log files.
#
*.=debug;\
auth,authpriv.none;\
news.none;mail.none :omfile:$limdebug
*.=info;*.=notice;*.=warn;\
auth,authpriv.none;\
cron,daemon.none;\
mail,news.none :omfile:$limmsgs
#
# Emergencies are sent to everybody logged in.
#
*.emerg :omusrmsg:*

View File

@@ -1,4 +0,0 @@
#!/bin/bash
LOG_FILE=$1
mv -f ${LOG_FILE} ${LOG_FILE}.1

View File

@@ -15,7 +15,7 @@
set -e # Exit immidiately on non-zero result
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/raspbian_lite/images/raspbian_lite-2019-09-30/2019-09-26-raspbian-buster-lite.zip"
export DEBIAN_FRONTEND=${DEBIAN_FRONTEND:='noninteractive'}
export LANG=${LANG:='C.UTF-8'}
@@ -89,40 +89,35 @@ shopt -s dotglob
for dir in ${REPO_DIR}/*; do
# Don't try to copy image into itself
if [[ $dir != *"images" && $dir != *"imgcache" ]]; then
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy $dir '/home/pi/catkin_ws/src/clover/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy $dir '/home/pi/catkin_ws/src/clever/'
fi;
done
# Monkey
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/monkey' '/root/'
# rsyslog config
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/rsyslog.conf' '/etc'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/rsysrot.sh' '/etc/rsyslog.d'
# Butterfly
${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/monkey.service' '/lib/systemd/system/'
# software install
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-software.sh'
# examples
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/examples' '/home/pi/'
# network setup
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-network.sh'
# avahi setup
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/avahi-services/sftp-ssh.service' '/etc/avahi/services'
# If RPi then use a one thread to build a ROS package on RPi, else use all
[[ $(arch) == 'armv7l' ]] && NUMBER_THREADS=1 || NUMBER_THREADS=$(nproc --all)
# Clover
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/clover.service' '/lib/systemd/system/'
# Clever
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/clever.service' '/lib/systemd/system/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/roscore.service' '/lib/systemd/system/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/melodic-rosdep-clover.yaml' '/etc/ros/rosdep/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/melodic-rosdep-clever.yaml' '/etc/ros/rosdep/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/python3.yaml' '/etc/ros/rosdep/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/ros_python_paths' '/etc/sudoers.d/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/pigpiod.service' '/lib/systemd/system/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/launch.nanorc' '/usr/share/nano/'
# ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/kinetic-ros-clover.rosinstall' '/home/pi/ros_catkin_ws/'
# ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/kinetic-ros-clever.rosinstall' '/home/pi/ros_catkin_ws/'
# Add PX4 udev rules
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${REPO_DIR}'/clover/config/99-px4fmu.rules' '/lib/udev/rules.d/'
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${REPO_DIR}'/clever/config/99-px4fmu.rules' '/lib/udev/rules.d/'
# Add rename script
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-ros.sh' ${REPO_URL} ${IMAGE_VERSION} false false ${NUMBER_THREADS}
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} exec ${SCRIPTS_DIR}'/image-validate.sh'

View File

@@ -34,12 +34,12 @@ echo_stamp() {
echo -e ${TEXT}
}
echo_stamp "Write Clover information"
echo_stamp "Write CLEVER information"
# Clover image version
echo "$1" >> /etc/clover_version
# Clever image version
echo "$1" >> /etc/clever_version
# Origin image file name
echo "${2%.*}" >> /etc/clover_origin
echo "${2%.*}" >> /etc/clever_origin
echo_stamp "Write magic script to /etc/rc.local"
MAGIC_SCRIPT="sudo /root/init_rpi.sh; sudo sed -i '/sudo \\\/root\\\/init_rpi.sh/d' /etc/rc.local && sudo reboot"

View File

@@ -34,24 +34,34 @@ echo_stamp() {
echo -e ${TEXT}
}
echo_stamp "#1 Write STATIC to /etc/dhcpcd.conf"
echo_stamp "#1 Write to /etc/wpa_supplicant/wpa_supplicant.conf"
# TODO: Use wpa_cli insted direct file edit
cat << EOF >> /etc/wpa_supplicant/wpa_supplicant.conf
network={
ssid="CLEVER"
psk="cleverwifi"
mode=2
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
group=CCMP
auth_alg=OPEN
}
EOF
echo_stamp "#2 Write STATIC to /etc/dhcpcd.conf"
cat << EOF >> /etc/dhcpcd.conf
interface wlan0
static ip_address=192.168.11.1/24
EOF
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
address=/clover/coex/192.168.11.1
address=/clever/coex/192.168.11.1
dhcp-range=192.168.11.100,192.168.11.200,12h
no-hosts
filterwin2k
@@ -60,4 +70,8 @@ domain-needed
quiet-dhcp6
EOF
echo_stamp "#4 End of network installation"
#echo_stamp "#4 Write magic script for rename SSID to /etc/rc.local"
#RENAME_SSID="sudo sed -i.OLD \"s/CLEVER/CLEVER-\$(head -c 100 /dev/urandom | xxd -ps -c 100 | sed -e 's/[^0-9]//g' | cut -c 1-4)/g\" /etc/wpa_supplicant/wpa_supplicant.conf && sudo sed -i '/sudo sed/d' /etc/rc.local && sudo reboot"
#sed -i "19a$RENAME_SSID" /etc/rc.local
echo_stamp "#5 End of network installation"

View File

@@ -65,10 +65,11 @@ my_travis_retry() {
return $result
}
# TODO: 'kinetic-rosdep-clover.yaml' should add only if we use our repo?
# TODO: 'kinetic-rosdep-clever.yaml' should add only if we use our repo?
echo_stamp "Init rosdep"
my_travis_retry rosdep init
echo "yaml file:///etc/ros/rosdep/melodic-rosdep-clover.yaml" >> /etc/ros/rosdep/sources.list.d/20-default.list
echo "yaml file:///etc/ros/rosdep/melodic-rosdep-clever.yaml" > /etc/ros/rosdep/sources.list.d/30-clever.list
echo "yaml file:///etc/ros/rosdep/python3.yaml" > /etc/ros/rosdep/sources.list.d/40-python3.list
my_travis_retry rosdep update
echo_stamp "Populate rosdep for ROS user"
@@ -88,29 +89,30 @@ resolve_rosdep() {
export ROS_IP='127.0.0.1' # needed for running tests
echo_stamp "Reconfiguring Clover repository for simplier unshallowing"
cd /home/pi/catkin_ws/src/clover
echo_stamp "Reconfiguring Clever repository for simplier unshallowing"
cd /home/pi/catkin_ws/src/clever
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
echo_stamp "Build and install Clover"
cd /home/pi/catkin_ws
resolve_rosdep $(pwd)
my_travis_retry pip install wheel
my_travis_retry pip install -r /home/pi/catkin_ws/src/clover/clover/requirements.txt
source /opt/ros/melodic/setup.bash
catkin_make -j2 -DCMAKE_BUILD_TYPE=Release
echo_stamp "Installing CLEVER" \
&& export ROS_PYTHON_VERSION=3 \
&& cd /home/pi/catkin_ws/src/clever \
&& git status \
&& cd /home/pi/catkin_ws \
&& resolve_rosdep $(pwd) \
&& my_travis_retry pip3 install wheel \
&& my_travis_retry pip3 install -r /home/pi/catkin_ws/src/clever/clever/requirements.txt \
&& source /opt/ros/melodic/setup.bash \
&& catkin_make -j2 -DCMAKE_BUILD_TYPE=Release \
&& systemctl enable roscore \
&& systemctl enable clever \
&& echo_stamp "All CLEVER was installed!" "SUCCESS" \
|| (echo_stamp "CLEVER installation was failed!" "ERROR"; exit 1)
echo_stamp "Install clever package (for backwards compatibility)"
cd /home/pi/catkin_ws/src/clover/builder/assets/clever
./setup.py install
rm -rf build # remove build artifacts
echo_stamp "Build Clover documentation"
cd /home/pi/catkin_ws/src/clover
echo_stamp "Build CLEVER documentation"
cd /home/pi/catkin_ws/src/clever
NPM_CONFIG_UNSAFE_PERM=true npm install gitbook-cli -g
NPM_CONFIG_UNSAFE_PERM=true gitbook install
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
echo_stamp "Installing additional ROS packages"
apt-get install -y --no-install-recommends \
@@ -128,8 +130,7 @@ echo_stamp "Install GeographicLib datasets (needed for mavros)" \
&& wget -qO- https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts/install_geographiclib_datasets.sh | bash
# FIXME: Buster comes with tornado==5.1.1 but we need tornado==4.2.1 for rosbridge_suite
# (note that Python 3 will still have a more recent version)
pip install tornado==4.2.1
pip3 install tornado==4.2.1
echo_stamp "Running tests"
cd /home/pi/catkin_ws
@@ -143,6 +144,7 @@ echo_stamp "Setup ROS environment"
cat << EOF >> /home/pi/.bashrc
LANG='C.UTF-8'
LC_ALL='C.UTF-8'
ROS_DISTRO='melodic'
export ROS_HOSTNAME=\`hostname\`.local
source /opt/ros/melodic/setup.bash
source /home/pi/catkin_ws/devel/setup.bash

View File

@@ -57,10 +57,6 @@ my_travis_retry() {
return $result
}
echo_stamp "Increase apt retries"
echo "APT::Acquire::Retries \"3\";" > /etc/apt/apt.conf.d/80-retries
echo_stamp "Install apt keys & repos"
# TODO: This STDOUT consist 'OK'
@@ -71,8 +67,10 @@ apt-get update \
echo "deb http://packages.ros.org/ros/ubuntu buster main" > /etc/apt/sources.list.d/ros-latest.list
echo "deb http://deb.coex.tech/opencv3 buster main" > /etc/apt/sources.list.d/opencv3.list
echo "deb http://deb.coex.tech/rpi-ros-melodic buster main" > /etc/apt/sources.list.d/rpi-ros-melodic.list
echo "deb http://deb.coex.tech/clover buster main" > /etc/apt/sources.list.d/clover.list
echo "deb http://deb.coex.tech/melodic-py3 buster main" > /etc/apt/sources.list.d/rpi-ros-melodic.list
# FIXME: We still don't have these packages built for Buster
# FIXME: Check these packages after their installation
echo "deb http://deb.coex.tech/clever stretch main" > /etc/apt/sources.list.d/clever.list
echo_stamp "Update apt cache"
@@ -99,23 +97,22 @@ libjpeg8 \
tcpdump \
ltrace \
libpoco-dev \
libzbar0 \
python-rosdep \
python-rosinstall-generator \
python-wstool \
python-rosinstall \
python3-rosdep \
python3-rosinstall-generator \
python3-wstool \
python3-rosinstall \
build-essential \
libffi-dev \
monkey \
pigpio python-pigpio python3-pigpio \
i2c-tools \
espeak espeak-data python-espeak \
espeak espeak-data python-espeak python3-espeak \
ntpdate \
python-dev \
python3-dev \
python-systemd \
python3-venv \
python3-systemd \
mjpg-streamer \
python3-opencv \
&& echo_stamp "Everything was installed!" "SUCCESS" \
|| (echo_stamp "Some packages wasn't installed!" "ERROR"; exit 1)
@@ -126,10 +123,9 @@ sed -i "s/updates_available//" /usr/share/byobu/status/status
echo_stamp "Installing pip"
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 get-pip.py
python get-pip.py
# Don't even bother installing pip for python2.7
# python get-pip.py
rm get-pip.py
#my_travis_retry pip install --upgrade pip
#my_travis_retry pip3 install --upgrade pip
echo_stamp "Make sure both pip and pip3 are installed"
pip --version
@@ -137,10 +133,14 @@ pip3 --version
echo_stamp "Install and enable Butterfly (web terminal)"
echo_stamp "Workaround for tornado >= 6.0 breaking butterfly"
my_travis_retry pip3 install tornado==5.1.1
my_travis_retry pip3 install butterfly
my_travis_retry pip3 install butterfly[systemd]
cd /root
python3 -m venv butterfly_env
source butterfly_env/bin/activate
my_travis_retry pip install tornado==5.1.1
my_travis_retry pip install butterfly
my_travis_retry pip install butterfly[systemd]
systemctl enable butterfly.socket
deactivate
echo_stamp "Install ws281x library"
my_travis_retry pip install --prefer-binary rpi_ws281x
@@ -158,14 +158,6 @@ 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 "Installing pyzbar"
my_travis_retry pip install pyzbar
my_travis_retry pip3 install pyzbar
echo_stamp "Add .vimrc"
cat << EOF > /home/pi/.vimrc
set mouse-=a

View File

@@ -18,14 +18,13 @@ echo "Run image tests"
export ROS_DISTRO='melodic'
export ROS_IP='127.0.0.1'
export ROS_PYTHON_VERSION=3
source /opt/ros/melodic/setup.bash
source /home/pi/catkin_ws/devel/setup.bash
cd /home/pi/catkin_ws/src/clover/builder/test/
cd /home/pi/catkin_ws/src/clever/builder/test/
./tests.sh
./tests.py
./tests_py3.py
[[ $(./tests_clever.py) == "Warning: clever package is renamed to clover" ]] # test backwards compatibility
echo "Move /etc/ld.so.preload back to its original position"
mv /etc/ld.so.preload.disabled-for-build /etc/ld.so.preload

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# Perform a "standalone install" in a Docker container
set -e
# Step 1: Install pip
apt update
apt install -y curl

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# validate all required modules installed
@@ -14,7 +14,7 @@ from mavros_msgs.msg import State, StatusText, ExtendedState
from mavros_msgs.srv import CommandBool, CommandLong, SetMode
from std_srvs.srv import Trigger
from clover.srv import GetTelemetry, Navigate, NavigateGlobal, SetPosition, SetVelocity, \
from clever.srv import GetTelemetry, Navigate, NavigateGlobal, SetPosition, SetVelocity, \
SetAttitude, SetRates, SetLEDEffect
import tf2_ros
@@ -26,6 +26,5 @@ from pymavlink import mavutil
import rpi_ws281x
import pigpio
from espeak import espeak
from pyzbar import pyzbar
print cv2.getBuildInformation()
print(cv2.getBuildInformation())

View File

@@ -12,10 +12,6 @@ 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
@@ -24,21 +20,23 @@ nmap --version
lsof -v
git --version
vim --version
pip --version
pip2 --version
pip3 --version
tcpdump --version
monkey --version
pigpiod -v
i2cdetect -V
# butterfly uses its own venv, so we honor that
. /root/butterfly_env/bin/activate
butterfly -h
# deactivate venv as needed
deactivate
espeak --version
mjpg_streamer --version
# ros stuff
roscore -h
rosversion clover
rosversion clever
rosversion aruco_pose
rosversion vl53l1x
rosversion mavros
@@ -52,6 +50,3 @@ rosversion usb_cam
rosversion cv_camera
rosversion web_video_server
rosversion rosshow
# validate examples are present
[[ $(ls /home/pi/examples/*) ]]

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env python
# test backwards compatibility
from clever.srv import GetTelemetry, Navigate, NavigateGlobal, SetPosition, SetVelocity, \
SetAttitude, SetRates, SetLEDEffect

View File

@@ -1,8 +0,0 @@
#!/usr/bin/env python3
# Make sure our Python 3 software is installed
import cv2
from pyzbar import pyzbar
print(cv2.getBuildInformation())

View File

@@ -17,8 +17,7 @@ EXCLUDE = 'rviz.png', 'ssid.png', 'sitl_docker_demo.png', 'qgc-params.png', 'but
'cl3_mountBEC.JPG', 'cl3_mountRpiCamera.JPG', 'clever4-front-black-large.png', \
'qgc-battery.png', 'qgc-radio.png', 'qgc-cal-acc.png', 'qgc-esc.png', 'qgc-cal-compass.png', \
'qgc.png', 'qgc-parameters.png', 'clever4-front-white-large.png', 'qgc-modes.png', \
'qgc-requires-setup.png', 'clever4-front-white.png', 'clever4-kit-white.png', '26_1.png', 'battery_holder.stl', \
'camera_case.stl', 'camera_mount.stl'
'qgc-requires-setup.png', 'clever4-front-white.png', 'clever4-kit-white.png', '26_1.png'
code = 0

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 2.8.3)
project(clover)
project(clever)
## Compile as C++11, supported in ROS Kinetic and newer
add_compile_options(-std=c++11)
@@ -30,12 +30,6 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
find_package(GeographicLib REQUIRED)
find_package(OpenCV 3 REQUIRED
COMPONENTS
calib3d
imgproc
)
## System dependencies are found with CMake's conventions
# find_package(Boost REQUIRED COMPONENTS system)
@@ -87,7 +81,6 @@ add_service_files(
SetAttitude.srv
SetRates.srv
SetLEDEffect.srv
Execute.srv
)
## Generate actions in the 'action' folder
@@ -134,7 +127,7 @@ generate_messages(
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
# INCLUDE_DIRS include
LIBRARIES ${PROJECT_NAME}
LIBRARIES clever
# CATKIN_DEPENDS other_catkin_pkg
# DEPENDS system_lib
)
@@ -152,7 +145,7 @@ include_directories(
)
# Declare a C++ library
add_library(${PROJECT_NAME}
add_library(clever
src/optical_flow.cpp
)
@@ -174,8 +167,6 @@ add_executable(vpe_publisher src/vpe_publisher.cpp)
add_executable(led src/led.cpp)
add_executable(shell src/shell.cpp)
target_link_libraries(simple_offboard
${catkin_LIBRARIES}
${GeographicLib_LIBRARIES}
@@ -189,13 +180,9 @@ target_link_libraries(vpe_publisher ${catkin_LIBRARIES})
target_link_libraries(led ${catkin_LIBRARIES})
target_link_libraries(shell ${catkin_LIBRARIES})
add_dependencies(simple_offboard clever_generate_messages_cpp)
add_dependencies(simple_offboard ${PROJECT_NAME}_generate_messages_cpp)
add_dependencies(led ${PROJECT_NAME}_generate_messages_cpp)
add_dependencies(shell ${PROJECT_NAME}_generate_messages_cpp)
add_dependencies(led clever_generate_messages_cpp)
## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
@@ -208,9 +195,8 @@ add_dependencies(shell ${PROJECT_NAME}_generate_messages_cpp)
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Specify libraries to link a library or executable target against
target_link_libraries(${PROJECT_NAME}
target_link_libraries(clever
${catkin_LIBRARIES}
${OpenCV_LIBRARIES}
)
#############
@@ -266,7 +252,7 @@ endif()
#############
## Add gtest based cpp test target and link libraries
# catkin_add_gtest(${PROJECT_NAME}-test test/test_${PROJECT_NAME}.cpp)
# catkin_add_gtest(${PROJECT_NAME}-test test/test_clever.cpp)
# if(TARGET ${PROJECT_NAME}-test)
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
# endif()

View File

@@ -0,0 +1,45 @@
image_width: 320
image_height: 240
distortion_model: plumb_bob
camera_name: raspicam
camera_matrix:
rows: 3
cols: 3
data:
- 166.23942373073172
- 0.
- 162.19011246829268
- 0.
- 166.5880923974026
- 109.82227735714285
- 0.
- 0.
- 1.
distortion_coefficients:
rows: 1
cols: 8
data: [ 2.15356885e-01, -1.17472846e-01, -3.06197672e-04,
-1.09444025e-04, -4.53657258e-03, 5.73090623e-01,
-1.27574577e-01, -2.86125589e-02, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00]
rectification_matrix:
rows: 3
cols: 3
data: [1, 0, 0, 0, 1, 0, 0, 0, 1]
projection_matrix:
rows: 3
cols: 4
data:
- 166.23942373073172
- 0.
- 162.19011246829268
- 0.
- 0.
- 166.5880923974026
- 109.82227735714285
- 0.
- 0.
- 0.
- 1.
- 0.

View File

@@ -1,17 +1,17 @@
image_width: 640
image_height: 480
distortion_model: plumb_bob
camera_name: main_camera_optical
camera_name: raspicam
camera_matrix:
rows: 3
cols: 3
data:
- 332.47884746146343
- 0.
- 320.0
- 324.38022493658536
- 0.
- 333.1761847948052
- 240.0
- 219.6445547142857
- 0.
- 0.
- 1.

View File

@@ -3,7 +3,7 @@
<arg name="aruco_map" default="false"/>
<arg name="aruco_vpe" default="false"/>
<!-- For additional help go to https://clover.coex.tech/aruco -->
<!-- For additional help go to https://clever.coex.tech/aruco -->
<!-- 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 nodelet_manager" output="screen" clear_params="true">
@@ -14,9 +14,6 @@
<param name="send_tf" value="true"/>
<param name="known_tilt" value="map"/>
<param name="length" value="0.33"/>
<!-- aruco detector parameters -->
<param name="cornerRefinementMethod" value="2"/> <!-- contour refinement -->
<param name="minMarkerPerimeterRate" value="0.075"/> <!-- 0.075 for 320x240, 0.0375 for 640x480 -->
</node>
<!-- aruco_map: estimate aruco map pose -->
@@ -34,7 +31,7 @@
</node>
<!-- vpe publisher from aruco markers -->
<node name="vpe_publisher" pkg="clover" type="vpe_publisher" if="$(arg aruco_vpe)" output="screen" clear_params="true">
<node name="vpe_publisher" pkg="clever" type="vpe_publisher" if="$(arg aruco_vpe)" output="screen" clear_params="true">
<remap from="~pose_cov" to="aruco_map/pose"/>
<remap from="~vpe" to="mavros/vision_pose/pose"/>
<param name="frame_id" value="aruco_map_detected"/>

View File

@@ -1,26 +1,23 @@
<launch>
<arg name="fcu_conn" default="usb"/>
<arg name="fcu_ip" default="127.0.0.1"/>
<arg name="fcu_sys_id" default="1"/>
<arg name="gcs_bridge" default="tcp"/>
<arg name="web_video_server" default="true"/>
<arg name="rosbridge" default="true"/>
<arg name="main_camera" default="true"/>
<arg name="optical_flow" default="true"/>
<arg name="optical_flow" default="false"/>
<arg name="aruco" default="false"/>
<arg name="rangefinder_vl53l1x" default="true"/>
<arg name="led" default="true"/>
<arg name="rangefinder_vl53l1x" default="false"/>
<arg name="led" default="false"/>
<arg name="rc" default="true"/>
<arg name="shell" default="true"/>
<!-- log formatting -->
<env name="ROSCONSOLE_FORMAT" value="[${severity}] [${time}]: ${logger}: ${message}"/>
<!-- mavros -->
<include file="$(find clover)/launch/mavros.launch">
<include file="$(find clever)/launch/mavros.launch">
<arg name="fcu_conn" value="$(arg fcu_conn)"/>
<arg name="fcu_ip" value="$(arg fcu_ip)"/>
<arg name="fcu_sys_id" value="$(arg fcu_sys_id)"/>
<arg name="gcs_bridge" value="$(arg gcs_bridge)"/>
</include>
@@ -31,14 +28,13 @@
</node>
<!-- aruco markers -->
<include file="$(find clover)/launch/aruco.launch" if="$(arg aruco)"/>
<include file="$(find clever)/launch/aruco.launch" if="$(arg aruco)"/>
<!-- optical flow -->
<node pkg="nodelet" type="nodelet" name="optical_flow" args="load clover/optical_flow nodelet_manager" if="$(arg optical_flow)" clear_params="true" output="screen">
<node pkg="nodelet" type="nodelet" name="optical_flow" args="load clever/optical_flow nodelet_manager" if="$(arg optical_flow)" clear_params="true" output="screen">
<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 -->
@@ -49,14 +45,14 @@
<node pkg="tf2_ros" type="static_transform_publisher" name="map_flipped_frame" args="0 0 0 3.1415926 3.1415926 0 map map_flipped"/>
<!-- simplified offboard control -->
<node name="simple_offboard" pkg="clover" type="simple_offboard" output="screen" clear_params="true">
<node name="simple_offboard" pkg="clever" type="simple_offboard" output="screen" clear_params="true">
<param name="reference_frames/body" value="map"/>
<param name="reference_frames/base_link" value="map"/>
<param name="reference_frames/navigate_target" value="map"/>
</node>
<!-- main camera -->
<include file="$(find clover)/launch/main_camera.launch" if="$(arg main_camera)"/>
<include file="$(find clever)/launch/main_camera.launch" if="$(arg main_camera)"/>
<!-- rosbridge -->
<include file="$(find rosbridge_server)/launch/rosbridge_websocket.launch" if="$(eval rosbridge or rc)"/>
@@ -67,24 +63,11 @@
<!-- vl53l1x ToF rangefinder -->
<node name="rangefinder" pkg="vl53l1x" type="vl53l1x_node" output="screen" if="$(arg rangefinder_vl53l1x)">
<param name="frame_id" value="rangefinder"/>
<param name="min_signal" value="0.4"/>
<param name="pass_statuses" type="yaml" value="[0, 6, 7, 11]"/>
</node>
<!-- led strip -->
<include file="$(find clover)/launch/led.launch" if="$(arg led)"/>
<include file="$(find clever)/launch/led.launch" if="$(arg led)"/>
<!-- rc backend -->
<node name="rc" pkg="clover" type="rc" output="screen" if="$(arg rc)" clear_params="true">
<!-- Send fake GCS heartbeats. Set to "true" for upstream PX4 -->
<param name="use_fake_gcs" value="false"/>
</node>
<!-- Shell access through ROS service -->
<node name="shell" pkg="clover" type="shell" output="screen" if="$(arg shell)"/>
<!-- Update static directory -->
<node pkg="roswww_static" name="roswww_static" type="main.py" clear_params="true">
<param name="default_package" value="clover"/>
</node>
<node name="rc" pkg="clever" type="rc" output="screen" if="$(arg rc)"/>
</launch>

View File

@@ -0,0 +1,6 @@
<launch>
<arg name="device" default="/dev/video1"/>
<arg name="port" default="9999"/>
<node name="fpv_camera" pkg="clever" type="fpv_camera" args="$(arg device) $(arg port)" output="screen"/>
</launch>

View File

@@ -3,13 +3,13 @@
<arg name="led_effect" default="true"/>
<arg name="led_notify" default="true"/>
<!-- For additional help go to https://clover.coex.tech/led -->
<!-- For additional help go to https://clever.coex.tech/led -->
<!-- ws281x led strip driver -->
<node pkg="ws281x" name="led" type="ws281x_node" clear_params="true" output="screen" if="$(arg ws281x)">
<param name="led_count" value="58"/>
<param name="gpio_pin" value="21"/>
<param name="brightness" value="64"/>
<param name="brightness" value="100"/>
<param name="strip_type" value="WS2811_STRIP_GRB"/>
<param name="target_frequency" value="800000"/>
<param name="dma" value="10"/>
@@ -17,7 +17,7 @@
</node>
<!-- high level led effects control, events notification with leds -->
<node pkg="clover" name="led_effect" type="led" ns="led" clear_params="true" output="screen" if="$(arg led_effect)">
<node pkg="clever" name="led_effect" type="led" ns="led" clear_params="true" output="screen" if="$(arg led_effect)">
<param name="blink_rate" value="2"/>
<param name="fade_period" value="0.5"/>
<param name="rainbow_period" value="5"/>

View File

@@ -0,0 +1,38 @@
<launch>
<!-- 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://clever.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"/>-->
<!-- camera node -->
<node pkg="nodelet" type="nodelet" name="main_camera" args="load cv_camera/CvCameraNodelet nodelet_manager" clear_params="true">
<param name="frame_id" value="main_camera_optical"/>
<param name="camera_info_url" value="file://$(find clever)/camera_info/fisheye_cam_320.yaml"/>
<param name="rate" value="100"/> <!-- poll rate -->
<param name="cv_cap_prop_fps" value="40"/> <!-- camera FPS -->
<param name="capture_delay" value="0.02"/> <!-- approximate delay on frame retrieving -->
<param name="rescale_camera_info" value="true"/> <!-- automatically rescale camera calibration info -->
<!-- camera resolution, NOTE: camera_info file should match it -->
<param name="image_width" value="320"/>
<param name="image_height" value="240"/>
</node>
<!-- camera visualization markers -->
<node pkg="clever" type="camera_markers" ns="main_camera" name="main_camera_markers">
<param name="scale" value="3.0"/>
</node>
</launch>

View File

@@ -1,7 +1,6 @@
<launch>
<arg name="fcu_conn" default="usb"/> <!-- options: usb, uart, tcp, udp, sitl -->
<arg name="fcu_conn" default="usb"/>
<arg name="fcu_ip" default="127.0.0.1"/>
<arg name="fcu_sys_id" default="1"/>
<arg name="gcs_bridge" default="tcp"/>
<arg name="viz" default="true"/>
<arg name="respawn" default="true"/>
@@ -14,15 +13,9 @@
<!-- USB connection -->
<param name="fcu_url" value="/dev/px4fmu" if="$(eval fcu_conn == 'usb')"/>
<!-- sitl before PX4 1.9.0 -->
<!-- sitl -->
<param name="fcu_url" value="udp://@$(arg fcu_ip):14557" if="$(eval fcu_conn == 'udp')"/>
<!-- sitl since PX4 1.9.0 -->
<param name="fcu_url" value="udp://@$(arg fcu_ip):14580" if="$(eval fcu_conn == 'sitl')"/>
<!-- set target_system_id -->
<param name="target_system_id" value="$(arg fcu_sys_id)" />
<!-- gcs bridge -->
<param name="gcs_url" value="tcp-l://0.0.0.0:5760" if="$(eval gcs_bridge == 'tcp')"/>
<param name="gcs_url" value="udp://0.0.0.0:14550@14550" if="$(eval gcs_bridge == 'udp')"/>
@@ -33,7 +26,7 @@
<param name="conn/timeout" value="8"/>
<!-- basic params -->
<rosparam command="load" file="$(find clover)/launch/mavros_config.yaml"/>
<rosparam command="load" file="$(find clever)/launch/mavros_config.yaml"/>
<!-- remap rangefinder -->
<remap from="mavros/distance_sensor/rangefinder_sub" to="rangefinder/range"/>

View File

@@ -1,9 +1,9 @@
<launch>
<!-- clover configuration for testing in sitl -->
<!-- Clever 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">
<include file="$(find clever)/launch/clever.launch">
<arg name="fcu_conn" value="udp"/>
<arg name="fcu_ip" value="$(arg ip)"/>
<arg name="gcs_bridge" value="false"/>
@@ -13,7 +13,6 @@
<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

@@ -0,0 +1,5 @@
<library path="lib/libclever">
<class name="clever/optical_flow" type="OpticalFlow" base_class_type="nodelet::Nodelet">
<description/>
</class>
</library>

View File

@@ -1,13 +1,13 @@
<?xml version="1.0"?>
<package format="2">
<name>clover</name>
<name>clever</name>
<version>0.0.1</version>
<description>The Clover package</description>
<description>The CLEVER package</description>
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
<license>MIT</license>
<url type="website">https://clover.coex.tech/</url>
<url type="website">https://clever.coex.tech/</url>
<author email="okalachev@gmail.com">Oleg Kalachev</author>
<author email="urpylka@gmail.com">Artem Smirnov</author>
@@ -15,7 +15,6 @@
<!-- Package format specifier version 2.0 allows specifying dependencies for both
build- and runtime in a single <depend> element -->
<depend>message_generation</depend>
<depend>roscpp</depend>
<depend>rospy</depend>
<depend>std_srvs</depend>
@@ -34,10 +33,12 @@
<depend>mavros_extras</depend>
<depend>cv_camera</depend>
<depend>cv_bridge</depend>
<!-- FIXME: OpenCV3 is not in Melodic -->
<!-- <depend>opencv3</depend> -->
<depend>rosbridge_server</depend>
<depend>web_video_server</depend>
<depend>tf2_web_republisher</depend>
<depend>python-lxml</depend>
<depend>python3-lxml</depend>
<exec_depend>python-pymavlink</exec_depend>
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->

5
clever/requirements.txt Normal file
View File

@@ -0,0 +1,5 @@
flask==1.1.1
docopt==0.6.2
geopy==1.20.0
smbus2==0.3.0
VL53L1X==0.0.4

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Usage
# camera_stream <video_device> <http port>
# fpv_camera <video_device> <http port>
echo "Starting camera stream $1 on :$2"
echo "Starting FPV camera $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"

View File

@@ -14,7 +14,7 @@
#include <string>
#include <boost/algorithm/string.hpp>
#include <clover/SetLEDEffect.h>
#include <clever/SetLEDEffect.h>
#include <led_msgs/SetLEDs.h>
#include <led_msgs/LEDState.h>
#include <led_msgs/LEDStateArray.h>
@@ -23,7 +23,7 @@
#include <mavros_msgs/State.h>
#include <rosgraph_msgs/Log.h>
clover::SetLEDEffect::Request current_effect;
clever::SetLEDEffect::Request current_effect;
int led_count;
ros::Timer timer;
ros::Time start_time;
@@ -144,7 +144,7 @@ void proceed(const ros::TimerEvent& event)
}
}
bool setEffect(clover::SetLEDEffect::Request& req, clover::SetLEDEffect::Response& res)
bool setEffect(clever::SetLEDEffect::Request& req, clever::SetLEDEffect::Response& res)
{
res.success = true;
@@ -237,7 +237,7 @@ void notify(const std::string& event)
ros::param::has("~notify/" + event + "/g") ||
ros::param::has("~notify/" + event + "/b")) {
ROS_INFO_THROTTLE(5, "led: notify %s", event.c_str());
clover::SetLEDEffect effect;
clever::SetLEDEffect effect;
effect.request.effect = ros::param::param("~notify/" + event + "/effect", std::string(""));
effect.request.r = ros::param::param("~notify/" + event + "/r", 0);
effect.request.g = ros::param::param("~notify/" + event + "/g", 0);
@@ -263,10 +263,7 @@ void handleMavrosState(const mavros_msgs::State& msg)
// remove the part before "."
mode = mode.substr(mode.find(".") + 1);
}
std::string err;
if (ros::names::validate(mode, err)) {
notify(mode);
}
notify(mode);
}
mavros_state = msg;
}
@@ -281,8 +278,7 @@ void handleLog(const rosgraph_msgs::Log& log)
void handleBattery(const sensor_msgs::BatteryState& msg)
{
for (auto const& voltage : msg.cell_voltage) {
if (voltage < low_battery_threshold &&
voltage > 2.0) { // voltage < 2.0 likely indicates incorrect voltage measurement
if (voltage < low_battery_threshold) {
// notify low battery every time
notify("low_battery");
}

View File

@@ -34,7 +34,9 @@ class OpticalFlow : public nodelet::Nodelet
{
public:
OpticalFlow():
camera_matrix_(3, 3, CV_64F)
camera_matrix_(3, 3, CV_64F),
dist_coeffs_(8, 1, CV_64F),
tf_listener_(tf_buffer_)
{}
private:
@@ -44,14 +46,12 @@ private:
image_transport::CameraSubscriber img_sub_;
image_transport::Publisher img_pub_;
mavros_msgs::OpticalFlowRad flow_;
int roi_px_;
double roi_rad_;
cv::Rect roi_;
int roi_, roi_2_;
Mat hann_;
Mat prev_, curr_;
Mat camera_matrix_, dist_coeffs_;
std::unique_ptr<tf2_ros::Buffer> tf_buffer_;
std::unique_ptr<tf2_ros::TransformListener> tf_listener_;
tf2_ros::Buffer tf_buffer_;
tf2_ros::TransformListener tf_listener_;
bool calc_flow_gyro_;
void onInit()
@@ -61,14 +61,11 @@ private:
image_transport::ImageTransport it(nh);
image_transport::ImageTransport it_priv(nh_priv);
tf_buffer_.reset(new tf2_ros::Buffer());
tf_listener_.reset(new tf2_ros::TransformListener(*tf_buffer_, nh));
local_frame_id_ = nh.param<std::string>("mavros/local_position/tf/frame_id", "map");
fcu_frame_id_ = nh.param<std::string>("mavros/local_position/tf/child_frame_id", "base_link");
roi_px_ = nh_priv.param("roi", 128);
roi_rad_ = nh_priv.param("roi_rad", 0.0);
calc_flow_gyro_ = nh_priv.param("calc_flow_gyro", false);
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("calc_flow_gyro", calc_flow_gyro_, false);
img_sub_ = it.subscribeCamera("image_raw", 1, &OpticalFlow::flow, this);
img_pub_ = it_priv.advertise("debug", 1);
@@ -92,7 +89,9 @@ private:
camera_matrix_.at<double>(i, j) = cinfo->K[3 * i + j];
}
}
dist_coeffs_ = cv::Mat(cinfo->D, true);
for (int k = 0; k < cinfo->D.size(); k++) {
dist_coeffs_.at<double>(k) = cinfo->D[k];
}
}
void drawFlow(Mat& frame, double x, double y, double quality) const
@@ -113,31 +112,9 @@ private:
auto img = cv_bridge::toCvShare(msg, "mono8")->image;
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_);
// Apply ROI
if (roi_ != 0) {
img = img(cv::Rect((msg->width / 2 - roi_2_), (msg->height / 2 - roi_2_), roi_, roi_));
}
img.convertTo(curr_, CV_32F);
@@ -185,7 +162,7 @@ private:
flow_camera.vector.x = flow_y; // +y means counter-clockwise rotation around Y axis
flow_camera.vector.y = -flow_x; // +x means clockwise rotation around X axis
try {
tf_buffer_->transform(flow_camera, flow_fcu, fcu_frame_id_);
tf_buffer_.transform(flow_camera, flow_fcu, fcu_frame_id_);
} catch (const tf2::TransformException& e) {
// transform is not available yet
return;
@@ -199,7 +176,7 @@ private:
try {
auto flow_gyro_camera = calcFlowGyro(msg->header.frame_id, prev_stamp_, msg->header.stamp);
static geometry_msgs::Vector3Stamped flow_gyro_fcu;
tf_buffer_->transform(flow_gyro_camera, flow_gyro_fcu, fcu_frame_id_);
tf_buffer_.transform(flow_gyro_camera, flow_gyro_fcu, fcu_frame_id_);
flow_.integrated_xgyro = flow_gyro_fcu.vector.x;
flow_.integrated_ygyro = flow_gyro_fcu.vector.y;
flow_.integrated_zgyro = flow_gyro_fcu.vector.z;
@@ -246,8 +223,8 @@ private:
geometry_msgs::Vector3Stamped calcFlowGyro(const std::string& frame_id, const ros::Time& prev, const ros::Time& curr)
{
tf2::Quaternion prev_rot, curr_rot;
tf2::fromMsg(tf_buffer_->lookupTransform(frame_id, local_frame_id_, prev).transform.rotation, prev_rot);
tf2::fromMsg(tf_buffer_->lookupTransform(frame_id, local_frame_id_, curr, ros::Duration(0.1)).transform.rotation, curr_rot);
tf2::fromMsg(tf_buffer_.lookupTransform(frame_id, local_frame_id_, prev).transform.rotation, prev_rot);
tf2::fromMsg(tf_buffer_.lookupTransform(frame_id, local_frame_id_, curr, ros::Duration(0.1)).transform.rotation, curr_rot);
geometry_msgs::Vector3Stamped flow;
flow.header.frame_id = frame_id;

View File

@@ -1,5 +1,5 @@
/*
* Clover mobile remote control backend
* CLEVER mobile remote control backend
* Send ManualControl messages through UDP
* 'latched_state' topic
*
@@ -34,15 +34,12 @@ public:
nh(),
nh_priv("~")
{
bool use_fake_gcs = nh_priv.param("use_fake_gcs", true);
// Create socket thread
std::thread t(&RC::socketThread, this);
t.detach();
if (use_fake_gcs) {
std::thread gcst(&RC::fakeGCSThread, this);
gcst.detach();
}
std::thread gcst(&RC::fakeGCSThread, this);
gcst.detach();
initLatchedState();
}

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# coding=utf-8
# Copyright (C) 2018 Copter Express Technologies
@@ -9,7 +9,6 @@
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
import os
import math
import subprocess
import re
@@ -95,7 +94,7 @@ def get_param(name):
return None
if not res.success:
failure('unable to retrieve PX4 parameter %s', name)
failure('Unable to retrieve PX4 parameter %s', name)
else:
if res.value.integer != 0:
return res.value.integer
@@ -200,17 +199,17 @@ def check_fcu():
info('no version data available from SITL')
r = re.compile(r'^FW (git tag|version): (v?\d\.\d\.\d.*)$')
is_clover_firmware = False
is_clever_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
if 'clever' in version:
is_clever_firmware = True
if not is_clover_firmware:
failure('not running Clover PX4 firmware, https://clover.coex.tech/firmware')
if not is_clever_firmware:
failure('not running Clever PX4 firmware, https://clever.coex.tech/firmware')
est = get_param('SYS_MC_EST_GROUP')
if est == 1:
@@ -225,12 +224,6 @@ def check_fcu():
else:
info('LPE_FUSION: barometer fusion is disabled')
mag_yaw_w = get_param('ATT_W_MAG')
if mag_yaw_w == 0:
info('magnetometer weight (ATT_W_MAG) is zero, better for indoor flights')
else:
info('magnetometer weight (ATT_W_MAG) is non-zero (%.2f), better for outdoor flights', mag_yaw_w)
elif est == 2:
info('selected estimator: EKF2')
else:
@@ -245,18 +238,15 @@ def check_fcu():
cbrk_usb_chk = get_param('CBRK_USB_CHK')
if cbrk_usb_chk != 197848:
failure('set parameter CBRK_USB_CHK to 197848 for flying with USB connected')
failure('Set parameter CBRK_USB_CHK to 197848 for flying with USB connected')
try:
battery = rospy.wait_for_message('mavros/battery', BatteryState, timeout=3)
if not battery.cell_voltage:
failure('cell voltage is not available, https://clover.coex.tech/power')
else:
cell = battery.cell_voltage[0]
if cell > 4.3 or cell < 3.0:
failure('incorrect cell voltage: %.2f V, https://clover.coex.tech/power', cell)
elif cell < 3.7:
failure('critically low cell voltage: %.2f V, recharge battery', cell)
cell = battery.cell_voltage[0]
if cell > 4.3 or cell < 3.0:
failure('Incorrect cell voltage: %.2f V, https://clever.coex.tech/power', cell)
elif cell < 3.7:
failure('Critically low cell voltage: %.2f V, recharge battery', cell)
except rospy.ROSException:
failure('no battery state')
@@ -311,7 +301,7 @@ def check_camera(name):
if not optical or not cable:
info('%s: custom camera orientation detected', name)
else:
info('camera is oriented %s, cable from camera goes %s', optical, cable)
info('camera is oriented %s, camera cable goes %s', optical, cable)
except tf2_ros.TransformException:
failure('cannot transform from base_link to camera frame')
@@ -339,11 +329,8 @@ def is_process_running(binary, exact=False, full=False):
@check('ArUco markers')
def check_aruco():
if is_process_running('aruco_detect', full=True):
try:
info('aruco_detect/length = %g m', rospy.get_param('aruco_detect/length'))
except KeyError:
failure('aruco_detect/length parameter is not set')
known_tilt = rospy.get_param('aruco_detect/known_tilt', '')
info('aruco_detect/length = %g m', rospy.get_param('aruco_detect/length'))
known_tilt = rospy.get_param('aruco_detect/known_tilt')
if known_tilt == 'map':
known_tilt += ' (ALL markers are on the floor)'
elif known_tilt == 'map_flipped':
@@ -359,7 +346,7 @@ def check_aruco():
return
if is_process_running('aruco_map', full=True):
known_tilt = rospy.get_param('aruco_map/known_tilt', '')
known_tilt = rospy.get_param('aruco_map/known_tilt')
if known_tilt == 'map':
known_tilt += ' (marker\'s map is on the floor)'
elif known_tilt == 'map_flipped':
@@ -519,7 +506,7 @@ def check_global_position():
try:
rospy.wait_for_message('mavros/global_position/global', NavSatFix, timeout=1)
except rospy.ROSException:
info('no global position')
failure('no global position')
@check('Optical flow')
@@ -632,16 +619,16 @@ def check_cpu_usage():
cpu.strip(), cmd.strip(), pid.strip())
@check('clover.service')
def check_clover_service():
@check('clever.service')
def check_clever_service():
try:
output = subprocess.check_output('systemctl show -p ActiveState --value clover.service'.split(),
output = subprocess.check_output('systemctl show -p ActiveState --value clever.service'.split(),
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
failure('systemctl returned %s: %s', e.returncode, e.output)
return
if 'inactive' in output:
failure('service is not running, try sudo systemctl restart clover')
failure('service is not running, try sudo systemctl restart clever')
return
elif 'failed' in output:
failure('service failed to run, check your launch-files')
@@ -649,7 +636,7 @@ def check_clover_service():
r = re.compile(r'^(.*)\[(FATAL|ERROR)\] \[\d+.\d+\]: (.*?)(\x1b(.*))?$')
error_count = OrderedDict()
try:
for line in open('/tmp/clover.err', 'r'):
for line in open('/tmp/clever.err', 'r'):
node_error = r.search(line)
if node_error:
msg = node_error.groups()[1] + ': ' + node_error.groups()[2]
@@ -673,9 +660,9 @@ def check_clover_service():
@check('Image')
def check_image():
try:
info('version: %s', open('/etc/clover_version').read().strip())
info('version: %s', open('/etc/clever_version').read().strip())
except IOError:
info('no /etc/clover_version file, not the Clover image?')
info('no /etc/clever_version file, not the Clever image?')
@check('Preflight status')
@@ -699,82 +686,9 @@ def check_preflight_status():
failure(' '.join([match.groups()[1], 'check:', check_status]))
@check('Network')
def check_network():
ros_hostname = os.environ.get('ROS_HOSTNAME', '').strip()
if not ros_hostname:
failure('no ROS_HOSTNAME is set')
elif ros_hostname.endswith('.local'):
# using mdns hostname
hosts = open('/etc/hosts', 'r')
for line in hosts:
parts = line.split()
if len(parts) < 2:
continue
ip = parts.pop(0).split('.')
if ip[0] == '127': # loopback ip
if ros_hostname in parts:
break
else:
failure('not found %s in /etc/hosts, ROS will malfunction if network interfaces are down, https://clover.coex.tech/hostname', ros_hostname)
@check('RPi health')
def check_rpi_health():
# `vcgencmd get_throttled` output codes taken from
# https://github.com/raspberrypi/documentation/blob/JamesH65-patch-vcgencmd-vcdbg-docs/raspbian/applications/vcgencmd.md#get_throttled
# TODO: support more base platforms?
FLAG_UNDERVOLTAGE_NOW = 0x1
FLAG_FREQ_CAP_NOW = 0x2
FLAG_THROTTLING_NOW = 0x4
FLAG_THERMAL_LIMIT_NOW = 0x8
FLAG_UNDERVOLTAGE_OCCURRED = 0x10000
FLAG_FREQ_CAP_OCCURRED = 0x20000
FLAG_THROTTLING_OCCURRED = 0x40000
FLAG_THERMAL_LIMIT_OCCURRED = 0x80000
FLAG_DESCRIPTIONS = (
(FLAG_THROTTLING_NOW, 'system throttled to prevent damage'),
(FLAG_THROTTLING_OCCURRED, 'your system is susceptible to throttling'),
(FLAG_UNDERVOLTAGE_NOW, 'not enough power for onboard computer, flight inadvisable'),
(FLAG_UNDERVOLTAGE_OCCURRED, 'power supply cannot provide enough power'),
(FLAG_FREQ_CAP_NOW, 'CPU reached thermal limit and is throttled now'),
(FLAG_FREQ_CAP_OCCURRED, 'CPU may overheat during drone operation, consider additional cooling'),
(FLAG_THERMAL_LIMIT_NOW, 'CPU reached soft thermal limit, frequency reduced'),
(FLAG_THERMAL_LIMIT_OCCURRED, 'CPU may reach soft thermal limit, consider additional cooling'),
)
try:
# vcgencmd outputs a single string in a form of
# <parameter>=<value>
# In case of `get_throttled`, <value> is a hexadecimal number
# with some of the FLAGs OR'ed together
output = subprocess.check_output(['vcgencmd', 'get_throttled'])
except OSError:
failure('could not call vcgencmd binary; not a Raspberry Pi?')
return
throttle_mask = int(output.split('=')[1], base=16)
for flag_description in FLAG_DESCRIPTIONS:
if throttle_mask & flag_description[0]:
failure(flag_description[1])
@check('Board')
def check_board():
try:
info('%s', open('/proc/device-tree/model').readline())
except IOError:
info('could not open /proc/device-tree/model, not a Raspberry Pi?')
def selfcheck():
check_image()
check_board()
check_clover_service()
check_network()
check_clever_service()
check_fcu()
check_imu()
check_local_position()
@@ -787,7 +701,6 @@ def selfcheck():
check_optical_flow()
check_vpe()
check_rangefinder()
check_rpi_health()
check_cpu_usage()
check_boot_duration()

View File

@@ -37,18 +37,18 @@
#include <mavros_msgs/State.h>
#include <mavros_msgs/StatusText.h>
#include <clover/GetTelemetry.h>
#include <clover/Navigate.h>
#include <clover/NavigateGlobal.h>
#include <clover/SetPosition.h>
#include <clover/SetVelocity.h>
#include <clover/SetAttitude.h>
#include <clover/SetRates.h>
#include <clever/GetTelemetry.h>
#include <clever/Navigate.h>
#include <clever/NavigateGlobal.h>
#include <clever/SetPosition.h>
#include <clever/SetVelocity.h>
#include <clever/SetAttitude.h>
#include <clever/SetRates.h>
using std::string;
using namespace geometry_msgs;
using namespace sensor_msgs;
using namespace clover;
using namespace clever;
using mavros_msgs::PositionTarget;
using mavros_msgs::AttitudeTarget;
using mavros_msgs::Thrust;
@@ -90,7 +90,7 @@ PositionTarget position_raw_msg;
AttitudeTarget att_raw_msg;
Thrust thrust_msg;
TwistStamped rates_msg;
TransformStamped target, setpoint;
TransformStamped target;
geometry_msgs::TransformStamped body;
// State
@@ -177,6 +177,8 @@ inline bool waitTransform(const string& target, const string& source,
ros::spinOnce();
r.sleep();
}
// At this point our node has been shut down
return false;
}
#define TIMEOUT(msg, timeout) (ros::Time::now() - msg.header.stamp > timeout)
@@ -433,17 +435,6 @@ void publish(const ros::Time stamp)
position_raw_msg.position = position_msg.pose.position;
position_raw_pub.publish(position_raw_msg);
}
// publish setpoint frame
if (!setpoint.child_frame_id.empty()) {
setpoint.transform.translation.x = position_msg.pose.position.x;
setpoint.transform.translation.y = position_msg.pose.position.y;
setpoint.transform.translation.z = position_msg.pose.position.z;
setpoint.transform.rotation = position_msg.pose.orientation;
setpoint.header.frame_id = position_msg.header.frame_id;
setpoint.header.stamp = position_msg.header.stamp;
transform_broadcaster->sendTransform(setpoint);
}
}
if (setpoint_type == VELOCITY) {
@@ -490,7 +481,7 @@ inline void checkState()
throw std::runtime_error("State timeout, check mavros settings");
if (!state.connected)
throw std::runtime_error("No connection to FCU, https://clover.coex.tech/connection");
throw std::runtime_error("No connection to FCU, https://clever.coex.tech/connection");
}
#define ENSURE_FINITE(var) { if (!std::isfinite(var)) throw std::runtime_error(#var " argument cannot be NaN or Inf"); }
@@ -760,6 +751,8 @@ bool land(std_srvs::Trigger::Request& req, std_srvs::Trigger::Response& res)
busy = false;
return true;
}
// We should not end up here, but if we did, our node has been shut down
return false;
}
int main(int argc, char **argv)
@@ -775,7 +768,6 @@ int main(int argc, char **argv)
nh.param<string>("mavros/local_position/tf/frame_id", local_frame, "map");
nh.param<string>("mavros/local_position/tf/child_frame_id", fcu_frame, "base_link");
nh_priv.param("target_frame", target.child_frame_id, string("navigate_target"));
nh_priv.param("setpoint", setpoint.child_frame_id, string("setpoint"));
nh_priv.param("auto_release", auto_release, true);
nh_priv.param("land_only_in_offboard", land_only_in_offboard, true);
nh_priv.param("nav_from_sp", nav_from_sp, true);

View File

@@ -1,12 +1,11 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import rospy
import pytest
from mavros_msgs.msg import State
from clover import srv
@pytest.fixture()
def node():
return rospy.init_node('clover_test', anonymous=True)
return rospy.init_node('clever_test', anonymous=True)
def test_state(node):
state = rospy.wait_for_message('mavros/state', State, timeout=10)
@@ -28,19 +27,3 @@ def test_simple_offboard_services_available():
def test_web_video_server(node):
import urllib2
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

@@ -3,7 +3,7 @@
<node pkg="mavros" type="mavros_node" name="mavros" required="true" output="screen">
<param name="fcu_url" value="udp://@127.0.1:14557"/>
<rosparam command="load" file="$(find clover)/launch/mavros_config.yaml"/>
<rosparam command="load" file="$(find clever)/launch/mavros_config.yaml"/>
</node>
<node name="visualization" pkg="mavros_extras" type="visualization" required="true">
@@ -23,21 +23,19 @@
<node pkg="tf2_ros" type="static_transform_publisher" name="map_flipped_frame" args="0 0 0 3.1415926 3.1415926 0 map map_flipped" required="true"/>
<node name="simple_offboard" pkg="clover" type="simple_offboard" required="true" output="screen">
<node name="simple_offboard" pkg="clever" type="simple_offboard" required="true" output="screen">
<param name="reference_frames/body" value="map"/>
<param name="reference_frames/base_link" value="map"/>
</node>
<node name="tf2_web_republisher" pkg="tf2_web_republisher" type="tf2_web_republisher" required="true"/>
<node name="rc" pkg="clover" type="rc" required="true" output="screen"/>
<node name="rc" pkg="clever" type="rc" required="true" output="screen"/>
<node name="shell" pkg="clover" type="shell" required="true" output="screen"/>
<node pkg="clover" name="led_effect" type="led" ns="led" clear_params="true" output="screen" required="true">
<node pkg="clever" name="led_effect" type="led" ns="led" clear_params="true" output="screen" required="true">
<rosparam param="notify">startup: { r: 255, g: 255, b: 255 }</rosparam>
</node>
<param name="test_module" value="$(find clover)/test/basic.py"/>
<param name="test_module" value="$(find clever)/test/basic.py"/>
<test test-name="basic_test" pkg="ros_pytest" type="ros_pytest_runner"/>
</launch>

14
clever/www/index.html Normal file
View File

@@ -0,0 +1,14 @@
<h1>CLEVER Drone Kit Tools</h1>
<ul>
<li><a href="docs">View documentation</a> (snapshot of <a href="https://clever.coex.tech">clever.coex.tech</a>)</li>
<li><a href="" id="wvs">View image topics</a> (<code>web_video_server</code>)</li>
<li><a href="" id="butterfly">Open web terminal</a> (<code>Butterfly</code>)</li>
<li><a href="viz.html">View 3D visualization</a> (<code>ros3djs</code>)</li>
<li><a href="aruco_map.html">3D visualization for markers map</a> (<code>ros3djs</code>)</li>
</ul>
<script type="text/javascript">
document.querySelector("#wvs").href = location.origin + ':8080';
document.querySelector("#butterfly").href = location.origin + ':57575';
</script>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

898
clever/www/js/three.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -7,7 +7,7 @@ var titleEl = document.querySelector('title');
ros.on('error', function(error) {
titleEl.innerText = 'Disconnected';
err = error;
alert('Connection error: please enable \'rosbridge\' in clover.launch!');
alert('Connection error: please enable \'rosbridge\' in clever.launch!');
});
ros.on('connection', function() {

View File

@@ -1,73 +0,0 @@
# `clover` ROS package
A bundle for autonomous navigation and drone control.
## Manual installation
Install ROS Melodic according to the [documentation](http://wiki.ros.org/melodic/Installation), then [create a Catkin workspace](http://wiki.ros.org/catkin/Tutorials/create_a_workspace).
Clone this repo to directory `~/catkin_ws/src/clover`:
```bash
cd ~/catkin_ws/src
git clone https://github.com/CopterExpress/clover.git clover
```
All the required ROS packages (including `mavros` and `opencv`) can be installed using `rosdep`:
```bash
cd ~/catkin_ws/
rosdep install -y --from-paths src --ignore-src
```
Build ROS packages (on memory constrained platforms you might be going to need to use `-j1` key):
```bash
cd ~/catkin_ws
catkin_make -j1
```
To complete `mavros` install you'll need to install `geographiclib` datasets:
```bash
curl https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts/install_geographiclib_datasets.sh | sudo bash
```
You may optionally install udev rules to provide `/dev/px4fmu` symlink to your PX4-based flight controller connected over USB. Copy `99-px4fmu.rules` to your `/lib/udev/rules.d` folder:
```bash
cd ~/catkin_ws/src/clover/clover/config
sudo cp 99-px4fmu.rules /lib/udev/rules.d
```
Alternatively you may change the `fcu_url` property in `mavros.launch` file to point to your flight controller device.
## Running
Enable systemd service `roscore` (if not running):
```bash
sudo systemctl enable /home/<username>/catkin_ws/src/clover/builder/assets/roscore.service
sudo systemctl start roscore
```
To start connection to SITL, use:
```bash
roslaunch clover sitl.launch
```
To start connection to the flight controller, use:
```bash
roslaunch clover clover.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`.
Also, you can enable and start the systemd service:
```bash
sudo systemctl enable /home/<username>/catkin_ws/src/clover/deploy/clover.service
sudo systemctl start clover
```

View File

@@ -1,37 +0,0 @@
<launch>
<!-- article about camera setup: https://clover.coex.tech/camera_setup -->
<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 -->
<!-- <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">
<param name="device_path" value="/dev/video0"/> <!-- v4l2 device -->
<param name="frame_id" value="main_camera_optical"/>
<param name="camera_info_url" value="file://$(find clover)/camera_info/fisheye_cam.yaml"/>
<param name="rate" value="100"/> <!-- poll rate -->
<param name="cv_cap_prop_fps" value="40"/> <!-- camera FPS -->
<param name="capture_delay" value="0.02"/> <!-- approximate delay on frame retrieving -->
<param name="rescale_camera_info" value="true"/> <!-- automatically rescale camera calibration info -->
<!-- camera resolution -->
<param name="image_width" value="320"/>
<param name="image_height" value="240"/>
</node>
<!-- camera visualization markers -->
<node pkg="clover" type="camera_markers" ns="main_camera" name="main_camera_markers">
<param name="scale" value="3.0"/>
</node>
</launch>

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