Addon: property and land\takeoff detection

This commit is contained in:
Artem30801
2020-07-17 14:15:50 +03:00
parent 6df2242131
commit f5c35caa1e
3 changed files with 103 additions and 66 deletions

View File

@@ -50,19 +50,19 @@ class CleverShowProperties(PropertyGroup):
options=set(), # not animateable
)
# takeoff_frames: IntProperty(
# name="Takeoff duration",
# description="Duration of takeoff in frames",
# default=70,
# min=1,
# )
#
# land_frames: IntProperty(
# name="Land duration",
# description="Duration of landing in frames",
# default=100,
# min=1,
# )
takeoff_frames: IntProperty(
name="Takeoff duration",
description="Duration of takeoff in frames",
default=70,
min=1,
)
land_frames: IntProperty(
name="Land duration",
description="Duration of landing in frames",
default=100,
min=1,
)
filter_obj: EnumProperty(
name="Filter objects:",

View File

@@ -16,8 +16,19 @@ def create_dir(folder_path):
os.mkdir(folder_path)
def iter_pairs(obj):
return zip(obj[::2], obj[1::2])
# def iter_pairs(obj):
# return zip(obj[::2], obj[1::2])
def neighbour_pairs(sequence):
iterable = iter(sequence)
try:
prev = next(iterable)
except StopIteration:
return ()
for item in iterable:
yield prev, item
prev = item
def get_rgb(drone_obj):
@@ -79,6 +90,7 @@ class ExportSwarmAnimation(Operator, ExportHelper):
pass
def _generate_animation(self, drone_obj, context):
# todo yield?
animation = list()
scene = context.scene
@@ -88,14 +100,13 @@ class ExportSwarmAnimation(Operator, ExportHelper):
frame_end = context.scene.frame_end
# Add frame with animation parameters
scene.frame_set(frame_start)
# animation.append({"set_fps": context.scene.render.fps,
# "drone_name": drone_obj.name,
# })
if clever_show.add_takeoff:
animation.append({"takeoff": {}})
animation.append({"set_fps": context.scene.render.fps,
"drone_name": drone_obj.name,
})
# Add flight and
# Add flight
previous_frame = dict()
for frame_num in range(frame_start, frame_end + 1):
scene.frame_set(frame_start)
position = [round(x, 3) for x in drone_obj.matrix_world.to_translation()]
@@ -103,11 +114,14 @@ class ExportSwarmAnimation(Operator, ExportHelper):
frame = dict()
# check to not update position or yaw if they are same as previous frame
if animation[-1]["fly"] != position:
if previous_frame.get("fly", None) != position:
frame.update({"fly": position})
if animation[-1]["yaw"] != yaw:
if previous_frame.get("yaw", None) != yaw:
frame.update({"yaw": yaw})
if clever_show.use_armed and previous_frame.get("armed") != drone_obj.armed:
frame.update({"armed": drone_obj.armed})
try:
led_color = get_rgb(drone_obj) # TODO!!!!!!
frame.update({"led_color": led_color})
@@ -115,6 +129,10 @@ class ExportSwarmAnimation(Operator, ExportHelper):
pass
animation.append(frame)
previous_frame = frame
if clever_show.add_takeoff:
animation.insert(0, {"takeoff": {}})
if clever_show.add_land:
animation.append({"land": {}})
@@ -124,28 +142,36 @@ class ExportSwarmAnimation(Operator, ExportHelper):
return animation
def _detect_armed_states(self, drone_obj, animation, context):
@staticmethod
def find_intervals(values):
j = None
vals = itertools.chain((-1, ), values) # to ensure detection from first element
for i, items in enumerate(neighbour_pairs(vals)):
item1, item2 = items
if item2 > item1:
j = i
elif j is not None and item2 < item1:
yield (j, i) # j+1, i+1
j = None
if j is not None:
yield (j, j) # j+1, j+1
@staticmethod
def pop_func(animation, func):
state = False
for frame in animation:
current = frame.pop(func, None)
state = current if current is not None else state
yield state
@classmethod
def _detect_states(cls, drone_obj, animation, context):
# clever_show = context.scene.clever_show
intervals = cls.find_intervals(cls.pop_func(animation, "armed"))
tracks = drone_obj.animation_data
if not tracks:
return animation
fcurve = next((fcurve for fcurve in tracks if fcurve.data_path == "drone.armed"), None)
if fcurve is None:
return animation
keyframes = fcurve.keyframe_points
if len(keyframes) % 2 != 0:
raise RuntimeError("Incorrect armed state keyframes!")
for frame1, frame2 in iter_pairs(keyframes):
if frame1 == frame2: # equal: wrong order
raise RuntimeError("Incorrect armed state keyframes!")
start_frame = frame1.co[0]
duration = frame2.co[0] - start_frame
# todo height?
for start, end in intervals:
# duration = max(end-start, 1)
if frame1 < frame2: # not armed -> armed: takeoff
func = "takeoff"
@@ -154,30 +180,47 @@ class ExportSwarmAnimation(Operator, ExportHelper):
animation[start_frame].update({func: {"duration": duration}})
@classmethod
def _detect_armed_states(cls, animation):
for i, items in enumerate(neighbour_pairs(vals)):
item1, item2 = items
if item2 > item1:
j = i
elif j is not None and item2 < item1:
yield (j, i) # j+1, i+1
j = None
return animation
def _detect_animation_takeoff_land(self, drone_obj, animation, context):
takeoff = False
land = False
floor_level = 0
start_frame = 0
for i, frames in enumerate(neighbour_pairs(animation)):
frame1, frame2 = frames
if frame1 == floor_level and frame2 > frame1: # takeoff start
pass
elif frame2 == floor_level and frame1 > frame2: # land start
pass
# previous_z = 0
def find(animation):
def get_z(index, default=float('nan')):
return animation[index].get("fly", None)[2] or default
i = 0
previous_z = animation[i]["fly"][2] # height of the first frame
previous_z = get_z(i) # height of the first frame
while i < len(animation):
z = animation[i]["fly"][2]
for frame in animation:
z = frame["fly"][2]
if previous_z == 0 and z > previous_z:
takeoff = True
#if p
current_z = get_z(i, previous_z)
if previous_z == 0:
while current_z > previous_z:
i += 1
previous_z = current_z
current_z = get_z(i, previous_z)
i += 1
previous_z = current_z
def _process_animation(self, animation, context): #delete unnececary flight functions while copter landed
# clever_show = context.scene.clever_show

View File

@@ -27,10 +27,7 @@ class ExportCsv(Operator, ExportHelper):
filename_ext = ''
use_filter_folder = True
use_namefilter: bpy.props.BoolProperty(
name="Use name filter for objects",
default=False,
)
use_namefilter: bpy.props.BoolProperty(name="Use name filter for objects", default=False)
drones_name: bpy.props.StringProperty(
name="Name identifier",
@@ -38,10 +35,7 @@ class ExportCsv(Operator, ExportHelper):
default="clever"
)
show_warnings: bpy.props.BoolProperty(
name="Show detailed animation warnings",
default=False,
)
show_warnings: bpy.props.BoolProperty(name="Show detailed animation warnings", default=False)
speed_warning_limit: bpy.props.FloatProperty(
name="Speed limit",