23 changed files with 741 additions and 20 deletions
@ -0,0 +1,94 @@ |
|||||
|
<launch> |
||||
|
|
||||
|
|
||||
|
<node name="Ratex_param" pkg="dynamic_reconfigure" type="dynparam" args="load /ratex $(find detect_targets)/params/rate.yaml"/> |
||||
|
<node name="Ratey_param" pkg="dynamic_reconfigure" type="dynparam" args="load /ratey $(find detect_targets)/params/rate.yaml"/> |
||||
|
<node name="Ratez_param" pkg="dynamic_reconfigure" type="dynparam" args="load /ratez $(find detect_targets)/params/rate.yaml"/> |
||||
|
<node name="Rateangz_param" pkg="dynamic_reconfigure" type="dynparam" args="load /rate_ang_z $(find detect_targets)/params/rate.yaml"/> |
||||
|
<node name="safe_param" pkg="dynamic_reconfigure" type="dynparam" args="load /safe $(find detect_targets)/params/settings_safe.yaml"/> |
||||
|
<node name="targets_param" pkg="dynamic_reconfigure" type="dynparam" args="load /targets $(find detect_targets)/params/settings_targets.yaml"/> |
||||
|
|
||||
|
<!-- <remap from="/reset" to="/bebop/reset"/> --> |
||||
|
<include file="$(find bebop_driver)/launch/bebop_node.launch" /> |
||||
|
|
||||
|
<node name="targets" pkg="detect_targets" type="target_publisher.py"> |
||||
|
</node> |
||||
|
|
||||
|
<node name="triangle" pkg="detect_targets" type="triangle.py" output="screen"> |
||||
|
<remap from="component_centers" to="targets"/> |
||||
|
</node> |
||||
|
|
||||
|
|
||||
|
<node name="ratex" pkg="detect_targets" type="control_compute.py" args="rate" output="screen"> |
||||
|
<remap from="input" to="linear_x" /> |
||||
|
<remap from="output" to="rated_x" /> |
||||
|
</node> |
||||
|
<include file="$(find detect_targets)/launch/control.launch" ns="controller_linear_x"> |
||||
|
<arg name="reset" value="/reset_pid" /> |
||||
|
<arg name="measure" value="/rated_x" /> |
||||
|
<arg name="param_P" value="simple_loop/linear_x/P.yaml" /> |
||||
|
<arg name="param_I" value="simple_loop/linear_x/I.yaml" /> |
||||
|
<arg name="param_D" value="simple_loop/linear_x/D.yaml" /> |
||||
|
<arg name="param_input" value="simple_loop/linear_x/input.yaml" /> |
||||
|
</include> |
||||
|
<node name="ratey" pkg="detect_targets" type="control_compute.py" args="rate" output="screen"> |
||||
|
<remap from="input" to="linear_y" /> |
||||
|
<remap from="output" to="rated_y" /> |
||||
|
</node> |
||||
|
<include file="$(find detect_targets)/launch/control.launch" ns="controller_linear_y"> |
||||
|
<arg name="reset" value="/reset_pid" /> |
||||
|
<arg name="measure" value="/rated_y" /> |
||||
|
<arg name="param_P" value="simple_loop/linear_y/P.yaml" /> |
||||
|
<arg name="param_I" value="simple_loop/linear_y/I.yaml" /> |
||||
|
<arg name="param_D" value="simple_loop/linear_y/D.yaml" /> |
||||
|
<arg name="param_input" value="simple_loop/linear_y/input.yaml" /> |
||||
|
</include> |
||||
|
<node name="ratez" pkg="detect_targets" type="control_compute.py" args="rate" output="screen"> |
||||
|
<remap from="input" to="linear_z" /> |
||||
|
<remap from="output" to="rated_z" /> |
||||
|
</node> |
||||
|
<include file="$(find detect_targets)/launch/control.launch" ns="controller_linear_z"> |
||||
|
<arg name="reset" value="/reset_pid" /> |
||||
|
<arg name="measure" value="/rated_z" /> |
||||
|
<arg name="param_P" value="simple_loop/linear_z/P.yaml" /> |
||||
|
<arg name="param_I" value="simple_loop/linear_z/I.yaml" /> |
||||
|
<arg name="param_D" value="simple_loop/linear_z/D.yaml" /> |
||||
|
<arg name="param_input" value="simple_loop/linear_z/input.yaml" /> |
||||
|
</include> |
||||
|
<node name="rate_ang_z" pkg="detect_targets" type="control_compute.py" args="rate" output="screen"> |
||||
|
<remap from="input" to="angular_z" /> |
||||
|
<remap from="output" to="rated_ang_z" /> |
||||
|
</node> |
||||
|
<include file="$(find detect_targets)/launch/control.launch" ns="controller_angular_z"> |
||||
|
<arg name="reset" value="/reset_pid" /> |
||||
|
<arg name="measure" value="/rated_ang_z" /> |
||||
|
<arg name="param_P" value="simple_loop/angular_z/P.yaml" /> |
||||
|
<arg name="param_I" value="simple_loop/angular_z/I.yaml" /> |
||||
|
<arg name="param_D" value="simple_loop/angular_z/D.yaml" /> |
||||
|
<arg name="param_input" value="simple_loop/angular_z/input.yaml" /> |
||||
|
</include> |
||||
|
|
||||
|
<node name="twister" pkg="detect_targets" type="twist_controls.py"> |
||||
|
<remap from="control_linear_z" to="controller_linear_z/output" /> |
||||
|
<remap from="control_angular_z" to="controller_angular_z/output" /> |
||||
|
<remap from="control_linear_x" to="controller_linear_x/output" /> |
||||
|
<remap from="control_linear_y" to="controller_linear_y/output" /> |
||||
|
</node> |
||||
|
|
||||
|
|
||||
|
<node name="safe" pkg="detect_targets" type="safe_drone_teleop.py" output="screen" launch-prefix="xterm -e"> |
||||
|
<remap from="takeoff" to="/bebop/takeoff"/> |
||||
|
<remap from="land" to="/bebop/land"/> |
||||
|
<remap from="reset" to="/bebop/reset"/> |
||||
|
<remap from="cmd_vel_out" to="/bebop/cmd_vel"/> |
||||
|
<remap from="cmd_vel_in" to="/cmd_vel"/> |
||||
|
</node> |
||||
|
|
||||
|
|
||||
|
<node name="view" pkg="rqt_image_view" type="rqt_image_view" args="/bebop/image_raw"/> |
||||
|
<node name="view_targets" pkg="rqt_image_view" type="rqt_image_view" args="/img_targets"/> |
||||
|
|
||||
|
<node name="graph" pkg="rqt_graph" type="rqt_graph" output="screen"></node> |
||||
|
<node name="reconf" pkg="rqt_reconfigure" type="rqt_reconfigure"/> |
||||
|
|
||||
|
</launch> |
||||
@ -0,0 +1,19 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
k: 1.0 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
refresh_time: 0.05 |
||||
|
state: true |
||||
|
type: '' |
||||
|
state: [] |
||||
|
k: 1.0 |
||||
|
refresh_time: 0.05 |
||||
|
state: [] |
||||
@ -0,0 +1,21 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
angular: 0.5 |
||||
|
delay: 2.0 |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
angular: 0.5 |
||||
|
delay: 2.0 |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
linear: 0.5 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
state: true |
||||
|
type: '' |
||||
|
state: [] |
||||
|
linear: 0.5 |
||||
|
state: [] |
||||
@ -0,0 +1,25 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
deriv: 1 |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
deriv: 1 |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
k: -0.67 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
poly_order: 2 |
||||
|
refresh_time: 0.05 |
||||
|
size: 19 |
||||
|
state: true |
||||
|
type: '' |
||||
|
state: [] |
||||
|
k: -0.67 |
||||
|
poly_order: 2 |
||||
|
refresh_time: 0.05 |
||||
|
size: 19 |
||||
|
state: [] |
||||
@ -0,0 +1,27 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
k: -0.8 |
||||
|
max: 0.0 |
||||
|
min: 0.0 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
refresh_time: 0.05 |
||||
|
state: true |
||||
|
type: '' |
||||
|
use_max: false |
||||
|
use_min: false |
||||
|
state: [] |
||||
|
k: -0.8 |
||||
|
max: 0.0 |
||||
|
min: 0.0 |
||||
|
refresh_time: 0.05 |
||||
|
use_max: false |
||||
|
use_min: false |
||||
|
state: [] |
||||
@ -0,0 +1,19 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
k: -1.1 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
refresh_time: 0.05 |
||||
|
state: true |
||||
|
type: '' |
||||
|
state: [] |
||||
|
k: -1.1 |
||||
|
refresh_time: 0.05 |
||||
|
state: [] |
||||
@ -0,0 +1,17 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
state: true |
||||
|
type: '' |
||||
|
value: 0.0 |
||||
|
state: [] |
||||
|
value: 0.0 |
||||
|
state: [] |
||||
@ -0,0 +1,25 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
deriv: 1 |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
deriv: 1 |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
k: -0.1 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
poly_order: 2 |
||||
|
refresh_time: 0.05 |
||||
|
size: 11 |
||||
|
state: true |
||||
|
type: '' |
||||
|
state: [] |
||||
|
k: -0.1 |
||||
|
poly_order: 2 |
||||
|
refresh_time: 0.05 |
||||
|
size: 11 |
||||
|
state: [] |
||||
@ -0,0 +1,27 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
k: 0.0 |
||||
|
max: 0.0 |
||||
|
min: 0.0 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
refresh_time: 0.05 |
||||
|
state: true |
||||
|
type: '' |
||||
|
use_max: false |
||||
|
use_min: false |
||||
|
state: [] |
||||
|
k: 0.0 |
||||
|
max: 0.0 |
||||
|
min: 0.0 |
||||
|
refresh_time: 0.05 |
||||
|
use_max: false |
||||
|
use_min: false |
||||
|
state: [] |
||||
@ -0,0 +1,19 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
k: -0.07 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
refresh_time: 0.05 |
||||
|
state: true |
||||
|
type: '' |
||||
|
state: [] |
||||
|
k: -0.07 |
||||
|
refresh_time: 0.05 |
||||
|
state: [] |
||||
@ -0,0 +1,17 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
state: true |
||||
|
type: '' |
||||
|
value: 2.5 |
||||
|
state: [] |
||||
|
value: 2.5 |
||||
|
state: [] |
||||
@ -0,0 +1,25 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
deriv: 1 |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
deriv: 1 |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
k: 0.14 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
poly_order: 2 |
||||
|
refresh_time: 0.05 |
||||
|
size: 11 |
||||
|
state: true |
||||
|
type: '' |
||||
|
state: [] |
||||
|
k: 0.14 |
||||
|
poly_order: 2 |
||||
|
refresh_time: 0.05 |
||||
|
size: 11 |
||||
|
state: [] |
||||
@ -0,0 +1,27 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
k: 0.0 |
||||
|
max: 0.0 |
||||
|
min: 0.0 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
refresh_time: 0.05 |
||||
|
state: true |
||||
|
type: '' |
||||
|
use_max: false |
||||
|
use_min: false |
||||
|
state: [] |
||||
|
k: 0.0 |
||||
|
max: 0.0 |
||||
|
min: 0.0 |
||||
|
refresh_time: 0.05 |
||||
|
use_max: false |
||||
|
use_min: false |
||||
|
state: [] |
||||
@ -0,0 +1,19 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
k: 0.27 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
refresh_time: 0.05 |
||||
|
state: true |
||||
|
type: '' |
||||
|
state: [] |
||||
|
k: 0.27 |
||||
|
refresh_time: 0.05 |
||||
|
state: [] |
||||
@ -0,0 +1,17 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
state: true |
||||
|
type: '' |
||||
|
value: 0.0 |
||||
|
state: [] |
||||
|
value: 0.0 |
||||
|
state: [] |
||||
@ -0,0 +1,25 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
deriv: 1 |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
deriv: 1 |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
k: 0.63 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
poly_order: 2 |
||||
|
refresh_time: 0.05 |
||||
|
size: 11 |
||||
|
state: true |
||||
|
type: '' |
||||
|
state: [] |
||||
|
k: 0.63 |
||||
|
poly_order: 2 |
||||
|
refresh_time: 0.05 |
||||
|
size: 11 |
||||
|
state: [] |
||||
@ -0,0 +1,27 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
k: 1.52 |
||||
|
max: 0.0 |
||||
|
min: 0.0 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
refresh_time: 0.05 |
||||
|
state: true |
||||
|
type: '' |
||||
|
use_max: false |
||||
|
use_min: false |
||||
|
state: [] |
||||
|
k: 1.52 |
||||
|
max: 0.0 |
||||
|
min: 0.0 |
||||
|
refresh_time: 0.05 |
||||
|
use_max: false |
||||
|
use_min: false |
||||
|
state: [] |
||||
@ -0,0 +1,19 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
k: 1.2 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
refresh_time: 0.05 |
||||
|
state: true |
||||
|
type: '' |
||||
|
state: [] |
||||
|
k: 1.2 |
||||
|
refresh_time: 0.05 |
||||
|
state: [] |
||||
@ -0,0 +1,17 @@ |
|||||
|
!!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
dictitems: |
||||
|
groups: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
id: 0 |
||||
|
name: Default |
||||
|
parameters: !!python/object/new:dynamic_reconfigure.encoding.Config |
||||
|
state: [] |
||||
|
parent: 0 |
||||
|
state: true |
||||
|
type: '' |
||||
|
value: 0.0 |
||||
|
state: [] |
||||
|
value: 0.0 |
||||
|
state: [] |
||||
@ -0,0 +1,221 @@ |
|||||
|
#! /usr/bin/env python |
||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
import curses |
||||
|
import math |
||||
|
import rospy |
||||
|
import sys |
||||
|
import dynamic_reconfigure.server |
||||
|
from std_msgs.msg import String |
||||
|
from std_msgs.msg import Empty |
||||
|
from geometry_msgs.msg import Twist |
||||
|
from demo_teleop.cfg import SafeDroneTeleopConfig |
||||
|
|
||||
|
class Status: |
||||
|
def __init__(self): |
||||
|
self.status = "landed" # "landing" "taking off" "automatic flight" "manual flight" |
||||
|
self.last_time = rospy.Time() |
||||
|
self.last_input = rospy.Time() |
||||
|
self.twist = Twist() |
||||
|
self.in_twist = Twist() |
||||
|
self.state_wait = 3.0 # transition between states (taking_off, landing, etc..) |
||||
|
self.watchdog_time = .25 # input crash security delay (no input twist => stop) |
||||
|
self.linear = 0.1 # initial value |
||||
|
self.angular = 0.5 # initial value |
||||
|
self.delay = 2.0 # initial value |
||||
|
self.status_pub = rospy.Publisher ('status', String, queue_size=1) |
||||
|
self.r_pub = rospy.Publisher ('reset', Empty, queue_size=1) |
||||
|
self.r_pid_pub = rospy.Publisher ('reset_pid', Empty, queue_size=1) |
||||
|
self.t_pub = rospy.Publisher ('takeoff', Empty, queue_size=1) |
||||
|
self.l_pub = rospy.Publisher ('land', Empty, queue_size=1) |
||||
|
self.twist_pub = rospy.Publisher ('cmd_vel_out', Twist, queue_size=1) |
||||
|
self.twist_sub = rospy.Subscriber('cmd_vel_in', Twist, self.on_twist, queue_size = 1) |
||||
|
self.config_srv = dynamic_reconfigure.server.Server(SafeDroneTeleopConfig, self.on_reconf) |
||||
|
|
||||
|
def on_reconf(self, config, level): |
||||
|
self.angular = config['angular'] |
||||
|
self.linear = config['linear'] |
||||
|
self.delay = config['delay'] |
||||
|
return config |
||||
|
|
||||
|
def on_twist(self, ros_data): |
||||
|
self.in_twist = ros_data |
||||
|
self.last_input = rospy.Time.now() |
||||
|
if self.status == "automatic flight": |
||||
|
self.twist_pub.publish(self.in_twist) |
||||
|
|
||||
|
def send_twist(self): |
||||
|
if self.status == "manual flight": |
||||
|
self.twist_pub.publish(self.twist) |
||||
|
|
||||
|
def take_off(self): |
||||
|
if self.status == "landed" : |
||||
|
self.twist = Twist() |
||||
|
self.status = "taking off" |
||||
|
self.status_pub.publish(self.status) |
||||
|
self.r_pub.publish(Empty()) |
||||
|
rospy.sleep(1.) |
||||
|
self.t_pub.publish(Empty()) |
||||
|
self.last_time = rospy.Time.now() |
||||
|
|
||||
|
def land(self): |
||||
|
self.last_time = rospy.Time.now() |
||||
|
self.twist = Twist() |
||||
|
self.status = "landing" |
||||
|
self.l_pub.publish(Empty()) |
||||
|
|
||||
|
def nop(self): |
||||
|
if self.status == "manual flight" : |
||||
|
time = rospy.Time.now() |
||||
|
if (time - self.last_time).to_sec() > self.delay : |
||||
|
self.status = "automatic flight" |
||||
|
self.r_pid_pub.publish(Empty()) |
||||
|
elif self.status == "taking off": |
||||
|
time = rospy.Time.now() |
||||
|
if (time - self.last_time).to_sec() > self.state_wait : |
||||
|
self.status = "manual flight" |
||||
|
self.last_time = time |
||||
|
self.twist = Twist() |
||||
|
elif self.status == "landing": |
||||
|
time = rospy.Time.now() |
||||
|
if (time - self.last_time).to_sec() > self.state_wait : |
||||
|
self.status = "landed" |
||||
|
self.status_pub.publish(self.status) |
||||
|
self.send_twist() |
||||
|
|
||||
|
def key_pressed(self): |
||||
|
self.last_time = rospy.Time.now() |
||||
|
if self.status != "manual flight": |
||||
|
self.twist = Twist() |
||||
|
if self.status == "automatic flight" : |
||||
|
self.status = "manual flight" |
||||
|
self.send_twist() |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
def main(stdscr): |
||||
|
xlevel = 0 |
||||
|
ylevel = 0 |
||||
|
zlevel = 0 |
||||
|
alevel = 0 |
||||
|
rospy.init_node('safe_drone_teleop', anonymous=True) |
||||
|
log_pub = rospy.Publisher ('log', String, queue_size=1) |
||||
|
rate = rospy.Rate(10) |
||||
|
keycode = -1 |
||||
|
status = Status() |
||||
|
stdscr.addstr("Safe drone controller\n") |
||||
|
stdscr.addstr("---------------------\n") |
||||
|
stdscr.addstr("\n") |
||||
|
stdscr.addstr("Command\n") |
||||
|
stdscr.addstr(" - UP/DOWN : control linear x\n") |
||||
|
stdscr.addstr(" - LEFT/RIGHT : control linear y\n") |
||||
|
stdscr.addstr(" - e/r : control angular z\n") |
||||
|
stdscr.addstr(" - t/l : take off / land\n") |
||||
|
stdscr.addstr(" - PAGE UP/DOWN : elevation control\n") |
||||
|
stdscr.addstr(" - any key : reset of the twist\n") |
||||
|
# We set the "wait for a key press" period to 100 ms. |
||||
|
stdscr.timeout(100) |
||||
|
while (not rospy.is_shutdown()): |
||||
|
keycode = stdscr.getch() # Wait for a key press for at most 100ms |
||||
|
if keycode == -1 : |
||||
|
status.nop() # No key has been pressed, we keep current twist. |
||||
|
elif keycode == curses.KEY_UP : |
||||
|
status.key_pressed() |
||||
|
if xlevel == -1 : |
||||
|
status.twist.linear.x = 0 |
||||
|
xlevel = 0 |
||||
|
elif xlevel == 0: |
||||
|
status.twist.linear.x = status.linear |
||||
|
xlevel = 1 |
||||
|
elif keycode == curses.KEY_DOWN : |
||||
|
status.key_pressed() |
||||
|
if xlevel == 0 : |
||||
|
status.twist.linear.x = -status.linear |
||||
|
xlevel = -1 |
||||
|
elif xlevel == 1: |
||||
|
status.twist.linear.x = 0 |
||||
|
xlevel = 0 |
||||
|
elif keycode == curses.KEY_LEFT : |
||||
|
status.key_pressed() |
||||
|
if ylevel == -1 : |
||||
|
status.twist.linear.y = 0 |
||||
|
ylevel = 0 |
||||
|
elif ylevel == 0: |
||||
|
status.twist.linear.y = status.linear |
||||
|
ylevel = 1 |
||||
|
elif keycode == curses.KEY_RIGHT : |
||||
|
status.key_pressed() |
||||
|
if ylevel == 0 : |
||||
|
status.twist.linear.y = -status.linear |
||||
|
ylevel = -1 |
||||
|
elif ylevel == 1: |
||||
|
status.twist.linear.y = 0 |
||||
|
ylevel = 0 |
||||
|
elif keycode == curses.KEY_PPAGE : |
||||
|
status.key_pressed() |
||||
|
if zlevel == -1 : |
||||
|
status.twist.linear.z = 0 |
||||
|
zlevel = 0 |
||||
|
elif zlevel == 0: |
||||
|
status.twist.linear.z = status.linear |
||||
|
zlevel = 1 |
||||
|
elif keycode == curses.KEY_NPAGE : |
||||
|
status.key_pressed() |
||||
|
if zlevel == 1 : |
||||
|
status.twist.linear.z = 0 |
||||
|
zlevel = 0 |
||||
|
elif zlevel == 0: |
||||
|
status.twist.linear.z = -status.linear |
||||
|
zlevel = -1 |
||||
|
elif keycode == 101 : # e |
||||
|
status.key_pressed() |
||||
|
if alevel == -1 : |
||||
|
status.twist.angular.z = 0 |
||||
|
alevel = 0 |
||||
|
elif alevel == 0: |
||||
|
status.twist.angular.z = status.angular |
||||
|
alevel = 1 |
||||
|
elif keycode == 114 : # r |
||||
|
status.key_pressed() |
||||
|
if alevel == 0 : |
||||
|
status.twist.angular.z = -status.angular |
||||
|
alevel = -1 |
||||
|
elif alevel == 1: |
||||
|
status.twist.angular.z = 0 |
||||
|
alevel = 0 |
||||
|
elif keycode == 116 : # t |
||||
|
status.take_off() |
||||
|
xlevel = 0 |
||||
|
ylevel = 0 |
||||
|
zlevel = 0 |
||||
|
alevel = 0 |
||||
|
elif keycode == 108 : # l |
||||
|
status.land() |
||||
|
xlevel = 0 |
||||
|
ylevel = 0 |
||||
|
zlevel = 0 |
||||
|
alevel = 0 |
||||
|
else : |
||||
|
status.key_pressed() |
||||
|
status.twist = Twist() |
||||
|
xlevel = 0 |
||||
|
ylevel = 0 |
||||
|
zlevel = 0 |
||||
|
alevel = 0 |
||||
|
if status.status == "automatic flight" : |
||||
|
xlevel = 0 |
||||
|
ylevel = 0 |
||||
|
zlevel = 0 |
||||
|
alevel = 0 |
||||
|
status.twist = Twist() |
||||
|
|
||||
|
|
||||
|
|
||||
|
# Starts curses (terminal handling) and run our main function. |
||||
|
if __name__ == '__main__': |
||||
|
try: |
||||
|
curses.wrapper(lambda w: main(w)) |
||||
|
except rospy.ROSInterruptException: |
||||
|
pass |
||||
Loading…
Reference in new issue