Drone: Rewrite copter_client with new animation module

This commit is contained in:
Arthur Golubtsov
2020-05-29 12:28:28 +03:00
parent d775ea4e8b
commit 4c5032b975
2 changed files with 232 additions and 195 deletions

View File

@@ -39,11 +39,11 @@ decrease_thrust_after = float(default=5.0, min=0)
[COPTER]
frame_id = string(default=map)
arming_time = float(default=0.5)
takeoff_height = float(default=1.0)
takeoff_time = float(default=5.0, min=0)
safe_takeoff = boolean(default=False)
reach_first_point_time = float(default=5.0, min=0)
land_time = float(default=1.0, min=0)
land_delay = float(default=1.0, min=0)
land_timeout = float(default=10.0, min=0)
# __list__ x y z
common_offset = float_list(default=list(0, 0, 0), min=3, max=3)
@@ -63,20 +63,28 @@ lon = string(default=0)
yaw = float(default=0)
[ANIMATION]
takeoff_detection = boolean(default=True)
land_detection = boolean(default=True)
# Available options:
# 'auto' - automatic action selection from 'takeoff' or 'fly' based on current copter level
# 'takeoff' - takeoff to first output animation point after static_begin_time then execute 'takeoff logic'
# 'fly' - execute animation frames after static_begin_time
start_action = string(default=auto)
takeoff_level = float(default=0.5)
ground_level = float(default=0)
frame_delay = float(default=0.1, min=0.01)
# Animation ratio (x, y, z)
# __list__ x y z
ratio = float_list(default=list(1.0, 1.0, 1.0), min=3, max=3)
# Available options: 'animation', 'nan' or a number in degrees
# Available options:
# 'animation' - take yaw from animation
# 'nan' - don't change yaw during flight
# or a number in degrees
yaw = string(default=180.0)
[[OUTPUT]]
static_begin = boolean(default=False)
takeoff = boolean(default=True)
route = boolean(default=True)
land = boolean(default=False)
static_end = boolean(default=False)
[[OUTPUT]]
static_begin = boolean(default=False)
takeoff = boolean(default=True)
route = boolean(default=True)
land = boolean(default=False)
static_end = boolean(default=False)
[LED]
use = boolean(default=False)

View File

