mirror of
https://github.com/CopterExpress/clover.git
synced 2026-06-01 07:29:32 +00:00
Compare commits
242 Commits
buster-py3
...
new-readme
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34560c0b34 | ||
|
|
4bf9f728b1 | ||
|
|
0172d6e892 | ||
|
|
bcb7351a90 | ||
|
|
c71a46ce9d | ||
|
|
91dd7799ef | ||
|
|
3682e253a7 | ||
|
|
66ecbb4d09 | ||
|
|
f041b6125b | ||
|
|
a4f2bab3d7 | ||
|
|
56bcfa5c87 | ||
|
|
998796045c | ||
|
|
c5e954b56a | ||
|
|
2814fea9cd | ||
|
|
b85326c02a | ||
|
|
98d5d50607 | ||
|
|
69c46786de | ||
|
|
abb495275b | ||
|
|
044d6c6d33 | ||
|
|
22d5a356b6 | ||
|
|
c7828557ca | ||
|
|
514c0f1b65 | ||
|
|
6a79b8292a | ||
|
|
10b6661266 | ||
|
|
7f2cb1c63e | ||
|
|
1d48c79c52 | ||
|
|
ad46a0918c | ||
|
|
9487522992 | ||
|
|
80b35d3b90 | ||
|
|
12e292c9d7 | ||
|
|
9b28e9cad2 | ||
|
|
d57ab82f38 | ||
|
|
c8da639eab | ||
|
|
c7e7edec70 | ||
|
|
72869fcf2b | ||
|
|
387d2c2341 | ||
|
|
a665caeea3 | ||
|
|
3079d2a3e1 | ||
|
|
7d5bdf4f22 | ||
|
|
2a3efa2908 | ||
|
|
ddee29a0e8 | ||
|
|
8596be07c6 | ||
|
|
a480ebe80a | ||
|
|
77ca50b901 | ||
|
|
ead9b904fa | ||
|
|
90956ecd44 | ||
|
|
f070c60e14 | ||
|
|
68edf07f6e | ||
|
|
7f161b1ad7 | ||
|
|
a41a432ef3 | ||
|
|
2b896b06d9 | ||
|
|
5070cafbfb | ||
|
|
9c0af7285c | ||
|
|
c67d937842 | ||
|
|
b79d87242f | ||
|
|
4d0ddcb319 | ||
|
|
3ff4ee6c4c | ||
|
|
90049182cf | ||
|
|
33f4601fdc | ||
|
|
2a62891d60 | ||
|
|
b043737e91 | ||
|
|
c61a0485ff | ||
|
|
f1539177eb | ||
|
|
6cbbb5580e | ||
|
|
c2d22ae12a | ||
|
|
7160d804cd | ||
|
|
3ac51baf7c | ||
|
|
48cc82001d | ||
|
|
43eae885c6 | ||
|
|
2bb29ff389 | ||
|
|
3811cbff3e | ||
|
|
2d49f58fb8 | ||
|
|
bbcf75b806 | ||
|
|
461f4f5904 | ||
|
|
4f8020ff35 | ||
|
|
267aaf45d3 | ||
|
|
0b74430a11 | ||
|
|
1746381da1 | ||
|
|
6879723771 | ||
|
|
b474f99665 | ||
|
|
60b0059ef1 | ||
|
|
8dfb9a8f6c | ||
|
|
2c36fdb560 | ||
|
|
8d37c424eb | ||
|
|
2f70ce4372 | ||
|
|
e9527b5efd | ||
|
|
351b33cc5f | ||
|
|
a427d86f41 | ||
|
|
ef0f926a79 | ||
|
|
0b587b7dae | ||
|
|
770a76a450 | ||
|
|
3e79c25147 | ||
|
|
16b2538dfa | ||
|
|
d01e6990b1 | ||
|
|
6fbdfb7817 | ||
|
|
e05431cc75 | ||
|
|
4c940f0b8b | ||
|
|
2672b6784f | ||
|
|
22ba3a1406 | ||
|
|
7cc91b2e32 | ||
|
|
d6f8f4017f | ||
|
|
2f69ad3f43 | ||
|
|
b08ad5a618 | ||
|
|
fca584cefe | ||
|
|
099e115def | ||
|
|
d2b9ec7166 | ||
|
|
bda966bc90 | ||
|
|
d182542153 | ||
|
|
bc74af3006 | ||
|
|
d88cbaee85 | ||
|
|
49d1fb5215 | ||
|
|
e750395e01 | ||
|
|
5439e5c1df | ||
|
|
aac7dcae2f | ||
|
|
df78f17efb | ||
|
|
0fa7e0e496 | ||
|
|
dee58f2e47 | ||
|
|
197e02f4ba | ||
|
|
f7934554e4 | ||
|
|
9a7ffef858 | ||
|
|
d0619b4543 | ||
|
|
0f0deb85da | ||
|
|
89ccf9c2b9 | ||
|
|
32ff2d4e15 | ||
|
|
366fcc14f6 | ||
|
|
2cd334c474 | ||
|
|
647652f85f | ||
|
|
4022eb773d | ||
|
|
79a6a802f4 | ||
|
|
77f2bc739e | ||
|
|
05464ce767 | ||
|
|
d5eae45e49 | ||
|
|
cfe35e1c83 | ||
|
|
10648825c0 | ||
|
|
f8fb8a0a1a | ||
|
|
a958742d9f | ||
|
|
8d7a12f2b4 | ||
|
|
856e0a5ed0 | ||
|
|
da6cb48b62 | ||
|
|
459a93986e | ||
|
|
f6b3c8ab86 | ||
|
|
20a29c3dd6 | ||
|
|
49b436b505 | ||
|
|
6739a685d8 | ||
|
|
d8d7839e0e | ||
|
|
331a2a40bc | ||
|
|
40856b9401 | ||
|
|
9ca597dfd7 | ||
|
|
1f2484a9ef | ||
|
|
81cb04c912 | ||
|
|
085850cfdd | ||
|
|
5bef4a1e21 | ||
|
|
1447e73fed | ||
|
|
75278552b3 | ||
|
|
320f7a43ce | ||
|
|
26e9ab0c7f | ||
|
|
fb0e841bd4 | ||
|
|
361b365f86 | ||
|
|
9487966b57 | ||
|
|
a75a0e12a0 | ||
|
|
aa835fcdff | ||
|
|
7fcbe95a80 | ||
|
|
9f097f56c5 | ||
|
|
0fb22e817d | ||
|
|
b8a8e7339d | ||
|
|
e1ab0e63b5 | ||
|
|
4a23a9274a | ||
|
|
5bc7443a7b | ||
|
|
5fe18152f0 | ||
|
|
b8d4a7fdcc | ||
|
|
c3a4f674ec | ||
|
|
591d57e2b2 | ||
|
|
4a67783706 | ||
|
|
7dc82e8154 | ||
|
|
4feac879eb | ||
|
|
6c883cab67 | ||
|
|
00048d4dfe | ||
|
|
a635b9d21d | ||
|
|
de693e3e58 | ||
|
|
9e2707ad6b | ||
|
|
a7e04fe22a | ||
|
|
3647337455 | ||
|
|
b771fbb398 | ||
|
|
7ed2dd398c | ||
|
|
45e6f396d0 | ||
|
|
0574f4cc46 | ||
|
|
f574637a3f | ||
|
|
6ede041c8a | ||
|
|
0fda24c63c | ||
|
|
a01c2b8d6c | ||
|
|
5ce348d14c | ||
|
|
5736c7acfb | ||
|
|
c6b3e837e3 | ||
|
|
78e42df0f2 | ||
|
|
a8824a696d | ||
|
|
7a216ede07 | ||
|
|
b68e42bfcc | ||
|
|
fdeab48bf5 | ||
|
|
5c1b19d9c9 | ||
|
|
7d25898694 | ||
|
|
2c6780202a | ||
|
|
cab76dea16 | ||
|
|
0e0b0aa90b | ||
|
|
e85be7ae49 | ||
|
|
bb99d68ff4 | ||
|
|
ae077304bb | ||
|
|
0baadf73a2 | ||
|
|
f0917347be | ||
|
|
eba8c7fc6a | ||
|
|
36573c12ee | ||
|
|
e293e54353 | ||
|
|
35801346d9 | ||
|
|
660b90a353 | ||
|
|
f88d9eea2e | ||
|
|
5ab5418866 | ||
|
|
910e3590b3 | ||
|
|
5ad08785c4 | ||
|
|
b75a40b9ad | ||
|
|
7bbbba31be | ||
|
|
241264a1d2 | ||
|
|
5c78b01b7b | ||
|
|
dab4e69be1 | ||
|
|
753e0a8ab4 | ||
|
|
112c51a2b9 | ||
|
|
9c6cb4cc38 | ||
|
|
b337dfa4c3 | ||
|
|
22607c5390 | ||
|
|
0f837d96a6 | ||
|
|
3fa5ee99c4 | ||
|
|
8749f1523e | ||
|
|
8b3a9dc07a | ||
|
|
a9b3613726 | ||
|
|
3530c9999e | ||
|
|
244005c9f7 | ||
|
|
761ab42a63 | ||
|
|
86feac089a | ||
|
|
13a5a0ea05 | ||
|
|
dfefad297c | ||
|
|
cb9924d083 | ||
|
|
13599a1b2e | ||
|
|
a46a96f729 | ||
|
|
b7a811d4d4 |
@@ -20,6 +20,7 @@
|
||||
"MAVLink",
|
||||
"ROS",
|
||||
"ROS Kinetic",
|
||||
"ROS Melodic",
|
||||
"OpenCV",
|
||||
"Gazebo",
|
||||
"GitHub",
|
||||
@@ -104,7 +105,8 @@
|
||||
"TCP",
|
||||
"UDP",
|
||||
"QR",
|
||||
"Li-ion"
|
||||
"Li-ion",
|
||||
"Nvidia"
|
||||
],
|
||||
"code_blocks": false
|
||||
},
|
||||
|
||||
25
.travis.yml
25
.travis.yml
@@ -1,4 +1,5 @@
|
||||
sudo: required
|
||||
os: linux
|
||||
dist: xenial
|
||||
language: generic
|
||||
services:
|
||||
- docker
|
||||
@@ -43,7 +44,7 @@ jobs:
|
||||
- cd images && zip ${IMAGE_NAME}.zip ${IMAGE_NAME}
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key: ${GITHUB_OAUTH_TOKEN}
|
||||
token: ${GITHUB_OAUTH_TOKEN}
|
||||
file: ${IMAGE_NAME}.zip
|
||||
skip_cleanup: true
|
||||
on:
|
||||
@@ -57,7 +58,7 @@ jobs:
|
||||
before_script:
|
||||
- docker pull ${NATIVE_DOCKER}
|
||||
script:
|
||||
- docker run --rm -v $(pwd):/root/catkin_ws/src/clever ${NATIVE_DOCKER} /root/catkin_ws/src/clever/builder/standalone-install.sh
|
||||
- docker run --rm -v $(pwd):/root/catkin_ws/src/clover ${NATIVE_DOCKER} /root/catkin_ws/src/clover/builder/standalone-install.sh
|
||||
- stage: Build
|
||||
name: "Native Melodic build"
|
||||
env:
|
||||
@@ -65,7 +66,7 @@ jobs:
|
||||
before_script:
|
||||
- docker pull ${NATIVE_DOCKER}
|
||||
script:
|
||||
- docker run --rm -v $(pwd):/root/catkin_ws/src/clever ${NATIVE_DOCKER} /root/catkin_ws/src/clever/builder/standalone-install.sh
|
||||
- docker run --rm -v $(pwd):/root/catkin_ws/src/clover ${NATIVE_DOCKER} /root/catkin_ws/src/clover/builder/standalone-install.sh
|
||||
- stage: Build
|
||||
name: "Documentation"
|
||||
language: node_js
|
||||
@@ -84,13 +85,13 @@ jobs:
|
||||
- gitbook build
|
||||
deploy:
|
||||
provider: pages
|
||||
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
|
||||
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
|
||||
verbose: true
|
||||
on:
|
||||
branch: master
|
||||
@@ -109,7 +110,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"
|
||||
- ./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"
|
||||
stages:
|
||||
- Build
|
||||
- Annotate
|
||||
|
||||
234
README.md
234
README.md
@@ -1,103 +1,173 @@
|
||||
# CLEVER
|
||||
# COEX Clover Drone Kit
|
||||
|
||||
<img src="docs/assets/clever4-front-white.png" align="right" width="400px" alt="CLEVER drone">
|
||||
<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>
|
||||
|
||||
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.
|
||||
This repository contains documentation, software platform source code and RPi image builder for COEX Clover drone kit.
|
||||
|
||||
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.
|
||||
<img src="docs/assets/clover42.png" align="right" width="400px" alt="COEX Clover">
|
||||
|
||||
**The main documentation is available [on Gitbook](https://clever.coex.tech/).**
|
||||
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.
|
||||
|
||||
Use it to learn how to assemble, configure, pilot and program autonomous CLEVER drone.
|
||||
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>.
|
||||
|
||||
## Raspberry Pi image
|
||||
## Autonomous flights video
|
||||
|
||||
**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).**
|
||||
[](https://youtu.be/u3omgsYC4Fk)
|
||||
|
||||
[](https://travis-ci.org/CopterExpress/clever)
|
||||
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 2016–2020](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.
|
||||
|
||||
Image includes:
|
||||
## Features
|
||||
|
||||
* Raspbian Buster
|
||||
* ROS Melodic
|
||||
* Configured networking
|
||||
* OpenCV
|
||||
* mavros
|
||||
* Periphery drivers (`pigpiod`, `rpi_ws281x`, etc)
|
||||
* CLEVER software bundle for autonomous drone control
|
||||
### Prebuilt RPi image
|
||||
|
||||
API description (in Russian) for autonomous flights is available [on GitBook](https://clever.coex.tech/simple_offboard.html).
|
||||
...
|
||||
|
||||
### 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.
|
||||
|
||||
## 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).
|
||||
For manual package installation and running see [`clover` package documentation](clover/README.md).
|
||||
|
||||
Clone this repo to directory `~/catkin_ws/src/clever`:
|
||||
## PX4 Dev Summit 2019 talk
|
||||
|
||||
```bash
|
||||
cd ~/catkin_ws/src
|
||||
git clone https://github.com/CopterExpress/clever.git clever
|
||||
```
|
||||
[](http://www.youtube.com/watch?v=CTG9E9PbJQ8)
|
||||
|
||||
All the required ROS packages (including `mavros` and `opencv`) can be installed using `rosdep`:
|
||||
## Other resources
|
||||
|
||||
```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
|
||||
```
|
||||
* 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).
|
||||
|
||||
## 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.
|
||||
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.
|
||||
|
||||
0
apps/CATKIN_IGNORE
Normal file
0
apps/CATKIN_IGNORE
Normal file
@@ -1,8 +1,6 @@
|
||||
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)
|
||||
|
||||
@@ -21,10 +19,11 @@ 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 "3")
|
||||
if ("${OpenCV_VERSION_MINOR}" LESS "9")
|
||||
message(STATUS "OpenCV version too low, using vendored ArUco package")
|
||||
include(vendor/VendorOpenCV.cmake)
|
||||
else()
|
||||
@@ -111,10 +110,9 @@ generate_messages(
|
||||
## and list every .cfg file to be processed
|
||||
|
||||
## Generate dynamic reconfigure parameters in the 'cfg' folder
|
||||
# generate_dynamic_reconfigure_options(
|
||||
# cfg/DynReconf1.cfg
|
||||
# cfg/DynReconf2.cfg
|
||||
# )
|
||||
generate_dynamic_reconfigure_options(
|
||||
cfg/DetectorParams.cfg
|
||||
)
|
||||
|
||||
###################################
|
||||
## catkin specific configuration ##
|
||||
@@ -151,7 +149,7 @@ add_library(aruco_pose
|
||||
src/draw.cpp
|
||||
)
|
||||
|
||||
add_dependencies(${PROJECT_NAME} aruco_pose_generate_messages_cpp)
|
||||
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}_generate_messages_cpp ${PROJECT_NAME}_gencfg)
|
||||
|
||||
## Declare a C++ executable
|
||||
## With catkin_make all packages are built within a single CMake context
|
||||
@@ -229,4 +227,5 @@ 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()
|
||||
|
||||
107
aruco_pose/cfg/DetectorParams.cfg
Executable file
107
aruco_pose/cfg/DetectorParams.cfg
Executable file
@@ -0,0 +1,107 @@
|
||||
#!/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"))
|
||||
@@ -1,3 +1,4 @@
|
||||
# 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
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
<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>
|
||||
@@ -29,6 +27,7 @@
|
||||
<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>
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#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>
|
||||
@@ -46,18 +47,21 @@
|
||||
|
||||
#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:
|
||||
ros::NodeHandle nh_, nh_priv_;
|
||||
tf2_ros::TransformBroadcaster br_;
|
||||
tf2_ros::Buffer tf_buffer_;
|
||||
tf2_ros::TransformListener tf_listener_{tf_buffer_};
|
||||
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_;
|
||||
cv::Ptr<cv::aruco::Dictionary> dictionary_;
|
||||
cv::Ptr<cv::aruco::DetectorParameters> parameters_;
|
||||
image_transport::Publisher debug_pub_;
|
||||
@@ -76,30 +80,32 @@ private:
|
||||
public:
|
||||
virtual void onInit()
|
||||
{
|
||||
nh_ = getNodeHandle();
|
||||
nh_priv_ = getPrivateNodeHandle();
|
||||
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_));
|
||||
|
||||
int dictionary;
|
||||
nh_priv_.param("dictionary", dictionary, 2);
|
||||
nh_priv_.param("estimate_poses", estimate_poses_, true);
|
||||
nh_priv_.param("send_tf", send_tf_, true);
|
||||
dictionary = nh_priv_.param("dictionary", 2);
|
||||
estimate_poses_ = nh_priv_.param("estimate_poses", true);
|
||||
send_tf_ = nh_priv_.param("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();
|
||||
readLengthOverride(nh_priv_);
|
||||
|
||||
nh_priv_.param<std::string>("known_tilt", known_tilt_, "");
|
||||
nh_priv_.param("auto_flip", auto_flip_, false);
|
||||
known_tilt_ = nh_priv_.param<std::string>("known_tilt", "");
|
||||
auto_flip_ = nh_priv_.param("auto_flip", false);
|
||||
|
||||
nh_priv_.param<std::string>("frame_id_prefix", frame_id_prefix_, "aruco_");
|
||||
frame_id_prefix_ = nh_priv_.param<std::string>("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_);
|
||||
@@ -110,6 +116,12 @@ 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");
|
||||
}
|
||||
|
||||
@@ -159,8 +171,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());
|
||||
}
|
||||
@@ -194,7 +206,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -315,10 +327,10 @@ private:
|
||||
return frame_id_prefix_ + std::to_string(id);
|
||||
}
|
||||
|
||||
void readLengthOverride()
|
||||
void readLengthOverride(ros::NodeHandle& nh)
|
||||
{
|
||||
std::map<std::string, double> length_override;
|
||||
nh_priv_.getParam("length_override", length_override);
|
||||
nh.getParam("length_override", length_override);
|
||||
for (auto const& item : length_override) {
|
||||
length_override_[std::stoi(item.first)] = item.second;
|
||||
}
|
||||
@@ -341,6 +353,37 @@ 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)
|
||||
|
||||
@@ -58,7 +58,6 @@ 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_;
|
||||
@@ -83,8 +82,8 @@ private:
|
||||
public:
|
||||
virtual void onInit()
|
||||
{
|
||||
nh_ = getNodeHandle();
|
||||
nh_priv_ = getPrivateNodeHandle();
|
||||
ros::NodeHandle &nh_ = getNodeHandle();
|
||||
ros::NodeHandle &nh_priv_ = getPrivateNodeHandle();
|
||||
|
||||
image_transport::ImageTransport it_priv(nh_priv_);
|
||||
|
||||
@@ -96,19 +95,18 @@ 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;
|
||||
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_, "");
|
||||
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", "");
|
||||
|
||||
// createStripLine();
|
||||
|
||||
@@ -116,7 +114,7 @@ public:
|
||||
param(nh_priv_, "map", map);
|
||||
loadMap(map);
|
||||
} else if (type == "gridboard") {
|
||||
createGridBoard();
|
||||
createGridBoard(nh_priv_);
|
||||
} else {
|
||||
NODELET_FATAL("unknown type: %s", type.c_str());
|
||||
ros::shutdown();
|
||||
@@ -331,7 +329,7 @@ publish_debug:
|
||||
NODELET_INFO("loading %s complete (%d markers)", filename.c_str(), static_cast<int>(board_->ids.size()));
|
||||
}
|
||||
|
||||
void createGridBoard()
|
||||
void createGridBoard(ros::NodeHandle& nh)
|
||||
{
|
||||
NODELET_INFO("generate gridboard");
|
||||
NODELET_WARN("gridboard maps are deprecated");
|
||||
@@ -339,15 +337,15 @@ publish_debug:
|
||||
int markers_x, markers_y, first_marker;
|
||||
double markers_side, markers_sep_x, markers_sep_y;
|
||||
std::vector<int> marker_ids;
|
||||
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);
|
||||
markers_x = nh.param("markers_x", 10);
|
||||
markers_y = nh.param("markers_y", 10);
|
||||
first_marker = nh.param("first_marker", 0);
|
||||
|
||||
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);
|
||||
param(nh, "markers_side", markers_side);
|
||||
param(nh, "markers_sep_x", markers_sep_x);
|
||||
param(nh, "markers_sep_y", markers_sep_y);
|
||||
|
||||
if (nh_priv_.getParam("marker_ids", marker_ids)) {
|
||||
if (nh.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();
|
||||
@@ -394,7 +392,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/clever/blob/master/aruco_pose/README.md#parameters for details",
|
||||
"Please see https://github.com/CopterExpress/clover/blob/master/aruco_pose/README.md#parameters for details",
|
||||
id, num_markers);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2018 Copter Express Technologies
|
||||
#
|
||||
@@ -13,17 +13,21 @@
|
||||
Generate map file for aruco_map nodelet.
|
||||
|
||||
Usage:
|
||||
genmap.py <length> <x> <y> <dist_x> <dist_y> <first> [--top-left]
|
||||
genmap.py <length> <x> <y> <dist_x> <dist_y> [<first>] [--top-left | --bottom-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
|
||||
--top-left First marker is on top-left (not bottom-left)
|
||||
<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
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
@@ -34,20 +38,21 @@ from docopt import docopt
|
||||
arguments = docopt(__doc__)
|
||||
|
||||
length = float(arguments['<length>'])
|
||||
first = int(arguments['<first>'])
|
||||
first = int(arguments['<first>'] if arguments['<first>'] is not None else 0)
|
||||
markers_x = int(arguments['<x>'])
|
||||
markers_y = int(arguments['<y>'])
|
||||
dist_x = float(arguments['<dist_x>'])
|
||||
dist_y = float(arguments['<dist_y>'])
|
||||
top_left = arguments['--top-left']
|
||||
bottom_left = arguments['--bottom-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 top_left:
|
||||
if not bottom_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
|
||||
|
||||
@@ -35,9 +35,7 @@ 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];
|
||||
|
||||
for (unsigned int k = 0; k < cinfo->D.size(); k++)
|
||||
dist.at<double>(k) = cinfo->D[k];
|
||||
dist = cv::Mat(cinfo->D, true);
|
||||
}
|
||||
|
||||
inline void rotatePoint(cv::Point3f& p, cv::Point3f origin, float angle)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<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">
|
||||
|
||||
BIN
aruco_pose/test/crash_image_01.png
Normal file
BIN
aruco_pose/test/crash_image_01.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 159 KiB |
BIN
aruco_pose/test/crash_image_02.png
Normal file
BIN
aruco_pose/test/crash_image_02.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 156 KiB |
BIN
aruco_pose/test/crash_image_03.png
Normal file
BIN
aruco_pose/test/crash_image_03.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 165 KiB |
18
aruco_pose/test/crash_opencv.py
Normal file
18
aruco_pose/test/crash_opencv.py
Normal file
@@ -0,0 +1,18 @@
|
||||
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)
|
||||
51
aruco_pose/test/crash_opencv.test
Normal file
51
aruco_pose/test/crash_opencv.test
Normal file
@@ -0,0 +1,51 @@
|
||||
<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>
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
import unittest
|
||||
import json
|
||||
|
||||
2
aruco_pose/vendor/aruco/src/aruco.cpp
vendored
2
aruco_pose/vendor/aruco/src/aruco.cpp
vendored
@@ -924,6 +924,8 @@ 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]);
|
||||
}
|
||||
|
||||
|
||||
12
book.json
12
book.json
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"title": "Clever",
|
||||
"title": "Clover",
|
||||
"description": "Конструктор квадрокоптера «Клевер»",
|
||||
"author": "Copter Express",
|
||||
"language": "en",
|
||||
@@ -28,7 +28,7 @@
|
||||
"blank": true
|
||||
},
|
||||
"sitemap": {
|
||||
"hostname": "https://clever.coex.tech"
|
||||
"hostname": "https://clover.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/clever/edit/master/docs/{{filepath_lang}}"
|
||||
"url": "https://github.com/CopterExpress/clover/edit/master/docs/{{filepath_lang}}"
|
||||
},
|
||||
{
|
||||
"label": "GitHub",
|
||||
"icon": "fa fa-github",
|
||||
"position" : "left",
|
||||
"url": "https://github.com/CopterExpress/clever"
|
||||
"url": "https://github.com/CopterExpress/clover"
|
||||
}
|
||||
]
|
||||
},
|
||||
"addcssjs": {
|
||||
"css": ["../clever.css"],
|
||||
"js": ["../clever.js"]
|
||||
"css": ["../clover.css"],
|
||||
"js": ["../clover.js"]
|
||||
},
|
||||
"language-picker": {
|
||||
"languages": [["ru", "Russian"], ["en", "English"]]
|
||||
|
||||
34
builder/assets/avahi-services/sftp-ssh.service
Normal file
34
builder/assets/avahi-services/sftp-ssh.service
Normal file
@@ -0,0 +1,34 @@
|
||||
<?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>
|
||||
@@ -2,5 +2,5 @@
|
||||
Description=Butterfly Terminal Server
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c ". /root/butterfly_env/bin/activate; butterfly.server.py --host="0.0.0.0" --unsecure"
|
||||
ExecStart=/usr/local/bin/butterfly.server.py --host="0.0.0.0" --unsecure
|
||||
User=pi
|
||||
|
||||
0
builder/assets/clever/clever/__init__.py
Normal file
0
builder/assets/clever/clever/__init__.py
Normal file
3
builder/assets/clever/clever/srv.py
Normal file
3
builder/assets/clever/clever/srv.py
Normal file
@@ -0,0 +1,3 @@
|
||||
print("Warning: clever package is renamed to clover")
|
||||
|
||||
from clover.srv import *
|
||||
10
builder/assets/clever/setup.py
Executable file
10
builder/assets/clever/setup.py
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/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'],
|
||||
)
|
||||
@@ -1,13 +1,12 @@
|
||||
[Unit]
|
||||
Description=Clever ROS package
|
||||
Description=Clover 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 clever clever.launch --wait --screen --skip-log-check \
|
||||
2> >(tee /tmp/clever.err)"
|
||||
ROS_HOSTNAME=`hostname`.local exec stdbuf -o L roslaunch clover clover.launch --wait --screen --skip-log-check \
|
||||
2> >(tee /tmp/clover.err)"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
31
builder/assets/examples/flight.py
Normal file
31
builder/assets/examples/flight.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# 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()
|
||||
37
builder/assets/examples/flight_marker.py
Normal file
37
builder/assets/examples/flight_marker.py
Normal file
@@ -0,0 +1,37 @@
|
||||
# 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()
|
||||
25
builder/assets/examples/leds.py
Normal file
25
builder/assets/examples/leds.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# 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
|
||||
41
builder/assets/examples/navigate_wait.py
Normal file
41
builder/assets/examples/navigate_wait.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# 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()
|
||||
@@ -35,9 +35,26 @@ echo_stamp() {
|
||||
echo -e ${TEXT}
|
||||
}
|
||||
|
||||
NEW_SSID='CLEVER-'$(head -c 100 /dev/urandom | xxd -ps -c 100 | sed -e "s/[^0-9]//g" | cut -c 1-4)
|
||||
NEW_SSID='clover-'$(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}"
|
||||
sudo sed -i.OLD "s/CLEVER/${NEW_SSID}/" /etc/wpa_supplicant/wpa_supplicant.conf
|
||||
# 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
|
||||
|
||||
NEW_HOSTNAME=$(echo ${NEW_SSID} | tr '[:upper:]' '[:lower:]')
|
||||
echo_stamp "Setting hostname to $NEW_HOSTNAME"
|
||||
@@ -45,6 +62,10 @@ 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
|
||||
|
||||
|
||||
@@ -1,723 +1,735 @@
|
||||
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:
|
||||
stretch: ros-melodic-ws281x
|
||||
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]
|
||||
|
||||
735
builder/assets/melodic-rosdep-clover.yaml
Normal file
735
builder/assets/melodic-rosdep-clover.yaml
Normal file
@@ -0,0 +1,735 @@
|
||||
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]
|
||||
@@ -20,7 +20,7 @@
|
||||
# Example:
|
||||
# DocumentRoot /home/krypton/htdocs
|
||||
|
||||
DocumentRoot /home/pi/catkin_ws/src/clever/clever/www
|
||||
DocumentRoot /home/pi/.ros/www
|
||||
|
||||
# Redirect:
|
||||
# ---------
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
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]
|
||||
@@ -1,6 +1,5 @@
|
||||
[Unit]
|
||||
Description=Launcher for the ROS master, parameter server and rosout logging node
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=pi
|
||||
|
||||
107
builder/assets/rsyslog.conf
Normal file
107
builder/assets/rsyslog.conf
Normal file
@@ -0,0 +1,107 @@
|
||||
# /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:*
|
||||
4
builder/assets/rsysrot.sh
Executable file
4
builder/assets/rsysrot.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
LOG_FILE=$1
|
||||
mv -f ${LOG_FILE} ${LOG_FILE}.1
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
set -e # Exit immidiately on non-zero result
|
||||
|
||||
SOURCE_IMAGE="https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2019-09-30/2019-09-26-raspbian-buster-lite.zip"
|
||||
SOURCE_IMAGE="https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2020-02-14/2020-02-13-raspbian-buster-lite.zip"
|
||||
|
||||
export DEBIAN_FRONTEND=${DEBIAN_FRONTEND:='noninteractive'}
|
||||
export LANG=${LANG:='C.UTF-8'}
|
||||
@@ -89,35 +89,40 @@ 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/clever/'
|
||||
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy $dir '/home/pi/catkin_ws/src/clover/'
|
||||
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)
|
||||
# Clever
|
||||
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/clever.service' '/lib/systemd/system/'
|
||||
# Clover
|
||||
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/clover.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-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/melodic-rosdep-clover.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-clever.rosinstall' '/home/pi/ros_catkin_ws/'
|
||||
# ${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${SCRIPTS_DIR}'/assets/kinetic-ros-clover.rosinstall' '/home/pi/ros_catkin_ws/'
|
||||
# Add PX4 udev rules
|
||||
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${REPO_DIR}'/clever/config/99-px4fmu.rules' '/lib/udev/rules.d/'
|
||||
${BUILDER_DIR}/image-chroot.sh ${IMAGE_PATH} copy ${REPO_DIR}'/clover/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'
|
||||
|
||||
@@ -34,12 +34,12 @@ echo_stamp() {
|
||||
echo -e ${TEXT}
|
||||
}
|
||||
|
||||
echo_stamp "Write CLEVER information"
|
||||
echo_stamp "Write Clover information"
|
||||
|
||||
# Clever image version
|
||||
echo "$1" >> /etc/clever_version
|
||||
# Clover image version
|
||||
echo "$1" >> /etc/clover_version
|
||||
# Origin image file name
|
||||
echo "${2%.*}" >> /etc/clever_origin
|
||||
echo "${2%.*}" >> /etc/clover_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"
|
||||
|
||||
@@ -34,34 +34,24 @@ echo_stamp() {
|
||||
echo -e ${TEXT}
|
||||
}
|
||||
|
||||
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"
|
||||
echo_stamp "#1 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=/clever/coex/192.168.11.1
|
||||
address=/clover/coex/192.168.11.1
|
||||
dhcp-range=192.168.11.100,192.168.11.200,12h
|
||||
no-hosts
|
||||
filterwin2k
|
||||
@@ -70,8 +60,4 @@ domain-needed
|
||||
quiet-dhcp6
|
||||
EOF
|
||||
|
||||
#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"
|
||||
echo_stamp "#4 End of network installation"
|
||||
|
||||
@@ -65,11 +65,10 @@ my_travis_retry() {
|
||||
return $result
|
||||
}
|
||||
|
||||
# TODO: 'kinetic-rosdep-clever.yaml' should add only if we use our repo?
|
||||
# TODO: 'kinetic-rosdep-clover.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-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
|
||||
echo "yaml file:///etc/ros/rosdep/melodic-rosdep-clover.yaml" >> /etc/ros/rosdep/sources.list.d/20-default.list
|
||||
my_travis_retry rosdep update
|
||||
|
||||
echo_stamp "Populate rosdep for ROS user"
|
||||
@@ -89,30 +88,29 @@ resolve_rosdep() {
|
||||
|
||||
export ROS_IP='127.0.0.1' # needed for running tests
|
||||
|
||||
echo_stamp "Reconfiguring Clever repository for simplier unshallowing"
|
||||
cd /home/pi/catkin_ws/src/clever
|
||||
echo_stamp "Reconfiguring Clover repository for simplier unshallowing"
|
||||
cd /home/pi/catkin_ws/src/clover
|
||||
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
||||
|
||||
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 "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 "Build CLEVER documentation"
|
||||
cd /home/pi/catkin_ws/src/clever
|
||||
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
|
||||
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 \
|
||||
@@ -130,7 +128,8 @@ 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
|
||||
pip3 install tornado==4.2.1
|
||||
# (note that Python 3 will still have a more recent version)
|
||||
pip install tornado==4.2.1
|
||||
|
||||
echo_stamp "Running tests"
|
||||
cd /home/pi/catkin_ws
|
||||
@@ -144,7 +143,6 @@ 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
|
||||
|
||||
@@ -57,6 +57,10 @@ 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'
|
||||
@@ -67,10 +71,8 @@ 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/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 "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_stamp "Update apt cache"
|
||||
|
||||
@@ -97,22 +99,23 @@ libjpeg8 \
|
||||
tcpdump \
|
||||
ltrace \
|
||||
libpoco-dev \
|
||||
python3-rosdep \
|
||||
python3-rosinstall-generator \
|
||||
python3-wstool \
|
||||
python3-rosinstall \
|
||||
libzbar0 \
|
||||
python-rosdep \
|
||||
python-rosinstall-generator \
|
||||
python-wstool \
|
||||
python-rosinstall \
|
||||
build-essential \
|
||||
libffi-dev \
|
||||
monkey \
|
||||
pigpio python-pigpio python3-pigpio \
|
||||
i2c-tools \
|
||||
espeak espeak-data python-espeak python3-espeak \
|
||||
espeak espeak-data python-espeak \
|
||||
ntpdate \
|
||||
python-dev \
|
||||
python3-dev \
|
||||
python3-venv \
|
||||
python3-systemd \
|
||||
python-systemd \
|
||||
mjpg-streamer \
|
||||
python3-opencv \
|
||||
&& echo_stamp "Everything was installed!" "SUCCESS" \
|
||||
|| (echo_stamp "Some packages wasn't installed!" "ERROR"; exit 1)
|
||||
|
||||
@@ -123,9 +126,10 @@ 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
|
||||
# Don't even bother installing pip for python2.7
|
||||
# python get-pip.py
|
||||
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
|
||||
@@ -133,14 +137,10 @@ pip3 --version
|
||||
|
||||
echo_stamp "Install and enable Butterfly (web terminal)"
|
||||
echo_stamp "Workaround for tornado >= 6.0 breaking butterfly"
|
||||
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]
|
||||
my_travis_retry pip3 install tornado==5.1.1
|
||||
my_travis_retry pip3 install butterfly
|
||||
my_travis_retry pip3 install butterfly[systemd]
|
||||
systemctl enable butterfly.socket
|
||||
deactivate
|
||||
|
||||
echo_stamp "Install ws281x library"
|
||||
my_travis_retry pip install --prefer-binary rpi_ws281x
|
||||
@@ -158,6 +158,14 @@ 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
|
||||
|
||||
@@ -18,13 +18,14 @@ 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/clever/builder/test/
|
||||
cd /home/pi/catkin_ws/src/clover/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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/env python
|
||||
|
||||
# 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 clever.srv import GetTelemetry, Navigate, NavigateGlobal, SetPosition, SetVelocity, \
|
||||
from clover.srv import GetTelemetry, Navigate, NavigateGlobal, SetPosition, SetVelocity, \
|
||||
SetAttitude, SetRates, SetLEDEffect
|
||||
|
||||
import tf2_ros
|
||||
@@ -26,5 +26,6 @@ from pymavlink import mavutil
|
||||
import rpi_ws281x
|
||||
import pigpio
|
||||
from espeak import espeak
|
||||
from pyzbar import pyzbar
|
||||
|
||||
print(cv2.getBuildInformation())
|
||||
print cv2.getBuildInformation()
|
||||
|
||||
@@ -12,6 +12,10 @@ python3 --version
|
||||
ipython --version
|
||||
ipython3 --version
|
||||
|
||||
# ptvsd does not have a stand-alone binary
|
||||
python -m ptvsd --version
|
||||
python3 -m ptvsd --version
|
||||
|
||||
node -v
|
||||
npm -v
|
||||
|
||||
@@ -20,23 +24,21 @@ 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 clever
|
||||
rosversion clover
|
||||
rosversion aruco_pose
|
||||
rosversion vl53l1x
|
||||
rosversion mavros
|
||||
@@ -50,3 +52,6 @@ rosversion usb_cam
|
||||
rosversion cv_camera
|
||||
rosversion web_video_server
|
||||
rosversion rosshow
|
||||
|
||||
# validate examples are present
|
||||
[[ $(ls /home/pi/examples/*) ]]
|
||||
|
||||
6
builder/test/tests_clever.py
Executable file
6
builder/test/tests_clever.py
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# test backwards compatibility
|
||||
|
||||
from clever.srv import GetTelemetry, Navigate, NavigateGlobal, SetPosition, SetVelocity, \
|
||||
SetAttitude, SetRates, SetLEDEffect
|
||||
8
builder/test/tests_py3.py
Executable file
8
builder/test/tests_py3.py
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Make sure our Python 3 software is installed
|
||||
|
||||
import cv2
|
||||
from pyzbar import pyzbar
|
||||
|
||||
print(cv2.getBuildInformation())
|
||||
@@ -17,7 +17,8 @@ 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'
|
||||
'qgc-requires-setup.png', 'clever4-front-white.png', 'clever4-kit-white.png', '26_1.png', 'battery_holder.stl', \
|
||||
'camera_case.stl', 'camera_mount.stl'
|
||||
|
||||
code = 0
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
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.
|
||||
@@ -1,6 +0,0 @@
|
||||
<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>
|
||||
@@ -1,38 +0,0 @@
|
||||
<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>
|
||||
@@ -1,5 +0,0 @@
|
||||
<library path="lib/libclever">
|
||||
<class name="clever/optical_flow" type="OpticalFlow" base_class_type="nodelet::Nodelet">
|
||||
<description/>
|
||||
</class>
|
||||
</library>
|
||||
@@ -1,5 +0,0 @@
|
||||
flask==1.1.1
|
||||
docopt==0.6.2
|
||||
geopy==1.20.0
|
||||
smbus2==0.3.0
|
||||
VL53L1X==0.0.4
|
||||
@@ -1,14 +0,0 @@
|
||||
<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>
|
||||
898
clever/www/js/three.min.js
vendored
898
clever/www/js/three.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 2.8.3)
|
||||
project(clever)
|
||||
project(clover)
|
||||
|
||||
## Compile as C++11, supported in ROS Kinetic and newer
|
||||
add_compile_options(-std=c++11)
|
||||
@@ -30,6 +30,12 @@ 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)
|
||||
|
||||
@@ -81,6 +87,7 @@ add_service_files(
|
||||
SetAttitude.srv
|
||||
SetRates.srv
|
||||
SetLEDEffect.srv
|
||||
Execute.srv
|
||||
)
|
||||
|
||||
## Generate actions in the 'action' folder
|
||||
@@ -127,7 +134,7 @@ generate_messages(
|
||||
## DEPENDS: system dependencies of this project that dependent projects also need
|
||||
catkin_package(
|
||||
# INCLUDE_DIRS include
|
||||
LIBRARIES clever
|
||||
LIBRARIES ${PROJECT_NAME}
|
||||
# CATKIN_DEPENDS other_catkin_pkg
|
||||
# DEPENDS system_lib
|
||||
)
|
||||
@@ -145,7 +152,7 @@ include_directories(
|
||||
)
|
||||
|
||||
# Declare a C++ library
|
||||
add_library(clever
|
||||
add_library(${PROJECT_NAME}
|
||||
src/optical_flow.cpp
|
||||
)
|
||||
|
||||
@@ -167,6 +174,8 @@ 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}
|
||||
@@ -180,9 +189,13 @@ target_link_libraries(vpe_publisher ${catkin_LIBRARIES})
|
||||
|
||||
target_link_libraries(led ${catkin_LIBRARIES})
|
||||
|
||||
add_dependencies(simple_offboard clever_generate_messages_cpp)
|
||||
target_link_libraries(shell ${catkin_LIBRARIES})
|
||||
|
||||
add_dependencies(led 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)
|
||||
|
||||
## Rename C++ executable without prefix
|
||||
## The above recommended prefix causes long target names, the following renames the
|
||||
@@ -195,8 +208,9 @@ add_dependencies(led clever_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(clever
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
${catkin_LIBRARIES}
|
||||
${OpenCV_LIBRARIES}
|
||||
)
|
||||
|
||||
#############
|
||||
@@ -252,7 +266,7 @@ endif()
|
||||
#############
|
||||
|
||||
## Add gtest based cpp test target and link libraries
|
||||
# catkin_add_gtest(${PROJECT_NAME}-test test/test_clever.cpp)
|
||||
# catkin_add_gtest(${PROJECT_NAME}-test test/test_${PROJECT_NAME}.cpp)
|
||||
# if(TARGET ${PROJECT_NAME}-test)
|
||||
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
|
||||
# endif()
|
||||
73
clover/README.md
Normal file
73
clover/README.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# `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
|
||||
```
|
||||
@@ -1,17 +1,17 @@
|
||||
image_width: 640
|
||||
image_height: 480
|
||||
distortion_model: plumb_bob
|
||||
camera_name: raspicam
|
||||
camera_name: main_camera_optical
|
||||
camera_matrix:
|
||||
rows: 3
|
||||
cols: 3
|
||||
data:
|
||||
- 332.47884746146343
|
||||
- 0.
|
||||
- 324.38022493658536
|
||||
- 320.0
|
||||
- 0.
|
||||
- 333.1761847948052
|
||||
- 219.6445547142857
|
||||
- 240.0
|
||||
- 0.
|
||||
- 0.
|
||||
- 1.
|
||||
@@ -3,7 +3,7 @@
|
||||
<arg name="aruco_map" default="false"/>
|
||||
<arg name="aruco_vpe" default="false"/>
|
||||
|
||||
<!-- For additional help go to https://clever.coex.tech/aruco -->
|
||||
<!-- For additional help go to https://clover.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,6 +14,9 @@
|
||||
<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 -->
|
||||
@@ -31,7 +34,7 @@
|
||||
</node>
|
||||
|
||||
<!-- vpe publisher from aruco markers -->
|
||||
<node name="vpe_publisher" pkg="clever" type="vpe_publisher" if="$(arg aruco_vpe)" output="screen" clear_params="true">
|
||||
<node name="vpe_publisher" pkg="clover" type="vpe_publisher" if="$(arg aruco_vpe)" output="screen" clear_params="true">
|
||||
<remap from="~pose_cov" to="aruco_map/pose"/>
|
||||
<remap from="~vpe" to="mavros/vision_pose/pose"/>
|
||||
<param name="frame_id" value="aruco_map_detected"/>
|
||||
@@ -1,23 +1,26 @@
|
||||
<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="false"/>
|
||||
<arg name="optical_flow" default="true"/>
|
||||
<arg name="aruco" default="false"/>
|
||||
<arg name="rangefinder_vl53l1x" default="false"/>
|
||||
<arg name="led" default="false"/>
|
||||
<arg name="rangefinder_vl53l1x" default="true"/>
|
||||
<arg name="led" default="true"/>
|
||||
<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 clever)/launch/mavros.launch">
|
||||
<include file="$(find clover)/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>
|
||||
|
||||
@@ -28,13 +31,14 @@
|
||||
</node>
|
||||
|
||||
<!-- aruco markers -->
|
||||
<include file="$(find clever)/launch/aruco.launch" if="$(arg aruco)"/>
|
||||
<include file="$(find clover)/launch/aruco.launch" if="$(arg aruco)"/>
|
||||
|
||||
<!-- optical flow -->
|
||||
<node pkg="nodelet" type="nodelet" name="optical_flow" args="load clever/optical_flow nodelet_manager" if="$(arg optical_flow)" clear_params="true" output="screen">
|
||||
<node pkg="nodelet" type="nodelet" name="optical_flow" args="load clover/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 -->
|
||||
@@ -45,14 +49,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="clever" type="simple_offboard" output="screen" clear_params="true">
|
||||
<node name="simple_offboard" pkg="clover" 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 clever)/launch/main_camera.launch" if="$(arg main_camera)"/>
|
||||
<include file="$(find clover)/launch/main_camera.launch" if="$(arg main_camera)"/>
|
||||
|
||||
<!-- rosbridge -->
|
||||
<include file="$(find rosbridge_server)/launch/rosbridge_websocket.launch" if="$(eval rosbridge or rc)"/>
|
||||
@@ -63,11 +67,24 @@
|
||||
<!-- 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 clever)/launch/led.launch" if="$(arg led)"/>
|
||||
<include file="$(find clover)/launch/led.launch" if="$(arg led)"/>
|
||||
|
||||
<!-- rc backend -->
|
||||
<node name="rc" pkg="clever" type="rc" output="screen" if="$(arg rc)"/>
|
||||
<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>
|
||||
</launch>
|
||||
@@ -3,13 +3,13 @@
|
||||
<arg name="led_effect" default="true"/>
|
||||
<arg name="led_notify" default="true"/>
|
||||
|
||||
<!-- For additional help go to https://clever.coex.tech/led -->
|
||||
<!-- For additional help go to https://clover.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="100"/>
|
||||
<param name="brightness" value="64"/>
|
||||
<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="clever" name="led_effect" type="led" ns="led" clear_params="true" output="screen" if="$(arg led_effect)">
|
||||
<node pkg="clover" 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"/>
|
||||
37
clover/launch/main_camera.launch
Normal file
37
clover/launch/main_camera.launch
Normal file
@@ -0,0 +1,37 @@
|
||||
<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>
|
||||
@@ -1,6 +1,7 @@
|
||||
<launch>
|
||||
<arg name="fcu_conn" default="usb"/>
|
||||
<arg name="fcu_conn" default="usb"/> <!-- options: usb, uart, tcp, udp, sitl -->
|
||||
<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"/>
|
||||
@@ -13,9 +14,15 @@
|
||||
<!-- USB connection -->
|
||||
<param name="fcu_url" value="/dev/px4fmu" if="$(eval fcu_conn == 'usb')"/>
|
||||
|
||||
<!-- sitl -->
|
||||
<!-- sitl before PX4 1.9.0 -->
|
||||
<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')"/>
|
||||
@@ -26,7 +33,7 @@
|
||||
<param name="conn/timeout" value="8"/>
|
||||
|
||||
<!-- basic params -->
|
||||
<rosparam command="load" file="$(find clever)/launch/mavros_config.yaml"/>
|
||||
<rosparam command="load" file="$(find clover)/launch/mavros_config.yaml"/>
|
||||
|
||||
<!-- remap rangefinder -->
|
||||
<remap from="mavros/distance_sensor/rangefinder_sub" to="rangefinder/range"/>
|
||||
@@ -1,9 +1,9 @@
|
||||
<launch>
|
||||
<!-- Clever configuration for testing in sitl -->
|
||||
<!-- clover configuration for testing in sitl -->
|
||||
<arg name="ip" default="127.0.0.1"/>
|
||||
<arg name="rosbridge" default="false"/>
|
||||
|
||||
<include file="$(find clever)/launch/clever.launch">
|
||||
<include file="$(find clover)/launch/clover.launch">
|
||||
<arg name="fcu_conn" value="udp"/>
|
||||
<arg name="fcu_ip" value="$(arg ip)"/>
|
||||
<arg name="gcs_bridge" value="false"/>
|
||||
@@ -13,6 +13,7 @@
|
||||
<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>
|
||||
5
clover/nodelet_plugins.xml
Normal file
5
clover/nodelet_plugins.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<library path="lib/libclover">
|
||||
<class name="clover/optical_flow" type="OpticalFlow" base_class_type="nodelet::Nodelet">
|
||||
<description/>
|
||||
</class>
|
||||
</library>
|
||||
@@ -1,13 +1,13 @@
|
||||
<?xml version="1.0"?>
|
||||
<package format="2">
|
||||
<name>clever</name>
|
||||
<name>clover</name>
|
||||
<version>0.0.1</version>
|
||||
<description>The CLEVER package</description>
|
||||
<description>The Clover package</description>
|
||||
|
||||
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
||||
<license>MIT</license>
|
||||
|
||||
<url type="website">https://clever.coex.tech/</url>
|
||||
<url type="website">https://clover.coex.tech/</url>
|
||||
<author email="okalachev@gmail.com">Oleg Kalachev</author>
|
||||
<author email="urpylka@gmail.com">Artem Smirnov</author>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<!-- 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>
|
||||
@@ -33,12 +34,10 @@
|
||||
<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>python3-lxml</depend>
|
||||
<depend>python-lxml</depend>
|
||||
<exec_depend>python-pymavlink</exec_depend>
|
||||
<!-- Use test_depend for packages you need only for testing: -->
|
||||
<!-- <test_depend>gtest</test_depend> -->
|
||||
5
clover/requirements.txt
Normal file
5
clover/requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
flask==1.1.1
|
||||
docopt==0.6.2
|
||||
geopy==1.11.0
|
||||
smbus2==0.2.1
|
||||
VL53L1X==0.0.2
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Usage
|
||||
# fpv_camera <video_device> <http port>
|
||||
# camera_stream <video_device> <http port>
|
||||
|
||||
echo "Starting FPV camera $1 on :$2"
|
||||
echo "Starting camera stream $1 on :$2"
|
||||
mjpg_streamer -i "/usr/lib/input_uvc.so -d $1 -r 320x240 -f 30" -o "/usr/lib/output_http.so -w /usr/share/mjpg_streamer/www -p $2"
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <string>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <clever/SetLEDEffect.h>
|
||||
#include <clover/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>
|
||||
|
||||
clever::SetLEDEffect::Request current_effect;
|
||||
clover::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(clever::SetLEDEffect::Request& req, clever::SetLEDEffect::Response& res)
|
||||
bool setEffect(clover::SetLEDEffect::Request& req, clover::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());
|
||||
clever::SetLEDEffect effect;
|
||||
clover::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,7 +263,10 @@ void handleMavrosState(const mavros_msgs::State& msg)
|
||||
// remove the part before "."
|
||||
mode = mode.substr(mode.find(".") + 1);
|
||||
}
|
||||
notify(mode);
|
||||
std::string err;
|
||||
if (ros::names::validate(mode, err)) {
|
||||
notify(mode);
|
||||
}
|
||||
}
|
||||
mavros_state = msg;
|
||||
}
|
||||
@@ -278,7 +281,8 @@ 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) {
|
||||
if (voltage < low_battery_threshold &&
|
||||
voltage > 2.0) { // voltage < 2.0 likely indicates incorrect voltage measurement
|
||||
// notify low battery every time
|
||||
notify("low_battery");
|
||||
}
|
||||
@@ -34,9 +34,7 @@ class OpticalFlow : public nodelet::Nodelet
|
||||
{
|
||||
public:
|
||||
OpticalFlow():
|
||||
camera_matrix_(3, 3, CV_64F),
|
||||
dist_coeffs_(8, 1, CV_64F),
|
||||
tf_listener_(tf_buffer_)
|
||||
camera_matrix_(3, 3, CV_64F)
|
||||
{}
|
||||
|
||||
private:
|
||||
@@ -46,12 +44,14 @@ private:
|
||||
image_transport::CameraSubscriber img_sub_;
|
||||
image_transport::Publisher img_pub_;
|
||||
mavros_msgs::OpticalFlowRad flow_;
|
||||
int roi_, roi_2_;
|
||||
int roi_px_;
|
||||
double roi_rad_;
|
||||
cv::Rect roi_;
|
||||
Mat hann_;
|
||||
Mat prev_, curr_;
|
||||
Mat camera_matrix_, dist_coeffs_;
|
||||
tf2_ros::Buffer tf_buffer_;
|
||||
tf2_ros::TransformListener tf_listener_;
|
||||
std::unique_ptr<tf2_ros::Buffer> tf_buffer_;
|
||||
std::unique_ptr<tf2_ros::TransformListener> tf_listener_;
|
||||
bool calc_flow_gyro_;
|
||||
|
||||
void onInit()
|
||||
@@ -61,11 +61,14 @@ private:
|
||||
image_transport::ImageTransport it(nh);
|
||||
image_transport::ImageTransport it_priv(nh_priv);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
img_sub_ = it.subscribeCamera("image_raw", 1, &OpticalFlow::flow, this);
|
||||
img_pub_ = it_priv.advertise("debug", 1);
|
||||
@@ -89,9 +92,7 @@ private:
|
||||
camera_matrix_.at<double>(i, j) = cinfo->K[3 * i + j];
|
||||
}
|
||||
}
|
||||
for (int k = 0; k < cinfo->D.size(); k++) {
|
||||
dist_coeffs_.at<double>(k) = cinfo->D[k];
|
||||
}
|
||||
dist_coeffs_ = cv::Mat(cinfo->D, true);
|
||||
}
|
||||
|
||||
void drawFlow(Mat& frame, double x, double y, double quality) const
|
||||
@@ -112,9 +113,31 @@ private:
|
||||
|
||||
auto img = cv_bridge::toCvShare(msg, "mono8")->image;
|
||||
|
||||
// Apply ROI
|
||||
if (roi_ != 0) {
|
||||
img = img(cv::Rect((msg->width / 2 - roi_2_), (msg->height / 2 - roi_2_), roi_, roi_));
|
||||
if (roi_.width == 0) { // ROI is not calculated
|
||||
// Calculate ROI
|
||||
if (roi_rad_ != 0) {
|
||||
std::vector<cv::Point3f> object_points = {
|
||||
cv::Point3f(-sin(roi_rad_ / 2), -sin(roi_rad_ / 2), cos(roi_rad_ / 2)),
|
||||
cv::Point3f(sin(roi_rad_ / 2), sin(roi_rad_ / 2), cos(roi_rad_ / 2)),
|
||||
};
|
||||
|
||||
std::vector<double> vec { 0, 0, 0 };
|
||||
std::vector<cv::Point2f> img_points;
|
||||
cv::projectPoints(object_points, vec, vec, camera_matrix_, dist_coeffs_, img_points);
|
||||
|
||||
roi_ = cv::Rect(cv::Point2i(round(img_points[0].x), round(img_points[0].y)),
|
||||
cv::Point2i(round(img_points[1].x), round(img_points[1].y)));
|
||||
|
||||
ROS_INFO("ROI: %d %d - %d %d ", roi_.tl().x, roi_.tl().y, roi_.br().x, roi_.br().y);
|
||||
|
||||
} else if (roi_px_ != 0) {
|
||||
roi_ = cv::Rect((msg->width / 2 - roi_px_ / 2), (msg->height / 2 - roi_px_ / 2), roi_px_, roi_px_);
|
||||
}
|
||||
}
|
||||
|
||||
if (roi_.width != 0) { // ROI is set
|
||||
// Apply ROI
|
||||
img = img(roi_);
|
||||
}
|
||||
|
||||
img.convertTo(curr_, CV_32F);
|
||||
@@ -162,7 +185,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;
|
||||
@@ -176,7 +199,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;
|
||||
@@ -223,8 +246,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;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* CLEVER mobile remote control backend
|
||||
* Clover mobile remote control backend
|
||||
* Send ManualControl messages through UDP
|
||||
* 'latched_state' topic
|
||||
*
|
||||
@@ -34,12 +34,15 @@ 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();
|
||||
|
||||
std::thread gcst(&RC::fakeGCSThread, this);
|
||||
gcst.detach();
|
||||
if (use_fake_gcs) {
|
||||
std::thread gcst(&RC::fakeGCSThread, this);
|
||||
gcst.detach();
|
||||
}
|
||||
|
||||
initLatchedState();
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
|
||||
# Copyright (C) 2018 Copter Express Technologies
|
||||
@@ -9,6 +9,7 @@
|
||||
# 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
|
||||
@@ -94,7 +95,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
|
||||
@@ -199,17 +200,17 @@ def check_fcu():
|
||||
info('no version data available from SITL')
|
||||
|
||||
r = re.compile(r'^FW (git tag|version): (v?\d\.\d\.\d.*)$')
|
||||
is_clever_firmware = False
|
||||
is_clover_firmware = False
|
||||
for ver_line in version_str.split('\n'):
|
||||
match = r.search(ver_line)
|
||||
if match is not None:
|
||||
field, version = match.groups()
|
||||
info('firmware %s: %s' % (field, version))
|
||||
if 'clever' in version:
|
||||
is_clever_firmware = True
|
||||
if 'clover' in version or 'clever' in version:
|
||||
is_clover_firmware = True
|
||||
|
||||
if not is_clever_firmware:
|
||||
failure('not running Clever PX4 firmware, https://clever.coex.tech/firmware')
|
||||
if not is_clover_firmware:
|
||||
failure('not running Clover PX4 firmware, https://clover.coex.tech/firmware')
|
||||
|
||||
est = get_param('SYS_MC_EST_GROUP')
|
||||
if est == 1:
|
||||
@@ -224,6 +225,12 @@ 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:
|
||||
@@ -238,15 +245,18 @@ 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)
|
||||
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)
|
||||
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)
|
||||
except rospy.ROSException:
|
||||
failure('no battery state')
|
||||
|
||||
@@ -301,7 +311,7 @@ def check_camera(name):
|
||||
if not optical or not cable:
|
||||
info('%s: custom camera orientation detected', name)
|
||||
else:
|
||||
info('camera is oriented %s, camera cable goes %s', optical, cable)
|
||||
info('camera is oriented %s, cable from camera goes %s', optical, cable)
|
||||
|
||||
except tf2_ros.TransformException:
|
||||
failure('cannot transform from base_link to camera frame')
|
||||
@@ -329,8 +339,11 @@ def is_process_running(binary, exact=False, full=False):
|
||||
@check('ArUco markers')
|
||||
def check_aruco():
|
||||
if is_process_running('aruco_detect', full=True):
|
||||
info('aruco_detect/length = %g m', rospy.get_param('aruco_detect/length'))
|
||||
known_tilt = rospy.get_param('aruco_detect/known_tilt')
|
||||
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', '')
|
||||
if known_tilt == 'map':
|
||||
known_tilt += ' (ALL markers are on the floor)'
|
||||
elif known_tilt == 'map_flipped':
|
||||
@@ -346,7 +359,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':
|
||||
@@ -506,7 +519,7 @@ def check_global_position():
|
||||
try:
|
||||
rospy.wait_for_message('mavros/global_position/global', NavSatFix, timeout=1)
|
||||
except rospy.ROSException:
|
||||
failure('no global position')
|
||||
info('no global position')
|
||||
|
||||
|
||||
@check('Optical flow')
|
||||
@@ -619,16 +632,16 @@ def check_cpu_usage():
|
||||
cpu.strip(), cmd.strip(), pid.strip())
|
||||
|
||||
|
||||
@check('clever.service')
|
||||
def check_clever_service():
|
||||
@check('clover.service')
|
||||
def check_clover_service():
|
||||
try:
|
||||
output = subprocess.check_output('systemctl show -p ActiveState --value clever.service'.split(),
|
||||
output = subprocess.check_output('systemctl show -p ActiveState --value clover.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 clever')
|
||||
failure('service is not running, try sudo systemctl restart clover')
|
||||
return
|
||||
elif 'failed' in output:
|
||||
failure('service failed to run, check your launch-files')
|
||||
@@ -636,7 +649,7 @@ def check_clever_service():
|
||||
r = re.compile(r'^(.*)\[(FATAL|ERROR)\] \[\d+.\d+\]: (.*?)(\x1b(.*))?$')
|
||||
error_count = OrderedDict()
|
||||
try:
|
||||
for line in open('/tmp/clever.err', 'r'):
|
||||
for line in open('/tmp/clover.err', 'r'):
|
||||
node_error = r.search(line)
|
||||
if node_error:
|
||||
msg = node_error.groups()[1] + ': ' + node_error.groups()[2]
|
||||
@@ -660,9 +673,9 @@ def check_clever_service():
|
||||
@check('Image')
|
||||
def check_image():
|
||||
try:
|
||||
info('version: %s', open('/etc/clever_version').read().strip())
|
||||
info('version: %s', open('/etc/clover_version').read().strip())
|
||||
except IOError:
|
||||
info('no /etc/clever_version file, not the Clever image?')
|
||||
info('no /etc/clover_version file, not the Clover image?')
|
||||
|
||||
|
||||
@check('Preflight status')
|
||||
@@ -686,9 +699,82 @@ 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_clever_service()
|
||||
check_board()
|
||||
check_clover_service()
|
||||
check_network()
|
||||
check_fcu()
|
||||
check_imu()
|
||||
check_local_position()
|
||||
@@ -701,6 +787,7 @@ def selfcheck():
|
||||
check_optical_flow()
|
||||
check_vpe()
|
||||
check_rangefinder()
|
||||
check_rpi_health()
|
||||
check_cpu_usage()
|
||||
check_boot_duration()
|
||||
|
||||
50
clover/src/shell.cpp
Normal file
50
clover/src/shell.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include <ros/ros.h>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <std_msgs/String.h>
|
||||
|
||||
#include <clover/Execute.h>
|
||||
|
||||
ros::Duration timeout;
|
||||
|
||||
// TODO: handle timeout
|
||||
bool handle(clover::Execute::Request& req, clover::Execute::Response& res)
|
||||
{
|
||||
ROS_INFO("Execute: %s", req.cmd.c_str());
|
||||
|
||||
std::array<char, 128> buffer;
|
||||
std::string result;
|
||||
|
||||
FILE *fp = popen(req.cmd.c_str(), "r");
|
||||
|
||||
if (fp == NULL) {
|
||||
res.code = clover::Execute::Request::CODE_FAIL;
|
||||
res.output = "popen() failed";
|
||||
return true;
|
||||
}
|
||||
|
||||
while (fgets(buffer.data(), buffer.size(), fp) != nullptr) {
|
||||
res.output += buffer.data();
|
||||
}
|
||||
|
||||
res.code = pclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ros::init(argc, argv, "shell");
|
||||
ros::NodeHandle nh, nh_priv("~");
|
||||
|
||||
timeout = ros::Duration(nh_priv.param("timeout", 3.0));
|
||||
|
||||
auto gt_serv = nh.advertiseService("exec", &handle);
|
||||
|
||||
ROS_INFO("shell: ready");
|
||||
ros::spin();
|
||||
}
|
||||
@@ -37,18 +37,18 @@
|
||||
#include <mavros_msgs/State.h>
|
||||
#include <mavros_msgs/StatusText.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>
|
||||
#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>
|
||||
|
||||
using std::string;
|
||||
using namespace geometry_msgs;
|
||||
using namespace sensor_msgs;
|
||||
using namespace clever;
|
||||
using namespace clover;
|
||||
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;
|
||||
TransformStamped target, setpoint;
|
||||
geometry_msgs::TransformStamped body;
|
||||
|
||||
// State
|
||||
@@ -177,8 +177,6 @@ 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)
|
||||
@@ -435,6 +433,17 @@ 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) {
|
||||
@@ -481,7 +490,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://clever.coex.tech/connection");
|
||||
throw std::runtime_error("No connection to FCU, https://clover.coex.tech/connection");
|
||||
}
|
||||
|
||||
#define ENSURE_FINITE(var) { if (!std::isfinite(var)) throw std::runtime_error(#var " argument cannot be NaN or Inf"); }
|
||||
@@ -751,8 +760,6 @@ 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)
|
||||
@@ -768,6 +775,7 @@ 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);
|
||||
7
clover/srv/Execute.srv
Normal file
7
clover/srv/Execute.srv
Normal file
@@ -0,0 +1,7 @@
|
||||
int32 CODE_FAIL = -1
|
||||
int32 CODE_TIMEOUT = -2
|
||||
|
||||
string cmd
|
||||
---
|
||||
string output
|
||||
int32 code
|
||||
@@ -1,11 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/env python
|
||||
import rospy
|
||||
import pytest
|
||||
from mavros_msgs.msg import State
|
||||
from clover import srv
|
||||
|
||||
@pytest.fixture()
|
||||
def node():
|
||||
return rospy.init_node('clever_test', anonymous=True)
|
||||
return rospy.init_node('clover_test', anonymous=True)
|
||||
|
||||
def test_state(node):
|
||||
state = rospy.wait_for_message('mavros/state', State, timeout=10)
|
||||
@@ -27,3 +28,19 @@ 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 == ''
|
||||
@@ -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 clever)/launch/mavros_config.yaml"/>
|
||||
<rosparam command="load" file="$(find clover)/launch/mavros_config.yaml"/>
|
||||
</node>
|
||||
|
||||
<node name="visualization" pkg="mavros_extras" type="visualization" required="true">
|
||||
@@ -23,19 +23,21 @@
|
||||
|
||||
<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="clever" type="simple_offboard" required="true" output="screen">
|
||||
<node name="simple_offboard" pkg="clover" 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="clever" type="rc" required="true" output="screen"/>
|
||||
<node name="rc" pkg="clover" type="rc" required="true" output="screen"/>
|
||||
|
||||
<node pkg="clever" name="led_effect" type="led" ns="led" clear_params="true" output="screen" required="true">
|
||||
<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">
|
||||
<rosparam param="notify">startup: { r: 255, g: 255, b: 255 }</rosparam>
|
||||
</node>
|
||||
|
||||
<param name="test_module" value="$(find clever)/test/basic.py"/>
|
||||
<param name="test_module" value="$(find clover)/test/basic.py"/>
|
||||
<test test-name="basic_test" pkg="ros_pytest" type="ros_pytest_runner"/>
|
||||
</launch>
|
||||
0
clover/www/CATKIN_IGNORE
Normal file
0
clover/www/CATKIN_IGNORE
Normal file
24
clover/www/index.html
Normal file
24
clover/www/index.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<h1>Clover Drone Kit Tools</h1>
|
||||
|
||||
<ul>
|
||||
<li><a href="docs">View documentation</a> (snapshot of <a href="https://clover.coex.tech">clover.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>
|
||||
|
||||
<div class="version"></div>
|
||||
|
||||
<script src="js/roslib.js"></script>
|
||||
<script type="text/javascript">
|
||||
document.querySelector("#wvs").href = location.protocol + '//' + location.hostname + ':8080';
|
||||
document.querySelector("#butterfly").href = location.protocol + '//' + location.hostname + ':57575';
|
||||
|
||||
// Determine image version
|
||||
var ros = new ROSLIB.Ros({ url: 'ws://' + location.hostname + ':9090' });
|
||||
var exec = new ROSLIB.Service({ ros: ros, name : '/exec', serviceType : 'clover/Execute' });
|
||||
exec.callService(new ROSLIB.ServiceRequest({ cmd: 'cat /etc/clover_version' }), function(result) {
|
||||
document.querySelector('.version').innerHTML = 'Version: ' + result.output;
|
||||
});
|
||||
</script>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user