Diff of /app/AnyPy.py [000000] .. [4de1c7]

Switch to unified view

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))