@@ -9,7 +9,10 @@ import numpy
try:
from clever import srv
except ImportError:
from clover import srv
try:
from clover import srv
except ImportError:
print("Can't import clever or clover")
import datetime
import logging
@@ -17,8 +20,17 @@ import threading
import psutil
import subprocess
from collections import namedtuple
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from FlightLib import FlightLib
try:
from FlightLib import FlightLib
except ImportError:
print("Can't import FlightLib")
try:
from FlightLib import LedLib
except ImportError:
print("Can't import LedLib")
import client
@@ -46,6 +58,12 @@ def azi(x, y):
def get_xy(dist, azi):
return dist*math.sin(math.radians(azi)), dist*math.cos(math.radians(azi))
def valid(pos):
for coord in pos:
if math.isnan(coord):
return False
return True
static_broadcaster = tf2_ros.StaticTransformBroadcaster()
emergency = False
@@ -96,8 +114,8 @@ class CopterClient(client.Client):
def __init__(self, config_path="config/client.ini"):
super(CopterClient, self).__init__(config_path)
self.load_config()
self.frames = {}
self.telemetry = None
self.animation = animation.Animation(self.config, "animation.csv")
def load_config(self):
super(CopterClient, self).load_config()
@@ -111,7 +129,7 @@ class CopterClient(client.Client):
if self.config.led_use:
from FlightLib import LedLib
LedLib.init_led(self.config.led_pin)
task_manager_instance.start() # TODO move to self
task_manager_instance.start()
start_subscriber()
self.telemetry = Telemetry()
self.telemetry.start_loop()
@@ -158,11 +176,11 @@ class CopterClient(client.Client):
lat = float(self.config.gps_frame_lat)
lon = float(self.config.gps_frame_lon)
geo_delta = Earth.Inverse(telem.lat, telem.lon, lat, lon)
logger.info("dist: {} | azi: {}".format(geo_delta['s12'], geo_delta['azi1']))
#logger.info("dist: {} | azi: {}".format(geo_delta['s12'], geo_delta['azi1']))
dx, dy = get_xy(geo_delta['s12'], geo_delta['azi1'])
gps_dx = telem.x + dx
gps_dy = telem.y + dy
logger.info("GPS frame dx: {} | dy: {}".format(gps_dx, gps_dy))
#logger.info("GPS frame dx: {} | dy: {}".format(gps_dx, gps_dy))
trans = TransformStamped()
trans.transform.translation.x = gps_dx
trans.transform.translation.y = gps_dy
@@ -314,13 +332,13 @@ def _execute(*args, **kwargs):
def _response_id(*args, **kwargs):
new_id = kwargs.get("new_id", None)
if new_id is not None:
old_id = client.active_client.client_id
old_id = copter.client_id
if new_id != old_id:
client.active_client.config.set('PRIVATE', 'id', new_id, write=True)
client.active_client.client_id = new_id
copter.config.set('PRIVATE', 'id', new_id, write=True)
copter.client_id = new_id
if new_id != '/hostname':
if client.active_client.config.system_restart_after_rename:
hostname = client.active_client.client_id
if copter.config.system_restart_after_rename:
hostname = copter.client_id
configure_hostname(hostname)
configure_hosts(hostname)
configure_bashrc(hostname)
@@ -347,28 +365,14 @@ def _response_selfcheck(*args, **kwargs):
@messaging.request_callback("telemetry")
def _response_telemetry(*args, **kwargs):
telemetry.update()
return telemetry.create_msg_contents()
copter.telemetry.update()
return copter.telemetry.create_msg_contents()
@messaging.request_callback("anim_id")
def _response_animation_id(*args, **kwargs):
# Load animation
result = animation.get_id()
if result != 'No animation':
logger.debug("Saving corrected animation")
offset = numpy.array(client.active_client.config.private_offset) + numpy.array(client.active_client.config.copter_common_offset)
frames = animation.load_animation(os.path.abspath("animation.csv"), client.active_client.config.animation_frame_delay,
offset[0], offset[1], offset[2], *client.active_client.config.animation_ratio)
# Correct start and land frames in animation
corrected_frames, start_action, start_delay = animation.correct_animation(frames,
check_takeoff=client.active_client.config.animation_takeoff_detection,
check_land=client.active_client.config.animation_land_detection,
)
logger.debug("Start action: {}".format(start_action))
# Save corrected animation
animation.save_corrected_animation(corrected_frames)
return result
return copter.animation.id
@messaging.request_callback("batt_voltage")
@@ -405,9 +409,9 @@ def _response_cal_status(*args, **kwargs):
@messaging.request_callback("position")
def _response_position(*args, **kwargs):
telem = FlightLib.get_telemetry_locked(client.active_client.config.copter_frame_id)
telem = copter.telemetry.ros_telemetry
return "{:.2f} {:.2f} {:.2f} {:.1f} {}".format(
telem.x, telem.y, telem.z, math.degrees(telem.yaw), client.active_client.config.copter_frame_id)
telem.x, telem.y, telem.z, math.degrees(telem.yaw), copter.config.copter_frame_id)
@messaging.request_callback("calibrate_gyro")
@@ -436,60 +440,61 @@ def _command_test(*args, **kwargs):
print("stdout test")
@messaging.message_callback("update_animation")
def _command_update_animation(*args, **kwargs):
copter.animation.update_frames(copter.config, "animation.csv")
@messaging.message_callback("move_start")
def _command_move_start_to_current_position(*args, **kwargs):
x_start, y_start = animation.get_start_xy(os.path.abspath("animation.csv"),
*client.active_client.config.animation_ratio)
logger.debug("x_start = {}, y_start = {}".format(x_start, y_start))
if not math.isnan(x_start):
telem = FlightLib.get_telemetry_locked(client.active_client.config.copter_frame_id)
logger.debug("x_telem = {}, y_telem = {}".format(telem.x, telem.y))
if not math.isnan(telem.x):
client.active_client.config.set('PRIVATE', 'offset',
[telem.x - x_start, telem.y - y_start, client.active_client.config.private_offset[2]],
write=True)
logger.info("Set start delta: {:.2f} {:.2f}".format(client.active_client.config.private_offset[0],
client.active_client.config.private_offset[1]))
else:
logger.debug("Wrong telemetry")
offset = numpy.array(copter.config.private_offset) + numpy.array(copter.config.copter_common_offset)
try:
xs, ys, zs = copter.animation.get_start_point(copter.config.ratio, offset)
except ValueError:
logger.error("Can't get start point. Check animation file!")
else:
logger.debug("Wrong animation file")
logger.debug("start x = {}, y = {}".format(xs, ys))
telem = copter.telemetry.ros_telemetry
logger.debug("telemetry x = {}, y = {}".format(telem.x, telem.y))
if valid([telem.x, telem.y, telem.z]):
copter.config.set('PRIVATE', 'offset',
[telem.x - xs, telem.y - ys, copter.config.private_offset[2]], write=True)
logger.info("Set start delta: {:.2f} {:.2f}".format(copter.config.private_offset[0],
copter.config.private_offset[1]))
else:
logger.error("Wrong telemetry")
@messaging.message_callback("reset_start")
def _command_reset_start(*args, **kwargs):
client.active_client.config.set('PRIVATE', 'offset',
[0, 0, client.active_client.config.private_offset[2]],
write=True)
logger.info("Reset start to {:.2f} {:.2f}".format(client.active_client.config.private_offset[0],
client.active_client.config.private_offset[1]))
copter.config.set('PRIVATE', 'offset',
[0, 0, copter.config.private_offset[2]], write=True)
logger.info("Reset start to {:.2f} {:.2f}".format(copter.config.private_offset[0],
copter.config.private_offset[1]))
@messaging.message_callback("set_z_to_ground")
def _command_set_z(*args, **kwargs):
telem = FlightLib.get_telemetry_locked(client.active_client.config.copter_frame_id)
client.active_client.config.set('PRIVATE', 'offset',
[client.active_client.config.private_offset[0], client.active_client.config.private_offset[1], telem.z],
write=True)
logger.info("Set z offset to {:.2f}".format(client.active_client.config.private_offset[2]))
telem = copter.telemetry.ros_telemetry
if valid([telem.x, telem.y, telem.z]):
copter.config.set('PRIVATE', 'offset',
[copter.config.private_offset[0], copter.config.private_offset[1], telem.z], write=True)
logger.info("Set z offset to {:.2f}".format(copter.config.private_offset[2]))
else:
logger.error("Wrong telemetry")
@messaging.message_callback("reset_z_offset")
def _command_reset_z(*args, **kwargs):
client.active_client.config.set('PRIVATE', 'offset',
[client.active_client.config.private_offset[0], client.active_client.config.private_offset[1], 0],
write=True)
logger.info("Reset z offset to {:.2f}".format(client.active_client.config.private_offset[2]))
copter.config.set('PRIVATE', 'offset',
[copter.config.private_offset[0], copter.config.private_offset[1], 0], write=True)
logger.info("Reset z offset to {:.2f}".format(copter.config.private_offset[2]))
@messaging.message_callback("update_repo")
def _command_update_repo(*args, **kwargs):
os.system("mv /home/pi/clever-show/Drone/client_config.ini /home/pi/clever-show/Drone/client_config_tmp.ini")
os.system("git reset --hard HEAD")
os.system("git checkout master")
os.system("git fetch")
os.system("git pull --rebase")
os.system("mv /home/pi/clever-show/Drone/client_config_tmp.ini /home/pi/clever-show/Drone/client_config.ini")
os.system("chown -R pi:pi /home/pi/clever-show")
@@ -512,7 +517,7 @@ def _command_service_restart(*args, **kwargs):
@messaging.message_callback("repair_chrony")
def _command_chrony_repair(*args, **kwargs):
repair_chrony(client.active_client.config.server_host)
repair_chrony(copter.config.server_host)
@messaging.message_callback("led_test")
@@ -527,13 +532,12 @@ def _command_led_fill(*args, **kwargs):
r = kwargs.get("red", 0)
g = kwargs.get("green", 0)
b = kwargs.get("blue", 0)
LedLib.fill(r, g, b)
@messaging.message_callback("flip")
def _copter_flip(*args, **kwargs):
FlightLib.flip(frame_id=client.active_client.config.copter_frame_id)
FlightLib.flip(frame_id=copter.config.copter_frame_id)
@messaging.message_callback("takeoff")
@@ -541,30 +545,36 @@ def _command_takeoff(*args, **kwargs):
logger.info("Takeoff at {}".format(datetime.datetime.now()))
task_manager.add_task(0, 0, animation.takeoff,
task_kwargs={
"z": client.active_client.config.copter_takeoff_height,
"timeout": client.active_client.config.copter_takeoff_time,
"safe_takeoff": client.active_client.config.copter_safe_takeoff,
"use_leds": client.active_client.config.led_use & client.active_client.config.led_takeoff_indication,
}
)
"z": copter.config.copter_takeoff_height,
"timeout": copter.config.copter_takeoff_time,
"safe_takeoff": False,
"use_leds": copter.config.led_use & copter.config.led_takeoff_indication,
})
@messaging.message_callback("takeoff_z")
def _command_takeoff_z(*args, **kwargs):
z_str = kwargs.get("z", None)
if z_str is not None:
telem = FlightLib.get_telemetry_locked(client.active_client.config.copter_frame_id)
logger.info("Takeoff to z = {} at {}".format(z_str, datetime.datetime.now()))
task_manager.add_task(0, 0, FlightLib.reach_point,
task_kwargs={
"x": telem.x,
"y": telem.y,
"z": float(z_str),
"frame_id": client.active_client.config.copter_frame_id,
"timeout": client.active_client.config.copter_takeoff_time,
"auto_arm": True,
}
)
try:
z = float(kwargs.get("z", None))
except TypeError:
logger.error("takeoff_z: No z argument!")
except ValueError:
logger.error("takeoff_z: Wrong z argument!")
else:
telem = FlightLib.get_telemetry_locked(copter.config.copter_frame_id)
if valid([telem.x, telem.y, telem.z]):
logger.info("Takeoff to z = {} at {}".format(z, datetime.datetime.now()))
task_manager.add_task(0, 0, FlightLib.reach_point,
task_kwargs={
"x": telem.x,
"y": telem.y,
"z": z,
"frame_id": copter.config.copter_frame_id,
"timeout": copter.config.copter_takeoff_time,
"auto_arm": True,
})
else:
logger.error("Wrong telemetry!")
@messaging.message_callback("land")
@@ -572,12 +582,11 @@ def _command_land(*args, **kwargs):
task_manager.reset()
task_manager.add_task(0, 0, animation.land,
task_kwargs={
"z": client.active_client.config.copter_takeoff_height,
"timeout": client.active_client.config.copter_takeoff_time,
"frame_id": client.active_client.config.copter_frame_id,
"use_leds": client.active_client.config.led_use & client.active_client.config.led_land_indication,
}
)
"z": copter.config.copter_takeoff_height,
"timeout": copter.config.copter_land_timeout,
"frame_id": copter.config.copter_frame_id,
"use_leds": copter.config.led_use & copter.config.led_land_indication,
})
@messaging.message_callback("emergency_land")
@@ -591,8 +600,7 @@ def _command_disarm(*args, **kwargs):
task_manager.add_task(-5, 0, FlightLib.arming_wrapper,
task_kwargs={
"state": False
}
)
})
@messaging.message_callback("stop")
@@ -612,109 +620,104 @@ def _command_resume(*args, **kwargs):
@messaging.message_callback("start")
def _play_animation(*args, **kwargs):
start_time = float(kwargs["time"])
# Check if animation file is available
if animation.get_id() == 'No animation':
logger.error("Can't start animation without animation file!")
# Validate start_time
try:
start_time = float(kwargs["time"])
except ValueError:
logger.error("start: Wrong time argument!")
return
except KeyError:
logger.error("start: No time argument!")
return
# Check animation state
if copter.animation.state is not "OK":
logger.error("start: Bad animation state")
return
# Get output frames
offset = numpy.array(copter.config.private_offset) + numpy.array(copter.config.copter_common_offset)
frames = copter.animation.get_scaled_output(copter.config.animation_ratio, offset)
if not frames:
logger.error("start: No frames in animation!")
return
# Get current telemetry
telem = copter.telemetry.ros_telemetry
if not valid([telem.x, telem.y, telem.z]):
logger.error("start: Position is not valid!")
return
# Get start action and delay
start_action, start_delay = copter.telemetry.start_action_and_delay
# Reset task manager
task_manager.reset(interrupt_next_task=False)
logger.info("Start time = {}, wait for {} seconds".format(start_time, start_time - time.time()))
# Load animation
offset = numpy.array(client.active_client.config.private_offset) + numpy.array(client.active_client.config.copter_common_offset)
frames = animation.load_animation(os.path.abspath("animation.csv"), client.active_client.config.animation_frame_delay,
offset[0], offset[1], offset[2], *client.active_client.config.animation_ratio)
# Correct start and land frames in animation
corrected_frames, start_action, start_delay = animation.correct_animation(frames,
check_takeoff=client.active_client.config.animation_takeoff_detection,
check_land=client.active_client.config.animation_land_detection,
)
# Choose start action
# Set animation logic
if start_action == 'takeoff':
# Takeoff first
task_manager.add_task(start_time, 0, animation.takeoff,
# Takeoff first at start_time + start_delay_time
takeoff_time = start_time + start_delay
task_manager.add_task(takeoff_time, 0, animation.takeoff,
task_kwargs={
"z": client.active_client.config.copter_takeoff_height,
"timeout": client.active_client.config.copter_takeoff_time,
"safe_takeoff": client.active_client.config.copter_safe_takeoff,
# "frame_id": client.active_client.config.copter_frame_id,
"use_leds": client.active_client.config.led_use & client.active_client.config.led_takeoff_indication,
}
)
"z": copter.config.copter_takeoff_height,
"timeout": copter.config.copter_takeoff_time,
"safe_takeoff": False,
"use_leds": copter.config.led_use & copter.config.led_takeoff_indication,
})
# Fly to first point
rfp_time = start_time + client.active_client.config.copter_takeoff_time
if client.active_client.config.animation_yaw == "animation":
yaw = frame["yaw"]
else:
yaw = math.radians(float(client.active_client.config.animation_yaw))
rfp_time = takeoff_time + copter.config.copter_takeoff_time
task_manager.add_task(rfp_time, 0, animation.execute_frame,
task_kwargs={
"point": animation.convert_frame(corrected_frames[0])[0],
"color": animation.convert_frame(corrected_frames[0])[1],
"yaw": yaw,
"frame_id": client.active_client.config.copter_frame_id,
"use_leds": client.active_client.config.led_use,
"frame": frames[0],
"frame_id": copter.config.copter_frame_id,
"use_leds": copter.config.led_use,
"flight_func": FlightLib.reach_point,
}
)
})
# Calculate first frame start time
frame_time = rfp_time + client.active_client.config.copter_reach_first_point_time
frame_time = rfp_time + copter.config.copter_reach_first_point_time
elif start_action == 'arm':
# Calculate start time
start_time += start_delay
frame_time = start_time # + 1.0
point, color, yaw = animation.convert_frame(corrected_frames[0])
task_manager.add_task(frame_time, 0, animation.execute_frame,
arm_time = start_time + start_delay # + 1.0
task_manager.add_task(arm_time, 0, animation.execute_frame,
task_kwargs={
"point": point,
"color": color,
"frame_id": client.active_client.config.copter_frame_id,
"use_leds": client.active_client.config.led_use,
"frame": frames[0],
"frame_id": copter.config.copter_frame_id,
"use_leds": copter.config.led_use,
"flight_func": FlightLib.navto,
"auto_arm": True,
}
)
})
# Calculate first frame start time
frame_time += corrected_frames[0]["delay"] # TODO Think about arming time
logger.debug(task_manager.task_queue)
frame_time = arm_time + copter.config.copter_arming_time
logger.debug("Start queue {}".format(task_manager.task_queue))
# Play animation file
for frame in corrected_frames:
point, color, yaw = animation.convert_frame(frame)
if client.active_client.config.animation_yaw == "animation":
yaw = frame["yaw"]
else:
yaw = math.radians(float(client.active_client.config.animation_yaw))
for frame in frames:
task_manager.add_task(frame_time, 0, animation.execute_frame,
task_kwargs={
"point": point,
"color": color,
"yaw": yaw,
"frame_id": client.active_client.config.copter_frame_id,
"use_leds": client.active_client.config.led_use,
"frame": frame,
"frame_id": copter.config.copter_frame_id,
"use_leds": copter.config.led_use,
"flight_func": FlightLib.navto,
}
)
frame_time += frame["delay"]
})
frame_time += frame.delay
# Calculate land_time
land_time = frame_time + client.active_client.config.copter_land_time
land_time = frame_time + copter.config.copter_land_delay
# Land
task_manager.add_task(land_time, 0, animation.land,
task_kwargs={
"timeout": client.active_client.config.copter_land_timeout,
"frame_id": client.active_client.config.copter_frame_id,
"use_leds": client.active_client.config.led_use & client.active_client.config.led_land_indication,
},
)
"timeout": copter.config.copter_land_timeout,
"frame_id": copter.config.copter_frame_id,
"use_leds": copter.config.led_use & copter.config.led_land_indication,
})
# noinspection PyAttributeOutsideInit
class Telemetry:
params_default_dict = {
"git_version": None,
"animation_id": None,
"animation_info": None,
"battery": None,
"armed": False,
"fcu_status": None,
@@ -723,6 +726,7 @@ class Telemetry:
"selfcheck": None,
"current_position": None,
"start_position": None,
"start_action_and_delay": None,
"last_task": None,
"time_delta": None,
"config_version": None,
@@ -759,16 +763,16 @@ class Telemetry:
@classmethod
def get_config_version(cls):
return "{} V{}".format(client.active_client.config.config_name, client.active_client.config.config_version)
return "{} V{}".format(copter.config.config_name, copter.config.config_version)
@classmethod
def get_start_position(cls):
x_start, y_start = animation.get_start_xy(os.path.abspath("animation.csv"),
*client.active_client.config.animation_ratio)
offset = numpy.array(client.active_client.config.private_offset) + numpy.array(client.active_client.config.copter_common_offset)
x_start, y_start, z_start = animation.get_start_pos(os.path.abspath("animation.csv"),
*copter.config.animation_ratio)
offset = numpy.array(copter.config.private_offset) + numpy.array(copter.config.copter_common_offset)
x = x_start + offset[0]
y = y_start + offset[1]
z = offset[2]
z = z_start + offset[2]
if not FlightLib._check_nans(x, y, z):
return x, y, z
return 'NO_POS'
@@ -807,14 +811,25 @@ class Telemetry:
def get_position(cls, ros_telemetry):
x, y, z = ros_telemetry.x, ros_telemetry.y, ros_telemetry.z
if not math.isnan(x):
return x, y, z, math.degrees(ros_telemetry.yaw), client.active_client.config.copter_frame_id
return x, y, z, math.degrees(ros_telemetry.yaw), copter.config.copter_frame_id
return 'NO_POS'
def get_ros_telemetry(self):
return self.ros_telemetry
def get_start_action_and_delay(self)
offset = numpy.array(copter.config.private_offset) + numpy.array(copter.config.copter_common_offset)
start_action = copter.animation.get_start_action(
copter.config.animation_start_action, self.ros_telemetry.z,
copter.config.animation_takeoff_level, copter.config.animation_ground_level,
copter.config.animation_ratio, offset)
start_delay = copter.animation.start_delay
return start_action, start_delay
def update_telemetry_fast(self):
self.start_position = self.get_start_position()
self.last_task = task_manager.get_current_task()
try:
self.ros_telemetry = FlightLib.get_telemetry_locked(client.active_client.config.copter_frame_id)
self.ros_telemetry = FlightLib.get_telemetry_locked(copter.config.copter_frame_id)
if self.ros_telemetry.connected:
self.armed = self.ros_telemetry.armed
self.mode = self.ros_telemetry.mode
@@ -832,13 +847,12 @@ class Telemetry:
self.time_delta = time.time()
self.round_telemetry()
def get_ros_telemetry(self):
return self.ros_telemetry
def update_telemetry_slow(self):
self.animation_id = animation.get_id()
self.animation_info = [copter.animation.id, copter.animation.state]
self.git_version = self.get_git_version()
self.config_version = self.get_config_version()
self.start_position = self.get_start_position()
self.start_action_and_delay = self.get_start_action_and_delay()
try:
self.calibration_status = get_calibration_status()
self.fcu_status = get_sys_status()
@@ -905,7 +919,7 @@ class Telemetry:
def transmit_message(self): # todo if connected
try:
client.active_client.server_connection.send_message('telemetry', kwargs={'value': self.create_msg_contents()})
copter.server_connection.send_message('telemetry', kwargs={'value': self.create_msg_contents()})
except AttributeError as e:
logger.debug(e)
@@ -935,7 +949,7 @@ class Telemetry:
self.update_telemetry_fast()
self.check_failsafe_and_interruption()
if client.active_client.config.telemetry_transmit and client.active_client.connected:
if copter.config.telemetry_transmit and copter.connected:
self.transmit_message()
rate.sleep()
@@ -944,14 +958,14 @@ class Telemetry:
rate = rospy.Rate(1)
while not rospy.is_shutdown():
self.update_telemetry_slow()
if client.active_client.config.telemetry_log_resources:
if copter.config.telemetry_log_resources:
self.log_cpu_and_memory()
rate.sleep()
def start_loop(self):
if client.active_client.config.telemetry_frequency > 0:
if copter.config.telemetry_frequency > 0:
telemetry_thread = threading.Thread(target=self._update_loop, name="Telemetry getting thread",
args=(client.active_client.config.telemetry_frequency,)) # TODO MOVE? Daemon?
args=(copter.config.telemetry_frequency,)) # TODO MOVE? Daemon?
slow_telemetry_thread = threading.Thread(target=self._slow_update_loop,
name="Slow telemetry getting thread")
slow_telemetry_thread.start()
@@ -971,8 +985,23 @@ def emergency_callback(data):
emergency = data.data
class AnimationEventHandler(FileSystemEventHandler):
def on_any_event(self, event):
logger.info('{} is {}'.format(event.src_path, event.event_type))
if event.src_path == "./animation.csv" and event.event_type == "modified":
copter.animation.update_frames(copter.config, "animation.csv")
if __name__ == "__main__":
copter_client = CopterClient()
copter = CopterClient()
task_manager = tasking.TaskManager()
rospy.Subscriber('/emergency', Bool, emergency_callback)
copter_client.start(task_manager)
copter.start(task_manager)
event_handler = AnimationEventHandler()
observer = Observer()
observer.schedule(event_handler, ".")
observer.start()
while not rospy.is_shutdown:
rospy.sleep(1)
observer.stop()
observer.join()