|
a |
|
b/app/AnyPy.py |
|
|
1 |
import datetime |
|
|
2 |
import glob |
|
|
3 |
import os |
|
|
4 |
import re |
|
|
5 |
import shutil |
|
|
6 |
import subprocess |
|
|
7 |
|
|
|
8 |
from anypytools import AnyMacro |
|
|
9 |
from anypytools import AnyPyProcess |
|
|
10 |
from anypytools.macro_commands import (MacroCommand, Load, Dump, |
|
|
11 |
SaveData, OperationRun) |
|
|
12 |
|
|
|
13 |
from AnyWriter import AnyWriter |
|
|
14 |
from AnybodyResults import AnybodyResults |
|
|
15 |
from config.Configuration import env |
|
|
16 |
|
|
|
17 |
|
|
|
18 |
class AnyPy: |
|
|
19 |
LOAD = 'load' |
|
|
20 |
INITIAL_CONDITIONS = 'initial_conditions' |
|
|
21 |
KINEMATICS = 'kinematics' |
|
|
22 |
INVERSE_DYNAMICS = 'inverse_dynamics' |
|
|
23 |
# SET_ORDER = 'set_order' |
|
|
24 |
SAVE_H5 = 'save_h5' |
|
|
25 |
LOAD_H5 = 'load_h5' |
|
|
26 |
DUMP_JOINT_ANGLES = 'dump_angles' |
|
|
27 |
DUMP_STEPS = 'dump_steps' |
|
|
28 |
DUMP_LEAP_VECTORS = 'dump_leap_vectors' |
|
|
29 |
REPLAY = 'replay' |
|
|
30 |
LOG_FILE = 'AnyPy{}.log'.format(datetime.datetime.today().strftime('%Y%m%d_%H%M%S')) |
|
|
31 |
|
|
|
32 |
INTERPOL_DIR = '/Model/InterpolVec' |
|
|
33 |
|
|
|
34 |
def __init__(self, main_filepath, template_directory): |
|
|
35 |
self.any_path, self.any_model = os.path.split(main_filepath) |
|
|
36 |
self.main_filepath = main_filepath |
|
|
37 |
self.template_directory = template_directory |
|
|
38 |
self.operations = [] |
|
|
39 |
self.macrolist = [] |
|
|
40 |
self.output = None |
|
|
41 |
|
|
|
42 |
if env.args('any_interpol_files'): |
|
|
43 |
print('Using interpolation files from "{}"'.format(os.path.normpath(self.any_path + AnyPy.INTERPOL_DIR))) |
|
|
44 |
|
|
|
45 |
if env.args('any_bvh_file'): |
|
|
46 |
print("Convert bvh file to anybody interpolation files") |
|
|
47 |
from resources.pymo.pymo.parsers import BVHParser as Pymo_BVHParser |
|
|
48 |
any_writer = AnyWriter(template_directory='config/anybody_templates/', |
|
|
49 |
output_directory=os.path.normpath(self.any_path + AnyPy.INTERPOL_DIR) + '/') |
|
|
50 |
any_writer.write(Pymo_BVHParser().parse(env.config.any_bvh_file)) |
|
|
51 |
|
|
|
52 |
if env.args('any_files_dir'): |
|
|
53 |
self.copy_files() |
|
|
54 |
|
|
|
55 |
# remove frames from start and end (cut) |
|
|
56 |
if env.config.start_frame or env.config.end_frame: |
|
|
57 |
start_frame = int(env.config.start_frame) - 1 if env.config.start_frame else 0 |
|
|
58 |
end_frame = int(env.config.end_frame) - 1 if 'end' not in env.config.end_frame.lower() else None |
|
|
59 |
any_writer = AnyWriter(output_directory=os.path.normpath(self.any_path + AnyPy.INTERPOL_DIR) + '/') |
|
|
60 |
any_writer.extract_frames(start_frame, end_frame) |
|
|
61 |
any_writer.extract_frame_timeseries(start_frame, end_frame) |
|
|
62 |
|
|
|
63 |
self.output_path = '' |
|
|
64 |
if env.args('output_file_path'): |
|
|
65 |
self.output_path = os.path.normpath( |
|
|
66 |
os.path.join(os.path.split(env.config.output_file_path)[0], |
|
|
67 |
os.path.split(env.config.output_file_path)[1].replace(".anydata.h5", "") + '.anydata.h5')) |
|
|
68 |
|
|
|
69 |
self.initialize_operations() |
|
|
70 |
|
|
|
71 |
def initialize_operations(self): |
|
|
72 |
"""build the macrolist executed by AnyPyTools""" |
|
|
73 |
operation_cmd = {AnyPy.LOAD: Load(self.main_filepath), |
|
|
74 |
AnyPy.INITIAL_CONDITIONS: OperationRun('Main.Study.InitialConditions'), |
|
|
75 |
AnyPy.KINEMATICS: OperationRun('Main.Study.Kinematics'), |
|
|
76 |
AnyPy.INVERSE_DYNAMICS: OperationRun('Main.Study.InverseDynamics'), |
|
|
77 |
# AnyPy.SET_ORDER: SetValue('Main.HumanModel.Mannequin.InterpolationFunctions.intorder', |
|
|
78 |
# env.config.order), |
|
|
79 |
AnyPy.SAVE_H5: SaveData('Main.Study', self.output_path), |
|
|
80 |
AnyPy.DUMP_JOINT_ANGLES: Dump('Main.Study.Output.JointAngleOutputs'), |
|
|
81 |
AnyPy.DUMP_STEPS: Dump('Main.Study.nStep'), |
|
|
82 |
AnyPy.DUMP_LEAP_VECTORS: Dump('Main.HumanModel.Mannequin.Posture.Right')} |
|
|
83 |
|
|
|
84 |
if env.config.load: |
|
|
85 |
self.add_operation(AnyPy.LOAD) |
|
|
86 |
if env.config.initial_conditions: |
|
|
87 |
self.add_operation(AnyPy.INITIAL_CONDITIONS) |
|
|
88 |
if env.config.kinematic: |
|
|
89 |
self.add_operation(AnyPy.KINEMATICS) |
|
|
90 |
if env.config.inverse_dynamics: |
|
|
91 |
self.add_operation(AnyPy.INVERSE_DYNAMICS) |
|
|
92 |
if env.config.nstep: |
|
|
93 |
self.set_step() |
|
|
94 |
# if env.config.order: |
|
|
95 |
# self.add_operation(AnyPy.SET_ORDER) |
|
|
96 |
if env.config.plot: |
|
|
97 |
# requirement for plot is run of kinematic analysis |
|
|
98 |
self.add_operation(AnyPy.LOAD) |
|
|
99 |
self.add_operation(AnyPy.KINEMATICS) |
|
|
100 |
# dump interpolated joint angles |
|
|
101 |
self.add_operation(AnyPy.DUMP_JOINT_ANGLES) |
|
|
102 |
# dump nStep |
|
|
103 |
self.add_operation(AnyPy.DUMP_STEPS) |
|
|
104 |
# dump Mannequin vectors including the joint angles from the bvh file |
|
|
105 |
self.add_operation(AnyPy.DUMP_LEAP_VECTORS) |
|
|
106 |
|
|
|
107 |
if self.output_path: |
|
|
108 |
# save study output to hdf5, to view and replay analysis later |
|
|
109 |
self.add_operation(AnyPy.SAVE_H5) |
|
|
110 |
|
|
|
111 |
for operation in self.operations: |
|
|
112 |
self.macrolist.append(operation_cmd[operation]) |
|
|
113 |
|
|
|
114 |
def post_operations(self): |
|
|
115 |
macro_output_path = 'classoperation Main.Study.Output "Load data" --file="{}"'.format(self.output_path) |
|
|
116 |
|
|
|
117 |
"""build the macrolist executed by AnyPyTools""" |
|
|
118 |
operation_cmd = {AnyPy.LOAD: Load(self.main_filepath), |
|
|
119 |
AnyPy.LOAD_H5: MacroCommand(macro_output_path), |
|
|
120 |
AnyPy.REPLAY: OperationRun("Main.Study.ReplayKinematics")} |
|
|
121 |
|
|
|
122 |
self.macrolist = [] |
|
|
123 |
for operation in operation_cmd: |
|
|
124 |
self.macrolist.append(str(operation_cmd[operation])) |
|
|
125 |
|
|
|
126 |
print('Starting Anybody with the macros:\n{}'.format(self.macrolist)) |
|
|
127 |
print('Executing "{}" in "{}"'.format(self.any_path, self.any_model)) |
|
|
128 |
|
|
|
129 |
# save current working directory and change to Anybody project folder |
|
|
130 |
cwd = os.getcwd() |
|
|
131 |
os.chdir(self.any_path) |
|
|
132 |
|
|
|
133 |
# write macro file to be opened by AnyBody GUI |
|
|
134 |
macro_replay_path = os.path.join(self.any_path, 'replay.anymcr') |
|
|
135 |
with open(macro_replay_path, 'wb') as macro_file: |
|
|
136 |
macro_file.write("\n".join(self.macrolist).encode("UTF-8")) |
|
|
137 |
macro_file.flush() |
|
|
138 |
anybodycmd = [os.path.realpath('C:/Program Files/AnyBody Technology/AnyBody.7.1/AnyBody.exe'), |
|
|
139 |
"-m", macro_file.name] |
|
|
140 |
|
|
|
141 |
# execute AnyBody GUI with the command from anybodycmd |
|
|
142 |
subprocess.Popen(anybodycmd) |
|
|
143 |
|
|
|
144 |
# change back to original folder |
|
|
145 |
os.chdir(cwd) |
|
|
146 |
|
|
|
147 |
def add_operation(self, operation): |
|
|
148 |
"""add operation to a list if not already in the list (unique)""" |
|
|
149 |
if operation not in self.operations: |
|
|
150 |
self.operations.append(operation) |
|
|
151 |
|
|
|
152 |
def copy_files(self): |
|
|
153 |
""""copy interpolation files""" |
|
|
154 |
for file in glob.glob(self.template_directory + r'/*.any'): |
|
|
155 |
print('copying "{}" to "{}"'.format(file, |
|
|
156 |
os.path.normpath(self.any_path + |
|
|
157 |
AnyPy.INTERPOL_DIR + "/" + os.path.split(file)[-1]))) |
|
|
158 |
shutil.copy(file, self.any_path + AnyPy.INTERPOL_DIR) |
|
|
159 |
|
|
|
160 |
def run(self): |
|
|
161 |
if not self.macrolist: |
|
|
162 |
print("No operation for AnyBody was selected -> will terminate now") |
|
|
163 |
return False |
|
|
164 |
|
|
|
165 |
# print('Starting Anybody with the operations: {}'.format(self.operations)) |
|
|
166 |
print('Starting Anybody with the macros:\n{}'.format(AnyMacro(self.macrolist))) |
|
|
167 |
print('Executing "{}" in "{}"'.format(self.any_path, self.any_model)) |
|
|
168 |
|
|
|
169 |
# save current working directory and change to Anybody project folder |
|
|
170 |
cwd = os.getcwd() |
|
|
171 |
os.chdir(self.any_path) |
|
|
172 |
app = AnyPyProcess() |
|
|
173 |
|
|
|
174 |
self.output = app.start_macro(macrolist=self.macrolist) |
|
|
175 |
|
|
|
176 |
# change back to original folder |
|
|
177 |
os.chdir(cwd) |
|
|
178 |
return True |
|
|
179 |
|
|
|
180 |
def plot(self): |
|
|
181 |
"""open the plot for the joint angles""" |
|
|
182 |
print('Loading the plot ...') |
|
|
183 |
AnybodyResults(self.output).plot() |
|
|
184 |
|
|
|
185 |
def set_step(self): |
|
|
186 |
"""replace the nstep value with the new selected value""" |
|
|
187 |
regex_step = re.compile(r'nStep\s*=.*\d+.*;') |
|
|
188 |
step_setting = 'nStep = {};'.format(env.config.nstep) |
|
|
189 |
with open(self.main_filepath) as file: |
|
|
190 |
old_file = file.read() |
|
|
191 |
new_file = re.sub(regex_step, step_setting, old_file) |
|
|
192 |
with open(self.main_filepath, 'w') as file: |
|
|
193 |
file.write(new_file) |
|
|
194 |
print('"{}" written to "{}"'.format(step_setting, self.main_filepath)) |