Compare commits
34 commits
Author | SHA1 | Date | |
---|---|---|---|
0e18015416 | |||
8568ff0690 | |||
1e9f97e136 | |||
191479e416 | |||
15b11c3bb5 | |||
f94492264d | |||
3ae5379f74 | |||
2366937861 | |||
c7d78bdd81 | |||
6241a63264 | |||
c68b58ee7f | |||
b3a620ba17 | |||
9ede58f0dd | |||
5ba7b67270 | |||
18cdda6865 | |||
b131764e63 | |||
04abfe70b2 | |||
72f54acbb6 | |||
bb06580aaa | |||
a47c525013 | |||
712ac24eac | |||
5a2a91aa08 | |||
a380f26986 | |||
b90ae8fc4e | |||
1333f5e1ee | |||
41fbfb30e1 | |||
02db6103aa | |||
f0a0536ded | |||
7103ef6277 | |||
a70483de20 | |||
3acd745d19 | |||
8e0ec310d4 | |||
16e9dae1a7 | |||
7032e7aa49 |
39
.travis.yml
Normal file
39
.travis.yml
Normal file
|
@ -0,0 +1,39 @@
|
|||
language:
|
||||
- cpp
|
||||
python:
|
||||
- "2.7"
|
||||
compiler:
|
||||
- gcc
|
||||
env:
|
||||
- ros_distro=hydro
|
||||
# - ros_distro=indigo
|
||||
before_install:
|
||||
- export CI_SOURCE_PATH="`pwd`"
|
||||
- export ROS_DISTRO=$ros_distro
|
||||
- sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu precise main" > /etc/apt/sources.list.d/ros-latest.list'
|
||||
- sudo apt-key adv --keyserver hkp://pool.sks-keyservers.net --recv-key 0xB01FA116
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -qq -y python-rosdep python-rosinstall-generator python-wstool python-rosinstall build-essential python-catkin-pkg
|
||||
- sudo rosdep init
|
||||
- rosdep update
|
||||
- sudo apt-get install ros-${ROS_DISTRO}-ros-base
|
||||
- sudo pip install cpplint
|
||||
install: # Use this to install any prerequisites or dependencies necessary to run your build
|
||||
- source /opt/ros/${ROS_DISTRO}/setup.bash
|
||||
- mkdir -p ~/hand_control_ws/src
|
||||
- cd ~/hand_control_ws/src
|
||||
- catkin_init_workspace
|
||||
# - curl -L 'https://github.com/AutonomyLab/ardrone_autonomy/archive/master.tar.gz' | tar -xz
|
||||
# - curl -L 'https://github.com/ros-drivers/rgbd_launch/archive/2.1.0.tar.gz' | tar -xz
|
||||
# - curl -L 'https://github.com/ros-drivers/freenect_stack/archive/master.tar.gz' | tar -xz
|
||||
- ln -s "$CI_SOURCE_PATH" .
|
||||
- cd ..
|
||||
- sudo rosdep install --from-paths src --ignore-src --rosdistro $ROS_DISTRO -y
|
||||
before_script: # Use this to prepare your build for testing e.g. copy database configurations, environment variables, etc.
|
||||
- source /opt/ros/${ROS_DISTRO}/setup.bash
|
||||
- cd ~/hand_control_ws
|
||||
- cd src
|
||||
- cpplint *.hpp *.cpp *.h
|
||||
- cd ..
|
||||
script: # All commands must exit with code 0 on success. Anything else is considered failure.
|
||||
- catkin_make -j2
|
5
AUTHORS
Normal file
5
AUTHORS
Normal file
|
@ -0,0 +1,5 @@
|
|||
Original Authors
|
||||
----------------
|
||||
Luc ABSIL <luc.absil@supelec.fr>
|
||||
Louis-Guillaume DUBOIS <contact@lgdubois.fr>
|
||||
Paul JANIN <paul.janin@supelec.fr>
|
|
@ -1,3 +1,20 @@
|
|||
# Copyright © 2015 CentraleSupélec
|
||||
#
|
||||
# This file is part of Hand Control.
|
||||
#
|
||||
# Hand Control is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Hand Control 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 General Public License
|
||||
# along with Hand Control. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.3)
|
||||
project(hand_control)
|
||||
|
||||
|
@ -38,12 +55,6 @@ pkg_check_modules ( ncursesw REQUIRED ncursesw)
|
|||
add_executable(filter src/filter.cpp)
|
||||
target_link_libraries(filter ${catkin_LIBRARIES})
|
||||
|
||||
add_executable(random_pcl_publisher src/random_pcl_publisher.cpp)
|
||||
target_link_libraries(random_pcl_publisher ${catkin_LIBRARIES})
|
||||
|
||||
add_executable(pcl_displayer src/pcl_displayer.cpp)
|
||||
target_link_libraries(pcl_displayer ${catkin_LIBRARIES})
|
||||
|
||||
add_library(display src/display.cpp)
|
||||
|
||||
add_executable(keyboard_cmd src/keyboard_cmd.cpp)
|
||||
|
@ -53,10 +64,6 @@ target_link_libraries(keyboard_cmd display ${catkin_LIBRARIES} ${ncursesw_LIBRAR
|
|||
target_link_libraries(estimator ${catkin_LIBRARIES})
|
||||
add_dependencies(estimator hand_control_generate_messages_cpp)
|
||||
|
||||
add_executable(commander_atan src/commander_atan.cpp)
|
||||
target_link_libraries(commander_atan ${catkin_LIBRARIES})
|
||||
add_dependencies(commander_atan hand_control_generate_messages_cpp)
|
||||
|
||||
add_executable(commander src/commander.cpp)
|
||||
target_link_libraries(commander ${catkin_LIBRARIES})
|
||||
add_dependencies(commander hand_control_generate_messages_cpp)
|
||||
|
@ -66,13 +73,11 @@ generate_dynamic_reconfigure_options(
|
|||
cfg/Filter.cfg
|
||||
cfg/Commander.cfg
|
||||
cfg/Estimator.cfg
|
||||
cfg/Commander_atan.cfg
|
||||
)
|
||||
|
||||
add_dependencies(filter ${PROJECT_NAME}_gencfg)
|
||||
add_dependencies(commander ${PROJECT_NAME}_gencfg)
|
||||
add_dependencies(estimator ${PROJECT_NAME}_gencfg)
|
||||
add_dependencies(commander_atan ${PROJECT_NAME}_gencfg)
|
||||
|
||||
catkin_package(
|
||||
CATKIN_DEPENDS message_runtime
|
||||
|
|
18
COPYING
Normal file
18
COPYING
Normal file
|
@ -0,0 +1,18 @@
|
|||
Hand Control -- "hand_control" ROS package
|
||||
|
||||
Controling a "Parrot AR Drone" with the hand movements measured by a Microsoft Kinect sensor.
|
||||
|
||||
Copyright © 2015 CentraleSupélec
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
451
LICENSES/FDL.txt
Normal file
451
LICENSES/FDL.txt
Normal file
|
@ -0,0 +1,451 @@
|
|||
|
||||
GNU Free Documentation License
|
||||
Version 1.3, 3 November 2008
|
||||
|
||||
|
||||
Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
|
||||
<http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
0. PREAMBLE
|
||||
|
||||
The purpose of this License is to make a manual, textbook, or other
|
||||
functional and useful document "free" in the sense of freedom: to
|
||||
assure everyone the effective freedom to copy and redistribute it,
|
||||
with or without modifying it, either commercially or noncommercially.
|
||||
Secondarily, this License preserves for the author and publisher a way
|
||||
to get credit for their work, while not being considered responsible
|
||||
for modifications made by others.
|
||||
|
||||
This License is a kind of "copyleft", which means that derivative
|
||||
works of the document must themselves be free in the same sense. It
|
||||
complements the GNU General Public License, which is a copyleft
|
||||
license designed for free software.
|
||||
|
||||
We have designed this License in order to use it for manuals for free
|
||||
software, because free software needs free documentation: a free
|
||||
program should come with manuals providing the same freedoms that the
|
||||
software does. But this License is not limited to software manuals;
|
||||
it can be used for any textual work, regardless of subject matter or
|
||||
whether it is published as a printed book. We recommend this License
|
||||
principally for works whose purpose is instruction or reference.
|
||||
|
||||
|
||||
1. APPLICABILITY AND DEFINITIONS
|
||||
|
||||
This License applies to any manual or other work, in any medium, that
|
||||
contains a notice placed by the copyright holder saying it can be
|
||||
distributed under the terms of this License. Such a notice grants a
|
||||
world-wide, royalty-free license, unlimited in duration, to use that
|
||||
work under the conditions stated herein. The "Document", below,
|
||||
refers to any such manual or work. Any member of the public is a
|
||||
licensee, and is addressed as "you". You accept the license if you
|
||||
copy, modify or distribute the work in a way requiring permission
|
||||
under copyright law.
|
||||
|
||||
A "Modified Version" of the Document means any work containing the
|
||||
Document or a portion of it, either copied verbatim, or with
|
||||
modifications and/or translated into another language.
|
||||
|
||||
A "Secondary Section" is a named appendix or a front-matter section of
|
||||
the Document that deals exclusively with the relationship of the
|
||||
publishers or authors of the Document to the Document's overall
|
||||
subject (or to related matters) and contains nothing that could fall
|
||||
directly within that overall subject. (Thus, if the Document is in
|
||||
part a textbook of mathematics, a Secondary Section may not explain
|
||||
any mathematics.) The relationship could be a matter of historical
|
||||
connection with the subject or with related matters, or of legal,
|
||||
commercial, philosophical, ethical or political position regarding
|
||||
them.
|
||||
|
||||
The "Invariant Sections" are certain Secondary Sections whose titles
|
||||
are designated, as being those of Invariant Sections, in the notice
|
||||
that says that the Document is released under this License. If a
|
||||
section does not fit the above definition of Secondary then it is not
|
||||
allowed to be designated as Invariant. The Document may contain zero
|
||||
Invariant Sections. If the Document does not identify any Invariant
|
||||
Sections then there are none.
|
||||
|
||||
The "Cover Texts" are certain short passages of text that are listed,
|
||||
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
|
||||
the Document is released under this License. A Front-Cover Text may
|
||||
be at most 5 words, and a Back-Cover Text may be at most 25 words.
|
||||
|
||||
A "Transparent" copy of the Document means a machine-readable copy,
|
||||
represented in a format whose specification is available to the
|
||||
general public, that is suitable for revising the document
|
||||
straightforwardly with generic text editors or (for images composed of
|
||||
pixels) generic paint programs or (for drawings) some widely available
|
||||
drawing editor, and that is suitable for input to text formatters or
|
||||
for automatic translation to a variety of formats suitable for input
|
||||
to text formatters. A copy made in an otherwise Transparent file
|
||||
format whose markup, or absence of markup, has been arranged to thwart
|
||||
or discourage subsequent modification by readers is not Transparent.
|
||||
An image format is not Transparent if used for any substantial amount
|
||||
of text. A copy that is not "Transparent" is called "Opaque".
|
||||
|
||||
Examples of suitable formats for Transparent copies include plain
|
||||
ASCII without markup, Texinfo input format, LaTeX input format, SGML
|
||||
or XML using a publicly available DTD, and standard-conforming simple
|
||||
HTML, PostScript or PDF designed for human modification. Examples of
|
||||
transparent image formats include PNG, XCF and JPG. Opaque formats
|
||||
include proprietary formats that can be read and edited only by
|
||||
proprietary word processors, SGML or XML for which the DTD and/or
|
||||
processing tools are not generally available, and the
|
||||
machine-generated HTML, PostScript or PDF produced by some word
|
||||
processors for output purposes only.
|
||||
|
||||
The "Title Page" means, for a printed book, the title page itself,
|
||||
plus such following pages as are needed to hold, legibly, the material
|
||||
this License requires to appear in the title page. For works in
|
||||
formats which do not have any title page as such, "Title Page" means
|
||||
the text near the most prominent appearance of the work's title,
|
||||
preceding the beginning of the body of the text.
|
||||
|
||||
The "publisher" means any person or entity that distributes copies of
|
||||
the Document to the public.
|
||||
|
||||
A section "Entitled XYZ" means a named subunit of the Document whose
|
||||
title either is precisely XYZ or contains XYZ in parentheses following
|
||||
text that translates XYZ in another language. (Here XYZ stands for a
|
||||
specific section name mentioned below, such as "Acknowledgements",
|
||||
"Dedications", "Endorsements", or "History".) To "Preserve the Title"
|
||||
of such a section when you modify the Document means that it remains a
|
||||
section "Entitled XYZ" according to this definition.
|
||||
|
||||
The Document may include Warranty Disclaimers next to the notice which
|
||||
states that this License applies to the Document. These Warranty
|
||||
Disclaimers are considered to be included by reference in this
|
||||
License, but only as regards disclaiming warranties: any other
|
||||
implication that these Warranty Disclaimers may have is void and has
|
||||
no effect on the meaning of this License.
|
||||
|
||||
2. VERBATIM COPYING
|
||||
|
||||
You may copy and distribute the Document in any medium, either
|
||||
commercially or noncommercially, provided that this License, the
|
||||
copyright notices, and the license notice saying this License applies
|
||||
to the Document are reproduced in all copies, and that you add no
|
||||
other conditions whatsoever to those of this License. You may not use
|
||||
technical measures to obstruct or control the reading or further
|
||||
copying of the copies you make or distribute. However, you may accept
|
||||
compensation in exchange for copies. If you distribute a large enough
|
||||
number of copies you must also follow the conditions in section 3.
|
||||
|
||||
You may also lend copies, under the same conditions stated above, and
|
||||
you may publicly display copies.
|
||||
|
||||
|
||||
3. COPYING IN QUANTITY
|
||||
|
||||
If you publish printed copies (or copies in media that commonly have
|
||||
printed covers) of the Document, numbering more than 100, and the
|
||||
Document's license notice requires Cover Texts, you must enclose the
|
||||
copies in covers that carry, clearly and legibly, all these Cover
|
||||
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
|
||||
the back cover. Both covers must also clearly and legibly identify
|
||||
you as the publisher of these copies. The front cover must present
|
||||
the full title with all words of the title equally prominent and
|
||||
visible. You may add other material on the covers in addition.
|
||||
Copying with changes limited to the covers, as long as they preserve
|
||||
the title of the Document and satisfy these conditions, can be treated
|
||||
as verbatim copying in other respects.
|
||||
|
||||
If the required texts for either cover are too voluminous to fit
|
||||
legibly, you should put the first ones listed (as many as fit
|
||||
reasonably) on the actual cover, and continue the rest onto adjacent
|
||||
pages.
|
||||
|
||||
If you publish or distribute Opaque copies of the Document numbering
|
||||
more than 100, you must either include a machine-readable Transparent
|
||||
copy along with each Opaque copy, or state in or with each Opaque copy
|
||||
a computer-network location from which the general network-using
|
||||
public has access to download using public-standard network protocols
|
||||
a complete Transparent copy of the Document, free of added material.
|
||||
If you use the latter option, you must take reasonably prudent steps,
|
||||
when you begin distribution of Opaque copies in quantity, to ensure
|
||||
that this Transparent copy will remain thus accessible at the stated
|
||||
location until at least one year after the last time you distribute an
|
||||
Opaque copy (directly or through your agents or retailers) of that
|
||||
edition to the public.
|
||||
|
||||
It is requested, but not required, that you contact the authors of the
|
||||
Document well before redistributing any large number of copies, to
|
||||
give them a chance to provide you with an updated version of the
|
||||
Document.
|
||||
|
||||
|
||||
4. MODIFICATIONS
|
||||
|
||||
You may copy and distribute a Modified Version of the Document under
|
||||
the conditions of sections 2 and 3 above, provided that you release
|
||||
the Modified Version under precisely this License, with the Modified
|
||||
Version filling the role of the Document, thus licensing distribution
|
||||
and modification of the Modified Version to whoever possesses a copy
|
||||
of it. In addition, you must do these things in the Modified Version:
|
||||
|
||||
A. Use in the Title Page (and on the covers, if any) a title distinct
|
||||
from that of the Document, and from those of previous versions
|
||||
(which should, if there were any, be listed in the History section
|
||||
of the Document). You may use the same title as a previous version
|
||||
if the original publisher of that version gives permission.
|
||||
B. List on the Title Page, as authors, one or more persons or entities
|
||||
responsible for authorship of the modifications in the Modified
|
||||
Version, together with at least five of the principal authors of the
|
||||
Document (all of its principal authors, if it has fewer than five),
|
||||
unless they release you from this requirement.
|
||||
C. State on the Title page the name of the publisher of the
|
||||
Modified Version, as the publisher.
|
||||
D. Preserve all the copyright notices of the Document.
|
||||
E. Add an appropriate copyright notice for your modifications
|
||||
adjacent to the other copyright notices.
|
||||
F. Include, immediately after the copyright notices, a license notice
|
||||
giving the public permission to use the Modified Version under the
|
||||
terms of this License, in the form shown in the Addendum below.
|
||||
G. Preserve in that license notice the full lists of Invariant Sections
|
||||
and required Cover Texts given in the Document's license notice.
|
||||
H. Include an unaltered copy of this License.
|
||||
I. Preserve the section Entitled "History", Preserve its Title, and add
|
||||
to it an item stating at least the title, year, new authors, and
|
||||
publisher of the Modified Version as given on the Title Page. If
|
||||
there is no section Entitled "History" in the Document, create one
|
||||
stating the title, year, authors, and publisher of the Document as
|
||||
given on its Title Page, then add an item describing the Modified
|
||||
Version as stated in the previous sentence.
|
||||
J. Preserve the network location, if any, given in the Document for
|
||||
public access to a Transparent copy of the Document, and likewise
|
||||
the network locations given in the Document for previous versions
|
||||
it was based on. These may be placed in the "History" section.
|
||||
You may omit a network location for a work that was published at
|
||||
least four years before the Document itself, or if the original
|
||||
publisher of the version it refers to gives permission.
|
||||
K. For any section Entitled "Acknowledgements" or "Dedications",
|
||||
Preserve the Title of the section, and preserve in the section all
|
||||
the substance and tone of each of the contributor acknowledgements
|
||||
and/or dedications given therein.
|
||||
L. Preserve all the Invariant Sections of the Document,
|
||||
unaltered in their text and in their titles. Section numbers
|
||||
or the equivalent are not considered part of the section titles.
|
||||
M. Delete any section Entitled "Endorsements". Such a section
|
||||
may not be included in the Modified Version.
|
||||
N. Do not retitle any existing section to be Entitled "Endorsements"
|
||||
or to conflict in title with any Invariant Section.
|
||||
O. Preserve any Warranty Disclaimers.
|
||||
|
||||
If the Modified Version includes new front-matter sections or
|
||||
appendices that qualify as Secondary Sections and contain no material
|
||||
copied from the Document, you may at your option designate some or all
|
||||
of these sections as invariant. To do this, add their titles to the
|
||||
list of Invariant Sections in the Modified Version's license notice.
|
||||
These titles must be distinct from any other section titles.
|
||||
|
||||
You may add a section Entitled "Endorsements", provided it contains
|
||||
nothing but endorsements of your Modified Version by various
|
||||
parties--for example, statements of peer review or that the text has
|
||||
been approved by an organization as the authoritative definition of a
|
||||
standard.
|
||||
|
||||
You may add a passage of up to five words as a Front-Cover Text, and a
|
||||
passage of up to 25 words as a Back-Cover Text, to the end of the list
|
||||
of Cover Texts in the Modified Version. Only one passage of
|
||||
Front-Cover Text and one of Back-Cover Text may be added by (or
|
||||
through arrangements made by) any one entity. If the Document already
|
||||
includes a cover text for the same cover, previously added by you or
|
||||
by arrangement made by the same entity you are acting on behalf of,
|
||||
you may not add another; but you may replace the old one, on explicit
|
||||
permission from the previous publisher that added the old one.
|
||||
|
||||
The author(s) and publisher(s) of the Document do not by this License
|
||||
give permission to use their names for publicity for or to assert or
|
||||
imply endorsement of any Modified Version.
|
||||
|
||||
|
||||
5. COMBINING DOCUMENTS
|
||||
|
||||
You may combine the Document with other documents released under this
|
||||
License, under the terms defined in section 4 above for modified
|
||||
versions, provided that you include in the combination all of the
|
||||
Invariant Sections of all of the original documents, unmodified, and
|
||||
list them all as Invariant Sections of your combined work in its
|
||||
license notice, and that you preserve all their Warranty Disclaimers.
|
||||
|
||||
The combined work need only contain one copy of this License, and
|
||||
multiple identical Invariant Sections may be replaced with a single
|
||||
copy. If there are multiple Invariant Sections with the same name but
|
||||
different contents, make the title of each such section unique by
|
||||
adding at the end of it, in parentheses, the name of the original
|
||||
author or publisher of that section if known, or else a unique number.
|
||||
Make the same adjustment to the section titles in the list of
|
||||
Invariant Sections in the license notice of the combined work.
|
||||
|
||||
In the combination, you must combine any sections Entitled "History"
|
||||
in the various original documents, forming one section Entitled
|
||||
"History"; likewise combine any sections Entitled "Acknowledgements",
|
||||
and any sections Entitled "Dedications". You must delete all sections
|
||||
Entitled "Endorsements".
|
||||
|
||||
|
||||
6. COLLECTIONS OF DOCUMENTS
|
||||
|
||||
You may make a collection consisting of the Document and other
|
||||
documents released under this License, and replace the individual
|
||||
copies of this License in the various documents with a single copy
|
||||
that is included in the collection, provided that you follow the rules
|
||||
of this License for verbatim copying of each of the documents in all
|
||||
other respects.
|
||||
|
||||
You may extract a single document from such a collection, and
|
||||
distribute it individually under this License, provided you insert a
|
||||
copy of this License into the extracted document, and follow this
|
||||
License in all other respects regarding verbatim copying of that
|
||||
document.
|
||||
|
||||
|
||||
7. AGGREGATION WITH INDEPENDENT WORKS
|
||||
|
||||
A compilation of the Document or its derivatives with other separate
|
||||
and independent documents or works, in or on a volume of a storage or
|
||||
distribution medium, is called an "aggregate" if the copyright
|
||||
resulting from the compilation is not used to limit the legal rights
|
||||
of the compilation's users beyond what the individual works permit.
|
||||
When the Document is included in an aggregate, this License does not
|
||||
apply to the other works in the aggregate which are not themselves
|
||||
derivative works of the Document.
|
||||
|
||||
If the Cover Text requirement of section 3 is applicable to these
|
||||
copies of the Document, then if the Document is less than one half of
|
||||
the entire aggregate, the Document's Cover Texts may be placed on
|
||||
covers that bracket the Document within the aggregate, or the
|
||||
electronic equivalent of covers if the Document is in electronic form.
|
||||
Otherwise they must appear on printed covers that bracket the whole
|
||||
aggregate.
|
||||
|
||||
|
||||
8. TRANSLATION
|
||||
|
||||
Translation is considered a kind of modification, so you may
|
||||
distribute translations of the Document under the terms of section 4.
|
||||
Replacing Invariant Sections with translations requires special
|
||||
permission from their copyright holders, but you may include
|
||||
translations of some or all Invariant Sections in addition to the
|
||||
original versions of these Invariant Sections. You may include a
|
||||
translation of this License, and all the license notices in the
|
||||
Document, and any Warranty Disclaimers, provided that you also include
|
||||
the original English version of this License and the original versions
|
||||
of those notices and disclaimers. In case of a disagreement between
|
||||
the translation and the original version of this License or a notice
|
||||
or disclaimer, the original version will prevail.
|
||||
|
||||
If a section in the Document is Entitled "Acknowledgements",
|
||||
"Dedications", or "History", the requirement (section 4) to Preserve
|
||||
its Title (section 1) will typically require changing the actual
|
||||
title.
|
||||
|
||||
|
||||
9. TERMINATION
|
||||
|
||||
You may not copy, modify, sublicense, or distribute the Document
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense, or distribute it is void, and
|
||||
will automatically terminate your rights under this License.
|
||||
|
||||
However, if you cease all violation of this License, then your license
|
||||
from a particular copyright holder is reinstated (a) provisionally,
|
||||
unless and until the copyright holder explicitly and finally
|
||||
terminates your license, and (b) permanently, if the copyright holder
|
||||
fails to notify you of the violation by some reasonable means prior to
|
||||
60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, receipt of a copy of some or all of the same material does
|
||||
not give you any rights to use it.
|
||||
|
||||
|
||||
10. FUTURE REVISIONS OF THIS LICENSE
|
||||
|
||||
The Free Software Foundation may publish new, revised versions of the
|
||||
GNU Free Documentation License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in
|
||||
detail to address new problems or concerns. See
|
||||
http://www.gnu.org/copyleft/.
|
||||
|
||||
Each version of the License is given a distinguishing version number.
|
||||
If the Document specifies that a particular numbered version of this
|
||||
License "or any later version" applies to it, you have the option of
|
||||
following the terms and conditions either of that specified version or
|
||||
of any later version that has been published (not as a draft) by the
|
||||
Free Software Foundation. If the Document does not specify a version
|
||||
number of this License, you may choose any version ever published (not
|
||||
as a draft) by the Free Software Foundation. If the Document
|
||||
specifies that a proxy can decide which future versions of this
|
||||
License can be used, that proxy's public statement of acceptance of a
|
||||
version permanently authorizes you to choose that version for the
|
||||
Document.
|
||||
|
||||
11. RELICENSING
|
||||
|
||||
"Massive Multiauthor Collaboration Site" (or "MMC Site") means any
|
||||
World Wide Web server that publishes copyrightable works and also
|
||||
provides prominent facilities for anybody to edit those works. A
|
||||
public wiki that anybody can edit is an example of such a server. A
|
||||
"Massive Multiauthor Collaboration" (or "MMC") contained in the site
|
||||
means any set of copyrightable works thus published on the MMC site.
|
||||
|
||||
"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
|
||||
license published by Creative Commons Corporation, a not-for-profit
|
||||
corporation with a principal place of business in San Francisco,
|
||||
California, as well as future copyleft versions of that license
|
||||
published by that same organization.
|
||||
|
||||
"Incorporate" means to publish or republish a Document, in whole or in
|
||||
part, as part of another Document.
|
||||
|
||||
An MMC is "eligible for relicensing" if it is licensed under this
|
||||
License, and if all works that were first published under this License
|
||||
somewhere other than this MMC, and subsequently incorporated in whole or
|
||||
in part into the MMC, (1) had no cover texts or invariant sections, and
|
||||
(2) were thus incorporated prior to November 1, 2008.
|
||||
|
||||
The operator of an MMC Site may republish an MMC contained in the site
|
||||
under CC-BY-SA on the same site at any time before August 1, 2009,
|
||||
provided the MMC is eligible for relicensing.
|
||||
|
||||
|
||||
ADDENDUM: How to use this License for your documents
|
||||
|
||||
To use this License in a document you have written, include a copy of
|
||||
the License in the document and put the following copyright and
|
||||
license notices just after the title page:
|
||||
|
||||
Copyright (c) YEAR YOUR NAME.
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3
|
||||
or any later version published by the Free Software Foundation;
|
||||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||||
A copy of the license is included in the section entitled "GNU
|
||||
Free Documentation License".
|
||||
|
||||
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
|
||||
replace the "with...Texts." line with this:
|
||||
|
||||
with the Invariant Sections being LIST THEIR TITLES, with the
|
||||
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
|
||||
|
||||
If you have Invariant Sections without Cover Texts, or some other
|
||||
combination of the three, merge those two alternatives to suit the
|
||||
situation.
|
||||
|
||||
If your document contains nontrivial examples of program code, we
|
||||
recommend releasing these examples in parallel under your choice of
|
||||
free software license, such as the GNU General Public License,
|
||||
to permit their use in free software.
|
674
LICENSES/GPL.txt
Normal file
674
LICENSES/GPL.txt
Normal file
|
@ -0,0 +1,674 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
158
LISEZMOI.md
Normal file
158
LISEZMOI.md
Normal file
|
@ -0,0 +1,158 @@
|
|||
Copyright © 2015 CentraleSupélec
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3
|
||||
or any later version published by the Free Software Foundation;
|
||||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||||
|
||||
|
||||
An english version of this file is available (README.md)
|
||||
|
||||
Une version anglaise de ce fichier est disponible (README.md)
|
||||
|
||||
# Vidéo de démonstration #
|
||||
|
||||
[à cette addresse](https://archive.org/details/hand_control)
|
||||
|
||||
# Installation #
|
||||
|
||||
## Installation des dépendances ##
|
||||
```
|
||||
#!sh
|
||||
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu trusty main" > /etc/apt/sources.list.d/ros-latest.list'
|
||||
wget https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -O - | sudo apt-key add -
|
||||
sudo apt-get update
|
||||
sudo apt-get install ros-indigo-desktop-full ros-indigo-freenect-stack ros-indigo-ardrone-autonomy libncursesw5-dev
|
||||
```
|
||||
## Installation du paquet ##
|
||||
|
||||
### Création d’un espace de travail catkin ###
|
||||
|
||||
Par exemple :
|
||||
|
||||
```
|
||||
#!sh
|
||||
source /opt/ros/indigo/setup.bash
|
||||
mkdir -p ~/hand_control_ws/src
|
||||
cd ~/hand_control_ws/src
|
||||
catkin_init_workspace
|
||||
```
|
||||
|
||||
### Déplacement du code ###
|
||||
|
||||
Renommer si besoin est le dossier qui contient ce fichier en `hand_control`, et le déplacer dans `~/hand_control_ws/src/`, ou dans le sous-dossier `src` de votre espace de travail catkin.
|
||||
|
||||
## Compilation ##
|
||||
|
||||
Il est ensuite possible de compiler :
|
||||
|
||||
```
|
||||
#!sh
|
||||
cd ~/hand_control_ws # ou votre espace de travail catkin
|
||||
catkin_make
|
||||
```
|
||||
|
||||
Puis pour pouvoir utiliser les commandes ROS, en remplaçant si besoin "hand_control_ws" par votre espace de travail catkin :
|
||||
|
||||
```
|
||||
#!sh
|
||||
source /opt/ros/indigo/setup.bash
|
||||
source ~/hand_control_ws/devel/setup.bash
|
||||
echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
|
||||
echo "source ~/hand_control_ws/devel/setup.bash" >> ~/.bashrc
|
||||
```
|
||||
|
||||
# Utilisation #
|
||||
|
||||
## Branchement de la Kinect et paramétrage ##
|
||||
|
||||
1. Brancher la Kinect (sous tension) à l’ordinateur par USB ;
|
||||
2. Poser la Kinect sur le sol, pointant le plafond, votre bras devra être perpendiculaire à la Kinect pour pouvoir bien piloter le drone ;
|
||||
2. Lancer le "launchfile" kinect_commander.launch : `roslaunch hand_control kinect_commander.launch` ;
|
||||
3. Vérifier les paramètres du filtre :
|
||||
- lancer rviz : `rosrun rqt_rviz rqt_rviz`
|
||||
- visualiser la sortie du filtrage (topic : `/filter/output` ; frame : `/camera_depth_optical_frame`) et repérer la main ;
|
||||
- lancer rqt_reconfigure : `rosrun rqt_reconfigure rqt_reconfigure` pour :
|
||||
- modifier les paramètres du filtre jusqu’à ne voir que les points de la main/gant/pancarte sur rviz (voir ci-dessous).
|
||||
- modifier le paramètre `neutral_alt` du nœud `commander` à la hauteur souhaitée (en mètres). C’est la hauteur de la main qui correspondra à l’immobilité de l’altitude.
|
||||
|
||||
### Paramètres du filtre ###
|
||||
|
||||
Les paramètres du filtre (modifiables avec `dynamic_reconfigure` et en particulier `rqt_reconfigure`) sont :
|
||||
|
||||
* `z_max` : en mètres, altitude maximale de la main, doit être inférieure à la hauteur du plafond.
|
||||
* pour un gant ou un carton *coloré* (vert, bleu etc.), on a généralement :
|
||||
- `hue` : par exemple 220 (bleu ciel) ou 150 (vert) ou 0 (rose/rouge) ;
|
||||
- `delta_hue` : entre 10 et 20 ;
|
||||
- `sat/val_min` : 0.0 ;
|
||||
- `sat/val_max` : 1.0 ;
|
||||
* pour un gant *noir* :
|
||||
- `hue` : 0 ;
|
||||
- `delta_hue` : 180 ;
|
||||
- `sat_min` : 0.0 ;
|
||||
- `sat_max` : 1.0 ;
|
||||
- `val_min` : 0.0 ;
|
||||
- `val_max` : 0.3 (à modifier à votre convenance);
|
||||
|
||||
### Autres paramètres ###
|
||||
|
||||
Toujours avec `rqt_reconfigure`, cette fois pour le nœud `estimator` :
|
||||
- `reverse` : échange x et y (axes de la Kinect) (valeur par défaut pour une utilisation normale : faux [décoché])
|
||||
- `reverse_angle` : modifie l’axe choisi pour calculer l’angle de la main (valeur par défaut pour un utilisation normale : faux [décoché])
|
||||
|
||||
## Connexion au drone et pilotage ##
|
||||
|
||||
* Connecter l’ordinateur au réseau wifi du drone ;
|
||||
* Lancer le "launchfile" ardrone.launch : `roslaunch hand_control ardrone.launch` ;
|
||||
* Pour décoller :
|
||||
- soit `rostopic pub /ardrone/takeoff std_msgs/Empty` ;
|
||||
- soit lancer le nœud keyboard_cmd : `rosrun hand_control keyboard_cmd` et utiliser la touche *t* du clavier.
|
||||
* Pour atterrir :
|
||||
- soit `rostopic pub /ardrone/land std_msgs/Empty` ;
|
||||
- soit, avec keyboard_cmd, utiliser la touche *b* du clavier.
|
||||
* Arrêt d’urgence :
|
||||
- soit `rostopic pub /ardrone/reset std_msgs/Empty` ;
|
||||
- soit, avec keyboard_cmd, utiliser la touche *g* du clavier.
|
||||
|
||||
### Commande à la main ###
|
||||
|
||||
* Avancer/reculer & translations latérales : inclinaison de la main ;
|
||||
* Tourner (rotation autours de l’axe z) : angle de l’axe de la main avec l’axe parallèle au sol et perpendiculaire à la Kinect ;
|
||||
* Monter/descendre : altitude de la main.
|
||||
|
||||
### Options et paramètres de la commande ###
|
||||
|
||||
Pour éditer les options de la commande, lancer si ce n’est déjà fait `rosrun rqt_reconfigure rqt_reconfigure` :
|
||||
|
||||
- `max_curvature` : non utilisé pour l’instantt ;
|
||||
- `x/y/z/theta_minimal_deviation` : seuils à partir desquels le mouvement de la main est pris en compte. Tout mettre à 0.0 rend le comportement complétement linéaire.
|
||||
* x, y : entre 0. et 1. (il s’agit des composantes x et y de la normale au plan);
|
||||
* z : en mètre ;
|
||||
* theta : en degrés.
|
||||
- `neutral_alt` : hauteur de la main qui correspond à l’immobilité de l’altitude du drone ;
|
||||
- `min_points_number` : nombre minimal de points (du nuage de points qui a servi à régresser le plan reçu) nécessaire pour qu’une commande soit envoyé au drone.
|
||||
- `angle/x/y/z_vel` : coefficients de proportionnalité à appliquer aux données en entrée pour établir la commande envoyée au drone. Les augmenter augmentera la vitesse du drone.
|
||||
- `up_fact` : coefficient de proportionnalité à appliquer à la commande augmentant l’altitude du drone, par rapport à la commande équivalente la diminuant (pour corriger l’effet de la gravité).
|
||||
|
||||
### Notes sur `keyboard_cmd` ###
|
||||
|
||||
Il permet de publier des commandes sur le topic `cmd_vel` et ainsi de piloter le drone. Il est prévu pour les claviers azerty. Pour le lancer :
|
||||
|
||||
```
|
||||
#!sh
|
||||
rosrun hand_control keyboard_cmd
|
||||
```
|
||||
|
||||
Pour augmenter/diminuer les vitesses (expliqué sur l’affichage du programme) : touches a,z,e,r et w,x,c,v
|
||||
|
||||
L’affichage des informations reçues du drone n’est mise à jour qu’à l’occasion de l’appui sur une touche.
|
||||
|
||||
Pour quitter : Ctr+C, et appui sur "Entrée" pour retrouver l’affichage de la console.
|
||||
|
||||
# Problème(s) rencontré(s) — Améliorations souhaitables #
|
||||
|
||||
- Si des commandes sont publiées sur `cmd_vel` (depuis la Kinect par exemple) après le lancement du fichier `ardrone.launch` et avant le décollage du drone, alors, après le décollage, de drone semble obéir aux commandes publiées avant le décollage.
|
||||
|
||||
- Comme écrit plus haut, l’affichage des informations reçues du drone sur `keyboard_cmd` n’est mise à jour qu’à l’occasion de l’appui sur une touche, et peut donc rester fixe quand on n’utilise pas la commande au clavier.
|
||||
|
||||
- Le décollage/atterrissage n’est pas possible à commander avec la main. Il faut utiliser le clavier (`keyboard_cmd` ou `rostopic pub`) à la place. Il est possible de de remédier à cela en créant deux nouveaux seuils, minimaux et maximaux, pour la hauteur de la main : une main très basse ferait atterrir le drone, une main très haute le ferait décoller.
|
156
README.md
156
README.md
|
@ -1,6 +1,26 @@
|
|||
[![Build Status](https://travis-ci.org/LGD-Fr/hand_control.svg)](https://travis-ci.org/LGD-Fr/hand_control)
|
||||
|
||||
Copyright © 2015 CentraleSupélec
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3
|
||||
or any later version published by the Free Software Foundation;
|
||||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||||
|
||||
|
||||
La documentation originale est en français : LISEZMOI.md. La documentation ci-dessous n’est qu’une traduction.
|
||||
|
||||
The original manual is the french "LISEZMOI.md", you read below a translation of this file.
|
||||
|
||||
# Video demonstration #
|
||||
|
||||
A video demonstration is [available here](https://archive.org/details/hand_control). It has been achived with a student who didn't know how the project works.
|
||||
|
||||
# Installation #
|
||||
|
||||
## Installation des dépendances ##
|
||||
This package was developped with the Indigo version of ROS.
|
||||
|
||||
## Dependencies installation ##
|
||||
```
|
||||
#!sh
|
||||
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu trusty main" > /etc/apt/sources.list.d/ros-latest.list'
|
||||
|
@ -8,11 +28,11 @@ wget https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -O - | sudo
|
|||
sudo apt-get update
|
||||
sudo apt-get install ros-indigo-desktop-full ros-indigo-freenect-stack ros-indigo-ardrone-autonomy libncursesw5-dev
|
||||
```
|
||||
## Installation du paquet ##
|
||||
## Package installation ##
|
||||
|
||||
### Création d’un espace de travail catkin ###
|
||||
### Catkin workspace creation ###
|
||||
|
||||
Par exemple :
|
||||
For instance :
|
||||
|
||||
```
|
||||
#!sh
|
||||
|
@ -22,21 +42,21 @@ cd ~/hand_control_ws/src
|
|||
catkin_init_workspace
|
||||
```
|
||||
|
||||
### Déplacement du code ###
|
||||
### Code location ###
|
||||
|
||||
Renommer si besoin est le dossier qui contient ce fichier en `hand_control`, et le déplacer dans `~/hand_control_ws/src/`, ou dans le sous-dossier `src` de votre espace de travail catkin.
|
||||
If necessary, rename the folder with the file named `hand_control`, and move it in `~/hand_control_ws/src/` or in the subfolder `src` of your catkin workspace.
|
||||
|
||||
## Compilation ##
|
||||
|
||||
Il est ensuite possible de compiler :
|
||||
You're now able to compile :
|
||||
|
||||
```
|
||||
#!sh
|
||||
cd ~/hand_control_ws # ou votre espace de travail catkin
|
||||
cd ~/hand_control_ws # or your catkin workspace
|
||||
catkin_make
|
||||
```
|
||||
|
||||
Puis pour pouvoir utiliser les commandes ROS, en remplaçant si besoin "hand_control_ws" par votre espace de travail catkin :
|
||||
Then you can run the following commands to be able to use the ROS commands. If necessary replace "hand_control_ws" by the name of your catkin workspace.
|
||||
|
||||
```
|
||||
#!sh
|
||||
|
@ -46,97 +66,97 @@ echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
|
|||
echo "source ~/hand_control_ws/devel/setup.bash" >> ~/.bashrc
|
||||
```
|
||||
|
||||
# Utilisation #
|
||||
# Use #
|
||||
|
||||
## Branchement de la Kinect et paramétrage ##
|
||||
## Connection and setting up of the Kinect ##
|
||||
|
||||
1. Brancher la Kinect (sous tension) à l’ordinateur par USB ;
|
||||
2. Poser la Kinect sur le sol, pointant le plafond, votre bras devra être perpendiculaire à la Kinect pour pouvoir bien piloter le drone ;
|
||||
2. Lancer le "launchfile" kinect_commander.launch : `roslaunch hand_control kinect_commander.launch` ;
|
||||
3. Vérifier les paramètres du filtre :
|
||||
- lancer rviz : `rosrun rqt_rviz rqt_rviz`
|
||||
- visualiser la sortie du filtrage (topic : `/filter/output` ; frame : `/camera_depth_optical_frame`) et repérer la main ;
|
||||
- lancer rqt_reconfigure : `rosrun rqt_reconfigure rqt_reconfigure` pour :
|
||||
- modifier les paramètres du filtre jusqu’à ne voir que les points de la main/gant/pancarte sur rviz (voir ci-dessous).
|
||||
- modifier le paramètre `neutral_alt` du nœud `commander` à la hauteur souhaitée (en mètres). C’est la hauteur de la main qui correspondra à l’immobilité de l’altitude.
|
||||
1. Connect the Kinect (under voltage) to the computer via USB ;
|
||||
2. Put the Kinect on the ground, pointed toward the roof ; be aware that your arm must be perpendicular to the Kinect in order to control the drone properly ;
|
||||
2. Launch the "launchfile" kinect_commander.launch : `roslaunch hand_control kinect_commander.launch` ;
|
||||
3. Check the drone parameters :
|
||||
- launch rviz : `rosrun rqt_rviz rqt_rviz`
|
||||
- display the output of the filtering (topic : `/filter/output` ; frame : `/camera_depth_optical_frame`) and locate the hand ;
|
||||
- launch rqt_reconfigure : `rosrun rqt_reconfigure rqt_reconfigure` in order to :
|
||||
- change the filter parameters until you only see the points of the hand/glove/panel on rviz (see above).
|
||||
- change the parameter `neutral_alt` of the node `commander` to the wanted height (in meters), correponding to the height of the hand for which the height of the drone will be stable.
|
||||
|
||||
### Paramètres du filtre ###
|
||||
### Parameters of the filter ###
|
||||
|
||||
Les paramètres du filtre (modifiables avec `dynamic_reconfigure` et en particulier `rqt_reconfigure`) sont :
|
||||
The parameters of the filter (that can be changed thanks to `dynamic_reconfigure` and in particular `rqt_reconfigure`) are :
|
||||
|
||||
* `z_max` : en mètres, altitude maximale de la main, doit être inférieure à la hauteur du plafond.
|
||||
* pour un gant ou un carton *coloré* (vert, bleu etc.), on a généralement :
|
||||
- `hue` : par exemple 220 (bleu ciel) ou 150 (vert) ou 0 (rose/rouge) ;
|
||||
- `delta_hue` : entre 10 et 20 ;
|
||||
* `z_max` : in meters, maximal height of the hand. It must be lower than the height of the roof.
|
||||
* for a glove or a *colored* panel (green, blue, etc.), we generaly have :
|
||||
- `hue` : for example 220 (sky blue) or 150 (green) or 0 (pink/red) ;
|
||||
- `delta_hue` : between 10 and 20 ;
|
||||
- `sat/val_min` : 0.0 ;
|
||||
- `sat/val_max` : 1.0 ;
|
||||
* pour un gant *noir* :
|
||||
* for a *black* glove :
|
||||
- `hue` : 0 ;
|
||||
- `delta_hue` : 180 ;
|
||||
- `sat_min` : 0.0 ;
|
||||
- `sat_max` : 1.0 ;
|
||||
- `val_min` : 0.0 ;
|
||||
- `val_max` : 0.3 (à modifier à votre convenance);
|
||||
- `val_max` : 0.3 (at your convenience);
|
||||
|
||||
### Autres paramètres ###
|
||||
### Other parameters ###
|
||||
|
||||
Toujours avec `rqt_reconfigure`, cette fois pour le nœud `estimator` :
|
||||
- `reverse` : échange x et y (axes de la Kinect) (valeur par défaut pour une utilisation normale : faux [décoché])
|
||||
- `reverse_angle` : modifie l’axe choisi pour calculer l’angle de la main (valeur par défaut pour un utilisation normale : faux [décoché])
|
||||
Always with `rqt_reconfigure`, but with the `estimator` node :
|
||||
- `reverse` : swap x and y, the axes of the Kinect (default : false, ie. unchecked)
|
||||
- `reverse_angle` : change the angle choosen for the compute of the angle of the hand (default : false, ie. unchecked)
|
||||
|
||||
## Connexion au drone et pilotage ##
|
||||
## Connection to the drone and steering ##
|
||||
|
||||
* Connecter l’ordinateur au réseau wifi du drone ;
|
||||
* Lancer le "launchfile" ardrone.launch : `roslaunch hand_control ardrone.launch` ;
|
||||
* Pour décoller :
|
||||
- soit `rostopic pub /ardrone/takeoff std_msgs/Empty` ;
|
||||
- soit lancer le nœud keyboard_cmd : `rosrun hand_control keyboard_cmd` et utiliser la touche *t* du clavier.
|
||||
* Pour atterrir :
|
||||
- soit `rostopic pub /ardrone/land std_msgs/Empty` ;
|
||||
- soit, avec keyboard_cmd, utiliser la touche *b* du clavier.
|
||||
* Arrêt d’urgence :
|
||||
- soit `rostopic pub /ardrone/reset std_msgs/Empty` ;
|
||||
- soit, avec keyboard_cmd, utiliser la touche *g* du clavier.
|
||||
* Connect the computer to the wifi network of the drone ;
|
||||
* Launch the "launchfile" ardrone.launch : `roslaunch hand_control ardrone.launch` ;
|
||||
* Taking off :
|
||||
- whether `rostopic pub /ardrone/takeoff std_msgs/Empty` ;
|
||||
- or launch the node keyboard_cmd : `rosrun hand_control keyboard_cmd` and use *t* on the keyboard.
|
||||
* Landing :
|
||||
- whether `rostopic pub /ardrone/land std_msgs/Empty` ;
|
||||
- or, launch the node keyboard_cmd, and use *b* on the keyboard.
|
||||
* Emergency stop :
|
||||
- whether `rostopic pub /ardrone/reset std_msgs/Empty` ;
|
||||
- or, launch the node keyboard_cmd, and use *g* on the keyboard.
|
||||
|
||||
### Commande à la main ###
|
||||
### Hand steering ###
|
||||
|
||||
* Avancer/reculer & translations latérales : inclinaison de la main ;
|
||||
* Tourner (rotation autours de l’axe z) : angle de l’axe de la main avec l’axe parallèle au sol et perpendiculaire à la Kinect ;
|
||||
* Monter/descendre : altitude de la main.
|
||||
* Forward/backward & side translations : hand tilt ;
|
||||
* Rotate (around the vertical axis z) : angle of the hand with the the axis parallel to the ground and perpendicular to the kinect ;
|
||||
* go up/go down : hand height.
|
||||
|
||||
### Options et paramètres de la commande ###
|
||||
### Options and parameters of the command ###
|
||||
|
||||
Pour éditer les options de la commande, lancer si ce n’est déjà fait `rosrun rqt_reconfigure rqt_reconfigure` :
|
||||
To edit the options of the command, change (if not already) `rosrun rqt_reconfigure rqt_reconfigure` :
|
||||
|
||||
- `max_curvature` : non utilisé pour l’instantt ;
|
||||
- `x/y/z/theta_minimal_deviation` : seuils à partir desquels le mouvement de la main est pris en compte. Tout mettre à 0.0 rend le comportement complétement linéaire.
|
||||
* x, y : entre 0. et 1. (il s’agit des composantes x et y de la normale au plan);
|
||||
* z : en mètre ;
|
||||
* theta : en degrés.
|
||||
- `neutral_alt` : hauteur de la main qui correspond à l’immobilité de l’altitude du drone ;
|
||||
- `min_points_number` : nombre minimal de points (du nuage de points qui a servi à régresser le plan reçu) nécessaire pour qu’une commande soit envoyé au drone.
|
||||
- `angle/x/y/z_vel` : coefficients de proportionnalité à appliquer aux données en entrée pour établir la commande envoyée au drone. Les augmenter augmentera la vitesse du drone.
|
||||
- `up_fact` : coefficient de proportionnalité à appliquer à la commande augmentant l’altitude du drone, par rapport à la commande équivalente la diminuant (pour corriger l’effet de la gravité).
|
||||
- `max_curvature` : not used for the moment ;
|
||||
- `x/y/z/theta_minimal_deviation` : thresholds required above which the movement of the hand is not taken into account. If all are 0.0, the drone responds linearly.
|
||||
* x, y : between 0. and 1. (corresponding to the x and y of the normal to the plane);
|
||||
* z : in meters ;
|
||||
* theta : in degrees.
|
||||
- `neutral_alt` : height of the hand for the immobility of the height of the drone ;
|
||||
- `min_points_number` : minimal number of points (for the point cloud used for the regression) necessary in order to send a command to the drone ;
|
||||
- `angle/x/y/z_vel` : proportionality coefficients to apply to the inputs in order to establish the command sent to the drone. Increase it will increase the speed of the drone ;
|
||||
- `up_fact` : proportionality coefficients to apply to the command that increases the height of the drone, compared to the equivalent command to reduce it (in order to correct the effect of gravity).
|
||||
|
||||
### Notes sur `keyboard_cmd` ###
|
||||
### About `keyboard_cmd` ###
|
||||
|
||||
Il permet de publier des commandes sur le topic `cmd_vel` et ainsi de piloter le drone. Il est prévu pour les claviers azerty. Pour le lancer :
|
||||
It allows you to publish commands on the topic `cmd_vel` and so to steer the drone. It is scheduled for azerty keyboards. To launch it, run :
|
||||
|
||||
```
|
||||
#!sh
|
||||
rosrun hand_control keyboard_cmd
|
||||
```
|
||||
|
||||
Pour augmenter/diminuer les vitesses (expliqué sur l’affichage du programme) : touches a,z,e,r et w,x,c,v
|
||||
To increase/decrease the speed (there is an explication on the controlpanel) : a,z,e,r and w,x,c,v
|
||||
|
||||
L’affichage des informations reçues du drone n’est mise à jour qu’à l’occasion de l’appui sur une touche.
|
||||
The informations of the drone are updated when a key is pressed.
|
||||
|
||||
Pour quitter : Ctr+C, et appui sur "Entrée" pour retrouver l’affichage de la console.
|
||||
To quit : CTRL+C and press "Enter" to return to the console.
|
||||
|
||||
# Problème(s) rencontré(s) — Améliorations souhaitables #
|
||||
# Problems - Possible improvements #
|
||||
|
||||
- Si des commandes sont publiées sur `cmd_vel` (depuis la Kinect par exemple) après le lancement du fichier `ardrone.launch` et avant le décollage du drone, alors, après le décollage, de drone semble obéir aux commandes publiées avant le décollage.
|
||||
- If commands are published on `cmd_vel` (from the Kinect for instance) after the launch of `ardrone.launch` and before the takeoff, then, after the takeoff, the drone seems to obey to commands published before the takeoff.
|
||||
|
||||
- Comme écrit plus haut, l’affichage des informations reçues du drone sur `keyboard_cmd` n’est mise à jour qu’à l’occasion de l’appui sur une touche, et peut donc rester fixe quand on n’utilise pas la commande au clavier.
|
||||
- As written above, the display of navigation data on `keyboard_cmd` is only updated when a key is pressed, and can therefore stay fixed when the keyboard commander is not used.
|
||||
|
||||
- Le décollage/atterrissage n’est pas possible à commander avec la main. Il faut utiliser le clavier (`keyboard_cmd` ou `rostopic pub`) à la place. Il est possible de de remédier à cela en créant deux nouveaux seuils, minimaux et maximaux, pour la hauteur de la main : une main très basse ferait atterrir le drone, une main très haute le ferait décoller.
|
||||
- The takeoff/landing is not controllable with the hand. The keyboard must be used (`keyboard_cmd` or `rostopic pub`) instead. We can correct this by creating two new thresholds, minimal and maximal, for the hand height : a very low hand would make the drone land and a very high hand would make the drone take off.
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright © 2015 CentraleSupélec
|
||||
#
|
||||
# This file is part of Hand Control.
|
||||
#
|
||||
# Hand Control is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Hand Control 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 General Public License
|
||||
# along with Hand Control. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
PACKAGE = "hand_control"
|
||||
from dynamic_reconfigure.parameter_generator_catkin import *
|
||||
gen = ParameterGenerator()
|
||||
|
@ -14,4 +33,5 @@ gen.add("angle_vel", double_t, 0, "Angular velocity", 0.01, 0., 10.)
|
|||
gen.add("x_vel", double_t, 0, "X Translation velocity", 0.5, 0., 10.)
|
||||
gen.add("y_vel", double_t, 0, "Y Translation velocity", 0.3, 0., 10.)
|
||||
gen.add("z_vel", double_t, 0, "Vertical translation velocity", 1.5, 0., 10.)
|
||||
gen.add("no_diag", bool_t, 0, "Drone cannot translate on a diagonal direction", True)
|
||||
exit(gen.generate(PACKAGE, "hand_control", "Commander"))
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
PACKAGE = "hand_control"
|
||||
from dynamic_reconfigure.parameter_generator_catkin import *
|
||||
gen = ParameterGenerator()
|
||||
gen.add("max_curvature", double_t, 0, "Maximum curvature of the estimated plane", 0.5, 0., 1.)
|
||||
gen.add("neutral_alt", double_t, 0, "Reference altitude for vertical movement command", 0.8, 0.)
|
||||
gen.add("min_points_number", int_t, 0, "Minimal number of plane points needed for a valid estimation", 1000, 0, 50000)
|
||||
gen.add("x_p", double_t, 0, "x gradient in 0", 0.5, 0.)
|
||||
gen.add("x_min", double_t, 0, "min x coord to be published", 0.1, 0., 1.)
|
||||
gen.add("x_max", double_t, 0, "max x coord to be published", 0.8, 0., 1.)
|
||||
gen.add("y_p", double_t, 0, "y gradient in 0", 0.5, 0.)
|
||||
gen.add("y_min", double_t, 0, "min y coord to be published", 0.1, 0., 1.)
|
||||
gen.add("y_max", double_t, 0, "max y coord to be published", 0.8, 0., 1.)
|
||||
gen.add("z_p", double_t, 0, "z gradient in 0", 1, 0.)
|
||||
gen.add("z_min", double_t, 0, "min z coord to be published", 0.1, 0., 1.)
|
||||
gen.add("z_max", double_t, 0, "max z coord to be published", 0.8, 0., 1.)
|
||||
gen.add("th_p", double_t, 0, "th gradient in 0", 0.005, 0.)
|
||||
gen.add("th_min", double_t, 0, "min th coord to be published", 0.1, 0., 1.)
|
||||
gen.add("th_max", double_t, 0, "max th coord to be published", 0.8, 0., 1.)
|
||||
gen.add("atan", bool_t, 0, "use atan function instead of linear function", False)
|
||||
exit(gen.generate(PACKAGE, "hand_control", "Commander_atan"))
|
|
@ -1,4 +1,23 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright © 2015 CentraleSupélec
|
||||
#
|
||||
# This file is part of Hand Control.
|
||||
#
|
||||
# Hand Control is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Hand Control 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 General Public License
|
||||
# along with Hand Control. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
PACKAGE = "hand_control"
|
||||
from dynamic_reconfigure.parameter_generator_catkin import *
|
||||
gen = ParameterGenerator()
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright © 2015 CentraleSupélec
|
||||
#
|
||||
# This file is part of Hand Control.
|
||||
#
|
||||
# Hand Control is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Hand Control 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 General Public License
|
||||
# along with Hand Control. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
PACKAGE = "hand_control"
|
||||
from dynamic_reconfigure.parameter_generator_catkin import *
|
||||
gen = ParameterGenerator()
|
||||
|
|
BIN
compte-rendu.pdf
Normal file
BIN
compte-rendu.pdf
Normal file
Binary file not shown.
|
@ -1,3 +1,21 @@
|
|||
<!--
|
||||
Copyright © 2015 CentraleSupélec
|
||||
|
||||
This file is part of Hand Control.
|
||||
|
||||
Hand Control is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Hand Control 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 General Public License
|
||||
along with Hand Control. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<!-- cf ARDrone Developer Guide -->
|
||||
<launch>
|
||||
<node name="ardrone_driver" pkg="ardrone_autonomy" type="ardrone_driver" output="screen" clear_params="true">
|
||||
|
@ -40,4 +58,3 @@
|
|||
<rosparam param="cov/imu_or">[1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 100000.0]</rosparam>
|
||||
</node>
|
||||
</launch>
|
||||
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
<!--
|
||||
Copyright © 2015 CentraleSupélec
|
||||
|
||||
This file is part of Hand Control.
|
||||
|
||||
Hand Control is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Hand Control 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 General Public License
|
||||
along with Hand Control. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<launch>
|
||||
<include file="$(find freenect_launch)/launch/freenect.launch">
|
||||
|
||||
|
|
|
@ -1,4 +1,21 @@
|
|||
<!--
|
||||
Copyright © 2015 CentraleSupélec
|
||||
|
||||
This file is part of Hand Control.
|
||||
|
||||
Hand Control is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Hand Control 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 General Public License
|
||||
along with Hand Control. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<launch>
|
||||
<include file="$(find hand_control)/launch/freenect-registered-xyzrgb.launch"/>
|
||||
|
||||
|
@ -13,5 +30,4 @@
|
|||
<node name="commander" pkg="hand_control" type="commander">
|
||||
<remap from="/commander/input" to="/estimator/output"/>
|
||||
</node>
|
||||
|
||||
</launch>
|
||||
|
|
39
package.xml
39
package.xml
|
@ -1,38 +1,33 @@
|
|||
<?xml version="1.0"?>
|
||||
<package>
|
||||
<package format="2">
|
||||
<name>hand_control</name>
|
||||
<version>1.0.0</version>
|
||||
<description>Contrôle d’un drone "Parrot AR Drone" par les mouvements de la main mesurés par une Kinect</description>
|
||||
<version>1.1.0</version>
|
||||
<description>
|
||||
Controling a "Parrot AR Drone" with the hand movements measured by a Microsoft Kinect sensor.
|
||||
</description>
|
||||
<license>GPLv3+</license>
|
||||
|
||||
<maintainer email="luc.absil@supelec.fr">Luc ABSIL</maintainer>
|
||||
<maintainer email="contact@lgdubois.fr">Louis-Guillaume DUBOIS</maintainer>
|
||||
<maintainer email="paul.janin@supelec.fr">Paul JANIN</maintainer>
|
||||
|
||||
<license>BSD</license>
|
||||
|
||||
<author email="luc.absil@supelec.fr">Luc ABSIL</author>
|
||||
<author email="contact@lgdubois.fr">Louis-Guillaume DUBOIS</author>
|
||||
<author email="paul.janin@supelec.fr">Paul JANIN</author>
|
||||
|
||||
<buildtool_depend>catkin</buildtool_depend>
|
||||
|
||||
<build_depend>pcl_ros</build_depend>
|
||||
<build_depend>pcl_msgs</build_depend>
|
||||
<build_depend>roscpp</build_depend>
|
||||
<build_depend>std_msgs</build_depend>
|
||||
<build_depend>geometry_msgs</build_depend>
|
||||
<depend>pcl_ros</depend>
|
||||
<depend>pcl_msgs</depend>
|
||||
<depend>roscpp</depend>
|
||||
<depend>std_msgs</depend>
|
||||
<depend>geometry_msgs</depend>
|
||||
<depend>dynamic_reconfigure</depend>
|
||||
|
||||
<build_depend>message_generation</build_depend>
|
||||
<build_depend>dynamic_reconfigure</build_depend>
|
||||
|
||||
<run_depend>pcl_ros</run_depend>
|
||||
<run_depend>pcl_msgs</run_depend>
|
||||
<run_depend>roscpp</run_depend>
|
||||
<run_depend>std_msgs</run_depend>
|
||||
<run_depend>geometry_msgs</run_depend>
|
||||
<run_depend>message_runtime</run_depend>
|
||||
<run_depend>ardrone_autonomy</run_depend>
|
||||
<run_depend>freenect_launch</run_depend>
|
||||
<run_depend>dynamic_reconfigure</run_depend>
|
||||
<run_depend>rqt_reconfigure</run_depend>
|
||||
|
||||
<exec_depend>message_runtime</exec_depend>
|
||||
<exec_depend>ardrone_autonomy</exec_depend>
|
||||
<exec_depend>freenect_launch</exec_depend>
|
||||
<exec_depend>rqt_reconfigure</exec_depend>
|
||||
</package>
|
||||
|
|
|
@ -1,150 +1,158 @@
|
|||
#include <ros/ros.h>
|
||||
#include <ros/time.h>
|
||||
#include <locale.h>
|
||||
#include <limits>
|
||||
/* Copyright © 2015 CentraleSupélec
|
||||
*
|
||||
* This file is part of Hand Control.
|
||||
*
|
||||
* Hand Control is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hand Control 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 General Public License
|
||||
* along with Hand Control. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include <ros/ros.h>
|
||||
#include <ros/time.h>
|
||||
|
||||
#include <pcl_ros/point_cloud.h>
|
||||
#include <pcl/point_types.h>
|
||||
|
||||
#include <hand_control/Plan.h>
|
||||
#include <geometry_msgs/Twist.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <dynamic_reconfigure/server.h>
|
||||
#include <hand_control/CommanderConfig.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
class Run
|
||||
{
|
||||
private:
|
||||
float xx, yy, zz, theta;
|
||||
// xx < 0 : forward
|
||||
// xx > 0 : backward
|
||||
|
||||
// yy > 0 : right
|
||||
// yy < 0 : left
|
||||
class Run {
|
||||
private:
|
||||
float xx, yy, zz, theta; // read coords
|
||||
|
||||
// zz > 0 : up
|
||||
// zz < 0 : down
|
||||
|
||||
float x_vel, y_vel, z_vel, angle_vel, up_factor, neutral_z;
|
||||
|
||||
float max_curv;
|
||||
float z_dev_min, x_dev_min, y_dev_min, th_dev_min;
|
||||
uint64_t min_number;
|
||||
|
||||
bool first_msg;
|
||||
// see README.md to know what are the parameters
|
||||
float x_vel, y_vel, z_vel, angle_vel,
|
||||
up_factor, neutral_z; // parameters
|
||||
float max_curv; // not used yet
|
||||
float z_dev_min, x_dev_min, y_dev_min,
|
||||
th_dev_min; // parameters : thresholds
|
||||
uint64_t min_number; // parameter
|
||||
bool no_diag; // parameter
|
||||
|
||||
ros::Publisher pub;
|
||||
|
||||
void publish()
|
||||
{
|
||||
geometry_msgs::Twist::Ptr mvt(new geometry_msgs::Twist());
|
||||
void publish() {
|
||||
// build and publish a message from the "xx",
|
||||
// "yy", "zz" and "theta" informations
|
||||
geometry_msgs::Twist::Ptr mvt(new geometry_msgs::Twist());
|
||||
|
||||
if (fabs(zz) > z_dev_min)
|
||||
{
|
||||
if (zz > 0)
|
||||
mvt->linear.z = zz * z_vel * up_factor ;
|
||||
else
|
||||
mvt->linear.z = zz * z_vel;
|
||||
}
|
||||
|
||||
if (fabs(yy) > fabs(xx) && fabs(yy) > y_dev_min)
|
||||
{
|
||||
mvt->linear.y = yy * y_vel;
|
||||
}
|
||||
else if (fabs(xx) > x_dev_min)
|
||||
{
|
||||
mvt->linear.x = - xx * x_vel;
|
||||
}
|
||||
|
||||
if (fabs(theta) > th_dev_min) {
|
||||
mvt->angular.z = theta * angle_vel;
|
||||
}
|
||||
|
||||
assert(mvt->linear.x == 0. || mvt->linear.y == 0.);
|
||||
pub.publish(mvt);
|
||||
ROS_INFO("cmd published");
|
||||
}//end publish
|
||||
|
||||
public:
|
||||
Run(const ros::Publisher& cmd_publisher) :
|
||||
pub(cmd_publisher)
|
||||
{
|
||||
}
|
||||
|
||||
void callback(const hand_control::Plan::ConstPtr& msg)
|
||||
{
|
||||
ROS_INFO("plan received");
|
||||
if (msg->curvature < max_curv && msg->number > min_number)
|
||||
{
|
||||
|
||||
if(msg->normal.z > 0)
|
||||
{
|
||||
yy = msg->normal.x;
|
||||
xx = msg->normal.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
yy = - msg->normal.x;
|
||||
xx = - msg->normal.y;
|
||||
if (fabs(zz) > z_dev_min) {
|
||||
// up_factor to balance out the gravity effect
|
||||
if (zz > 0)
|
||||
mvt->linear.z = zz * z_vel * up_factor;
|
||||
else
|
||||
mvt->linear.z = zz * z_vel;
|
||||
}
|
||||
|
||||
zz = msg->altitude - neutral_z;
|
||||
|
||||
theta = msg->angle;
|
||||
// theta between -90 and 90
|
||||
|
||||
if (first_msg)
|
||||
{
|
||||
first_msg = false;
|
||||
ROS_INFO("first msg received");
|
||||
// no_diag true : the drone can only translate on the "x" axis
|
||||
// or the "y" axis but not on a linear combination of these axes.
|
||||
if (no_diag) {
|
||||
if (fabs(yy) > fabs(xx) && fabs(yy) > y_dev_min)
|
||||
mvt->linear.y = yy * y_vel;
|
||||
else if (fabs(xx) > x_dev_min)
|
||||
mvt->linear.x = - xx * x_vel;
|
||||
} else {
|
||||
// no_diag false : the drone can translate on any possible direction
|
||||
if (fabs(yy) > y_dev_min)
|
||||
mvt->linear.y = yy * y_vel;
|
||||
if (fabs(xx) > x_dev_min)
|
||||
mvt->linear.x = - xx * x_vel;
|
||||
}
|
||||
ROS_INFO("coords updated");
|
||||
} else {
|
||||
xx = yy = zz = 0.;
|
||||
}
|
||||
publish();
|
||||
};
|
||||
|
||||
void reconfigure(const hand_control::CommanderConfig& c, const uint32_t& level) {
|
||||
max_curv = c.max_curvature;
|
||||
x_dev_min = c.x_minimal_deviation;
|
||||
y_dev_min = c.y_minimal_deviation;
|
||||
z_dev_min = c.z_minimal_deviation;
|
||||
th_dev_min = c.theta_minimal_deviation;
|
||||
neutral_z = c.neutral_alt;
|
||||
min_number = c.min_points_number;
|
||||
up_factor = c.up_fact;
|
||||
x_vel = c.x_vel;
|
||||
y_vel = c.y_vel;
|
||||
z_vel = c.z_vel;
|
||||
angle_vel = c.angle_vel;
|
||||
}
|
||||
if (fabs(theta) > th_dev_min) {
|
||||
mvt->angular.z = theta * angle_vel;
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
ros::spin();
|
||||
pub.publish(mvt);
|
||||
ROS_INFO("cmd published");
|
||||
}
|
||||
|
||||
public:
|
||||
explicit Run(const ros::Publisher& cmd_publisher) :
|
||||
pub(cmd_publisher) {}
|
||||
|
||||
// handle received messages
|
||||
void callback(const hand_control::Plan::ConstPtr& msg) {
|
||||
ROS_INFO("plan received");
|
||||
|
||||
// we ever have msg->curvature == 0 in fact (not implemented yet)
|
||||
if (msg->curvature < max_curv && msg->number > min_number) {
|
||||
if (msg->normal.z > 0) {
|
||||
yy = msg->normal.x;
|
||||
xx = msg->normal.y;
|
||||
} else {
|
||||
yy = - msg->normal.x;
|
||||
xx = - msg->normal.y;
|
||||
}
|
||||
zz = msg->altitude - neutral_z;
|
||||
theta = msg->angle;
|
||||
// theta between -90 and 90
|
||||
ROS_INFO("coords updated");
|
||||
} else {
|
||||
xx = yy = zz = 0.;
|
||||
}
|
||||
publish();
|
||||
}
|
||||
|
||||
// updates the parameters (received with dynamic_reconfigure)
|
||||
void reconfigure(const hand_control::CommanderConfig& c,
|
||||
const uint32_t& level) {
|
||||
max_curv = c.max_curvature;
|
||||
x_dev_min = c.x_minimal_deviation;
|
||||
y_dev_min = c.y_minimal_deviation;
|
||||
z_dev_min = c.z_minimal_deviation;
|
||||
th_dev_min = c.theta_minimal_deviation;
|
||||
neutral_z = c.neutral_alt;
|
||||
min_number = c.min_points_number;
|
||||
up_factor = c.up_fact;
|
||||
x_vel = c.x_vel;
|
||||
y_vel = c.y_vel;
|
||||
z_vel = c.z_vel;
|
||||
angle_vel = c.angle_vel;
|
||||
no_diag = c.no_diag;
|
||||
}
|
||||
|
||||
// runs the callbacks and publications process
|
||||
void run() {
|
||||
ros::spin();
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
ros::init(argc, argv, "commander");
|
||||
ros::NodeHandle node("commander");
|
||||
int main(int argc, char** argv) {
|
||||
ros::init(argc, argv, "commander");
|
||||
ros::NodeHandle node("commander");
|
||||
ros::Publisher cmd_pub =\
|
||||
node.advertise<geometry_msgs::Twist>("/cmd_vel", 1);
|
||||
Run run(cmd_pub);
|
||||
ros::Subscriber plan_sub =\
|
||||
node.subscribe<hand_control::Plan>("input", 1, &Run::callback, &run);
|
||||
|
||||
ros::Publisher cmd_pub = node.advertise<geometry_msgs::Twist>("/cmd_vel", 1);
|
||||
Run run(cmd_pub);
|
||||
ros::Subscriber plan_sub = node.subscribe<hand_control::Plan>("input", 1, &Run::callback, &run);
|
||||
// setting up dynamic_reconfigure (for rqt_reconfigure)
|
||||
dynamic_reconfigure::Server<hand_control::CommanderConfig> server;
|
||||
dynamic_reconfigure::Server<hand_control::CommanderConfig>::CallbackType f;
|
||||
f = boost::bind(&Run::reconfigure, &run, _1, _2);
|
||||
server.setCallback(f);
|
||||
|
||||
dynamic_reconfigure::Server<hand_control::CommanderConfig> server;
|
||||
dynamic_reconfigure::Server<hand_control::CommanderConfig>::CallbackType f;
|
||||
f = boost::bind(&Run::reconfigure, &run, _1, _2);
|
||||
server.setCallback(f);
|
||||
|
||||
run.run();
|
||||
return 0;
|
||||
// starts working
|
||||
run.run();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,187 +0,0 @@
|
|||
// this code doesn’t work
|
||||
// :-(
|
||||
#include <ros/ros.h>
|
||||
#include <ros/time.h>
|
||||
#include <locale.h>
|
||||
#include <limits>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <pcl_ros/point_cloud.h>
|
||||
#include <pcl/point_types.h>
|
||||
|
||||
#include <hand_control/Plan.h>
|
||||
#include <geometry_msgs/Twist.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <dynamic_reconfigure/server.h>
|
||||
#include <hand_control/Commander_atanConfig.h>
|
||||
#include "data.h"
|
||||
|
||||
class Run
|
||||
{
|
||||
private:
|
||||
|
||||
enum FType { f_lin, f_atan, f_undef };
|
||||
|
||||
class Function
|
||||
{
|
||||
private:
|
||||
virtual void set_grad(const float& grad) = 0;
|
||||
protected:
|
||||
float min, max;
|
||||
FType type;
|
||||
public:
|
||||
Function() : min(0.1f), max(0.8f) {}
|
||||
virtual float f(const float& arg) = 0;
|
||||
void set(const float& minimum, const float& maximum, const float& grad)
|
||||
{
|
||||
min = minimum;
|
||||
max = maximum;
|
||||
set_grad(grad);
|
||||
}
|
||||
FType get_type() { return type; }
|
||||
};
|
||||
|
||||
class Atan : public Function
|
||||
{
|
||||
private:
|
||||
static const float demi_pi;
|
||||
float t;
|
||||
virtual void set_grad(const float& grad)
|
||||
{
|
||||
t = grad*demi_pi/max;
|
||||
}
|
||||
public:
|
||||
Atan() :t(demi_pi) { type = f_atan; }
|
||||
virtual float f(const float& arg)
|
||||
{
|
||||
float out = max * atan(t * arg) / demi_pi;
|
||||
if (fabs(out) > min)
|
||||
return out;
|
||||
else
|
||||
return 0.;
|
||||
}
|
||||
};
|
||||
|
||||
class Lin : public Function
|
||||
{
|
||||
private:
|
||||
float t;
|
||||
virtual void set_grad(const float& grad)
|
||||
{
|
||||
t = grad;
|
||||
}
|
||||
public:
|
||||
Lin() { type = f_lin; }
|
||||
virtual float f(const float& arg)
|
||||
{
|
||||
float out = std::min(t * arg, max);
|
||||
if (fabs(out) > min)
|
||||
return out;
|
||||
else
|
||||
return 0.;
|
||||
}
|
||||
};
|
||||
|
||||
Data<boost::shared_ptr<Function> > f;
|
||||
float neutral_z;
|
||||
float max_curv;
|
||||
uint64_t min_number;
|
||||
ros::Publisher pub;
|
||||
|
||||
public:
|
||||
Run(const ros::Publisher& cmd_publisher) :
|
||||
pub(cmd_publisher) {
|
||||
f.x = boost::make_shared<Lin>();
|
||||
f.y = boost::make_shared<Lin>();
|
||||
f.z = boost::make_shared<Lin>();
|
||||
f.th = boost::make_shared<Lin>();
|
||||
}
|
||||
|
||||
void callback(const hand_control::Plan::ConstPtr& msg)
|
||||
{
|
||||
ROS_INFO("plan received");
|
||||
Data<float> in, out;
|
||||
in.x = in.y = in.z = in.th = 0.;
|
||||
if (msg->curvature < max_curv && msg->number > min_number)
|
||||
{
|
||||
if(msg->normal.z > 0)
|
||||
{
|
||||
in.y = - msg->normal.x;
|
||||
in.x = msg->normal.y;
|
||||
} else
|
||||
{
|
||||
in.y = - msg->normal.x;
|
||||
in.x = msg->normal.y;
|
||||
}
|
||||
in.z = msg->altitude - neutral_z;
|
||||
in.th = msg->angle;
|
||||
}
|
||||
|
||||
geometry_msgs::Twist::Ptr mvt(new geometry_msgs::Twist());
|
||||
|
||||
if (fabs(in.y) > fabs(in.x))
|
||||
{
|
||||
mvt->linear.y = f.y->f(in.y);
|
||||
} else
|
||||
{
|
||||
mvt->linear.x = f.x->f(in.x);
|
||||
}
|
||||
|
||||
mvt->linear.z = f.z->f(in.z);
|
||||
|
||||
mvt->angular.z = f.th->f(in.th);
|
||||
|
||||
pub.publish(mvt);
|
||||
ROS_INFO("cmd published");
|
||||
}
|
||||
|
||||
void reconfigure(const hand_control::Commander_atanConfig& c, const uint32_t& level)
|
||||
{
|
||||
max_curv = c.max_curvature;
|
||||
neutral_z = c.neutral_alt;
|
||||
min_number = c.min_points_number;
|
||||
|
||||
if (c.atan and f.x->get_type() != f_atan)
|
||||
{
|
||||
f.x = boost::make_shared<Atan>();
|
||||
f.y = boost::make_shared<Atan>();
|
||||
f.z = boost::make_shared<Atan>();
|
||||
f.th = boost::make_shared<Atan>();
|
||||
} else if (!c.atan and f.x->get_type() == f_atan)
|
||||
{
|
||||
f.x = boost::make_shared<Lin>();
|
||||
f.y = boost::make_shared<Lin>();
|
||||
f.z = boost::make_shared<Lin>();
|
||||
f.th = boost::make_shared<Lin>();
|
||||
}
|
||||
f.x->set(c.x_min, c.x_max, c.x_p);
|
||||
f.y->set(c.y_min, c.y_max, c.y_p);
|
||||
f.z->set(c.z_min, c.z_max, c.z_p);
|
||||
f.th->set(c.th_min, c.th_max, c.th_p);
|
||||
ROS_INFO("parameters reconfigured");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
ros::init(argc, argv, "commander_atan");
|
||||
ros::NodeHandle node("commander_atan");
|
||||
|
||||
ros::Publisher cmd_pub = node.advertise<geometry_msgs::Twist>("/cmd_vel", 1);
|
||||
Run run(cmd_pub);
|
||||
ros::Subscriber plan_sub = node.subscribe<hand_control::Plan>("input", 1, &Run::callback, &run);
|
||||
|
||||
dynamic_reconfigure::Server<hand_control::Commander_atanConfig> server;
|
||||
dynamic_reconfigure::Server<hand_control::Commander_atanConfig>::CallbackType f;
|
||||
f = boost::bind(&Run::reconfigure, &run, _1, _2);
|
||||
server.setCallback(f);
|
||||
|
||||
ROS_INFO("start spinning");
|
||||
ros::spin();
|
||||
return 0;
|
||||
}
|
||||
|
||||
const float Run::Atan::demi_pi = 2*atan(1);
|
|
@ -1,9 +0,0 @@
|
|||
#ifndef DATA_H
|
||||
#define DATA_H
|
||||
template <typename T>
|
||||
struct Data
|
||||
{
|
||||
public:
|
||||
T x, y, z, th;
|
||||
};
|
||||
#endif
|
217
src/display.cpp
217
src/display.cpp
|
@ -1,7 +1,28 @@
|
|||
/* Copyright © 2015 CentraleSupélec
|
||||
*
|
||||
* This file is part of Hand Control.
|
||||
*
|
||||
* Hand Control is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hand Control 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 General Public License
|
||||
* along with Hand Control. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// library used by "keyboard_cmd.cpp"
|
||||
|
||||
#include "./display.h"
|
||||
|
||||
#include <ncurses.h>
|
||||
#include <string>
|
||||
#include <geometry_msgs/Twist.h>
|
||||
#include "display.h"
|
||||
#include <string>
|
||||
|
||||
const int Curses::cmd_kbd_lines = 8;
|
||||
const int Curses::cmd_kbd_columns = 55;
|
||||
|
@ -22,110 +43,110 @@ const int Curses::topic_lines = 8;
|
|||
const int Curses::topic_columns = 22;
|
||||
|
||||
Curses::Curses() {
|
||||
initscr();
|
||||
cbreak();
|
||||
start_color();
|
||||
//noecho();
|
||||
initscr();
|
||||
cbreak();
|
||||
start_color();
|
||||
// noecho();
|
||||
|
||||
cmd_kbd = newwin(cmd_kbd_lines, cmd_kbd_columns, 0, 0);
|
||||
cmd_kbd = newwin(cmd_kbd_lines, cmd_kbd_columns, 0, 0);
|
||||
|
||||
get = newwin(get_lines, get_columns,
|
||||
get = newwin(get_lines, get_columns,
|
||||
cmd_kbd_lines, cmd_kbd_columns/2);
|
||||
|
||||
cmd_speed = newwin(cmd_speed_lines, cmd_speed_columns,
|
||||
cmd_speed = newwin(cmd_speed_lines, cmd_speed_columns,
|
||||
cmd_kbd_lines + get_lines, 0);
|
||||
|
||||
log_sent_title = newwin(1, log_sent_w_columns,
|
||||
log_sent_title = newwin(1, log_sent_w_columns,
|
||||
0, cmd_kbd_columns + 1);
|
||||
waddstr(log_sent_title, "SENT COMMANDS");
|
||||
wrefresh(log_sent_title);
|
||||
log_sent_w = newwin(log_sent_w_lines - 1, log_sent_w_columns,
|
||||
waddstr(log_sent_title, "SENT COMMANDS");
|
||||
wrefresh(log_sent_title);
|
||||
log_sent_w = newwin(log_sent_w_lines - 1, log_sent_w_columns,
|
||||
1, cmd_kbd_columns + 1);
|
||||
log_line_number = log_sent_w_lines - 2;
|
||||
wattron(log_sent_w, A_BOLD);
|
||||
init_pair(1, COLOR_GREEN, COLOR_BLACK);
|
||||
wattron(log_sent_w, COLOR_PAIR(1));
|
||||
scrollok(log_sent_w, TRUE);
|
||||
log_line_number = log_sent_w_lines - 2;
|
||||
wattron(log_sent_w, A_BOLD);
|
||||
init_pair(1, COLOR_GREEN, COLOR_BLACK);
|
||||
wattron(log_sent_w, COLOR_PAIR(1));
|
||||
scrollok(log_sent_w, TRUE);
|
||||
|
||||
nav_data = newwin(nav_data_lines, nav_data_columns,
|
||||
nav_data = newwin(nav_data_lines, nav_data_columns,
|
||||
cmd_kbd_lines + get_lines + cmd_speed_lines + 1, 0);
|
||||
init_pair(2, COLOR_RED, COLOR_BLACK);
|
||||
wattron(nav_data, COLOR_PAIR(2));
|
||||
wattron(nav_data, A_BOLD);
|
||||
init_pair(2, COLOR_RED, COLOR_BLACK);
|
||||
wattron(nav_data, COLOR_PAIR(2));
|
||||
wattron(nav_data, A_BOLD);
|
||||
|
||||
topic = newwin(topic_lines, topic_columns,
|
||||
topic = newwin(topic_lines, topic_columns,
|
||||
cmd_kbd_lines + get_lines + cmd_speed_lines + 1,
|
||||
nav_data_columns + 1);
|
||||
init_pair(3, COLOR_BLUE, COLOR_BLACK);
|
||||
wattron(topic, COLOR_PAIR(3));
|
||||
wattron(topic, A_BOLD);
|
||||
init_pair(3, COLOR_BLUE, COLOR_BLACK);
|
||||
wattron(topic, COLOR_PAIR(3));
|
||||
wattron(topic, A_BOLD);
|
||||
|
||||
print_nav_data();
|
||||
print_cmd_kbd();
|
||||
print_cmd_speed();
|
||||
print_topic();
|
||||
print_nav_data();
|
||||
print_cmd_kbd();
|
||||
print_cmd_speed();
|
||||
print_topic();
|
||||
|
||||
wmove(get, 0, 0);
|
||||
wrefresh(get);
|
||||
wmove(get, 0, 0);
|
||||
wrefresh(get);
|
||||
}
|
||||
|
||||
Curses::~Curses() {
|
||||
delwin(cmd_kbd);
|
||||
delwin(cmd_speed);
|
||||
delwin(log_sent_w);
|
||||
delwin(log_sent_title);
|
||||
delwin(nav_data);
|
||||
delwin(get);
|
||||
delwin(topic);
|
||||
endwin();
|
||||
delwin(cmd_kbd);
|
||||
delwin(cmd_speed);
|
||||
delwin(log_sent_w);
|
||||
delwin(log_sent_title);
|
||||
delwin(nav_data);
|
||||
delwin(get);
|
||||
delwin(topic);
|
||||
endwin();
|
||||
}
|
||||
|
||||
char Curses::getchar() {
|
||||
return wgetch(get);
|
||||
return wgetch(get);
|
||||
}
|
||||
|
||||
void Curses::print_cmd_kbd() {
|
||||
wmove(cmd_kbd, 0, 0);
|
||||
waddstr(cmd_kbd, " ---------------------\n");
|
||||
waddstr(cmd_kbd, " takeoff>| t|⇑ y|↖ u|↑ i|↗ o|\n");
|
||||
waddstr(cmd_kbd, " |---|---|---|---|---|----\n");
|
||||
waddstr(cmd_kbd, " reset>| g|⇐ h|← j| k|→ l|⇒ m|\n");
|
||||
waddstr(cmd_kbd, " |---|---|---|---|---|----\n");
|
||||
waddstr(cmd_kbd, " land>| b|⇓ n|↙ ,|↓ ;|↘ :|\n");
|
||||
waddstr(cmd_kbd, " ---------------------\n");
|
||||
waddstr(cmd_kbd, " Press ctrl + C to quit");
|
||||
wrefresh(cmd_kbd);
|
||||
wmove(cmd_kbd, 0, 0);
|
||||
waddstr(cmd_kbd, " ---------------------\n");
|
||||
waddstr(cmd_kbd, " takeoff>| t|⇑ y|↖ u|↑ i|↗ o|\n");
|
||||
waddstr(cmd_kbd, " |---|---|---|---|---|----\n");
|
||||
waddstr(cmd_kbd, " reset>| g|⇐ h|← j| k|→ l|⇒ m|\n");
|
||||
waddstr(cmd_kbd, " |---|---|---|---|---|----\n");
|
||||
waddstr(cmd_kbd, " land>| b|⇓ n|↙ ,|↓ ;|↘ :|\n");
|
||||
waddstr(cmd_kbd, " ---------------------\n");
|
||||
waddstr(cmd_kbd, " Press ctrl + C to quit");
|
||||
wrefresh(cmd_kbd);
|
||||
}
|
||||
|
||||
void Curses::print_cmd_speed() {
|
||||
wmove(cmd_speed, 0, 0);
|
||||
waddstr(cmd_speed, " `x` cmd speed : (a/w : increase/decrease)\n");
|
||||
waddstr(cmd_speed, " `y` cmd speed : (z/x : increase/decrease)\n");
|
||||
waddstr(cmd_speed, " `z` cmd speed : (e/c : increase/decrease)\n");
|
||||
waddstr(cmd_speed, "rotation speed : (r/v : increase/decrease)\n");
|
||||
wrefresh(cmd_speed);
|
||||
wmove(cmd_speed, 0, 0);
|
||||
waddstr(cmd_speed, " `x` cmd speed : (a/w : increase/decrease)\n");
|
||||
waddstr(cmd_speed, " `y` cmd speed : (z/x : increase/decrease)\n");
|
||||
waddstr(cmd_speed, " `z` cmd speed : (e/c : increase/decrease)\n");
|
||||
waddstr(cmd_speed, "rotation speed : (r/v : increase/decrease)\n");
|
||||
wrefresh(cmd_speed);
|
||||
}
|
||||
|
||||
void Curses::update_cmd_speed(const char& coord, const float& v) {
|
||||
switch(coord) {
|
||||
case 'x':
|
||||
wmove(cmd_speed, 0, 16);
|
||||
wprintw(cmd_speed, "%f", v);
|
||||
break;
|
||||
case 'y':
|
||||
wmove(cmd_speed, 1, 16);
|
||||
wprintw(cmd_speed, "%f", v);
|
||||
break;
|
||||
case 'z':
|
||||
wmove(cmd_speed, 2, 16);
|
||||
wprintw(cmd_speed, "%f", v);
|
||||
break;
|
||||
case 't':
|
||||
wmove(cmd_speed, 3, 16);
|
||||
wprintw(cmd_speed, "%f", v);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
switch (coord) {
|
||||
case 'x':
|
||||
wmove(cmd_speed, 0, 16);
|
||||
wprintw(cmd_speed, "%f", v);
|
||||
break;
|
||||
case 'y':
|
||||
wmove(cmd_speed, 1, 16);
|
||||
wprintw(cmd_speed, "%f", v);
|
||||
break;
|
||||
case 'z':
|
||||
wmove(cmd_speed, 2, 16);
|
||||
wprintw(cmd_speed, "%f", v);
|
||||
break;
|
||||
case 't':
|
||||
wmove(cmd_speed, 3, 16);
|
||||
wprintw(cmd_speed, "%f", v);
|
||||
break;
|
||||
default:
|
||||
{}
|
||||
}
|
||||
wrefresh(cmd_speed);
|
||||
}
|
||||
|
@ -151,39 +172,39 @@ void Curses::update_nav_data(const float& batteryPercent,
|
|||
wmove(nav_data, 2, 10);
|
||||
wprintw(nav_data, "%f %", time);
|
||||
wmove(nav_data, 1, 10);
|
||||
switch(state) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
waddstr(nav_data, "unknown ");
|
||||
break;
|
||||
waddstr(nav_data, "unknown ");
|
||||
break;
|
||||
case 1:
|
||||
waddstr(nav_data, "inited ");
|
||||
break;
|
||||
waddstr(nav_data, "inited ");
|
||||
break;
|
||||
case 2:
|
||||
waddstr(nav_data, "landed ");
|
||||
break;
|
||||
waddstr(nav_data, "landed ");
|
||||
break;
|
||||
case 3:
|
||||
waddstr(nav_data, "flying ");
|
||||
break;
|
||||
waddstr(nav_data, "flying ");
|
||||
break;
|
||||
case 4:
|
||||
waddstr(nav_data, "hovering ");
|
||||
break;
|
||||
waddstr(nav_data, "hovering ");
|
||||
break;
|
||||
case 5:
|
||||
waddstr(nav_data, "test ");
|
||||
break;
|
||||
waddstr(nav_data, "test ");
|
||||
break;
|
||||
case 6:
|
||||
waddstr(nav_data, "taking off ");
|
||||
break;
|
||||
waddstr(nav_data, "taking off ");
|
||||
break;
|
||||
case 7:
|
||||
waddstr(nav_data, "flying ");
|
||||
break;
|
||||
waddstr(nav_data, "flying ");
|
||||
break;
|
||||
case 8:
|
||||
waddstr(nav_data, "landing ");
|
||||
break;
|
||||
waddstr(nav_data, "landing ");
|
||||
break;
|
||||
case 9:
|
||||
waddstr(nav_data, "looping ");
|
||||
break;
|
||||
waddstr(nav_data, "looping ");
|
||||
break;
|
||||
default:
|
||||
;
|
||||
{}
|
||||
}
|
||||
wrefresh(nav_data);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,30 @@
|
|||
#ifndef CURSES_DISPLAY
|
||||
#define CURSES_DISPLAY
|
||||
/* Copyright © 2015 CentraleSupélec
|
||||
*
|
||||
* This file is part of Hand Control.
|
||||
*
|
||||
* Hand Control is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hand Control 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 General Public License
|
||||
* along with Hand Control. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SRC_DISPLAY_H_
|
||||
#define SRC_DISPLAY_H_
|
||||
|
||||
#include <ncurses.h>
|
||||
#include <string>
|
||||
#include <geometry_msgs/Twist.h>
|
||||
#include <string>
|
||||
|
||||
class Curses
|
||||
{
|
||||
private:
|
||||
class Curses {
|
||||
private:
|
||||
static const int cmd_kbd_lines;
|
||||
static const int cmd_kbd_columns;
|
||||
WINDOW* cmd_kbd;
|
||||
|
@ -32,18 +49,17 @@ class Curses
|
|||
static const int nav_data_columns;
|
||||
WINDOW* nav_data;
|
||||
void print_nav_data();
|
||||
|
||||
|
||||
static const int topic_lines;
|
||||
static const int topic_columns;
|
||||
WINDOW* topic;
|
||||
void print_topic();
|
||||
|
||||
public:
|
||||
public:
|
||||
Curses();
|
||||
~Curses();
|
||||
char getchar();
|
||||
|
||||
// TODO
|
||||
void update_cmd_speed(const char& coord, const float& v);
|
||||
void update_nav_data(const float& batteryPercent,
|
||||
const int& state,
|
||||
|
@ -52,4 +68,4 @@ class Curses
|
|||
void update_topic(const geometry_msgs::Twist::ConstPtr& twist);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // SRC_DISPLAY_H_
|
||||
|
|
|
@ -1,3 +1,25 @@
|
|||
/* Copyright © 2015 CentraleSupélec
|
||||
*
|
||||
|
||||
* This file is part of Hand Control.
|
||||
*
|
||||
|
||||
* Hand Control is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
|
||||
* Hand Control 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 General Public License
|
||||
* along with Hand Control. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <ros/ros.h>
|
||||
#include <pcl_ros/point_cloud.h>
|
||||
#include <pcl/point_types.h>
|
||||
|
@ -15,122 +37,143 @@ typedef pcl::PointCloud<Point> PointCloud;
|
|||
typedef Eigen::Matrix3f& Matrix;
|
||||
|
||||
class Callback {
|
||||
public:
|
||||
void callback(const PointCloud::ConstPtr& msg)
|
||||
{
|
||||
ROS_INFO("PointCloud received");
|
||||
public:
|
||||
// handles received messages and publish the plan estimation
|
||||
void callback(const PointCloud::ConstPtr& msg) {
|
||||
ROS_INFO("PointCloud received");
|
||||
|
||||
if (msg->width > 3){
|
||||
if (msg->width > 3) {
|
||||
// else, no plan can be estimated…
|
||||
analyser.setInputCloud(msg);
|
||||
Matrix eg = analyser.getEigenVectors();
|
||||
|
||||
analyser.setInputCloud(msg);
|
||||
Matrix eg = analyser.getEigenVectors();
|
||||
// to build the "Plan" message to be published
|
||||
float x, y, z, th, h, c;
|
||||
x = y = z = th = h = c = 0.;
|
||||
|
||||
float x, y, z, th, h, c;
|
||||
x = y = z = th = h = c = 0.;
|
||||
// v = eg_1 ^ eg_2 is the plan normal
|
||||
Eigen::Vector3f v = eg.col(0).cross(eg.col(1));
|
||||
v.normalize(); // to have norm(v) == 1
|
||||
|
||||
// we consider the whole PointCloud
|
||||
std::vector<int> indices;
|
||||
for (int i = 0; i < msg->points.size(); ++i)
|
||||
indices.push_back(i);
|
||||
// x, y and z are the coords of the plan normal
|
||||
if (!reverse) {
|
||||
x = v(0); y = v(1);
|
||||
} else {
|
||||
// if "x" and "y" axes are inverted
|
||||
// (reverse is a parameter to set with dynamic_reconfigure)
|
||||
x = v(1); y = v(0);
|
||||
}
|
||||
z = v(2);
|
||||
|
||||
// v = eg_1 ^ eg_2 is the plan normal
|
||||
Eigen::Vector3f v = eg.col(0).cross(eg.col(1));
|
||||
// norm(v) == 1
|
||||
v.normalize();
|
||||
if (!reverse)
|
||||
{
|
||||
x = v(0); y=v(1);
|
||||
} else {
|
||||
x = v(1); y = v(0);
|
||||
// h is the altitude
|
||||
h = (analyser.getMean())(2);
|
||||
|
||||
|
||||
// angle calculation
|
||||
|
||||
|
||||
// m_x and m_y are the "x" and "y" coords
|
||||
// of the first principal component
|
||||
float m_x, m_y;
|
||||
|
||||
|
||||
|
||||
// parameter to set
|
||||
// with dynamic_reconfigure
|
||||
if (reverse_angle) {
|
||||
m_x = eg(0, 0);
|
||||
m_y = eg(1, 0);
|
||||
} else {
|
||||
m_x = eg(1, 0);
|
||||
m_y = eg(0, 0);
|
||||
}
|
||||
|
||||
// because we want "th" only between -90° and 90°
|
||||
if (m_x < 0.)
|
||||
m_y *= -1;
|
||||
|
||||
th = - asin(m_y / sqrt(pow(m_y, 2)+ pow(m_x, 2))); // 0 <= th <= pi
|
||||
th *= _RAD2DEG; // -90 <= th <= 90
|
||||
|
||||
// TODO(someone)
|
||||
// -> calculate "c" (the curvature)
|
||||
// ( c == 0 for the moment)
|
||||
|
||||
// publication
|
||||
ROS_INFO("Plan published");
|
||||
publisher.publish(
|
||||
to_Plan(
|
||||
x, y, z, h, th, c,
|
||||
msg->header.seq,
|
||||
msg->header.stamp,
|
||||
msg->width));
|
||||
}
|
||||
z=v(2);
|
||||
|
||||
// h is the altitude
|
||||
h = (analyser.getMean())(2);
|
||||
|
||||
// this formula is good only if :
|
||||
// -pi/2 <= th <= pi/2
|
||||
// ie cos(th) == m_x >= 0
|
||||
float m_x, m_y;
|
||||
if (reverse_angle)
|
||||
{
|
||||
m_x = eg(0,0);
|
||||
m_y = eg(1,0);
|
||||
} else {
|
||||
m_x = eg(1,0);
|
||||
m_y = eg(0,0);
|
||||
}
|
||||
|
||||
if (m_x < 0.)
|
||||
m_y *= -1;
|
||||
|
||||
th = - asin(m_y / sqrt(pow(m_y,2)+ pow(m_x,2)));
|
||||
// 0 <= th <= pi
|
||||
th *= _RAD2DEG;
|
||||
// -90 <= th <= 90
|
||||
|
||||
// publication
|
||||
ROS_INFO("Plan published");
|
||||
publisher.publish(to_Plan(x, y, z, h, th, c, msg->header.seq, msg->header.stamp, msg->width));
|
||||
}
|
||||
}
|
||||
|
||||
Callback(ros::Publisher& pub):publisher(pub), _RAD2DEG(45.f/atan(1.)), reverse(false), reverse_angle(false) {};
|
||||
explicit Callback(const ros::Publisher& pub) :
|
||||
publisher(pub),
|
||||
_RAD2DEG(45.f/atan(1.)),
|
||||
reverse(false),
|
||||
reverse_angle(false) {}
|
||||
|
||||
|
||||
void reconfigure(const hand_control::EstimatorConfig& c, const uint32_t& level) {
|
||||
reverse = c.reverse ;
|
||||
reverse_angle = c.reverse_angle;
|
||||
// updates the parameters received from dynamic_reconfigure
|
||||
void reconfigure(const hand_control::EstimatorConfig& c,
|
||||
const uint32_t& level) {
|
||||
reverse = c.reverse;
|
||||
reverse_angle = c.reverse_angle;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
ros::Publisher publisher;
|
||||
pcl::PCA<Point> analyser;
|
||||
const float _RAD2DEG;
|
||||
bool reverse, reverse_angle;
|
||||
|
||||
// return a "Plan" message build with
|
||||
// the informations provided
|
||||
inline const hand_control::Plan::ConstPtr
|
||||
to_Plan(const float& x, const float& y,
|
||||
const float& z, const float& h,
|
||||
const float& th,
|
||||
const float& c, const uint32_t& seq,
|
||||
const uint64_t& msec64, const uint64_t& number)
|
||||
{
|
||||
hand_control::Plan::Ptr ros_msg(new hand_control::Plan());
|
||||
ros_msg->normal.x = x;
|
||||
ros_msg->normal.y = y;
|
||||
ros_msg->normal.z = z;
|
||||
ros_msg->altitude = h;
|
||||
ros_msg->angle = th;
|
||||
ros_msg->curvature = c;
|
||||
ros_msg->number = number;
|
||||
// uint64_t msec64 is in ms (10-6)
|
||||
uint64_t sec64 = msec64 / 1000000;
|
||||
uint64_t nsec64 = (msec64 % 1000000) * 1000;
|
||||
ros_msg->header.stamp.sec = (uint32_t) sec64;
|
||||
ros_msg->header.stamp.nsec = (uint32_t) nsec64;
|
||||
ros_msg->header.seq = seq;
|
||||
ros_msg->header.frame_id = "0";
|
||||
return ros_msg;
|
||||
}
|
||||
to_Plan(const float& x, const float& y,
|
||||
const float& z, const float& h,
|
||||
const float& th,
|
||||
const float& c, const uint32_t& seq,
|
||||
const uint64_t& msec64, const uint64_t& number) {
|
||||
hand_control::Plan::Ptr ros_msg(new hand_control::Plan());
|
||||
ros_msg->normal.x = x;
|
||||
ros_msg->normal.y = y;
|
||||
ros_msg->normal.z = z;
|
||||
|
||||
ros_msg->altitude = h;
|
||||
ros_msg->angle = th;
|
||||
ros_msg->curvature = c;
|
||||
|
||||
ros_msg->number = number;
|
||||
uint64_t sec64 = msec64 / 1000000;
|
||||
uint64_t nsec64 = (msec64 % 1000000) * 1000;
|
||||
ros_msg->header.stamp.sec = (uint32_t) sec64;
|
||||
ros_msg->header.stamp.nsec = (uint32_t) nsec64;
|
||||
ros_msg->header.seq = seq;
|
||||
ros_msg->header.frame_id = "0";
|
||||
return ros_msg;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
ros::init(argc, argv, "estimator");
|
||||
ros::NodeHandle node("estimator");
|
||||
int main(int argc, char** argv) {
|
||||
ros::init(argc, argv, "estimator");
|
||||
ros::NodeHandle node("estimator");
|
||||
ros::Publisher publisher = node.advertise<hand_control::Plan>("output", 1);
|
||||
Callback callback(publisher);
|
||||
ros::Subscriber subscriber =
|
||||
node.subscribe<PointCloud>("input", 1, &Callback::callback, &callback);
|
||||
|
||||
ros::Publisher publisher = node.advertise<hand_control::Plan>("output", 1);
|
||||
Callback callback(publisher);
|
||||
ros::Subscriber subscriber = node.subscribe<PointCloud>("input", 1, &Callback::callback, &callback);
|
||||
// sets up dynamic_reconfigure
|
||||
dynamic_reconfigure::Server<hand_control::EstimatorConfig> server;
|
||||
dynamic_reconfigure::Server<hand_control::EstimatorConfig>::CallbackType f;
|
||||
f = boost::bind(&Callback::reconfigure, &callback, _1, _2);
|
||||
server.setCallback(f);
|
||||
|
||||
dynamic_reconfigure::Server<hand_control::EstimatorConfig> server;
|
||||
dynamic_reconfigure::Server<hand_control::EstimatorConfig>::CallbackType f;
|
||||
f = boost::bind(&Callback::reconfigure, &callback, _1, _2);
|
||||
server.setCallback(f);
|
||||
|
||||
ROS_INFO("node started");
|
||||
ros::spin();
|
||||
ROS_INFO("exit");
|
||||
return 0;
|
||||
// begins working
|
||||
ROS_INFO("node started");
|
||||
ros::spin();
|
||||
ROS_INFO("exit");
|
||||
return 0;
|
||||
}
|
||||
|
|
182
src/filter.cpp
182
src/filter.cpp
|
@ -1,99 +1,137 @@
|
|||
/* Copyright © 2015 CentraleSupélec
|
||||
*
|
||||
* This file is part of Hand Control.
|
||||
*
|
||||
* Hand Control is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hand Control 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 General Public License
|
||||
* along with Hand Control. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <hand_control/FilterConfig.h>
|
||||
#include <ros/ros.h>
|
||||
#include <pcl_ros/point_cloud.h>
|
||||
#include <pcl/point_types.h>
|
||||
#include <pcl/tracking/impl/hsv_color_coherence.hpp>
|
||||
#include <assert.h>
|
||||
#include <dynamic_reconfigure/server.h>
|
||||
#include <hand_control/FilterConfig.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
typedef pcl::PointXYZRGB Point;
|
||||
typedef pcl::PointCloud<Point> PointCloud;
|
||||
|
||||
class Callback {
|
||||
public:
|
||||
void
|
||||
callback(const PointCloud::ConstPtr& msg)
|
||||
{
|
||||
PointCloud::Ptr pcl(new PointCloud());
|
||||
copy_info(msg, pcl);
|
||||
BOOST_FOREACH (const Point& pt, msg->points)
|
||||
{
|
||||
float hue_dist, sat, val;
|
||||
hdist_s_v(pt, hue_dist, sat, val);
|
||||
if (pt.z < z_max and hue_dist < delta_hue and sat < sat_max and sat > sat_min and val < val_max and val > val_min)
|
||||
pcl->push_back(pt);
|
||||
}
|
||||
pcl->height = 1;
|
||||
pcl->width = pcl->points.size();
|
||||
publisher.publish(pcl);
|
||||
public:
|
||||
// handles and filters the received PointCloud and
|
||||
// publishes the filtered PointCloud
|
||||
void callback(const PointCloud::ConstPtr& msg) {
|
||||
PointCloud::Ptr pcl(new PointCloud());
|
||||
copy_info(msg, pcl); // copy the header
|
||||
BOOST_FOREACH(const Point& pt, msg->points) {
|
||||
float hue_dist, sat, val;
|
||||
hdist_s_v(pt, hue_dist, sat, val);
|
||||
if (pt.z < z_max &&
|
||||
hue_dist < delta_hue &&
|
||||
sat < sat_max &&
|
||||
sat > sat_min &&
|
||||
val < val_max &&
|
||||
val > val_min) {
|
||||
pcl->push_back(pt);
|
||||
}
|
||||
}
|
||||
pcl->height = 1;
|
||||
pcl->width = pcl->points.size();
|
||||
publisher.publish(pcl);
|
||||
}
|
||||
|
||||
Callback(const ros::Publisher& pub)
|
||||
: publisher(pub), z_max(90.), hue(0.), delta_hue(20.), sat_min(0.3), sat_max(1.), val_min(0.3), val_max(1.)
|
||||
{}
|
||||
explicit Callback(const ros::Publisher& pub) :
|
||||
publisher(pub),
|
||||
z_max(90.),
|
||||
hue(0.),
|
||||
delta_hue(20.),
|
||||
sat_min(0.3),
|
||||
sat_max(1.),
|
||||
val_min(0.3),
|
||||
val_max(1.) {}
|
||||
|
||||
void
|
||||
reconfigure(const hand_control::FilterConfig& c, const uint32_t& level) {
|
||||
z_max = c.z_max;
|
||||
hue = c.hue;
|
||||
delta_hue = c.delta_hue;
|
||||
val_min = c.val_min;
|
||||
val_max = c.val_max;
|
||||
sat_min = c.sat_min;
|
||||
sat_max = c.sat_max;
|
||||
// updates the parameters
|
||||
void reconfigure(const hand_control::FilterConfig& c,
|
||||
const uint32_t& level) {
|
||||
z_max = c.z_max;
|
||||
hue = c.hue;
|
||||
delta_hue = c.delta_hue;
|
||||
val_min = c.val_min;
|
||||
val_max = c.val_max;
|
||||
sat_min = c.sat_min;
|
||||
sat_max = c.sat_max;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
ros::Publisher publisher;
|
||||
float z_max, hue, delta_hue, val_min, val_max, sat_min, sat_max;
|
||||
float z_max, hue, delta_hue, val_min,
|
||||
val_max, sat_min, sat_max;
|
||||
|
||||
inline
|
||||
void
|
||||
copy_info(const PointCloud::ConstPtr& a,
|
||||
PointCloud::Ptr& b)
|
||||
{
|
||||
b->header = a->header;
|
||||
b->sensor_origin_ = a->sensor_origin_;
|
||||
b->sensor_orientation_ = a->sensor_orientation_;
|
||||
b->is_dense = a->is_dense;
|
||||
// copy the header info (useful in order to use rviz)
|
||||
inline void copy_info(const PointCloud::ConstPtr& a,
|
||||
PointCloud::Ptr& b) {
|
||||
b->header = a->header;
|
||||
b->sensor_origin_ = a->sensor_origin_;
|
||||
b->sensor_orientation_ = a->sensor_orientation_;
|
||||
b->is_dense = a->is_dense;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
hdist_s_v(const Point& pt, float& h_dist, float& s, float& v)
|
||||
{
|
||||
float h, diff1, diff2;
|
||||
pcl::tracking::RGB2HSV(pt.r, pt.g, pt.b, h, s, v);
|
||||
h *= 360.0f ;
|
||||
diff1 = std::fabs(h - hue);
|
||||
if (h < hue)
|
||||
diff2 = std::fabs(360.0f + h - hue);
|
||||
else
|
||||
diff2 = std::fabs(360.0f + hue - h);
|
||||
h_dist = std::min(diff1, diff2);
|
||||
// calculate the distance from the wished hue,
|
||||
// the saturation and the value of the point
|
||||
inline void hdist_s_v(const Point& pt,
|
||||
float& h_dist,
|
||||
float& s,
|
||||
float& v) {
|
||||
float h, diff1, diff2;
|
||||
pcl::tracking::RGB2HSV(pt.r, pt.g, pt.b, h, s, v);
|
||||
h *= 360.0f;
|
||||
diff1 = std::fabs(h - hue);
|
||||
// hue is periodic
|
||||
if (h < hue)
|
||||
diff2 = std::fabs(360.0f + h - hue);
|
||||
else
|
||||
diff2 = std::fabs(360.0f + hue - h);
|
||||
h_dist = std::min(diff1, diff2);
|
||||
}
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
ros::init(argc, argv, "filter");
|
||||
ros::NodeHandle node("filter");
|
||||
int main(int argc, char** argv) {
|
||||
ros::init(argc, argv, "filter");
|
||||
ros::NodeHandle node("filter");
|
||||
|
||||
// initialisation
|
||||
ros::Publisher publisher = node.advertise<PointCloud>("output", 1);
|
||||
Callback my_callback(publisher);
|
||||
ros::Subscriber subscriber = node.subscribe<PointCloud>("input", 1, &Callback::callback, &my_callback);
|
||||
ros::Publisher publisher =
|
||||
node.advertise<PointCloud>("output", 1);
|
||||
|
||||
dynamic_reconfigure::Server<hand_control::FilterConfig> server;
|
||||
dynamic_reconfigure::Server<hand_control::FilterConfig>::CallbackType f;
|
||||
f = boost::bind(&Callback::reconfigure, &my_callback, _1, _2);
|
||||
server.setCallback(f);
|
||||
Callback my_callback(publisher);
|
||||
|
||||
// démarrage
|
||||
ROS_INFO("node started");
|
||||
ros::spin();
|
||||
ROS_INFO("exit");
|
||||
return 0;
|
||||
ros::Subscriber subscriber =
|
||||
node.subscribe<PointCloud>("input", 1,
|
||||
&Callback::callback,
|
||||
&my_callback);
|
||||
|
||||
// sets up dynamic_reconfigure
|
||||
dynamic_reconfigure::Server<hand_control::FilterConfig> server;
|
||||
dynamic_reconfigure::Server<hand_control::FilterConfig>::CallbackType f;
|
||||
f = boost::bind(&Callback::reconfigure, &my_callback, _1, _2);
|
||||
server.setCallback(f);
|
||||
|
||||
// begins working
|
||||
ROS_INFO("node started");
|
||||
ros::spin();
|
||||
ROS_INFO("exit");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,127 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import roslib;# roslib.load_manifest('teleop_twist_keyboard')
|
||||
import rospy
|
||||
|
||||
from geometry_msgs.msg import Twist
|
||||
from std_msgs.msg import Empty
|
||||
|
||||
import sys, select, termios, tty
|
||||
|
||||
msg = """
|
||||
---------------------
|
||||
takeoff>| t|⇑ y|↖ u|↑ i|↗ o|
|
||||
|---|---|---|---|---|----
|
||||
reset>| g|⇐ h|← j| k|→ l|⇒ m|
|
||||
|---|---|---|---|---|----
|
||||
land>| b|⇓ n|↙ ,|↓ ;|↘ :|
|
||||
---------------------
|
||||
|
||||
a/w : increase/decrease max speeds by 10%
|
||||
z/x : increase/decrease only linear speed by 10%
|
||||
e/c : increase/decrease only angular speed by 10%
|
||||
anything else : stop
|
||||
|
||||
CTRL-C to quit
|
||||
"""
|
||||
|
||||
moveBindings = {
|
||||
# x th y z
|
||||
'i':(1,0,0,0),
|
||||
'o':(1,-1,0,0),
|
||||
'j':(0,1,0,0),
|
||||
'l':(0,-1,0,0),
|
||||
'u':(1,1,0,0),
|
||||
';':(-1,0,0,0),
|
||||
':':(-1,1,0,0),
|
||||
',':(-1,-1,0,0),
|
||||
'h':(0,0,-1,0),
|
||||
'm':(0,0,1,0),
|
||||
'y':(0,0,0,1),
|
||||
'n':(0,0,0,-1),
|
||||
}
|
||||
|
||||
speedBindings={
|
||||
'a':(1.1,1.1),
|
||||
'w':(.9,.9),
|
||||
'z':(1.1,1),
|
||||
'x':(.9,1),
|
||||
'e':(1,1.1),
|
||||
'c':(1,.9),
|
||||
}
|
||||
|
||||
def getKey():
|
||||
tty.setraw(sys.stdin.fileno())
|
||||
select.select([sys.stdin], [], [], 0)
|
||||
key = sys.stdin.read(1)
|
||||
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
|
||||
return key
|
||||
|
||||
speed = 0.1
|
||||
turn = 0.5
|
||||
|
||||
def vels(speed,turn):
|
||||
return "currently:\tspeed %s\tturn %s " % (speed,turn)
|
||||
|
||||
if __name__=="__main__":
|
||||
settings = termios.tcgetattr(sys.stdin)
|
||||
pub = rospy.Publisher('/cmd_vel', Twist, queue_size=1)
|
||||
land = rospy.Publisher('/ardrone/land', Empty, queue_size=1)
|
||||
takeoff = rospy.Publisher('/ardrone/takeoff', Empty, queue_size=1)
|
||||
reset = rospy.Publisher('/ardrone/reset', Empty, queue_size=1)
|
||||
rospy.init_node('keyboard_azerty')
|
||||
x = 0
|
||||
th = 0
|
||||
y = 0
|
||||
z = 0
|
||||
status = 0
|
||||
try:
|
||||
print msg
|
||||
print vels(speed,turn)
|
||||
while(1):
|
||||
key = getKey()
|
||||
if (key == 't'):
|
||||
takeoff.publish(Empty())
|
||||
print "takeoff"
|
||||
elif (key == 'g'):
|
||||
reset.publish(Empty())
|
||||
print "reset"
|
||||
elif (key == 'b'):
|
||||
land.publish(Empty())
|
||||
print "land"
|
||||
else:
|
||||
if key in moveBindings.keys():
|
||||
x = moveBindings[key][0]
|
||||
th = moveBindings[key][1]
|
||||
y = moveBindings[key][2]
|
||||
z = moveBindings[key][3]
|
||||
elif key in speedBindings.keys():
|
||||
speed = speed * speedBindings[key][0]
|
||||
turn = turn * speedBindings[key][1]
|
||||
print vels(speed,turn)
|
||||
if (status == 14):
|
||||
print msg
|
||||
status = (status + 1) % 15
|
||||
else:
|
||||
x = 0
|
||||
th = 0
|
||||
y = 0
|
||||
z = 0
|
||||
if (key == '\x03'):
|
||||
break
|
||||
twist = Twist()
|
||||
twist.linear.x = x*speed
|
||||
twist.linear.y = y*speed
|
||||
twist.linear.z = z*speed
|
||||
twist.angular.x = 0; twist.angular.y = 0;
|
||||
twist.angular.z = th*turn
|
||||
pub.publish(twist)
|
||||
except:
|
||||
print e
|
||||
finally:
|
||||
twist = Twist()
|
||||
twist.linear.x = 0; twist.linear.y = 0; twist.linear.z = 0
|
||||
twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = 0
|
||||
pub.publish(twist)
|
||||
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
|
||||
|
|
@ -1,277 +1,269 @@
|
|||
/* Copyright © 2015 CentraleSupélec
|
||||
*
|
||||
* This file is part of Hand Control.
|
||||
*
|
||||
* Hand Control is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hand Control 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 General Public License
|
||||
* along with Hand Control. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <ros/ros.h>
|
||||
#include <ros/time.h>
|
||||
#include <locale.h>
|
||||
#include "display.h"
|
||||
|
||||
#include <std_msgs/Empty.h>
|
||||
#include <geometry_msgs/Twist.h>
|
||||
#include <ardrone_autonomy/Navdata.h>
|
||||
|
||||
class NavdataCallback
|
||||
{
|
||||
private:
|
||||
#include "./display.h"
|
||||
|
||||
class NavdataCallback {
|
||||
private:
|
||||
boost::shared_ptr<Curses> term;
|
||||
|
||||
public:
|
||||
NavdataCallback(const boost::shared_ptr<Curses>& terminal) :
|
||||
term(terminal) {}
|
||||
public:
|
||||
explicit NavdataCallback(const boost::shared_ptr<Curses>& terminal) :
|
||||
term(terminal) {}
|
||||
|
||||
void operator()(const ardrone_autonomy::Navdata::ConstPtr& msg) {
|
||||
term->update_nav_data(msg->batteryPercent, msg->state, msg->tm);
|
||||
term->update_nav_data(msg->batteryPercent, msg->state, msg->tm);
|
||||
}
|
||||
}; // class NavdataCallback
|
||||
};
|
||||
|
||||
class CmdVelCallback
|
||||
{
|
||||
private:
|
||||
class CmdVelCallback {
|
||||
private:
|
||||
boost::shared_ptr<Curses> term;
|
||||
|
||||
public:
|
||||
CmdVelCallback(const boost::shared_ptr<Curses>& terminal) :
|
||||
public:
|
||||
explicit CmdVelCallback(const boost::shared_ptr<Curses>& terminal) :
|
||||
term(terminal) {}
|
||||
|
||||
void operator()(const geometry_msgs::Twist::ConstPtr& msg) {
|
||||
term->update_topic(msg);
|
||||
}
|
||||
}; // class CmdVelCallback
|
||||
};
|
||||
|
||||
class Run
|
||||
{
|
||||
private:
|
||||
class Run {
|
||||
private:
|
||||
std_msgs::Empty empty;
|
||||
ros::NodeHandle n;
|
||||
ros::Rate loop_rate;
|
||||
ros::Publisher cmd, pub_takeoff, pub_land, pub_reset;
|
||||
ros::Subscriber data_subscriber, cmdvel_subscriber;
|
||||
void land() { pub_land.publish(empty); };
|
||||
void takeoff() { pub_takeoff.publish(empty); };
|
||||
void reset() { pub_reset.publish(empty); };
|
||||
void land() { pub_land.publish(empty); }
|
||||
void takeoff() { pub_takeoff.publish(empty); }
|
||||
void reset() { pub_reset.publish(empty); }
|
||||
float x_speed, y_speed, z_speed, turn;
|
||||
boost::shared_ptr<Curses> term;
|
||||
NavdataCallback data_callback;
|
||||
CmdVelCallback cmdvel_callback;
|
||||
|
||||
public:
|
||||
Run(const boost::shared_ptr<Curses>& terminal) :
|
||||
data_callback(terminal),
|
||||
cmdvel_callback(terminal),
|
||||
term(terminal),
|
||||
loop_rate(30),
|
||||
x_speed(0.1),
|
||||
y_speed(0.1),
|
||||
z_speed(0.1),
|
||||
turn(0.1) {
|
||||
cmd = n.advertise<geometry_msgs::Twist>("/cmd_vel",1);
|
||||
pub_takeoff = n.advertise<std_msgs::Empty>("/ardrone/takeoff", 1);
|
||||
pub_land = n.advertise<std_msgs::Empty>("/ardrone/land", 1);
|
||||
pub_reset = n.advertise<std_msgs::Empty>("/ardrone/reset", 1);
|
||||
data_subscriber = n.subscribe<ardrone_autonomy::Navdata>("/ardrone/navdata", 1, data_callback);
|
||||
cmdvel_subscriber = n.subscribe<geometry_msgs::Twist>("/cmd_vel", 1, cmdvel_callback);
|
||||
public:
|
||||
explicit Run(const boost::shared_ptr<Curses>& terminal) :
|
||||
data_callback(terminal),
|
||||
cmdvel_callback(terminal),
|
||||
term(terminal),
|
||||
loop_rate(30),
|
||||
x_speed(0.1),
|
||||
y_speed(0.1),
|
||||
z_speed(0.1),
|
||||
turn(0.1) {
|
||||
cmd = n.advertise<geometry_msgs::Twist>("/cmd_vel", 1);
|
||||
pub_takeoff = n.advertise<std_msgs::Empty>("/ardrone/takeoff", 1);
|
||||
pub_land = n.advertise<std_msgs::Empty>("/ardrone/land", 1);
|
||||
pub_reset = n.advertise<std_msgs::Empty>("/ardrone/reset", 1);
|
||||
|
||||
term->update_cmd_speed('x', x_speed);
|
||||
term->update_cmd_speed('y', y_speed);
|
||||
term->update_cmd_speed('z', z_speed);
|
||||
term->update_cmd_speed('t', turn);
|
||||
data_subscriber =
|
||||
n.subscribe<ardrone_autonomy::Navdata>(
|
||||
"/ardrone/navdata", 1, data_callback);
|
||||
|
||||
float a(0);
|
||||
int s(0);
|
||||
float time(0);
|
||||
term->update_nav_data(a, s, time);
|
||||
}
|
||||
cmdvel_subscriber =
|
||||
n.subscribe<geometry_msgs::Twist>(
|
||||
"/cmd_vel", 1, cmdvel_callback);
|
||||
|
||||
void operator()()
|
||||
{
|
||||
while (ros::ok())
|
||||
{
|
||||
ros::spinOnce();
|
||||
term->update_cmd_speed('x', x_speed);
|
||||
term->update_cmd_speed('y', y_speed);
|
||||
term->update_cmd_speed('z', z_speed);
|
||||
term->update_cmd_speed('t', turn);
|
||||
|
||||
geometry_msgs::Twist::Ptr msg(new geometry_msgs::Twist());
|
||||
msg->linear.x = msg->linear.y = msg->linear.z =
|
||||
msg->angular.x = msg->angular.y = msg->angular.z = 0.;
|
||||
float a(0);
|
||||
int s(0);
|
||||
float time(0);
|
||||
term->update_nav_data(a, s, time);
|
||||
}
|
||||
|
||||
char c = term->getchar();
|
||||
void operator()() {
|
||||
while (ros::ok()) {
|
||||
ros::spinOnce();
|
||||
|
||||
switch(c)
|
||||
{
|
||||
case 'k' :
|
||||
{// hover
|
||||
cmd.publish(msg);
|
||||
term->log_sent("hover !");
|
||||
break;
|
||||
}
|
||||
case 'i' :
|
||||
{// forward
|
||||
msg->linear.x = x_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("forward !");
|
||||
break;
|
||||
}
|
||||
case ';' :
|
||||
{// backward
|
||||
msg->linear.x = -x_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("backward !");
|
||||
break;
|
||||
}
|
||||
case 'h' :
|
||||
{//translate left
|
||||
msg->linear.y = -y_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("translate left !");
|
||||
break;
|
||||
}
|
||||
case 'm' :
|
||||
{//translate right
|
||||
msg->linear.y = y_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("translate right !");
|
||||
break;
|
||||
}
|
||||
case 'j' :
|
||||
{//rotate left
|
||||
msg->angular.z = turn;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("rotate left !");
|
||||
break;
|
||||
}
|
||||
case 'l' :
|
||||
{//rotate right
|
||||
msg->angular.z = -turn;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("rotate right !");
|
||||
break;
|
||||
}
|
||||
case 'u' :
|
||||
{//turn left
|
||||
msg->angular.z = turn;
|
||||
msg->linear.x = x_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("forward left !");
|
||||
break;
|
||||
}
|
||||
case 'o' :
|
||||
{//turn right
|
||||
msg->angular.z = -turn;
|
||||
msg->linear.x = x_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("forward right !");
|
||||
break;
|
||||
}
|
||||
case ',' :
|
||||
{//turn left backward
|
||||
msg->angular.z = turn;
|
||||
msg->linear.x = -x_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("backward left !");
|
||||
break;
|
||||
}
|
||||
case ':' :
|
||||
{//turn right backward
|
||||
msg->angular.z = -turn;
|
||||
msg->linear.x = -x_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("backward right !");
|
||||
break;
|
||||
}
|
||||
case 'y' :
|
||||
{//up
|
||||
msg->linear.z = z_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("up !");
|
||||
break;
|
||||
}
|
||||
case 'n' :
|
||||
{//down
|
||||
msg->linear.z = -z_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("down !");
|
||||
break;
|
||||
}
|
||||
case 't' :
|
||||
{//takeoff
|
||||
takeoff();
|
||||
term->log_sent("takeoff !");
|
||||
break;
|
||||
}
|
||||
case 'b' :
|
||||
{//land
|
||||
land();
|
||||
term->log_sent("land !");
|
||||
break;
|
||||
}
|
||||
case 'g' :
|
||||
{//reset
|
||||
reset();
|
||||
term->log_sent("reset !");
|
||||
break;
|
||||
}
|
||||
case 'a' :
|
||||
{// + x_speed
|
||||
x_speed *= 1.1;
|
||||
term->update_cmd_speed('x', x_speed);
|
||||
break;
|
||||
}
|
||||
case 'w' :
|
||||
{// - x_speed
|
||||
x_speed *= 0.9;
|
||||
term->update_cmd_speed('x', x_speed);
|
||||
break;
|
||||
}
|
||||
case 'z' :
|
||||
{// + y_speed
|
||||
y_speed *= 1.1;
|
||||
term->update_cmd_speed('y', y_speed);
|
||||
break;
|
||||
}
|
||||
case 'x' :
|
||||
{// - y_speed
|
||||
y_speed *= 0.9;
|
||||
term->update_cmd_speed('y', y_speed);
|
||||
break;
|
||||
}
|
||||
case 'e' :
|
||||
{// + z_speed
|
||||
z_speed *= 1.1;
|
||||
term->update_cmd_speed('z', z_speed);
|
||||
break;
|
||||
}
|
||||
case 'c' :
|
||||
{// - z_speed
|
||||
z_speed *= 0.9;
|
||||
term->update_cmd_speed('z', z_speed);
|
||||
break;
|
||||
}
|
||||
case 'r' :
|
||||
{// + turn speed
|
||||
turn *= 1.1;
|
||||
term->update_cmd_speed('t', turn);
|
||||
break;
|
||||
}
|
||||
case 'v' :
|
||||
{// - turn speed
|
||||
turn *= 0.9;
|
||||
term->update_cmd_speed('t', turn);
|
||||
break;
|
||||
}
|
||||
default :
|
||||
{
|
||||
cmd.publish(msg);
|
||||
term->log_sent("hover !");
|
||||
}
|
||||
} // switch(c)
|
||||
loop_rate.sleep();
|
||||
} // while
|
||||
} //void run()
|
||||
geometry_msgs::Twist::Ptr msg(new geometry_msgs::Twist());
|
||||
msg->linear.x = msg->linear.y = msg->linear.z =
|
||||
msg->angular.x = msg->angular.y = msg->angular.z = 0.;
|
||||
|
||||
}; // class Run
|
||||
char c = term->getchar();
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
setlocale(LC_ALL, "");
|
||||
ros::init(argc, argv, "keyboard_cmd");
|
||||
boost::shared_ptr<Curses> term(new Curses());
|
||||
Run fun(term);
|
||||
fun();
|
||||
return 0;
|
||||
} // main
|
||||
switch (c) {
|
||||
case 'k' : { // hover
|
||||
cmd.publish(msg);
|
||||
term->log_sent("hover !");
|
||||
break;
|
||||
}
|
||||
case 'i' : { // forward
|
||||
msg->linear.x = x_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("forward !");
|
||||
break;
|
||||
}
|
||||
case ';' : { // backward
|
||||
msg->linear.x = -x_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("backward !");
|
||||
break;
|
||||
}
|
||||
case 'h' : { // translate left
|
||||
msg->linear.y = -y_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("translate left !");
|
||||
break;
|
||||
}
|
||||
case 'm' : { // translate right
|
||||
msg->linear.y = y_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("translate right !");
|
||||
break;
|
||||
}
|
||||
case 'j' : { // rotate left
|
||||
msg->angular.z = turn;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("rotate left !");
|
||||
break;
|
||||
}
|
||||
case 'l' : { // rotate right
|
||||
msg->angular.z = -turn;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("rotate right !");
|
||||
break;
|
||||
}
|
||||
case 'u' : { // turn left
|
||||
msg->angular.z = turn;
|
||||
msg->linear.x = x_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("forward left !");
|
||||
break;
|
||||
}
|
||||
case 'o' : { // turn right
|
||||
msg->angular.z = -turn;
|
||||
msg->linear.x = x_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("forward right !");
|
||||
break;
|
||||
}
|
||||
case ',' : { // turn left backward
|
||||
msg->angular.z = turn;
|
||||
msg->linear.x = -x_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("backward left !");
|
||||
break;
|
||||
}
|
||||
case ':' : { // turn right backward
|
||||
msg->angular.z = -turn;
|
||||
msg->linear.x = -x_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("backward right !");
|
||||
break;
|
||||
}
|
||||
case 'y' : { // up
|
||||
msg->linear.z = z_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("up !");
|
||||
break;
|
||||
}
|
||||
case 'n' : { // down
|
||||
msg->linear.z = -z_speed;
|
||||
cmd.publish(msg);
|
||||
term->log_sent("down !");
|
||||
break;
|
||||
}
|
||||
case 't' : { // takeoff
|
||||
takeoff();
|
||||
term->log_sent("takeoff !");
|
||||
break;
|
||||
}
|
||||
case 'b' : { // land
|
||||
land();
|
||||
term->log_sent("land !");
|
||||
break;
|
||||
}
|
||||
case 'g' : { // reset
|
||||
reset();
|
||||
term->log_sent("reset !");
|
||||
break;
|
||||
}
|
||||
case 'a' : { // + x_speed
|
||||
x_speed *= 1.1;
|
||||
term->update_cmd_speed('x', x_speed);
|
||||
break;
|
||||
}
|
||||
case 'w' : { // - x_speed
|
||||
x_speed *= 0.9;
|
||||
term->update_cmd_speed('x', x_speed);
|
||||
break;
|
||||
}
|
||||
case 'z' : { // + y_speed
|
||||
y_speed *= 1.1;
|
||||
term->update_cmd_speed('y', y_speed);
|
||||
break;
|
||||
}
|
||||
case 'x' : { // - y_speed
|
||||
y_speed *= 0.9;
|
||||
term->update_cmd_speed('y', y_speed);
|
||||
break;
|
||||
}
|
||||
case 'e' : { // + z_speed
|
||||
z_speed *= 1.1;
|
||||
term->update_cmd_speed('z', z_speed);
|
||||
break;
|
||||
}
|
||||
case 'c' : { // - z_speed
|
||||
z_speed *= 0.9;
|
||||
term->update_cmd_speed('z', z_speed);
|
||||
break;
|
||||
}
|
||||
case 'r' : { // + turn speed
|
||||
turn *= 1.1;
|
||||
term->update_cmd_speed('t', turn);
|
||||
break;
|
||||
}
|
||||
case 'v' : { // - turn speed
|
||||
turn *= 0.9;
|
||||
term->update_cmd_speed('t', turn);
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
cmd.publish(msg);
|
||||
term->log_sent("hover !");
|
||||
}
|
||||
} // switch(c)
|
||||
loop_rate.sleep();
|
||||
} // while
|
||||
} // void run()
|
||||
}; // class Run
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
setlocale(LC_ALL, "");
|
||||
ros::init(argc, argv, "keyboard_cmd");
|
||||
boost::shared_ptr<Curses> term(new Curses());
|
||||
Run fun(term);
|
||||
fun();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
#include <ros/ros.h>
|
||||
#include <pcl_ros/point_cloud.h>
|
||||
#include <pcl/point_types.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
typedef pcl::PointCloud<pcl::PointXYZRGB> PointCloud;
|
||||
|
||||
class Callback {
|
||||
public:
|
||||
void
|
||||
operator()(const PointCloud::ConstPtr& msg)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "PointCloud published :" << std::endl;
|
||||
for(int i = 0; i < msg->points.size(); ++i)
|
||||
{
|
||||
pcl::PointXYZRGB p = msg->points[i];
|
||||
stream << std::endl
|
||||
<< "point # " << i << std::endl
|
||||
<< "x : " << p.x << std::endl
|
||||
<< "y : " << p.y << std::endl
|
||||
<< "z : " << p.z << std::endl
|
||||
<< "r : " << (int) p.r << std::endl
|
||||
<< "g : " << (int) p.g << std::endl
|
||||
<< "b : " << (int) p.b << std::endl;
|
||||
}
|
||||
ROS_INFO("%s", stream.str().c_str());
|
||||
}
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
ros::init(argc, argv, "pcl_displayer");
|
||||
ros::NodeHandle node;
|
||||
|
||||
// initialisation
|
||||
ros::Subscriber subscriber = node.subscribe<PointCloud>("input", 1, Callback());
|
||||
|
||||
// démarrage
|
||||
ROS_INFO("node started");
|
||||
ros::spin();
|
||||
ROS_INFO("exit");
|
||||
return 0;
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
#include <ros/ros.h>
|
||||
#include <time.h>
|
||||
#include <pcl_ros/point_cloud.h>
|
||||
#include <pcl/point_types.h>
|
||||
// for UniformGenerator
|
||||
#include <pcl/common/random.h>
|
||||
// for CloudGenerator
|
||||
#include <pcl/common/generate.h>
|
||||
|
||||
typedef pcl::PointCloud<pcl::PointXYZRGB> PointCloud;
|
||||
typedef pcl::common::UniformGenerator<float> UGenerator;
|
||||
|
||||
class Generator
|
||||
{
|
||||
public:
|
||||
Generator(int len, double m, double M)
|
||||
: length(len), min(m), max(M), cgen(), number(0)
|
||||
{
|
||||
UGenerator::Parameters params(min, max, -1);
|
||||
cgen.setParameters(params);
|
||||
}
|
||||
|
||||
PointCloud::Ptr
|
||||
operator()()
|
||||
{
|
||||
PointCloud::Ptr pcl(new PointCloud());
|
||||
cgen.fill(length, length, *pcl);
|
||||
for (int i = 0; i < pcl->points.size(); ++i)
|
||||
{
|
||||
pcl->points[i].r = (uint8_t) 175;
|
||||
pcl->points[i].g = (uint8_t) 120;
|
||||
pcl->points[i].b = (uint8_t) 118;
|
||||
}
|
||||
ros::Time now = ros::Time::now();
|
||||
pcl->header.stamp = now.toNSec() / 1000;
|
||||
pcl->header.seq = number++;
|
||||
pcl->header.frame_id = "0";
|
||||
return pcl;
|
||||
}
|
||||
|
||||
private:
|
||||
pcl::common::CloudGenerator<pcl::PointXYZRGB, UGenerator> cgen;
|
||||
int length;
|
||||
double min, max;
|
||||
uint32_t number;
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
ros::init(argc, argv, "random_pcl_publisher");
|
||||
ros::NodeHandle node("random");
|
||||
// paramètres
|
||||
double freq;
|
||||
if (node.getParam("freq", freq))
|
||||
{
|
||||
ROS_INFO("freq : %f" , freq);
|
||||
} else {
|
||||
node.setParam("freq", 10);
|
||||
node.getParam("freq", freq);
|
||||
ROS_INFO("freq : %f (default value)", freq);
|
||||
}
|
||||
double min, max;
|
||||
if (node.getParam("min", min))
|
||||
{
|
||||
ROS_INFO("min : %f" , min);
|
||||
} else {
|
||||
node.setParam("min", 0.);
|
||||
node.getParam("min", min);
|
||||
ROS_INFO("min : %f (default value)", min);
|
||||
}
|
||||
if (node.getParam("max", max))
|
||||
{
|
||||
ROS_INFO("max : %f" , max);
|
||||
} else {
|
||||
node.setParam("max", 100.);
|
||||
node.getParam("max", max);
|
||||
ROS_INFO("max : %f (default value)", max);
|
||||
}
|
||||
int length;
|
||||
if (node.getParam("length", length))
|
||||
{
|
||||
ROS_INFO("length : %d" , length);
|
||||
} else {
|
||||
node.setParam("length", 10);
|
||||
node.getParam("length", length);
|
||||
ROS_INFO("length : %d (default value)", length);
|
||||
}
|
||||
// initialisation
|
||||
ros::Publisher publisher = node.advertise<PointCloud>("output", 1);
|
||||
Generator generator(length, min, max);
|
||||
ros::Rate loop_rate(freq);
|
||||
ROS_INFO("node started");
|
||||
while (ros::ok())
|
||||
{
|
||||
publisher.publish(generator());
|
||||
ROS_INFO("random PointCloud published");
|
||||
ros::spinOnce();
|
||||
loop_rate.sleep();
|
||||
}
|
||||
ROS_INFO("exit");
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue