diff --git a/frogger/baselines.py b/frogger/baselines.py deleted file mode 100644 index eb2cb54..0000000 --- a/frogger/baselines.py +++ /dev/null @@ -1,192 +0,0 @@ -from dataclasses import dataclass, fields, make_dataclass -from typing import Callable, Tuple - -import numpy as np -import torch -from qpth.qp import QPFunction - -from frogger.robots.robot_core import RobotModel, RobotModelConfig - -# ##### # -# UTILS # -# ##### # - - -def combine_dataclasses(cls_a: type, cls_b: type) -> type: - """Combines two config dataclasses into a new one, prioritizing attributes of cls_b. - - Parameters - ---------- - cls_a : type - The first dataclass type. - cls_b : type - The second dataclass type. - - Returns - ------- - new_cls : type - The new dataclass type. - """ - # extract attributes from cls_a - attributes = { - field.name: (field.type, getattr(cls_a, field.name)) for field in fields(cls_a) - } - - # remove fields that are methods in cls_b - for k in list(attributes.keys()): - if k in cls_b.__dict__ and isinstance(getattr(cls_b, k), Callable): - del attributes[k] - - # include attributes from cls_b, prioritizing non-callable attributes - for field in fields(cls_b): - if field.name not in attributes and not isinstance( - getattr(cls_b, field.name), Callable - ): - attributes[field.name] = field.type, getattr(cls_b, field.name) - - # combine methods, prioritizing those from B - # note that we look through ALL attributes of cls_a, but only through the __dict__ of cls_b. - # this is so that we have inherited methods but only override them with cls_b impls if they - # are explicitly overridden. - methods = {} - for method_name in dir(cls_a): - method = getattr(cls_a, method_name) - if isinstance(method, Callable) and method_name not in cls_b.__dict__: - methods[method_name] = method - for method_name, method in cls_b.__dict__.items(): - if isinstance(method, Callable): - methods[method_name] = method - - # generate the new class - new_class_name = cls_a.__name__ + cls_b.__name__.replace("Config", "") - new_cls = make_dataclass( - new_class_name, - [(name, type_, default) for name, (type_, default) in attributes.items()], - kw_only=True, - bases=(cls_a, cls_b), - ) - - # add methods to the new dataclass - for method_name, method in methods.items(): - if method_name != "__class__": - setattr(new_cls, method_name, method) - - return new_cls - - -# ######### # -# BASELINES # -# ######### # - - -@dataclass(kw_only=True) -class BaselineConfig(RobotModelConfig): - """Configuration for a generic baseline. - - Typically, we want to modify some RobotModelConfig that has already been - instantiated with desirable properties. To do this, we will use the `from_cfg` - method of BaselineConfig to load all of the attributes of an existing config - into a baseline config that is the combination of the baseline attributes and - the original config attributes. - """ - - @classmethod - def from_cfg(cls, config_cls: type, **kwargs) -> "BaselineConfig": - """Creates a baseline config from an existing robot model config class.""" - CombinedDataClass = combine_dataclasses(config_cls, cls) - return CombinedDataClass - - -@dataclass(kw_only=True) -class WuBaselineConfig(BaselineConfig): - """Configuration for the Wu baseline solver. - - Note - ---- - All of the torch functions use the default device, which is CPU unless changed - elsewhere. In testing, the device did not have a large difference on run time. - """ - - n_g_extra: int = 0 - n_h_extra: int = 1 - - def _init_baseline_cons(self, model: RobotModel) -> None: - """Initializes constraints for the baseline. - - Equation (5) of the paper: - "Learning Diverse and Physically Feasible Dexterous Grasps with Generative - Model and Bilevel Optimization" - """ - # setting up the feasibility QP - # (i) friction cone constraint - Lambda_i = np.vstack( - ( - np.append(np.cos(2 * np.pi * np.arange(model.ns) / model.ns), 0.0), - np.append(np.sin(2 * np.pi * np.arange(model.ns) / model.ns), 0.0), - -np.append( - model.mu * np.cos(np.pi * np.ones(model.ns) / model.ns), 1.0 - ), - ) - ).T # pyramidal friction cone approx in contact frame + min normal force - - # Ain has shape((ns + 1) * nc, 3 * nc) - fn_min = 1.0 # hard code min normal force to 1, that's what they use - A_in = torch.tensor(np.kron(np.eye(model.nc), Lambda_i)) - b_in = torch.zeros((model.ns + 1) * model.nc).double() - b_in[model.ns :: model.ns + 1] = -fn_min - - A_eq = torch.Tensor().double() # empty - b_eq = torch.Tensor().double() - - # (ii) setting up QP constraint function - def bilevel_constraint_func(G: torch.Tensor) -> torch.Tensor: - """Constraint function for bilevel optimization. - - Takes in the grasp map and returns a cost. - """ - if G.dtype == torch.float32: - G = G.double() - Q = G.T @ G + 1e-7 * torch.eye(3 * model.nc).double() - f_opt = QPFunction(verbose=-1, check_Q_spd=False)( - Q, torch.zeros(3 * model.nc).double(), A_in, b_in, A_eq, b_eq - ).squeeze() - h = f_opt @ Q @ f_opt - return h - - # adding the bilevel constraint to the model - model._bilevel_cons = bilevel_constraint_func - - @staticmethod - def custom_compute_l(robot: RobotModel) -> Tuple[np.ndarray, np.ndarray]: - """Cost function for Wu baseline. Since it's a feas program, does nothing.""" - return 0.0, np.zeros(robot.n) - - @staticmethod - def custom_compute_h(robot: RobotModel) -> Tuple[np.ndarray, np.ndarray]: - """Extra equality constraints for Wu baseline. This is the force closure QP. - - Warning - ------- - Requires robot.DG to have been computed and cached already! - """ - # equality constraint - G = torch.tensor(robot.G).double() - h = (robot._bilevel_cons(G)).cpu().detach().numpy()[..., None] # (1,) - - # gradient - Dh_G = ( - torch.autograd.functional.jacobian( - robot._bilevel_cons, G, create_graph=True, strict=True - ) - .cpu() - .detach() - .numpy() - ) - DG = robot.DG - Dh = (Dh_G.reshape(-1) @ DG.reshape((-1, DG.shape[-1])))[None, ...] # (1, n) - - return h, Dh - - def create_pre_warmstart(self, model: RobotModel) -> None: - """Initializes the baseline constraints.""" - self._init_baseline_cons(model) diff --git a/frogger/baselines/base.py b/frogger/baselines/base.py new file mode 100644 index 0000000..bc60da2 --- /dev/null +++ b/frogger/baselines/base.py @@ -0,0 +1,84 @@ +from dataclasses import dataclass, fields, make_dataclass +from typing import Callable + +from frogger.robots.robot_core import RobotModelConfig + + +def combine_dataclasses(cls_a: type, cls_b: type) -> type: + """Combines two config dataclasses into a new one, prioritizing attributes of cls_b. + + Parameters + ---------- + cls_a : type + The first dataclass type. + cls_b : type + The second dataclass type. + + Returns + ------- + new_cls : type + The new dataclass type. + """ + # extract attributes from cls_a + attributes = { + field.name: (field.type, getattr(cls_a, field.name)) for field in fields(cls_a) + } + + # remove fields that are methods in cls_b + for k in list(attributes.keys()): + if k in cls_b.__dict__ and isinstance(getattr(cls_b, k), Callable): + del attributes[k] + + # include attributes from cls_b, prioritizing non-callable attributes + for field in fields(cls_b): + if field.name not in attributes and not isinstance( + getattr(cls_b, field.name), Callable + ): + attributes[field.name] = field.type, getattr(cls_b, field.name) + + # combine methods, prioritizing those from B + # note that we look through ALL attributes of cls_a, but only through the __dict__ of cls_b. + # this is so that we have inherited methods but only override them with cls_b impls if they + # are explicitly overridden. + methods = {} + for method_name in dir(cls_a): + method = getattr(cls_a, method_name) + if isinstance(method, Callable) and method_name not in cls_b.__dict__: + methods[method_name] = method + for method_name, method in cls_b.__dict__.items(): + if isinstance(method, Callable): + methods[method_name] = method + + # generate the new class + new_class_name = cls_a.__name__.replace("Config", "") + cls_b.__name__ + new_cls = make_dataclass( + new_class_name, + [(name, type_, default) for name, (type_, default) in attributes.items()], + kw_only=True, + bases=(cls_a, cls_b), + ) + + # add methods to the new dataclass + for method_name, method in methods.items(): + if method_name != "__class__": + setattr(new_cls, method_name, method) + + return new_cls + + +@dataclass(kw_only=True) +class BaselineConfig(RobotModelConfig): + """Configuration for a generic baseline. + + Typically, we want to modify some RobotModelConfig that has already been + instantiated with desirable properties. To do this, we will use the `from_cfg` + method of BaselineConfig to load all of the attributes of an existing config + into a baseline config that is the combination of the baseline attributes and + the original config attributes. + """ + + @classmethod + def from_cfg(cls, config_cls: type, **kwargs) -> "BaselineConfig": + """Creates a baseline config from an existing robot model config class.""" + CombinedDataClass = combine_dataclasses(config_cls, cls) + return CombinedDataClass diff --git a/frogger/baselines/classifier/Train_DexGraspNet_NeRF_Grasp_Metric_workspaces/75bottle_augmented_pose_HALTON_400_cnn-3d-xyz_l2_passed-eval_2024-03-12_16-20-12-513415/.gitignore b/frogger/baselines/classifier/Train_DexGraspNet_NeRF_Grasp_Metric_workspaces/75bottle_augmented_pose_HALTON_400_cnn-3d-xyz_l2_passed-eval_2024-03-12_16-20-12-513415/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/frogger/baselines/classifier/config.yaml b/frogger/baselines/classifier/config.yaml new file mode 100644 index 0000000..238471f --- /dev/null +++ b/frogger/baselines/classifier/config.yaml @@ -0,0 +1,119 @@ +# tyro YAML. +!dataclass:ClassifierConfig +checkpoint_workspace: !dataclass:CheckpointWorkspaceConfig + input_leaf_dir_name: null + output_leaf_dir_name: 75bottle_augmented_pose_HALTON_400_cnn-3d-xyz_l2_passed-eval_2024-03-12_16-20-12-513415 + root_dir: !!python/object/apply:pathlib.PosixPath + - / + - home + - albert + - research + - frogger + - frogger + - baselines + - classifier + - Train_DexGraspNet_NeRF_Grasp_Metric_workspaces +data: !dataclass:ClassifierDataConfig + debug_shuffle_labels: false + frac_test: 0.1 + frac_train: 0.8 + frac_val: 0.1 + max_num_data_points: null + nerf_density_threshold_value: null + use_random_rotations: true +dataloader: !dataclass:ClassifierDataLoaderConfig + batch_size: 256 + load_grasp_labels_in_ram: false + load_grasp_transforms_in_ram: false + load_nerf_configs_in_ram: false + load_nerf_grid_inputs_in_ram: false + num_workers: 8 + pin_memory: true +model_config: !dataclass:CNN_3D_XYZ_ModelConfig + conv_channels: + - 32 + - 64 + - 128 + mlp_hidden_layers: + - 256 + - 256 + n_fingers: 4 +name: 75bottle_augmented_pose_HALTON_400_cnn-3d-xyz_l2_passed-eval +nerfdata_config: !dataclass:GridNerfDataConfig + cameras_samples_chunk_size: 2000 + config_dict_visualize_index: 0 + dexgraspnet_data_root: !!python/object/apply:pathlib.PosixPath + - / + - home + dexgraspnet_meshdata_root: !!python/object/apply:pathlib.PosixPath + - / + - home + evaled_grasp_config_dicts_path: !!python/object/apply:pathlib.PosixPath + - / + - home + fingertip_config: !dataclass:EvenlySpacedFingertipConfig + distance_between_pts_mm: 2 + finger_height_mm: 60.0 + finger_width_mm: 60.0 + grasp_depth_mm: 80.0 + n_fingers: 4 + num_pts_x: 31 + num_pts_y: 31 + num_pts_z: 41 + grasp_visualize_index: 0 + limit_num_configs: null + max_num_data_points_per_file: null + nerf_checkpoints_path: !!python/object/apply:pathlib.PosixPath + - / + - home + - albert + - research + - frogger + - frogger + - baselines + - nerf + output_filepath: null + plot_all_high_density_points: true + plot_alpha_images_each_finger: true + plot_alphas_each_finger_1D: true + plot_only_one: false + print_timing: true + ray_samples_chunk_size: 50 + save_dataset: true +nerfdata_config_path: null +random_seed: 42 +task_type: !enum:TaskType 'PASSED_EVAL' +test_dataset_filepath: null +train_dataset_filepath: !!python/object/apply:pathlib.PosixPath +- / +- scr +- tylerlum +- data +- 2024-03-10_75bottle_augmented_pose_HALTON_400 +- grid_dataset +- train_dataset.h5 +training: !dataclass:ClassifierTrainingConfig + betas: !!python/tuple + - 0.9 + - 0.999 + extra_punish_false_positive_factor: 0.0 + grad_clip_val: 1.0 + label_smoothing: 0.0 + loss_fn: l2 + lr: 0.0001 + lr_scheduler_name: constant + lr_scheduler_num_warmup_steps: 0 + n_epochs: 1000 + save_checkpoint_freq: 1 + save_checkpoint_on_epoch_0: false + val_freq: 5 + val_on_epoch_0: false + weight_decay: 0.001 +val_dataset_filepath: null +wandb: !dataclass:WandbConfig + entity: null + group: null + job_type: null + name: 75bottle_augmented_pose_HALTON_400_cnn-3d-xyz_l2_passed-eval_2024-03-12_16-20-12-513415 + project: learned_metric + resume: never diff --git a/frogger/baselines/nerf/config.yml b/frogger/baselines/nerf/config.yml new file mode 100644 index 0000000..c27e757 --- /dev/null +++ b/frogger/baselines/nerf/config.yml @@ -0,0 +1,213 @@ +!!python/object:nerfstudio.engine.trainer.TrainerConfig +_target: !!python/name:nerfstudio.engine.trainer.Trainer '' +data: &id003 !!python/object/apply:pathlib.PosixPath +- / +- home +- albert +- research +- frogger +- frogger +- baselines +- nerf +experiment_name: core-bottle-2d912be96504cb8cd5473a45f1da0225_0_0915 +gradient_accumulation_steps: 1 +load_checkpoint: null +load_config: null +load_dir: null +load_step: null +log_gradients: false +logging: !!python/object:nerfstudio.configs.base_config.LoggingConfig + local_writer: !!python/object:nerfstudio.configs.base_config.LocalWriterConfig + _target: !!python/name:nerfstudio.utils.writer.LocalWriter '' + enable: true + max_log_size: 10 + stats_to_track: !!python/tuple + - !!python/object/apply:nerfstudio.utils.writer.EventName + - Train Iter (time) + - !!python/object/apply:nerfstudio.utils.writer.EventName + - Train Rays / Sec + - !!python/object/apply:nerfstudio.utils.writer.EventName + - Test PSNR + - !!python/object/apply:nerfstudio.utils.writer.EventName + - Vis Rays / Sec + - !!python/object/apply:nerfstudio.utils.writer.EventName + - Test Rays / Sec + - !!python/object/apply:nerfstudio.utils.writer.EventName + - ETA (time) + max_buffer_size: 20 + profiler: basic + relative_log_dir: !!python/object/apply:pathlib.PosixPath [] + steps_per_log: 10 +machine: !!python/object:nerfstudio.configs.base_config.MachineConfig + device_type: cuda + dist_url: auto + machine_rank: 0 + num_devices: 1 + num_machines: 1 + seed: 42 +max_num_iterations: 200 +method_name: nerfacto +mixed_precision: true +optimizers: + fields: + optimizer: !!python/object:nerfstudio.engine.optimizers.AdamOptimizerConfig + _target: &id001 !!python/name:torch.optim.adam.Adam '' + eps: 1.0e-15 + lr: 0.01 + max_norm: null + weight_decay: 0 + scheduler: !!python/object:nerfstudio.engine.schedulers.ExponentialDecaySchedulerConfig + _target: &id002 !!python/name:nerfstudio.engine.schedulers.ExponentialDecayScheduler '' + lr_final: 0.0001 + lr_pre_warmup: 1.0e-08 + max_steps: 200000 + ramp: cosine + warmup_steps: 0 + proposal_networks: + optimizer: !!python/object:nerfstudio.engine.optimizers.AdamOptimizerConfig + _target: *id001 + eps: 1.0e-15 + lr: 0.01 + max_norm: null + weight_decay: 0 + scheduler: !!python/object:nerfstudio.engine.schedulers.ExponentialDecaySchedulerConfig + _target: *id002 + lr_final: 0.0001 + lr_pre_warmup: 1.0e-08 + max_steps: 200000 + ramp: cosine + warmup_steps: 0 +output_dir: !!python/object/apply:pathlib.PosixPath +- / +- home +- albert +- research +- frogger +- frogger +- baselines +- nerf +pipeline: !!python/object:nerfstudio.pipelines.base_pipeline.VanillaPipelineConfig + _target: !!python/name:nerfstudio.pipelines.base_pipeline.VanillaPipeline '' + datamanager: !!python/object:nerfstudio.data.datamanagers.base_datamanager.VanillaDataManagerConfig + _target: !!python/name:nerfstudio.data.datamanagers.base_datamanager.VanillaDataManager '' + camera_optimizer: !!python/object:nerfstudio.cameras.camera_optimizers.CameraOptimizerConfig + _target: !!python/name:nerfstudio.cameras.camera_optimizers.CameraOptimizer '' + mode: SO3xR3 + optimizer: !!python/object:nerfstudio.engine.optimizers.AdamOptimizerConfig + _target: *id001 + eps: 1.0e-08 + lr: 0.0006 + max_norm: null + weight_decay: 0.01 + orientation_noise_std: 0.0 + param_group: camera_opt + position_noise_std: 0.0 + scheduler: !!python/object:nerfstudio.engine.schedulers.ExponentialDecaySchedulerConfig + _target: *id002 + lr_final: 6.0e-06 + lr_pre_warmup: 1.0e-08 + max_steps: 200000 + ramp: cosine + warmup_steps: 0 + camera_res_scale_factor: 1.0 + collate_fn: !!python/name:nerfstudio.data.utils.nerfstudio_collate.nerfstudio_collate '' + data: *id003 + dataparser: !!python/object:nerfstudio.data.dataparsers.nerfstudio_dataparser.NerfstudioDataParserConfig + _target: !!python/name:nerfstudio.data.dataparsers.nerfstudio_dataparser.Nerfstudio '' + auto_scale_poses: false + center_method: none + data: !!python/object/apply:pathlib.PosixPath [] + depth_unit_scale_factor: 0.001 + downscale_factor: null + orientation_method: none + scale_factor: 1.0 + scene_scale: 0.2 + train_split_fraction: 0.9 + eval_image_indices: !!python/tuple + - 0 + eval_num_images_to_sample_from: -1 + eval_num_rays_per_batch: 4096 + eval_num_times_to_repeat_images: -1 + masks_on_gpu: null + patch_size: 1 + train_num_images_to_sample_from: -1 + train_num_rays_per_batch: 4096 + train_num_times_to_repeat_images: -1 + model: !!python/object:nerfstudio.models.nerfacto.NerfactoModelConfig + _target: !!python/name:nerfstudio.models.nerfacto.NerfactoModel '' + appearance_embed_dim: 32 + background_color: black + base_res: 16 + collider_params: + far_plane: 6.0 + near_plane: 2.0 + disable_scene_contraction: true + distortion_loss_mult: 0.002 + enable_collider: true + eval_num_rays_per_chunk: 32768 + far_plane: 1000.0 + features_per_level: 2 + hidden_dim: 64 + hidden_dim_color: 64 + hidden_dim_transient: 64 + implementation: tcnn + interlevel_loss_mult: 1.0 + log2_hashmap_size: 19 + loss_coefficients: + rgb_loss_coarse: 1.0 + rgb_loss_fine: 1.0 + max_res: 2048 + near_plane: 0.05 + num_levels: 16 + num_nerf_samples_per_ray: 48 + num_proposal_iterations: 2 + num_proposal_samples_per_ray: !!python/tuple + - 256 + - 96 + orientation_loss_mult: 0.0001 + pred_normal_loss_mult: 0.001 + predict_normals: false + prompt: null + proposal_initial_sampler: piecewise + proposal_net_args_list: + - hidden_dim: 16 + log2_hashmap_size: 17 + max_res: 128 + num_levels: 5 + use_linear: false + - hidden_dim: 16 + log2_hashmap_size: 17 + max_res: 256 + num_levels: 5 + use_linear: false + proposal_update_every: 5 + proposal_warmup: 5000 + proposal_weights_anneal_max_num_iters: 1000 + proposal_weights_anneal_slope: 10.0 + use_average_appearance_embedding: true + use_gradient_scaling: false + use_proposal_weight_anneal: true + use_same_proposal_network: false + use_single_jitter: true +project_name: nerfstudio-project +prompt: null +relative_model_dir: !!python/object/apply:pathlib.PosixPath +- nerfstudio_models +save_only_latest_checkpoint: true +steps_per_eval_all_images: 25000 +steps_per_eval_batch: 500 +steps_per_eval_image: 500 +steps_per_save: 2000 +timestamp: 2024-03-10_230229 +use_grad_scaler: false +viewer: !!python/object:nerfstudio.configs.base_config.ViewerConfig + image_format: jpeg + jpeg_quality: 90 + max_num_display_images: 512 + num_rays_per_chunk: 32768 + quit_on_train_completion: false + relative_log_filename: viewer_log_filename.txt + websocket_host: 0.0.0.0 + websocket_port: null + websocket_port_default: 7007 +vis: wandb diff --git a/frogger/baselines/nerf/core-bottle-2d912be96504cb8cd5473a45f1da0225_0_0915/nerfacto/2024-03-10_230229/nerfstudio_models/.gitignore b/frogger/baselines/nerf/core-bottle-2d912be96504cb8cd5473a45f1da0225_0_0915/nerfacto/2024-03-10_230229/nerfstudio_models/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/frogger/baselines/nerf/transforms.json b/frogger/baselines/nerf/transforms.json new file mode 100644 index 0000000..1427d9b --- /dev/null +++ b/frogger/baselines/nerf/transforms.json @@ -0,0 +1 @@ +{"fl_x": 634.3189239501953, "fl_y": 634.3189239501953, "cx": 200, "cy": 200, "h": 400, "w": 400, "frames": [{"transform_matrix": [[-0.6850337300422048, 0.6778808636215115, -0.2668451300665195, -0.07324898988008499], [-4.350734181451084e-08, 0.3662881874457811, 0.930501458213625, 0.2554226517677307], [0.728511351115727, 0.6374248963395125, -0.2509197338235872, -0.06887747347354889], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/0.png"}, {"transform_matrix": [[0.9407525184005875, 0.09701506932115947, -0.3249196446008811, -0.08919044584035873], [-2.6542618112701637e-08, 0.9581995278018566, 0.28610079503611685, 0.07853467017412186], [0.33909393849337904, -0.2691500348224191, 0.9014286214848842, 0.24744215607643127], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/1.png"}, {"transform_matrix": [[0.6616665049719238, 0.5345491707404907, 0.5257895208720813, 0.1443292498588562], [-1.4867525943431365e-08, 0.7012413249849612, -0.7129239820158498, -0.195697620511055], [-0.7497982636671272, 0.4717179116739047, 0.46398790459210393, 0.12736468017101288], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/2.png"}, {"transform_matrix": [[0.4422380557112448, 0.8026732285757378, -0.40017644884293174, -0.10984842479228973], [-8.85669933033329e-09, 0.44617847488839346, 0.8949440030226848, 0.2456621378660202], [0.8968977099317056, -0.39577829232294803, 0.19731710834388697, 0.054163508117198944], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/3.png"}, {"transform_matrix": [[-0.8904186056059086, -0.28895108381676504, 0.3516560506403187, 0.09652957320213318], [4.328503139752824e-08, 0.7726283887439443, 0.6348585455886488, 0.1742686629295349], [-0.45514251261646355, 0.5652898761414828, -0.6879626800496661, -0.18884576857089996], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/4.png"}, {"transform_matrix": [[-0.7112499014958136, -0.17821895850211147, -0.6799717497459863, -0.18665221333503723], [1.0953647277374722e-07, 0.9673264623556255, -0.2535340514142802, -0.06959507614374161], [0.7029392417714234, -0.18032614357594834, -0.6880108315432563, -0.1888590157032013], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/5.png"}, {"transform_matrix": [[-0.8989579633938549, 0.08001448892512207, 0.43066490640963995, 0.11821755021810532], [-4.9999373436931986e-08, 0.9831748360234258, -0.18266702441958982, -0.05014210194349289], [-0.43803490734274814, -0.16420999778442555, -0.8838328442510319, -0.2426120936870575], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/6.png"}, {"transform_matrix": [[0.9553504115384743, -0.18973920687103013, -0.22650524176985573, -0.0621756874024868], [6.863254404056544e-08, 0.7665796902795317, -0.6421491870670966, -0.17626993358135223], [0.295475195529614, 0.6134774745880163, 0.732352235607871, 0.2010307013988495], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/7.png"}, {"transform_matrix": [[0.22253444692715174, -0.40685799773652626, -0.8859712126297626, -0.24319911003112793], [9.7604522594793e-09, 0.9087584891061414, -0.4173224274796691, -0.1145550012588501], [0.9749248278358835, 0.09286860694200473, 0.20223007173470722, 0.055512141436338425], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/8.png"}, {"transform_matrix": [[0.48766036042471234, -0.4551455666534514, 0.7450032792049633, 0.2045034021139145], [5.489394016808699e-09, 0.8533502309844422, 0.5213380700455313, 0.14310728013515472], [-0.8730334317026124, -0.2542359070519111, 0.41614508370885794, 0.11423184722661972], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/9.png"}, {"transform_matrix": [[-0.9762015700124923, -0.04072892582766925, -0.21300621893754487, -0.05847013741731644], [-1.9613538686023923e-08, 0.9822058514997707, -0.1878075218930536, -0.05155307799577713], [0.2168651532753584, -0.1833379935543487, -0.9588308951083715, -0.263199120759964], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/10.png"}, {"transform_matrix": [[0.9400337408998214, 0.007278042345771445, 0.34100380653227386, 0.09360554814338684], [6.547943071084024e-08, 0.9997723122270189, -0.021338315402950392, -0.005857365671545267], [-0.3410814652980766, 0.02005875878147082, 0.9398197062342668, 0.25798049569129944], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/11.png"}, {"transform_matrix": [[0.8132131076722504, -0.3350858902953196, 0.47581707371114135, 0.13061179220676422], [-3.4974538113454676e-08, 0.8176028253317135, 0.5757826152373814, 0.15805234014987946], [-0.5819660140506827, -0.4682339865223289, 0.6648853227101407, 0.18251101672649384], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/12.png"}, {"transform_matrix": [[-0.5778801316477048, -0.07670840035429474, -0.8125086921146856, -0.22303365170955658], [1.224899460185054e-07, 0.9955730029886334, -0.09399146620933163, -0.02580064721405506], [0.816121653582857, -0.05431590039095524, -0.5753218486359644, -0.1579258292913437], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/13.png"}, {"transform_matrix": [[-0.7544960225837097, 0.3526121354212354, 0.5535344920228893, 0.15194524824619293], [2.5316629344914955e-08, 0.8434109511239731, -0.5372689899148786, -0.14748035371303558], [-0.656304618226446, -0.4053673019347158, -0.6363502169535323, -0.17467808723449707], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/14.png"}, {"transform_matrix": [[-0.9974987769003749, -0.0546168859914875, -0.044868539611278284, -0.012316402979195118], [2.2503617402253844e-08, 0.6347786186476665, -0.7726940567312265, -0.21210449934005737], [0.07068373279797469, -0.7707613775172918, -0.6331908944744794, -0.1738109290599823], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/15.png"}, {"transform_matrix": [[-0.7930729495182324, -0.5297268774532417, -0.300707053535646, -0.08254408091306686], [1.3980468713079928e-09, 0.4936691639755843, -0.8696497895932868, -0.2387188822031021], [0.6091266672396239, -0.6896957241010606, -0.3915156592197336, -0.10747101157903671], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/16.png"}, {"transform_matrix": [[0.16619610955624126, -0.9413155815925944, -0.29377513342583234, -0.08064127713441849], [-2.317937224429337e-08, 0.2979183637396273, -0.954591351598527, -0.2620353102684021], [0.9860927203708428, 0.1586493756612324, 0.04951285119978297, 0.0135912811383605], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/17.png"}, {"transform_matrix": [[-0.2114805675506809, 0.7480470324489326, -0.629048175255908, -0.17267373204231262], [2.5244641409206706e-08, 0.64360510944832, 0.7653577353708624, 0.21009069681167603], [0.9773822023898537, 0.16185827237543818, -0.13610999270882793, -0.03736218437552452], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/18.png"}, {"transform_matrix": [[-0.8617858451887921, 0.4437551731960463, -0.24577734495674403, -0.06746586412191391], [-1.0595414573832783e-07, 0.4845075890796214, 0.8747870575884407, 0.24012905359268188], [0.5072722711052007, 0.7538791298251994, -0.4175417351376652, -0.11461520195007324], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/19.png"}, {"transform_matrix": [[0.5329666487041822, 0.7679920286961105, 0.3551546074996989, 0.09748995304107666], [-7.586245666774418e-08, 0.4197369451340898, -0.9076457992463228, -0.24914877116680145], [-0.8461362487029066, 0.4837449128918407, 0.2237058512472091, 0.061407238245010376], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/20.png"}, {"transform_matrix": [[-0.9425523102119392, 0.2151607079556249, 0.25554062742775596, 0.07014591246843338], [-7.90976169459762e-08, 0.764957363642384, -0.6440809202338534, -0.1768002212047577], [-0.33405859143888306, -0.6070799795425048, -0.7210123132960641, -0.1979178637266159], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/21.png"}, {"transform_matrix": [[-0.5629685032830133, 0.5573229597790103, 0.6102930302850001, 0.16752541065216064], [-1.242984940275687e-08, 0.7384259067268253, -0.6743346204034509, -0.1851048469543457], [-0.8264783507819695, -0.3796291595462999, -0.4157105205679622, -0.11411258578300476], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/22.png"}, {"transform_matrix": [[-0.30855449569825544, 0.4752814157909211, 0.8239549132010642, 0.22617562115192413], [2.544892703320494e-08, 0.8662207128935502, -0.4996615620139189, -0.13715709745883942], [-0.9512066669154474, -0.15417280031823882, -0.2672763073256548, -0.07336734980344772], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/23.png"}, {"transform_matrix": [[-0.08808196213000602, -0.07065501347793857, -0.9936042658009074, -0.27274438738822937], [-5.498153882233375e-08, 0.9974812458425071, -0.0709306999294156, -0.01947048120200634], [0.9961132304850313, -0.006247660595146123, -0.08786010920641231, -0.02411757782101631], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/24.png"}, {"transform_matrix": [[0.5703693791814338, -0.006427723035649868, -0.821363169169864, -0.22546419501304626], [-5.709504358187414e-08, 0.9999693804841943, -0.00782547724125926, -0.0021480985451489687], [0.8213883194276519, 0.0044634594916614055, 0.5703519143802218, 0.15656159818172455], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/25.png"}, {"transform_matrix": [[-0.9291991508018428, 0.28198260820302873, 0.23890321642906281, 0.06557895243167877], [1.0235157410974235e-07, 0.6464193740391523, -0.7629823018044523, -0.20943862199783325], [-0.36957940709558473, -0.708962482461412, -0.6006523622804028, -0.16487909853458405], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/26.png"}, {"transform_matrix": [[0.048381920172285695, -0.8076090191653982, -0.5877302629294718, -0.16133195161819458], [-3.1853090524293403e-09, 0.5884193553140905, -0.8085559116670599, -0.22194859385490417], [0.9988289091733592, 0.03911948944520787, 0.02846885570414982, 0.007814706303179264], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/27.png"}, {"transform_matrix": [[0.534681615754785, -0.7929577862716473, -0.29211901506923793, -0.08018667995929718], [6.355717892995851e-08, 0.3456810910626677, -0.9383520572161177, -0.25757765769958496], [0.8450535898828245, 0.5017195755328796, 0.18482937470342392, 0.05073559656739235], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/28.png"}, {"transform_matrix": [[-0.991441784975566, 0.052691626623340954, 0.11944362472836295, 0.03278731182217598], [8.134965723811537e-09, 0.9149293963705428, -0.4036139240128295, -0.11079204827547073], [-0.13054955765709633, -0.4001597082926025, -0.9070992342928726, -0.2489987164735794], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/29.png"}, {"transform_matrix": [[0.27482708625765295, 0.5985100267066249, 0.7524997146781941, 0.20656117796897888], [-1.536267610099107e-11, 0.7826361629928212, -0.6224794264679546, -0.1708705872297287], [-0.961493667508595, 0.17107420701996254, 0.21508961628438134, 0.05904212221503258], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/30.png"}, {"transform_matrix": [[-0.8577007963143081, 0.32911581035200016, -0.39500902189462445, -0.10842999815940857], [3.0263939691694195e-08, 0.7682771464868063, 0.6401173534486388, 0.1757122427225113], [0.5141491456783729, 0.5490291518329756, -0.6589519302921591, -0.1808822602033615], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/31.png"}, {"transform_matrix": [[-0.927707786869276, 0.12972023648299252, -0.3500441721110446, -0.09608709067106247], [1.1715218947757395e-08, 0.9376839775521965, 0.3474892203247348, 0.09538576751947403], [0.3733071954598651, 0.3223684514475458, -0.8698967291174289, -0.23878668248653412], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/32.png"}, {"transform_matrix": [[0.9260507635052835, -0.09255382890092069, 0.36587398399867194, 0.10043243318796158], [3.906776673711356e-08, 0.9694620835187524, 0.2452412457550281, 0.06731872260570526], [-0.3773989711317186, -0.22710582858055112, 0.8977711062478351, 0.2464381605386734], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/33.png"}, {"transform_matrix": [[0.9453634452298842, -0.05609602005332778, -0.32115602587723646, -0.08815731853246689], [-4.099610373729284e-08, 0.9850857519726401, -0.17206411961968215, -0.047231610864400864], [0.32601833755646614, 0.1626631420902554, 0.931264058032008, 0.2556319832801819], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/34.png"}, {"transform_matrix": [[0.6266040700567352, -0.1373587716598272, 0.7671374760995827, 0.2105792611837387], [-7.28126891211333e-08, 0.9843453127085423, 0.17625068893118417, 0.048380810767412186], [-0.7793377569374712, -0.11043945489192614, 0.6167947692829807, 0.16931013762950897], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/35.png"}, {"transform_matrix": [[-0.3986177695189391, 0.18105843969209656, -0.8990671361138776, -0.2467939257621765], [-5.1618339884580705e-08, 0.9803187393352563, 0.19742129902351396, 0.05419214069843292], [0.9171171538160997, 0.07869568428063772, -0.39077245994550197, -0.10726703703403473], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/36.png"}, {"transform_matrix": [[-0.8147852436688323, -0.09113449204596438, -0.5725552471675073, -0.15716642141342163], [5.745103276168349e-08, 0.9875679373785498, -0.15719277674840304, -0.043149422854185104], [0.5797628883427415, -0.12807838779981817, -0.8046557772607372, -0.220878005027771], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/37.png"}, {"transform_matrix": [[0.867208157950162, 0.4507634913000203, -0.21157099445742367, -0.058076269924640656], [-7.741595853541223e-08, 0.42488772683993176, 0.9052460547170529, 0.24849005043506622], [0.4979457910101066, -0.7850367472238557, 0.3684661378247766, 0.10114393383264542], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/38.png"}, {"transform_matrix": [[-0.14182031031191758, -0.5309347471936057, -0.8354611264478397, -0.22933408617973328], [-1.3063060168240915e-08, 0.8439918440552482, -0.5363560078606571, -0.14722971618175507], [0.9898924181864568, -0.07606616455878071, -0.11969519216027542, -0.032856281846761703], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/39.png"}, {"transform_matrix": [[-0.7618695070497794, -0.0807665538624017, 0.642675359730648, 0.1764143854379654], [1.0503472902372203e-07, 0.9921955330219714, 0.12469171685094105, 0.03422786667943001], [-0.6477305413732746, 0.09499888435364931, -0.7559235131571493, -0.20750100910663605], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/40.png"}, {"transform_matrix": [[-0.00991798132089591, -0.23249548615327598, 0.9725469050718687, 0.2669641375541687], [-1.8614941159705636e-08, 0.9725947415902712, 0.23250692168396478, 0.0638231560587883], [-0.9999508156137071, 0.0023059812023371712, -0.009646180807783691, -0.002647876273840666], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/41.png"}, {"transform_matrix": [[-0.9854624383059665, 0.05558651554118106, 0.16054258618213874, 0.04406893998384476], [-1.6053986180439758e-08, 0.9449604186381181, -0.3271846683560715, -0.08981221914291382], [-0.16989344510033091, -0.3224282036318517, -0.9312229973613615, -0.25562068819999695], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/42.png"}, {"transform_matrix": [[0.9126635658754528, 0.18067969285477686, -0.3666061430382834, -0.10063338279724121], [8.177080138493493e-08, 0.8969798318898831, 0.4420714661486199, 0.12134861946105957], [0.4087116532758714, -0.4034625506446671, 0.8186407971166617, 0.2247169017791748], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/43.png"}, {"transform_matrix": [[-0.6195103406865413, -0.492456334836886, 0.6113049125121328, 0.16780318319797516], [-4.4608483261988895e-08, 0.7787438077050304, 0.6273420773079619, 0.1722053736448288], [-0.784988495318526, 0.388644876770673, -0.48243986358660784, -0.1324297934770584], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/44.png"}, {"transform_matrix": [[0.32790235722420535, -0.12445593509377167, -0.9364778504304008, -0.2570631504058838], [2.7421733382056858e-08, 0.9912843583459643, -0.13173959502984997, -0.036162521690130234], [0.9447116195574228, 0.04319769807020412, 0.32504448119392304, 0.08922473341226578], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/45.png"}, {"transform_matrix": [[-0.9556366225072244, 0.2707148254657299, 0.1160695007142012, 0.03186110407114029], [8.138067646038429e-08, 0.3940596811788727, -0.9190848533564235, -0.2522887885570526], [-0.2945482061106093, -0.8783111356132658, -0.3765778848190073, -0.10337062180042267], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/46.png"}, {"transform_matrix": [[0.18522895326727967, -0.9593483626045558, 0.21293415423427425, 0.05845044180750847], [-1.2530722050722302e-08, 0.21668377967984864, 0.9762418448436097, 0.26797837018966675], [-0.9826953927191822, -0.18082825772431854, 0.04013609767876854, 0.01101734396070242], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/47.png"}, {"transform_matrix": [[0.1298635184275489, -0.6887393339984156, -0.7132836717499121, -0.19579637050628662], [-1.1373997788735592e-07, 0.719375419767247, -0.6946214835683417, -0.1906735897064209], [0.9915318787520675, 0.09020607096041781, 0.09342054474407303, 0.02564394287765026], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/48.png"}, {"transform_matrix": [[-0.6866164511939182, -0.28837726352187865, 0.6673802535537766, 0.18319590389728546], [7.858337770349322e-08, 0.9179670136598979, 0.39665673047652056, 0.10888229310512543], [-0.7270198408227, 0.2723510890669654, -0.6302912305705785, -0.17301490902900696], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/49.png"}, {"transform_matrix": [[0.9448590909563568, -0.03588460015765483, 0.3255051362246875, 0.08935115486383438], [1.0855517122760471e-08, 0.9939781001395405, 0.10957890510034135, 0.030079394578933716], [-0.3274771720855165, -0.10353662112757492, 0.9391692445179187, 0.25780194997787476], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/50.png"}, {"transform_matrix": [[0.5577654091830324, -0.13565230294604314, -0.8188383241057537, -0.22477111220359802], [6.074202884821606e-08, 0.9865538166742072, -0.16343673640143155, -0.04486338794231415], [0.8299986435644824, 0.09115930841658273, 0.5502656014781675, 0.15104791522026062], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/51.png"}, {"transform_matrix": [[0.8854416390579518, -0.055967042604637904, -0.46136839289710596, -0.12664563953876495], [-2.446878599899392e-08, 0.9927225651349485, -0.12042387085576967, -0.03305633366107941], [0.464750582379804, 0.10662832088136025, 0.8789978938334576, 0.24128492176532745], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/52.png"}, {"transform_matrix": [[0.8926803944107776, -0.21018965923355704, -0.39867533230173685, -0.10943636298179626], [4.119918620361947e-08, 0.8845883346437089, -0.4663726816745043, -0.1280193030834198], [0.4506902633013248, 0.41632173299450914, 0.7896546721205616, 0.21676021814346313], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/53.png"}, {"transform_matrix": [[0.8001735383366713, -0.5815353637455067, -0.14676147062207248, -0.04028600454330444], [6.61821514140667e-09, 0.24469685311362885, -0.9695996339089076, -0.26615509390830994], [0.599768545812276, 0.7758479688635325, 0.19579995062450725, 0.053747087717056274], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/54.png"}, {"transform_matrix": [[0.8465387317375757, 0.04318502495923812, 0.5305725485618412, 0.14564216136932373], [3.118672317541458e-08, 0.9967039332279559, -0.0811250238084496, -0.022268828004598618], [-0.5323271321923544, 0.06867549131380475, 0.8437484822058476, 0.23160895705223083], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/55.png"}, {"transform_matrix": [[-0.8244062813468765, -0.03286972829897286, -0.5650432410332562, -0.15510433912277222], [-5.273134923193539e-08, 0.9983122924756103, -0.0580738038369194, -0.01594127155840397], [0.5659984834571661, -0.04787637886937024, -0.8230149263959583, -0.22591762244701385], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/56.png"}, {"transform_matrix": [[-0.8658607363946708, 0.35617747583011616, -0.351315799362006, -0.09643619507551193], [-5.184922668492758e-09, 0.7022311746582108, 0.711948999113103, 0.19543002545833588], [0.5002851038858525, 0.6164486864690655, -0.6080344001621004, -0.16690540313720703], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/57.png"}, {"transform_matrix": [[-0.9919079948801127, 0.05065228947062936, 0.11641681693079489, 0.03195641189813614], [-3.479005750606991e-08, 0.9169654185495089, -0.3989666918231686, -0.10951630026102066], [-0.12695877162651434, -0.3957382553604186, -0.9095453279256505, -0.24967022240161896], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/58.png"}, {"transform_matrix": [[-0.9438352128618496, 0.3069507079794492, -0.1222961726013616, -0.033570319414138794], [6.178592129482739e-08, 0.370127434249671, 0.9289809914178825, 0.25500527024269104], [0.3304165415986665, 0.8768049642233273, -0.34933932465628076, -0.09589365124702454], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/59.png"}, {"transform_matrix": [[-0.23911781641826005, 0.3541542541241634, -0.9041003451813968, -0.24817554652690887], [-3.081823636705586e-08, 0.9311113605563025, 0.3647350192166777, 0.10011975467205048], [0.9709905611649179, 0.08721466922914223, -0.22264530446404882, -0.06111616641283035], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/60.png"}, {"transform_matrix": [[-0.5041197618183189, -0.36346080175993445, 0.7834280511497321, 0.21505102515220642], [1.9383507139842924e-08, 0.9071299505635486, 0.4208506300227834, 0.11552350223064423], [-0.863633756718808, 0.21215913455375818, -0.45730212757121425, -0.12552937865257263], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/61.png"}, {"transform_matrix": [[0.6622211260672521, -0.08954944827146402, 0.7439382208923647, 0.2042110413312912], [3.880654376849548e-08, 0.9928330664227778, 0.1195094231328328, 0.032805342227220535], [-0.7493084679824584, -0.0791416358930011, 0.6574750347183995, 0.18047688901424408], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/62.png"}, {"transform_matrix": [[-0.29387971204571656, 0.21295308752783304, 0.9318184894926105, 0.25578418374061584], [-2.5082312856086792e-08, 0.9748662300754016, -0.22279100847784242, -0.06115613505244255], [-0.9558424110950123, -0.06547378079000597, -0.2864934016362962, -0.07864242047071457], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/63.png"}, {"transform_matrix": [[-0.6878483864535617, 0.5595597398266912, 0.46233915561881384, 0.12691210210323334], [4.370958756120691e-08, 0.6369585751479265, -0.7708980305757188, -0.21161150932312012], [-0.7258543912199128, -0.5302609462430827, -0.4381309526113863, -0.12026695162057877], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/64.png"}, {"transform_matrix": [[0.2492695035294797, -0.9098365418964556, -0.3317562081409565, -0.09106706827878952], [-1.2074197343599e-08, 0.3425697072328047, -0.9394924138525175, -0.2578906714916229], [0.9684341560530412, 0.23418681157641946, 0.08539216986061443, 0.023440150544047356], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/65.png"}, {"transform_matrix": [[-0.7752717423385362, 0.23795453684160864, -0.5850909022774717, -0.16060742735862732], [-3.196851688631104e-09, 0.9263222206083724, 0.3767321908294721, 0.10341296344995499], [0.6316278378375754, 0.2920698238498276, -0.7181514411772493, -0.19713260233402252], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/66.png"}, {"transform_matrix": [[0.8533305202634236, -0.36805357327400157, 0.3692744106855961, 0.10136580467224121], [-2.7114928743862324e-08, 0.7082765773593638, 0.7059350465617249, 0.19377918541431427], [-0.5213703320931815, -0.6023959305675501, 0.6043940102687164, 0.1659061461687088], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/67.png"}, {"transform_matrix": [[-0.9460797107468132, -0.14160415726650058, 0.2913442011746082, 0.07997394353151321], [-1.393047428745144e-07, 0.8993941227358615, 0.43713866448550476, 0.11999450623989105], [-0.3239339144226905, 0.41356798066706546, -0.8508985512114583, -0.23357169330120087], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/68.png"}, {"transform_matrix": [[0.9999999364269061, 8.11242879881214e-05, -0.00034722475925458296, -9.531517571303993e-05], [3.0916033563807953e-09, 0.973773925365718, 0.22751778453088162, 0.06245362013578415], [0.00035657563507824285, -0.2275177700679456, 0.9737738634596462, 0.26730093359947205], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/69.png"}, {"transform_matrix": [[0.563153473062492, -0.2109795426748023, -0.7989654550419464, -0.2193160057067871], [-8.692712272953915e-08, 0.9668581039059508, -0.2553143296240581, -0.07008377462625504], [0.8263523254506189, 0.1437812209021784, 0.5444894808334072, 0.14946237206459045], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/70.png"}, {"transform_matrix": [[-0.9598625964014798, -0.21831904511525077, -0.1760698457129297, -0.04833115637302399], [5.796071156422344e-08, 0.6277654743412808, -0.7784025367540007, -0.2136714905500412], [0.28047066875059573, -0.7471594901793269, -0.6025685854785011, -0.16540509462356567], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/71.png"}, {"transform_matrix": [[-0.9968037345099181, -0.010005186912023161, -0.0792604005915667, -0.021756913512945175], [-5.2260929030517195e-08, 0.9921268102304132, -0.1252373443587107, -0.034377571195364], [0.07988939145517024, -0.12483704841464523, -0.9889557100679693, -0.2714683711528778], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/72.png"}, {"transform_matrix": [[0.9745719990163779, 0.17078147360787907, -0.14506242451283635, -0.039819635450839996], [9.608181158445755e-09, 0.6473845246223298, 0.7621635502170908, 0.20921388268470764], [0.22407458297009264, -0.7427832561062758, 0.6309228286525522, 0.17318832874298096], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/73.png"}, {"transform_matrix": [[0.427828451055092, 0.23024497823550066, 0.8740423710925775, 0.23992463946342468], [4.354549304088814e-09, 0.9670108369528958, -0.2547352374832753, -0.06992483139038086], [-0.9038599540126785, 0.10898298588768127, 0.41371474752443227, 0.11356468498706818], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/74.png"}, {"transform_matrix": [[0.9893029738180752, -0.12930037694326815, -0.06753546118182388, -0.018538489937782288], [8.878659799142348e-09, 0.4629668814137569, -0.8863755788118376, -0.2433101236820221], [0.14587537830186695, 0.8768939954386442, 0.4580145137099239, 0.1257249414920807], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/75.png"}, {"transform_matrix": [[0.5653773036863473, -0.2320581288136959, -0.7915159690921227, -0.2172711342573166], [-1.6127876432212978e-08, 0.9596082270709875, -0.2813397421938041, -0.07722775638103485], [0.824832409933288, 0.15906311762681677, 0.542540708274026, 0.14892742037773132], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/76.png"}, {"transform_matrix": [[-0.9052375269488712, -0.14368347405840043, -0.3998750793510401, -0.10976575314998627], [5.882080160526179e-08, 0.9410908764314933, -0.33815375540928183, -0.09282320737838745], [0.4249058952326835, -0.3061094927961444, -0.8519107691634137, -0.23384948074817657], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/77.png"}, {"transform_matrix": [[-0.31958023266388325, 0.43981932324381245, -0.8393017560995883, -0.2303883284330368], [4.3475742689286057e-10, 0.8857512424452882, 0.46416024873595985, 0.12741200625896454], [0.9475592197274522, 0.1483364399194713, -0.28306858833420356, -0.07770231366157532], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/78.png"}, {"transform_matrix": [[-0.9999294584047397, -0.007602616985058765, 0.009125701583020672, 0.002505047945305705], [-1.20321852810453e-07, 0.7683161297157929, 0.6400705623745949, 0.175699383020401], [-0.01187763505035291, 0.6400254096780246, -0.7682619323850995, -0.2108878791332245], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/79.png"}, {"transform_matrix": [[0.8632349713674072, 0.2729099918328636, -0.4246710733804437, -0.11657219380140305], [5.585553324666527e-08, 0.8412620720608827, 0.5406275299240942, 0.14840225875377655], [0.5048023219125569, -0.4666886140346868, 0.7262068254444285, 0.19934378564357758], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/80.png"}, {"transform_matrix": [[0.9817586820295978, 0.18403581872431993, 0.04775675539624512, 0.013109239749610424], [-5.080537551745355e-08, 0.2511780939488748, -0.9679408892696951, -0.2656997740268707], [-0.19013124482710603, 0.9502843693056726, 0.24659628381996265, 0.06769067049026489], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/81.png"}, {"transform_matrix": [[-0.33943225607473343, -0.07994586560139483, 0.937226974702105, 0.2572688162326813], [1.2894094041678107e-08, 0.9963816516148049, 0.08499178975261895, 0.02333024889230728], [-0.9406305031924153, 0.028848967028253604, -0.3382040708882528, -0.09283698350191116], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/82.png"}, {"transform_matrix": [[-0.9230330809071925, -0.12508528399022062, 0.36381809091915956, 0.0998680368065834], [-5.8912238044402177e-08, 0.9456684125114084, 0.32513267073327023, 0.0892489030957222], [-0.3847205889356229, 0.3001081893371763, -0.8728832356860733, -0.23960646986961365], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/83.png"}, {"transform_matrix": [[-0.3919272686595751, -0.24277140864524294, 0.8873866458457945, 0.24358762800693512], [1.272171560363737e-08, 0.9645546800100131, 0.26388305984049243, 0.0724358931183815], [-0.9199962043840425, 0.10342297817789595, -0.3780352781206662, -0.10377070307731628], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/84.png"}, {"transform_matrix": [[-0.35990004267791526, -0.2212561519310315, 0.906376121989711, 0.24880024790763855], [1.4530357882785723e-08, 0.9714737325865871, 0.23714718403195165, 0.0650968998670578], [-0.93299086773689, 0.0853492948240162, -0.34963343460345525, -0.09597435593605042], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/85.png"}, {"transform_matrix": [[0.6433237473041009, 0.53617405376219, 0.5464905673722366, 0.15001167356967926], [5.5013560004993296e-08, 0.7138122345395078, -0.7003371286899698, -0.19224253296852112], [-0.7655942503406133, 0.4505435360694174, 0.4592123320986266, 0.1260537952184677], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/86.png"}, {"transform_matrix": [[0.705968912641182, -0.6522508986734795, -0.2760011948594893, -0.0757623240351677], [-8.307085022314399e-08, 0.38969846558685756, -0.9209425095624818, -0.25279873609542847], [0.7082428216256204, 0.6501568050085205, 0.2751149478252542, 0.07551905512809753], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/87.png"}, {"transform_matrix": [[0.7785028702867249, 0.0641529880088759, -0.6243538060145573, -0.17138512432575226], [7.04927178284992e-08, 0.9947625409565254, 0.10221294981416057, 0.028057469055056572], [0.6276410446706983, -0.07957311882319376, 0.7744254888660524, 0.21257980167865753], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/88.png"}, {"transform_matrix": [[-0.06796994697747562, -0.574498985319917, 0.8156782467212573, 0.22390368580818176], [-8.846309020619914e-08, 0.8175689855454981, 0.5758306642356734, 0.15806549787521362], [-0.9976873690229173, 0.03913910755868499, -0.055570171419911656, -0.015254005789756775], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/89.png"}, {"transform_matrix": [[-0.7612562256820787, 0.02215849144252855, -0.6480724960351791, -0.1778959482908249], [-3.679648336043151e-08, 0.9994159853775142, 0.03417145258678567, 0.009380060248076916], [0.6484512000607867, 0.02601325486907943, -0.7608116400994676, -0.20884275436401367], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/90.png"}, {"transform_matrix": [[0.43137444722585744, 0.13538486975836575, -0.8919568505937361, -0.24484215676784515], [-3.29224834641648e-08, 0.988676087910187, 0.15006529643660893, 0.0411929190158844], [0.902172980243027, -0.06473430493269196, 0.4264896053648862, 0.11707139015197754], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/91.png"}, {"transform_matrix": [[0.796515871341674, -0.45696368994754144, 0.3959124306842871, 0.10867798328399658], [2.6833118921922668e-08, 0.6548146027942746, 0.7557895447592371, 0.20746424794197083], [-0.604617620236801, -0.6019983571712658, 0.521570236173695, 0.14317099750041962], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/92.png"}, {"transform_matrix": [[0.1337634008442333, 0.397114601478564, -0.9079688022653127, -0.24923743307590485], [5.7593615968843365e-08, 0.9162024394229065, 0.4007157221716068, 0.10999647527933121], [0.9910132958717467, -0.053601150062633524, 0.12255433128772474, 0.033641181886196136], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/93.png"}, {"transform_matrix": [[0.6259191243992732, 0.3902191895581424, -0.6752438328573122, -0.18535441160202026], [3.617970570153818e-08, 0.8658215606634796, 0.5003529005514561, 0.13734686374664307], [0.7798879725391628, -0.31318047383392705, 0.5419342590184818, 0.14876097440719604], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/94.png"}, {"transform_matrix": [[-0.01662026565467987, -0.6651658201538895, -0.7465106820860444, -0.20491716265678406], [-3.527771636000181e-08, 0.7466138093705857, -0.6652577092053434, -0.18261325359344482], [0.999861873845366, -0.011056733520624414, -0.012408943318722722, -0.0034062175545841455], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/95.png"}, {"transform_matrix": [[0.0687052409654858, -0.7479523674548415, -0.6601869779710686, -0.18122132122516632], [-1.1898767206824908e-07, 0.6617506866932489, -0.7497239683116711, -0.20579923689365387], [0.9976370030546484, 0.051510044454565244, 0.04546565139122434, 0.012480323202908039], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/96.png"}, {"transform_matrix": [[-0.15085858617027562, -0.2746804249994935, 0.9496274801735691, 0.26067274808883667], [-4.3330609196257875e-08, 0.9606214549400299, 0.2778604331474662, 0.07627268880605698], [-0.9885553535228582, 0.04191759094934988, -0.14491800643915626, -0.03977997973561287], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/97.png"}, {"transform_matrix": [[-0.9737103709887462, 0.050826734589977204, -0.22204674390739987, -0.06095185875892639], [-2.6389884005875467e-08, 0.9747886358180691, 0.22313026571926003, 0.061249297112226486], [0.22778962537604236, 0.21726425967210602, -0.9491618028767141, -0.26054489612579346], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/98.png"}, {"transform_matrix": [[-0.8738273046535495, -0.21448588332947427, -0.43637328916225854, -0.11978445202112198], [-3.097190728386081e-08, 0.897450903564758, -0.4411143567044705, -0.12108588963747025], [0.4862364050972654, -0.38545775584773884, -0.7842171107639219, -0.215267613530159], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/99.png"}, {"transform_matrix": [[-0.9371637100704845, -0.002398950664056535, -0.3488816784565165, -0.09576796740293503], [-2.884223021526991e-08, 0.9999763608898362, -0.006875875327471581, -0.0018874185625463724], [0.34888992608976815, -0.00644381076934978, -0.9371415564234918, -0.25724539160728455], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/100.png"}, {"transform_matrix": [[0.41578821300236807, 0.6863045389266214, 0.5967463797770498, 0.16380688548088074], [7.822042750319581e-08, 0.6561535328064277, -0.7546274189198521, -0.20714522898197174], [-0.9094614680833328, 0.31376523267303164, 0.2728208511777408, 0.07488931715488434], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/101.png"}, {"transform_matrix": [[-0.5931595559757974, -0.627856179156761, -0.5039428136696346, -0.1383323073387146], [-8.611102858335799e-09, 0.6259498845154148, -0.7798632842204709, -0.21407248079776764], [0.8050849279141888, -0.46258335505053816, -0.37128816096879924, -0.10191856324672699], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/102.png"}, {"transform_matrix": [[0.03294035824287642, -0.8534742582073269, 0.5200928987943252, 0.14276549220085144], [-1.6716394763888132e-08, 0.5203752960330361, 0.8539376741182755, 0.23440590500831604], [-0.9994573191481619, -0.028129021596622842, 0.017141334405058488, 0.004705309402197599], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/103.png"}, {"transform_matrix": [[0.8415333854685245, -0.13424867635212254, 0.5232579230547653, 0.14363431930541992], [1.6544220139664443e-08, 0.9686282424671158, 0.24851424082950685, 0.06821718066930771], [-0.5402051102515444, -0.20913302176550086, 0.8151330063648186, 0.22375398874282837], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/104.png"}, {"transform_matrix": [[-0.6795581319525432, -0.49516464916842634, -0.5413064894411291, -0.148588627576828], [2.025013634284869e-08, 0.7378550920915944, -0.6749591565972748, -0.18527626991271973], [0.7336216635958684, -0.45867399456303826, -0.501415418006284, -0.13763856887817383], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/105.png"}, {"transform_matrix": [[-0.18166748661177343, -0.16040689184179885, 0.9701889266312076, 0.26631686091423035], [-6.386598277512193e-09, 0.9866060338117285, 0.16312122500242132, 0.04477677494287491], [-0.9833600176477387, 0.029633816763016522, -0.17923423946304146, -0.049199774861335754], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/106.png"}, {"transform_matrix": [[0.5695096549509443, -0.3626031433050505, -0.7376840200132798, -0.20249424874782562], [5.0907374126705786e-08, 0.8974425973875292, -0.4411312552906701, -0.12109053134918213], [0.8219846427504917, 0.2512284714351102, 0.511102242435625, 0.14029757678508759], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/107.png"}, {"transform_matrix": [[-0.5701459235910032, 0.2531485261465192, 0.7815685827375659, 0.21454057097434998], [7.965054621030626e-08, 0.9513417763638305, -0.30813767141475135, -0.08458380401134491], [-0.8215434412205819, -0.17568337500958, -0.5424036558990801, -0.14888980984687805], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/108.png"}, {"transform_matrix": [[-0.8722831633162502, -0.11904495886654057, -0.4742893428735878, -0.13019244372844696], [-4.31321917739543e-09, 0.9699146620635739, -0.24344516490187879, -0.06682570278644562], [0.48900110735559277, -0.21235311648894303, -0.8460402300850931, -0.2322380244731903], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/109.png"}, {"transform_matrix": [[-0.519086330008017, 0.5011499184338474, -0.692385832648644, -0.19005991518497467], [1.114336896779359e-07, 0.8100715975154618, 0.5863309704413842, 0.16094785928726196], [0.8547218155626986, 0.30435631446134925, -0.420497148443017, -0.1154264509677887], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/110.png"}, {"transform_matrix": [[-0.8290484840236756, -0.3222275229000408, -0.45699894378843925, -0.12544618546962738], [-1.608454198892083e-08, 0.8172710523341775, -0.5762534399173559, -0.1581815630197525], [0.5591767262127825, -0.47774203342629346, -0.677557332156966, -0.18598951399326324], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/111.png"}, {"transform_matrix": [[0.8670501607519727, 0.06605752391706618, -0.493822257774925, -0.1355542093515396], [3.9757650725207625e-08, 0.9911713848526211, 0.13258689923720102, 0.036395084112882614], [0.49822085337727157, -0.11495951193043366, 0.8593953059429287, 0.2359040081501007], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/112.png"}, {"transform_matrix": [[0.6321077514729264, -0.1725278278286835, -0.7554296387834918, -0.20736542344093323], [-8.528060818658147e-09, 0.9748982414687736, -0.22265088991758494, -0.06111766770482063], [0.7748805008050214, 0.1407393598316006, 0.6162407338584088, 0.16915808618068695], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/113.png"}, {"transform_matrix": [[0.28442979937375445, 0.33220564182765827, 0.8992992276022922, 0.2468576282262802], [-9.187636297471134e-09, 0.9380433548040586, -0.3465179136898218, -0.0951191708445549], [-0.9586968703548613, 0.0985600124077738, 0.26680748626298656, 0.07323866337537766], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/114.png"}, {"transform_matrix": [[0.8269384938714933, 0.24694695875880862, -0.5051632675812063, -0.13866733014583588], [5.519442622912143e-08, 0.8983995873208348, 0.43917898572421554, 0.12055462598800659], [0.5622923859999733, -0.36317403687698957, 0.7429211880037666, 0.20393186807632446], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/115.png"}, {"transform_matrix": [[0.618834274130684, 0.15066878357994826, 0.7709364816998142, 0.21162205934524536], [-3.988290181857032e-08, 0.9814326089019763, -0.19180728396976687, -0.05265110731124878], [-0.7855215726898579, 0.11869689060122467, 0.6073441421471464, 0.16671596467494965], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/116.png"}, {"transform_matrix": [[-0.696746177045713, 0.3131209678658431, 0.6453681308020573, 0.1771535724401474], [6.047473396039923e-08, 0.8996963238830379, -0.43651635111567577, -0.11982374638319016], [-0.7173177571844852, -0.3041410598293253, -0.6268599931034956, -0.17207303643226624], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/117.png"}, {"transform_matrix": [[0.9669875240021861, -0.14875763405707773, 0.20689682146872637, 0.05679317191243172], [6.974833241511414e-08, 0.8119215142262968, 0.5837666098163483, 0.1602439284324646], [-0.25482372029329725, -0.5644950141907524, 0.7851179851013893, 0.2155148833990097], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/118.png"}, {"transform_matrix": [[0.08673915044130771, -0.4192498587107064, 0.9037178075880621, 0.24807053804397583], [-4.1692171999310914e-08, 0.9071367523924353, 0.4208359685897874, 0.1155194565653801], [-0.9962310574262976, -0.03650299206858124, 0.07868425375716943, 0.02159889042377472], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/119.png"}, {"transform_matrix": [[0.6952194390051805, -0.33542878910060353, 0.6357337957603206, 0.1745089292526245], [-7.860686141571834e-09, 0.8844406672712115, 0.4666526610626519, 0.12809616327285767], [-0.7187975595599378, -0.32442600623155543, 0.6148803418969587, 0.16878464818000793], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/120.png"}, {"transform_matrix": [[0.7941149763420301, -0.04237331408832704, 0.6062886330803746, 0.16642622649669647], [5.1548945889116435e-08, 0.9975666323819968, 0.06971953785015689, 0.019138017669320107], [-0.6077675578288911, -0.05536529789691462, 0.7921826048579277, 0.21745412051677704], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/121.png"}, {"transform_matrix": [[-0.4263896246939324, -0.4711077926239488, 0.7721718304123493, 0.21196116507053375], [5.570312262262527e-09, 0.8536628238081598, 0.5208260585338244, 0.14296673238277435], [-0.9045395999918232, 0.22207483193029562, -0.3639929684345063, -0.09991609305143356], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/122.png"}, {"transform_matrix": [[-0.9502118433370144, -0.17801114002404722, -0.25575278455847145, -0.07020413875579834], [6.722718211466203e-08, 0.8207603924008883, -0.5712725954095252, -0.1568143516778946], [0.31160464178517683, -0.5428300031255445, -0.7798962334340721, -0.21408149600028992], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/123.png"}, {"transform_matrix": [[-0.5839348758787145, -0.29459354939756505, 0.7564619629471497, 0.20764876902103424], [-7.60036145004789e-08, 0.9318323577357971, 0.36288904237595826, 0.09961303323507309], [-0.8118005055015087, 0.2119035104237073, -0.5441294345443971, -0.14936359226703644], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/124.png"}, {"transform_matrix": [[-0.33110556802908786, 0.8472083385981944, -0.41546014710176754, -0.11404383182525635], [3.381248185669774e-08, 0.4402955950798132, 0.8978528771203623, 0.24646060168743134], [0.9435937170308704, 0.29728407283774966, -0.14578435175582338, -0.04001782462000847], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/125.png"}, {"transform_matrix": [[0.8264793052176928, 0.3594930679899273, 0.43323976284970633, 0.11892431229352951], [-8.287100566449434e-08, 0.7695650509060208, -0.63856842423033, -0.17528705298900604], [-0.5629671021000013, 0.5277635516888252, 0.6360296183841784, 0.1745901107788086], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/126.png"}, {"transform_matrix": [[0.7251614841133125, -0.06947179802657243, 0.6850653189569105, 0.18805046379566193], [-8.890613672459859e-08, 0.9948974183400949, 0.10089165961667201, 0.02769475430250168], [-0.6885788422240189, -0.07316280652879188, 0.7214612822475371, 0.19804109632968903], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/127.png"}, {"transform_matrix": [[-0.9978020505481551, 0.010120644940200747, 0.06548771234278386, 0.01797635294497013], [-6.589912168991232e-08, 0.9882678689446367, -0.15273054446187911, -0.04192448407411575], [-0.06626513353108468, -0.15239485476098188, -0.9860957054568722, -0.27068328857421875], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/128.png"}, {"transform_matrix": [[0.10751144515330374, 0.9741313457038878, -0.1987697423608039, -0.05456233024597168], [-8.5555127660191e-08, 0.1999285679652298, 0.9798104754039756, 0.2689579725265503], [0.9942038468850543, -0.10534082318125632, 0.02149469261130402, 0.005900268908590078], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/129.png"}, {"transform_matrix": [[-0.22164756435540361, -0.6502235851098539, 0.7266922640170363, 0.19947703182697296], [-7.899038476195031e-08, 0.7452284612499114, 0.666809223498808, 0.183039128780365], [-0.9751268416033431, 0.14779658287652725, -0.1651781246857793, -0.045341357588768005], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/130.png"}, {"transform_matrix": [[-0.8975345372509688, -0.34623203231116967, -0.2730478607192643, -0.07495161145925522], [8.768288642252084e-08, 0.6192344113991555, -0.7852061791269437, -0.2155390828847885], [0.44094416249870216, -0.704749688570927, -0.5557842405263929, -0.15256281197071075], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/131.png"}, {"transform_matrix": [[-0.861633972881098, -0.23883345378498566, -0.44782304332210277, -0.12292739003896713], [6.808767186336103e-08, 0.8823573886182297, -0.4705798962459122, -0.129174143075943], [0.5075301929709504, -0.4054676560515688, -0.7602690859945026, -0.20869390666484833], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/132.png"}, {"transform_matrix": [[-0.4314457479005791, 0.5938861240842086, 0.6790830864030897, 0.18640832602977753], [2.875179421343806e-08, 0.7527478377947793, -0.6583089644652304, -0.18070581555366516], [-0.9021388843290757, -0.2840245839984999, -0.324769870933204, -0.08914927393198013], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/133.png"}, {"transform_matrix": [[0.9987984748178258, -0.022640414096323547, -0.043462838737618976, -0.011930558830499649], [3.6572553349519813e-08, 0.8868850082400318, -0.46199024032881636, -0.12681631743907928], [0.04900619044145282, 0.4614351458315955, 0.8858193943969562, 0.24315743148326874], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/134.png"}, {"transform_matrix": [[-0.7535837451005262, 0.5804962985619896, 0.3084405720330824, 0.08466694504022598], [1.209974177112479e-08, 0.4692168280276189, -0.8830829906049035, -0.24240627884864807], [-0.6573519142135857, -0.6654769835625646, -0.35359418155309774, -0.09706158936023712], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/135.png"}, {"transform_matrix": [[0.18486954846815795, 0.9622424736632036, -0.1997815605297404, -0.05484004691243172], [-5.28793345326216e-08, 0.20328558975858368, 0.979119486577865, 0.268768310546875], [0.9827630691317093, -0.18100936681570862, 0.03758136607149422, 0.010316051542758942], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/136.png"}, {"transform_matrix": [[0.710322607410027, -0.5775413147616348, 0.4023528590001853, 0.11044585704803467], [-1.955541990634459e-09, 0.5716244162459739, 0.8205154031165104, 0.22523145377635956], [-0.7038762628489619, -0.5828306413486269, 0.4060377446776684, 0.11145740747451782], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/137.png"}, {"transform_matrix": [[-0.9999071901317007, 0.01310728792191071, 0.003716197822964369, 0.0010200828546658158], [-5.7271472422303663e-08, 0.27276609533201224, -0.9620803798214183, -0.2640910744667053], [-0.013623917311991826, -0.9619910894809058, -0.2727407791959542, -0.07486734539270401], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/138.png"}, {"transform_matrix": [[0.9925568173936561, 0.03778856158478259, 0.11577127821152151, 0.0317792072892189], [5.912537253141891e-08, 0.9506399604099766, -0.310296093548911, -0.08517628908157349], [-0.12178244637620371, 0.30798650990761123, 0.9435641713574948, 0.25900837779045105], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/139.png"}, {"transform_matrix": [[0.9251323737224327, 0.008606505465378654, 0.37954712375984484, 0.10418570786714554], [-2.472430712946605e-08, 0.9997430062614484, -0.022669835273341543, -0.0062228902243077755], [-0.37964469058673267, 0.020972589134283282, 0.9248946207078448, 0.25388357043266296], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/140.png"}, {"transform_matrix": [[-0.5568536643585841, 0.37628316378524956, -0.7404896873975897, -0.20326440036296844], [3.637083132257422e-08, 0.8915003995011734, 0.45301990871179915, 0.12435395270586014], [0.8306106166492311, 0.2522657692613312, -0.4964352779251016, -0.13627152144908905], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/141.png"}, {"transform_matrix": [[-0.007932424053254124, 0.720196623486116, -0.6937246573157371, -0.19042742252349854], [-2.308840009318603e-08, 0.6937464839540722, 0.7202192832751436, 0.19770020246505737], [0.9999685378293852, 0.00571310078326165, -0.005503074667989937, -0.001510570291429758], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/142.png"}, {"transform_matrix": [[-0.9346283470391724, 0.32172660402312475, 0.15153166393388476, 0.04159544035792351], [-2.7382865834768593e-08, 0.42609831722293656, -0.9046768616803355, -0.24833382666110992], [-0.35562600145493234, -0.8455366439862492, -0.3982435570924497, -0.10931780934333801], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/143.png"}, {"transform_matrix": [[-0.6617550365470962, 0.5695650741585215, -0.48752015127925685, -0.13382430374622345], [7.618828171690896e-08, 0.6502695750333538, 0.7597035473037727, 0.20853863656520844], [0.7497201288511238, 0.502737611567644, -0.4303192097858461, -0.11812257021665573], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/144.png"}, {"transform_matrix": [[-0.9381426537357911, 0.055012211569645496, 0.3418508707313524, 0.09383813291788101], [5.044855061026746e-10, 0.9872978212064554, -0.15888049672941468, -0.04361269250512123], [-0.3462489873509629, -0.14905257065613492, -0.9262261980419417, -0.25424906611442566], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/145.png"}, {"transform_matrix": [[0.3359269499413675, 0.7139056315612646, 0.6144036405557848, 0.16865380108356476], [8.337034824219784e-08, 0.6523106693253197, -0.757951707356311, -0.2080577313899994], [-0.9418880423400029, 0.254616456478103, 0.21912867404210543, 0.06015082076191902], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/146.png"}, {"transform_matrix": [[0.005939526326153145, 0.4314760142457277, -0.9021048559661132, -0.24762777984142303], [4.5868785774329555e-09, 0.9021207685907497, 0.4314836252712674, 0.11844227463006973], [0.9999823608579411, -0.0025628124894480644, 0.00535816807528619, 0.0014707837253808975], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/147.png"}, {"transform_matrix": [[-0.9999963648584781, 0.0011916068412327614, 0.002418748222882378, 0.0006639563362114131], [-1.0702863368451242e-08, 0.897045659596816, -0.4419378741390164, -0.12131188809871674], [-0.0026963437892180567, -0.4419362676581875, -0.8970423986961381, -0.24623817205429077], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/148.png"}, {"transform_matrix": [[-0.9983334638250314, 0.05172437698115578, 0.025590698173866097, 0.007024651393294334], [6.794866799013898e-09, 0.44344614587551834, -0.8963010184687666, -0.246034637093544], [-0.05770870824333691, -0.894807300223942, -0.4427071271832267, -0.12152308970689774], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/149.png"}, {"transform_matrix": [[0.871120710232575, -0.17110303634441174, 0.4602960559874667, 0.1263512820005417], [-5.9560262034888985e-08, 0.9373348551380677, 0.3484298628752912, 0.09564399719238281], [-0.4910689444506654, -0.3035244970295161, 0.8165317945426794, 0.22413797676563263], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/150.png"}, {"transform_matrix": [[-0.5977608501145626, 0.39331022431022045, 0.6985621185859993, 0.1917552947998047], [-1.7518985645217881e-09, 0.8713787686386306, -0.49061088610611175, -0.13467267155647278], [-0.801674476374492, -0.29326798157805817, -0.520876112824169, -0.14298051595687866], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/151.png"}, {"transform_matrix": [[-0.7104019575523212, -0.016348162625853056, -0.7036062793100902, -0.1931399255990982], [4.378601814452713e-08, 0.9997301798726478, -0.023228591257357767, -0.006376247387379408], [0.7037961769616458, -0.016501667508526996, -0.7102102760898422, -0.19495271146297455], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/152.png"}, {"transform_matrix": [[-0.045609427483536, 0.88569182857595, 0.46202788326941235, 0.126826673746109], [1.83477482013104e-08, 0.4625091948596113, -0.8866144848074123, -0.24337567389011383], [-0.9989593485846274, -0.04043797057350503, -0.021094795833868762, -0.005790434777736664], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/153.png"}, {"transform_matrix": [[0.9946011746840279, 0.0223300508917362, -0.10134037766025997, -0.02781793847680092], [2.066281098480022e-08, 0.9765732552562267, 0.21518521584499306, 0.059068337082862854], [0.1037713993215434, -0.2140234705480433, 0.9713009063814466, 0.2666220963001251], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/154.png"}, {"transform_matrix": [[-0.6051899319416005, 0.4162086800061988, 0.6786129095176563, 0.18627922236919403], [-1.9377426674978333e-08, 0.8524419033789535, -0.5228219595270142, -0.14351460337638855], [-0.7960811178997532, -0.31640659925349984, -0.5158892494250241, -0.14161165058612823], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/155.png"}, {"transform_matrix": [[0.43118177466191626, 0.5432353092881853, -0.7204010521521816, -0.19775007665157318], [1.3053301617035583e-08, 0.7984361398623137, 0.6020795051833004, 0.1652708351612091], [0.9022650814474649, -0.25960571893611617, 0.34427110464902805, 0.09450241923332214], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/156.png"}, {"transform_matrix": [[0.5241210988912439, -0.04938229990054882, 0.8502108339427152, 0.23338288068771362], [-5.238106195694653e-09, 0.9983174721461444, 0.05798469459894259, 0.01591680943965912], [-0.8516437481112834, -0.03039100630556564, 0.5232392502848962, 0.14362916350364685], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/157.png"}, {"transform_matrix": [[-0.5969465756123946, 0.3825232967057314, 0.7052167846428606, 0.19358199834823608], [1.3525234637153595e-08, 0.8790147066404336, -0.47679465759363576, -0.13088011741638184], [-0.8022809893451518, -0.2846209285825827, -0.5247248242156578, -0.14403699338436127], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/158.png"}, {"transform_matrix": [[0.5212067101898051, -0.41204808060173964, 0.7473686804553312, 0.2051527053117752], [-3.319487499508094e-08, 0.8757229784191662, 0.4828139031435028, 0.13253241777420044], [-0.8534304689036594, -0.2516458709001341, 0.45643267894158673, 0.12529078125953674], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/159.png"}, {"transform_matrix": [[-0.5449554498305365, 0.7331381811109579, -0.40685619707375004, -0.11168202012777328], [-5.858151980503672e-08, 0.4852392988770095, 0.8743813943728131, 0.24001769721508026], [0.8384650008795802, 0.47649892992814247, -0.2644337574466259, -0.07258705794811249], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/160.png"}, {"transform_matrix": [[0.27717427229458497, 0.2859831753722845, 0.9172720676996284, 0.25179120898246765], [-4.4538286811740185e-08, 0.9546766242462515, -0.2976449951162943, -0.0817035511136055], [-0.9608196619438867, 0.08249949406975778, 0.26461181133930645, 0.07263590395450592], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/161.png"}, {"transform_matrix": [[0.27943435780154197, 0.28257171495670347, 0.917643539500207, 0.25189316272735596], [4.831226719780637e-08, 0.9557146203012538, -0.29429502976168065, -0.08078398555517197], [-0.9601647981883308, 0.08223618697908076, 0.2670594875137451, 0.0733078122138977], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/162.png"}, {"transform_matrix": [[0.07985542826153931, -0.4426642468434953, -0.8931245574630939, -0.245162695646286], [6.758892188063157e-08, 0.8959859304177946, -0.4440824388481877, -0.12190062552690506], [0.9968064559267068, 0.035462332972324914, 0.07154937010902597, 0.019640302285552025], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/163.png"}, {"transform_matrix": [[-0.9040017063317503, -0.1805630057826026, -0.38752795498136133, -0.10637647658586502], [-1.3362026450539191e-08, 0.9064369875253985, -0.4223410797517577, -0.1159326434135437], [0.42752884692063053, -0.38179705157142396, -0.8194205858178593, -0.22493091225624084], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/164.png"}, {"transform_matrix": [[0.6901176068299371, 0.17087434989716913, -0.7032351280265654, -0.19303803145885468], [-2.0309253229883062e-08, 0.9717256012467902, 0.2361130150617781, 0.0648130252957344], [0.7236972355504198, -0.16294573461365489, 0.6706049498981471, 0.1840810626745224], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/165.png"}, {"transform_matrix": [[-0.8198220814220505, 0.5149877835301355, -0.2503584183276756, -0.06872336566448212], [-7.173010931067107e-08, 0.43721681824235314, 0.8993561329340165, 0.24687327444553375], [0.5726183325853373, 0.7373120347998883, -0.35843996502404224, -0.09839174151420593], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/166.png"}, {"transform_matrix": [[-0.8614736510821744, 0.3482563587851778, -0.36956820352519254, -0.1014464795589447], [4.430960120544553e-08, 0.7277797862164793, 0.6858108943248818, 0.18825511634349823], [0.5078022730267625, 0.5908079987105673, -0.626963125046815, -0.17210133373737335], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/167.png"}, {"transform_matrix": [[-0.9803019240551603, -0.06904442635185894, -0.185043251385975, -0.05079440400004387], [5.131427562019677e-08, 0.9369050957574557, -0.3495838119016809, -0.09596084803342819], [0.19750477891369558, -0.34269769292111546, -0.9184498644851534, -0.2521144449710846], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/168.png"}, {"transform_matrix": [[0.9967594152282759, 0.0790913580108779, 0.01467055696899135, 0.004027045797556639], [7.793291466215476e-08, 0.18237687811997813, -0.9832286988931946, -0.2698962688446045], [-0.08044046341101727, 0.9800424640877587, 0.18178586422220788, 0.049900226294994354], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/169.png"}, {"transform_matrix": [[0.8269656223726269, 0.5077687238747287, 0.24145140808966775, 0.06627840548753738], [1.108105489132336e-08, 0.4294358945335049, -0.9030973438595689, -0.24790021777153015], [-0.5622524872455912, 0.746830459703431, 0.35512871616543257, 0.0974828377366066], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/170.png"}, {"transform_matrix": [[-0.9978882673464309, 0.016080475736377206, 0.06293190123005715, 0.017274854704737663], [-4.094733136586582e-08, 0.9688704639049202, -0.24756822124954292, -0.06795760244131088], [-0.06495387511408546, -0.24704542592963766, -0.9668244678507609, -0.26539328694343567], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/171.png"}, {"transform_matrix": [[0.028781301794072667, -0.5418266998565294, 0.8399972999894828, 0.23057927191257477], [-2.5999862090432163e-08, 0.8403454273623926, 0.5420512546901053, 0.1487930566072464], [-0.9995857325247486, -0.015600962588905634, 0.02418622126876657, 0.006639088969677687], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/172.png"}, {"transform_matrix": [[-0.5472440982789089, 0.024558644774882708, -0.8366126761325847, -0.22965018451213837], [-1.5292758059988325e-08, 0.9995694241690116, 0.02934222667812192, 0.008054436184465885], [0.8369730562562356, 0.01605737317407945, -0.5470084678209695, -0.15015381574630737], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/173.png"}, {"transform_matrix": [[0.30857023959405033, -0.32205619403997776, 0.8950219076186652, 0.24568350613117218], [1.3623780264250441e-08, 0.9409382269032912, 0.33857828216247143, 0.09293973445892334], [-0.9512015597321475, -0.10447516945463399, 0.2903455385063723, 0.07969985902309418], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/174.png"}, {"transform_matrix": [[-0.6695939346045785, -0.17257988846825953, -0.7223988820845739, -0.19829848408699036], [1.170392775967932e-07, 0.9726299072697617, -0.23235977165680038, -0.06378274410963058], [0.7427273811707398, -0.1555867782965417, -0.6512670663242208, -0.17877283692359924], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/175.png"}, {"transform_matrix": [[0.40483009794156904, 0.3035293304699408, -0.8625442234141324, -0.23676839470863342], [6.875702084203587e-08, 0.9432981536203465, 0.3319466724888803, 0.09111936390399933], [0.9143919246147216, -0.1343820632410226, 0.3818754630484537, 0.10482481867074966], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/176.png"}, {"transform_matrix": [[-0.2921895163385141, 0.6040511455696218, 0.7414495937539468, 0.20352792739868164], [-2.897667141087799e-08, 0.7752825810038007, -0.6316145340253694, -0.17337818443775177], [-0.9563604375662266, -0.1845511666939898, -0.22652942486578376, -0.06218229606747627], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/177.png"}, {"transform_matrix": [[0.9495612224276296, 0.12300407762102362, -0.28845013737273045, -0.07917957007884979], [2.691180732673803e-09, 0.91985639792191, 0.39225528320486525, 0.10767406225204468], [0.31358170364634774, -0.3724704069999793, 0.8734599653375786, 0.2397647649049759], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/178.png"}, {"transform_matrix": [[-0.8175111702310581, -0.2661745645408001, 0.5107118441342061, 0.14019042253494263], [-4.8126475885193614e-08, 0.8867868775215239, 0.46217857355747666, 0.12686802446842194], [-0.5759127421297813, 0.3778361219459325, -0.7249581907982106, -0.1990009993314743], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/179.png"}, {"transform_matrix": [[-0.47397479501685963, -0.6531670222036363, 0.5905258121321709, 0.16209933161735535], [2.9340832642703016e-09, 0.6706417386852048, 0.7417814087271837, 0.20361900329589844], [-0.8805384112511649, 0.3515856928814363, -0.3178672787066239, -0.08725457638502121], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/180.png"}, {"transform_matrix": [[-0.9982467033716926, 0.037448779404178, 0.04583784603016585, 0.012582467868924141], [-9.716060769284535e-08, 0.7744107422714278, -0.6326831768386185, -0.17367154359817505], [-0.059190533090508174, -0.6315739000115135, -0.7730529668895321, -0.2122030407190323], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/181.png"}, {"transform_matrix": [[0.9092892552565265, -0.14855143701180068, -0.3887486602378977, -0.10671151429414749], [2.6467031662785118e-08, 0.9341221803921859, -0.3569534312754926, -0.09798372536897659], [0.4161646912882335, 0.3245739093967313, 0.8493872656591289, 0.23315680027008057], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/182.png"}, {"transform_matrix": [[0.8193425933624261, -0.2232315881904369, 0.5280581149230732, 0.1449519544839859], [-4.711247205222905e-08, 0.9210783606528318, 0.3893772637649633, 0.10688406229019165], [-0.5733042078182683, -0.3190334019676735, 0.7546787221903112, 0.20715931057929993], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/183.png"}, {"transform_matrix": [[-0.5394544043076914, -0.37147944706246155, 0.7556401035434805, 0.20742319524288177], [-2.970030976892048e-10, 0.8974190141966836, 0.4411792299715084, 0.1211036965250969], [-0.8420148132147286, 0.23799607847277857, -0.484116639828198, -0.13289004564285278], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/184.png"}, {"transform_matrix": [[0.7440939037148031, -0.6031540564841248, -0.28727938770682915, -0.07885816693305969], [-7.010246734661983e-08, 0.43001058612233034, -0.9028238453999347, -0.24782516062259674], [0.6680750425322446, 0.6717857396294411, 0.31996821338386777, 0.08783124387264252], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/185.png"}, {"transform_matrix": [[0.6749490781004542, -0.25176351881719455, 0.6935840775018779, 0.19038884341716766], [-4.5612264600178056e-08, 0.9399886352056713, 0.34120575271260795, 0.09366098046302795], [-0.7378643113549705, -0.23029653987188672, 0.6344444512734679, 0.17415498197078705], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/186.png"}, {"transform_matrix": [[0.24671301087343242, 0.8666451693045899, 0.4336575155428349, 0.11903899908065796], [-3.942288627267974e-08, 0.4474900745614822, -0.8942888980463513, -0.24548229575157166], [-0.9690885874190056, 0.22063268953166842, 0.11040165779669403, 0.030305245891213417], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/187.png"}, {"transform_matrix": [[0.21375853474346734, -0.9385419601464033, -0.2710097375905033, -0.0743921548128128], [2.9760094117353013e-08, 0.2774219276250541, -0.960748184527454, -0.2637253701686859], [0.9768865281210124, 0.20536811611675965, 0.059301332685936896, 0.016278168186545372], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/188.png"}, {"transform_matrix": [[-0.5685938624014045, -0.34461465541925357, 0.7469549912208379, 0.2050391286611557], [-1.6024858311378092e-09, 0.9080212628780112, 0.41892408162031197, 0.11499466001987457], [-0.8226183924757899, 0.23819766042446963, -0.5162953175546496, -0.14172309637069702], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/189.png"}, {"transform_matrix": [[-0.8517856093477862, -0.1547157261807471, 0.5005240451570578, 0.13739384710788727], [-3.782891764716507e-08, 0.955398192358257, 0.2953206630741801, 0.08106551319360733], [-0.5238905188185973, 0.2515498720153499, -0.8137944373003799, -0.22338658571243286], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/190.png"}, {"transform_matrix": [[0.7954635860260304, 0.030860676217386383, 0.6052150873615212, 0.16613152623176575], [-3.597447588461423e-08, 0.9987024781446342, -0.05092504440611689, -0.013978929258883], [-0.6060013888652457, 0.04050899666952901, 0.7944314557482106, 0.21807144582271576], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/191.png"}, {"transform_matrix": [[0.8849013249713018, 0.19814707155971673, -0.4215298128203305, -0.11570996791124344], [-5.6413943093635995e-08, 0.9050005550377986, 0.4254103846655286, 0.11677516251802444], [0.4657785364999456, -0.37644618926691853, 0.8008362014309692, 0.2198295146226883], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/192.png"}, {"transform_matrix": [[0.37275723734905114, 0.6495476668390999, -0.662676293908108, -0.1819046437740326], [3.211373510761851e-08, 0.7141455407706059, 0.6999972475642016, 0.19214925169944763], [0.9279288992179855, -0.2609290614349826, 0.26620289798339347, 0.07307270169258118], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/193.png"}, {"transform_matrix": [[-0.6625510577442367, 0.6546471318890051, 0.36395498154509826, 0.09990566968917847], [7.06221230838767e-08, 0.48591039000164654, -0.8740086343328898, -0.2399153709411621], [-0.7490167527378732, -0.5790753194515784, -0.32194048909707573, -0.08837264776229858], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/194.png"}, {"transform_matrix": [[-0.31723622455472844, 0.2942345414244374, 0.9015471215987623, 0.24747470021247864], [-8.354716881693072e-08, 0.9506515460093894, -0.3102605970308691, -0.08516653627157211], [-0.9483465494376279, -0.09842597575187849, -0.3015810827406714, -0.08278394490480423], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/195.png"}, {"transform_matrix": [[0.45330537364184387, 0.06984909379959613, 0.8886142820835166, 0.24392463266849518], [4.4907000298227674e-08, 0.99692490606698, -0.07836282066988656, -0.02151060290634632], [-0.8913552817072585, 0.035522327608393606, 0.4519114139008393, 0.12404967099428177], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/196.png"}, {"transform_matrix": [[0.9998681921076327, 0.009863119914276016, 0.01289640558337968, 0.003540071425959468], [-5.239866423105139e-08, 0.7943252359701186, -0.6074927320561234, -0.1667567640542984], [-0.016235714071505068, 0.6074126590437281, 0.7942205381517253, 0.21801353991031647], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/197.png"}, {"transform_matrix": [[0.8640179380851964, 0.22354883594197048, -0.4511085463788022, -0.12382930517196655], [3.5266038566298354e-08, 0.8960148082229201, 0.44402416988858007, 0.12188462913036346], [0.5034610239800145, -0.3836448636359332, 0.7741728592108882, 0.21251045167446136], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/198.png"}, {"transform_matrix": [[0.6152579970424594, -0.32722211185764827, 0.7172051914108832, 0.19687281548976898], [-9.942143233609254e-08, 0.9097826668039375, 0.41508493008432146, 0.11394080519676208], [-0.7883258191098979, -0.2553843939917563, 0.5597510287888466, 0.1536516696214676], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/199.png"}, {"transform_matrix": [[0.8676783927500517, 0.4697301666481507, 0.16275065989232573, 0.0446750782430172], [-8.050102432935285e-08, 0.32738328589458987, -0.9448916255935674, -0.2593727707862854], [-0.497125946571571, 0.8198620339164153, 0.28406344113200804, 0.07797537744045258], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/200.png"}, {"transform_matrix": [[-0.8487287567221928, -0.10533996404637166, -0.5182306334900608, -0.1422543227672577], [9.410803491593175e-08, 0.979959847554586, -0.1991951233860496, -0.05467905476689339], [0.5288284197287357, -0.16906267818623227, -0.8317200931393365, -0.22830715775489807], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/201.png"}, {"transform_matrix": [[-0.7189086481607881, 0.2345556131815338, -0.6543347919258631, -0.17961493134498596], [5.939068524559661e-08, 0.9413473018935337, 0.33743926448734485, 0.09262710064649582], [0.695104564507833, 0.24258796660757606, -0.6767427301845044, -0.1857658326625824], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/202.png"}, {"transform_matrix": [[0.8460373594109618, 0.17867322725850218, 0.5022914137649165, 0.13787899911403656], [-1.793319977135457e-08, 0.9421668949356511, -0.3351440616918544, -0.09199704974889755], [-0.5331236127587359, 0.2835443879683487, 0.7971083951199661, 0.21880625188350677], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/203.png"}, {"transform_matrix": [[0.27365300823997185, -0.6044736294218943, 0.7481481553908532, 0.20536667108535767], [2.5400369928144532e-08, 0.7778394722473191, 0.6284630103785037, 0.17251309752464294], [-0.9618284831929302, -0.1719807743543863, 0.21285812686212477, 0.05842955410480499], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/204.png"}, {"transform_matrix": [[-0.9816443962843754, 0.0016866104373712103, -0.19071296387166983, -0.05235086753964424], [-3.895506212049129e-08, 0.9999608949037757, 0.008843566205919529, 0.002427563536912203], [0.19072042167393283, 0.008681244638446115, -0.9816060089200986, -0.2694508135318756], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/205.png"}, {"transform_matrix": [[-0.797796227682628, -0.02595261508201525, 0.602368359781432, 0.165350079536438], [-1.1921600807949836e-07, 0.9990731687632177, 0.04304420352856453, 0.011815637350082397], [-0.6029271756152261, 0.034340431386740804, -0.797056808312192, -0.218792125582695], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/206.png"}, {"transform_matrix": [[0.3327399335721277, 0.1743501800371224, -0.9267611080140552, -0.2543959319591522], [1.4770092423068731e-08, 0.9827601253901813, 0.18488519665748, 0.05075099319219589], [0.9430186300420665, -0.06151870174262681, 0.3270035362644966, 0.08976247161626816], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/207.png"}, {"transform_matrix": [[-0.9910756138545347, -0.0065542082443493, 0.1331396634258438, 0.0365469753742218], [-7.771193577801205e-09, 0.9987904994523948, 0.04916846757461091, 0.013496791012585163], [-0.13330089130556178, 0.048729668149140204, -0.9898769074077935, -0.2717211842536926], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/208.png"}, {"transform_matrix": [[-0.7827832096044604, -0.3104939917243061, 0.5392994788282723, 0.14803770184516907], [9.001357536933664e-08, 0.8666305780581229, 0.49895033938723377, 0.13696184754371643], [-0.6222945016319295, 0.390569996643048, -0.6783838374850318, -0.18621638417243958], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/209.png"}, {"transform_matrix": [[0.13128290610964546, -0.6641311779624699, 0.7359990333020744, 0.20203173160552979], [-4.6177157670024815e-09, 0.7424247605613097, 0.6699294551708274, 0.18389564752578735], [-0.9913449442870054, -0.08795028916191203, 0.09746767706747737, 0.026754850521683693], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/210.png"}, {"transform_matrix": [[0.5747274436082771, -0.6091434449198366, -0.5464728987559111, -0.15000680088996887], [6.604769712654296e-08, 0.6677782570732663, -0.7443602618223154, -0.20432691276073456], [0.8183448940168748, 0.4278042343074507, 0.38379053081743114, 0.10535046458244324], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/211.png"}, {"transform_matrix": [[0.996980237374311, -0.07395948917231498, -0.02367277437126138, -0.006498183123767376], [2.3447546971776098e-08, 0.3048430378703694, -0.9524026051318653, -0.26143452525138855], [0.07765569061608993, 0.9495265747852107, 0.3039224859920756, 0.08342672884464264], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/212.png"}, {"transform_matrix": [[-0.6068105742798913, -0.331658515772549, -0.7223458699664992, -0.19828394055366516], [-7.447493229700027e-08, 0.9087866737789704, -0.41726104726148316, -0.11453815549612045], [0.7948464801092742, -0.2531983619167098, -0.5514613881139747, -0.1513761430978775], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/213.png"}, {"transform_matrix": [[0.43434418003921726, 0.19203432906217588, 0.8800386069529563, 0.2415706068277359], [-5.672711140919167e-08, 0.9770097770237244, -0.2131945018053915, -0.05852189660072327], [-0.9007469862653202, 0.09259974115348407, 0.4243585213852208, 0.11648639291524887], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/214.png"}, {"transform_matrix": [[-0.6581705189884205, 0.45329489632978304, -0.6011117241377717, -0.165005162358284], [6.262145153500058e-08, 0.7984281933580367, 0.6020900431422345, 0.1652737408876419], [0.7528688915970093, 0.3962778785301963, -0.5255019267834302, -0.14425024390220642], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/215.png"}, {"transform_matrix": [[-0.8585975895700924, 0.4683352078537892, -0.20850014932602523, -0.0572332963347435], [5.356029173657861e-08, 0.4067104831460273, 0.9135571043449455, 0.2507714331150055], [0.5126501528181026, 0.784377916557875, -0.3492006655662372, -0.09585556387901306], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/216.png"}, {"transform_matrix": [[0.6412087672733795, 0.4906915985239237, 0.5899771791432186, 0.16194875538349152], [2.569609389576258e-08, 0.7688336445620737, -0.639448846264811, -0.17552870512008667], [-0.7673664813970912, 0.4100202216079532, 0.4929828608590896, 0.13532377779483795], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/217.png"}, {"transform_matrix": [[0.8848385460470214, -0.4384419017831511, 0.1575736214922, 0.04325399175286293], [1.1284735086622344e-07, 0.33821520522001886, 0.9410687939560891, 0.25832340121269226], [-0.46589778646113, -0.832693925592564, 0.29926589991488356, 0.0821484625339508], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/218.png"}, {"transform_matrix": [[0.7080222687562503, 0.1157495059483056, 0.6966394467857638, 0.191227525472641], [2.4981204671309553e-08, 0.986475790550631, -0.16390703053105132, -0.04499248042702675], [-0.7061901068021637, 0.11604984502458758, 0.6984468244072113, 0.19172365963459015], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/219.png"}, {"transform_matrix": [[0.3160553652782595, -0.06869345122037476, 0.9462506094255685, 0.2597458064556122], [2.7809750764655544e-08, 0.9973753235502426, 0.07240486152909828, 0.01987513341009617], [-0.9487407475590078, -0.022883918643507372, 0.31522582411454203, 0.08652947843074799], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/220.png"}, {"transform_matrix": [[0.1390532231885571, 0.18455465259604814, 0.972935651174334, 0.26707082986831665], [2.6679529959851132e-08, 0.9824805382544489, -0.18636521121509714, -0.05115725100040436], [-0.990284909064494, 0.02591470926714138, 0.1366170806404782, 0.03750142455101013], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/221.png"}, {"transform_matrix": [[-0.8227363812971822, -0.08873185535544287, 0.5614548109467035, 0.1541193425655365], [-4.587992425137055e-08, 0.9877409873191514, 0.1561017039297969, 0.04284992069005966], [-0.5684231231134211, 0.12843052524602108, -0.8126504496368753, -0.22307255864143372], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/222.png"}, {"transform_matrix": [[-0.3336738703355827, 0.5744347242583071, 0.7474533402303822, 0.2051759511232376], [-8.317269880894312e-08, 0.7928952823210967, -0.6093579172152778, -0.16726873815059662], [-0.9426885743739901, -0.20332687682456294, -0.26456838984561865, -0.07262402772903442], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/223.png"}, {"transform_matrix": [[-0.475182110229523, -0.13452770017125917, -0.8695425579029752, -0.23868943750858307], [-9.26159665887318e-09, 0.9882429139598944, -0.15289193244921936, -0.04196884110569954], [0.8798874712813095, -0.07265150304493727, -0.46959535452077683, -0.12890389561653137], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/224.png"}, {"transform_matrix": [[-0.5123898968258883, 0.032595858848764016, 0.8581340825399416, 0.23555779457092285], [-4.550165375055052e-08, 0.9992793647012338, -0.03795722964465245, -0.010419263504445553], [-0.858752929328776, -0.0194489400279399, -0.5120206490963388, -0.1405496895313263], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/225.png"}, {"transform_matrix": [[0.9561191143513151, -0.04246801556481605, 0.28988395406790446, 0.07957316190004349], [-6.967578183428065e-09, 0.9894385668001924, 0.14495282863187253, 0.039789553731679916], [-0.2929782230338226, -0.13859217215401298, 0.9460211258981355, 0.2596828043460846], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/226.png"}, {"transform_matrix": [[-0.22601836602249062, -0.3158887074860453, -0.9214825135092467, -0.2529469430446625], [2.651459461898955e-08, 0.9459611087751878, -0.32428009603553615, -0.08901487290859222], [0.9741230405962701, -0.07329328187230355, -0.21380457575053038, -0.05868934839963913], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/227.png"}, {"transform_matrix": [[0.7897013925665869, 0.07298551797368477, 0.6091344882244857, 0.16720739006996155], [2.884562977210029e-08, 0.9928981485865997, -0.11896750200496453, -0.03265657275915146], [-0.6134914103542057, 0.09394881957435659, 0.7840930485103106, 0.21523356437683105], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/228.png"}, {"transform_matrix": [[0.2648692077708797, -0.13457202545350838, -0.9548479841001745, -0.2621057629585266], [-6.517748176678911e-09, 0.9902141275702674, -0.13955637412979074, -0.03830822557210922], [0.9642843474695764, 0.03696419247859296, 0.262277230615963, 0.07199510931968689], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/229.png"}, {"transform_matrix": [[0.7280915027576613, -0.4021568789442678, -0.5551149505551946, -0.15237905085086823], [-1.8755448514302804e-08, 0.8098193703608878, -0.5866792883580388, -0.1610434651374817], [0.6854799512838359, 0.42715621510882973, 0.5896225947856893, 0.1618514060974121], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/230.png"}, {"transform_matrix": [[0.015775016467737393, -0.9423334556641393, -0.33430346571868563, -0.09176630526781082], [-3.320103579077636e-08, 0.33434506889005605, -0.9424507281067285, -0.25870272517204285], [0.9998755666858961, 0.014867186855136048, 0.0052742676812005986, 0.001447764108888805], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/231.png"}, {"transform_matrix": [[0.16013911541149348, 0.2748132733579367, -0.9480681033035127, -0.2602446973323822], [8.132891653699645e-08, 0.96046340304306, 0.27840627043035066, 0.07642253488302231], [0.987094455315811, -0.04458381097708106, 0.15380773739816261, 0.042220231145620346], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/232.png"}, {"transform_matrix": [[-0.021509277945659815, -0.718133559785201, -0.6955728152195798, -0.19093473255634308], [-1.3418730361151316e-08, 0.6957337743265334, -0.7182997391488851, -0.19717328250408173], [0.9997686487194208, -0.015450099403944258, -0.014964740764612964, -0.004107785876840353], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/233.png"}, {"transform_matrix": [[-0.6652280806170379, -0.29911294680202055, -0.6841074811855105, -0.18778745830059052], [4.1050354374904744e-08, 0.9162478293753138, -0.40061192588966243, -0.10996794700622559], [0.7466402083725268, -0.2664983306147298, -0.6095137726261747, -0.16731159389019012], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/234.png"}, {"transform_matrix": [[0.5212810771039272, 0.4447177557024842, 0.7283489249091504, 0.1999317705631256], [4.404624628439761e-08, 0.8534821595471891, -0.5211220618383612, -0.1430479884147644], [-0.8533850471231421, 0.2716511017787564, 0.4449040798295968, 0.12212621420621872], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/235.png"}, {"transform_matrix": [[-0.45321968078809427, -0.22566984336152243, 0.8623601583697638, 0.23671786487102509], [-6.345956462000878e-09, 0.9674234525199003, 0.2531637089206828, 0.06949345022439957], [-0.8913988562626374, 0.11473876987166186, -0.43845534977007633, -0.12035597115755081], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/236.png"}, {"transform_matrix": [[-0.9980464477289502, 0.018883132682509088, -0.05955430694516189, -0.016347646713256836], [-3.4564346895031805e-08, 0.9532301952820342, 0.3022452560464325, 0.08296627551317215], [0.06247630091180657, 0.3016548061985247, -0.9513680096165247, -0.2611505389213562], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/237.png"}, {"transform_matrix": [[0.3043285995130272, 0.27938349547860186, 0.9106750056812791, 0.24998030066490173], [6.037190487755835e-09, 0.9560218837515507, -0.2932953422544188, -0.08050958067178726], [-0.9525671123435029, 0.08925816624989975, 0.29094479929922407, 0.07986429333686829], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/238.png"}, {"transform_matrix": [[-0.7387771492202599, 0.3273463142973832, 0.5891118011938861, 0.1617111712694168], [-1.76191601258689e-08, 0.8741182218503686, -0.4857132222095148, -0.13332827389240265], [-0.6739497932264581, -0.3588338400221871, -0.6457785622525309, -0.17726624011993408], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/239.png"}, {"transform_matrix": [[0.8884756247806714, 0.05973431771870426, -0.4550196429356392, -0.1249028891324997], [2.979204727171342e-08, 0.9914927679206736, 0.1301617884058165, 0.03572939336299896], [0.4589238108560013, -0.11564558983239405, 0.88091715466423, 0.24181176722049713], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/240.png"}, {"transform_matrix": [[0.9478079157566028, -0.09159394039286198, -0.3054025293157106, -0.08383297175168991], [-1.737302082287841e-07, 0.9578492838221245, -0.28727121241331033, -0.07885593920946121], [0.3188418962888887, 0.272277982151977, 0.9078571173957681, 0.2492067813873291], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/241.png"}, {"transform_matrix": [[0.993433913618738, 0.06291570404943522, -0.0955545574848288, -0.02622973546385765], [-2.0336363237365652e-09, 0.8352129000335814, 0.5499267329540314, 0.15095490217208862], [0.1144074266477381, -0.5463158663277669, 0.8297288201131644, 0.22776055335998535], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/242.png"}, {"transform_matrix": [[-0.5785850408960854, -0.7288565637221752, 0.36607029375569156, 0.10048627853393555], [8.664767929796277e-08, 0.4488233770791935, 0.8936204877839479, 0.2452988177537918], [-0.815622063489744, 0.5170354781891966, -0.2596824288287546, -0.07128287106752396], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/243.png"}, {"transform_matrix": [[-0.9705983378841625, 0.01342835206373976, -0.24033007688875155, -0.06597062200307846], [-1.4684301830393785e-08, 0.9984426555727695, 0.05578766470104196, 0.015313706360757351], [0.2407049365852325, 0.054147418162349685, -0.9690867817743934, -0.26601430773735046], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/244.png"}, {"transform_matrix": [[0.9396282052965612, 0.1406116160626851, -0.31197309056936806, -0.08563664555549622], [-3.6516319709872406e-08, 0.9116767224519915, 0.4109082059769468, 0.11279430240392685], [0.342197071599337, -0.38610092873163926, 0.8566371676628348, 0.2351468950510025], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/245.png"}, {"transform_matrix": [[-0.1654732826944964, -0.4897073900755985, -0.8560404574666156, -0.23498311638832092], [7.467083033675727e-09, 0.8680065581012651, -0.4965527314326189, -0.13630372285842896], [0.986214273225807, -0.08216621689319926, -0.14363189091268175, -0.039426904171705246], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/246.png"}, {"transform_matrix": [[0.9468461120228049, -0.0542005249108693, 0.31708791091223315, 0.08704064041376114], [1.3103857634689494e-08, 0.9857036326892055, 0.16848842246072504, 0.04625007137656212], [-0.32168686660679496, -0.15953260357271845, 0.9333096529287651, 0.25619348883628845], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/247.png"}, {"transform_matrix": [[0.928912683559729, 0.022212597566911896, 0.3696320154304729, 0.10146397352218628], [2.425729708725993e-08, 0.9981992389081589, -0.05998566031287472, -0.0164660532027483], [-0.37029883381110235, 0.05572144966260832, 0.9272399332026393, 0.25452736020088196], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/248.png"}, {"transform_matrix": [[0.7073483953628747, 0.04331762106879319, 0.7055365555961692, 0.19366979598999023], [9.336786306560109e-08, 0.9981205283664142, -0.061281407078665084, -0.01682174950838089], [-0.7068650844238645, 0.043347370837113416, 0.7060189500742542, 0.19380219280719757], [0.0, 0.0, 0.0, 1.0]], "file_path": "images/249.png"}]} \ No newline at end of file diff --git a/frogger/baselines/ng.py b/frogger/baselines/ng.py new file mode 100644 index 0000000..fc0ffb8 --- /dev/null +++ b/frogger/baselines/ng.py @@ -0,0 +1,187 @@ +from dataclasses import dataclass +from pathlib import Path +from typing import Tuple + +import numpy as np +import pypose as pp +import pytorch_kinematics as pk +import torch + +from frogger import ROOT +from frogger.baselines.base import BaselineConfig +from frogger.robots.robot_core import RobotModel +from frogger.robots.robots import AlgrModel, FR3AlgrModel, FR3AlgrZed2iModel + +try: + import nerf_grasping + from nerf_grasping.config.grasp_metric_config import GraspMetricConfig + from nerf_grasping.optimizer_utils import AllegroGraspConfig, GraspMetric +except ImportError: + raise ImportError( + "The NeRF grasping baseline requires the `nerf_grasping` package. " + "Please install it with frogger using `pip install -e .[ng]` or " + "`pip install -e .[all]`." + ) + +device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + + +@dataclass(kw_only=True) +class NerfGraspingBaselineConfig(BaselineConfig): + """Configuration for the NeRF grasping baseline.""" + + n_g_extra: int = 1 + min_success_prob: float = 0.0 + + # def __post_init__(self) -> None: + # """Post-initialization checks.""" + # # TODO(ahl): figure out how to annotate the model class correctly + # super().__post_init__() + + def _init_baseline_obj(self, model: RobotModel) -> None: + """Initialize the objective function.""" + # checking the model class to initialize the kinematics chain + model_class = type(self).__name__ + substrings = ["AlgrModel", "FR3AlgrModel", "FR3AlgrZed2iModel"] + assert any(sub in model_class for sub in substrings) + + # TODO(ahl): for now, we use pytorch_kinematics, so we must ensure we have + # URDFs of all the relevant models for compatibility reasons. + assert "FR3AlgrZed2iModel" in model_class + if "AlgrModel" in model_class: + assert self.hand == "rh" # TODO(ahl): for now, rh only + raise NotImplementedError + elif "FR3AlgrModel" in model_class: + raise NotImplementedError + elif "FR3AlgrZed2iModel" in model_class: + model_path = Path(ROOT) / "models/fr3_algr_zed2i/fr3_algr_zed2i.urdf" + with open(model_path) as f: + chain = pk.build_chain_from_urdf(f.read()) + chain = chain.to(device="cuda", dtype=torch.float32) + + # initializing the grasp metric + # TODO(ahl): expose this somehow + base_path = Path(ROOT) / "frogger/baselines" + grasp_metric_config = GraspMetricConfig( + # classifier_config=None, # use default + classifier_config_path=base_path / "classifier/config.yaml", + classifier_checkpoint=-1, # load latest checkpoint + nerf_checkpoint_path=base_path / "nerf/config.yml", + object_transform_world_frame=None, # TODO(ahl): fill this in + ) + grasp_metric = GraspMetric.from_config(grasp_metric_config) + grasp_metric = grasp_metric.to(device) + grasp_metric.eval() + + FINGERTIP_LINK_NAMES = [ + "algr_rh_if_ds_tip", + "algr_rh_mf_ds_tip", + "algr_rh_rf_ds_tip", + "algr_rh_th_ds_tip", + ] + + R_OOyup = torch.tensor( + [ + [1.0, 0.0, 0.0], + [0.0, 0.0, -1.0], + [0.0, 1.0, 0.0], + ], + device=device, + dtype=torch.float32, + ) # rotate to y up + + def q_to_failure_prob( + q: torch.Tensor, grasp_orientations: torch.Tensor + ) -> torch.Tensor: + """From the model configuration, computes the failure prob.""" + # computing the entries of the grasp config dict + if "AlgrModel" in model_class and self.hand == "lh": + body_name = "algr_lh_palm" + else: + body_name = "algr_rh_palm" + link_poses_hand_frame = chain.forward_kinematics(q) + X_WWrist = link_poses_hand_frame[body_name].get_matrix() + X_WO = torch.tensor( + model.obj.X_WO.GetAsMatrix4(), device=device, dtype=torch.float32 + ) # (4, 4) + X_OWrist = torch.inverse(X_WO) @ X_WWrist # TODO(ahl): not optimized + R_OyupWrist = R_OOyup.T @ X_OWrist[:3, :3] + X_OyupWrist = X_OWrist + X_OyupWrist[:3, :3] = R_OyupWrist + + # computing fingertip transforms + fingertip_poses = [link_poses_hand_frame[ln] for ln in FINGERTIP_LINK_NAMES] + fingertip_pyposes = [ + pp.from_matrix(fp.get_matrix(), pp.SE3_type) for fp in fingertip_poses + ] + wrist_pose = pp.from_matrix(X_OyupWrist, ltype=pp.SE3_type) + X_WristW_pp = pp.from_matrix(torch.inverse(X_WWrist), ltype=pp.SE3_type) + fingertip_transforms = torch.stack( + [wrist_pose @ X_WristW_pp @ fp for fp in fingertip_pyposes], dim=1 + ) + + # call alternative forward pass to avoid using grasp_config, which breaks the + # compute graph and prevents us from getting gradients + fingertip_positions_pp = fingertip_transforms.translation() # (1, nc, 3) + grasp_orientations_pp = pp.from_matrix( + grasp_orientations[None, ...], pp.SO3_type + ) # (1, nc, 4) + grasp_frame_transforms = pp.SE3( + torch.cat( + [ + fingertip_positions_pp, + grasp_orientations_pp, + ], + dim=-1, + ) + ) + failure_prob = grasp_metric.forward_alt(grasp_frame_transforms) + return failure_prob + + # adding this function to the model attributes + model._q_to_failure_prob = q_to_failure_prob + + @staticmethod + def custom_compute_g(model: RobotModel) -> Tuple[np.ndarray, np.ndarray]: + """Adding minimum success probability constraint.""" + g_extra = -model.l + model.min_success_prob # success probability + Dg_extra = -model.Dl + return g_extra, Dg_extra + + @staticmethod + def custom_compute_l(model: RobotModel) -> Tuple[np.ndarray, np.ndarray]: + """Cost function for NeRF grasping baseline.""" + R_OOyup = torch.tensor( + [ + [1.0, 0.0, 0.0], + [0.0, 0.0, -1.0], + [0.0, 1.0, 0.0], + ], + device=device, + dtype=torch.float32, + ) # rotate to y up + + # computing the failure probability + grasp_orientations = ( + R_OOyup.T @ torch.tensor(model.R_cf_O, device=device, dtype=torch.float32) + ).requires_grad_(True) + q = torch.tensor(model.q, device=device, dtype=torch.float32).requires_grad_( + True + ) + _l_torch = model._q_to_failure_prob(q, grasp_orientations) + _l = _l_torch.item() + + # compute gradients using chain rule + total derivative + _l_torch.backward() + Dl_q = q.grad.cpu().detach().numpy() # (23,), this is a partial derivative + Dl_go = grasp_orientations.grad.cpu().detach().numpy() # (4, 3, 3) + Dgo_q = np.einsum( + "jk,iklm->ijlm", R_OOyup.T.cpu().numpy(), model.DR_cf_O + ) # (4, 3, 3, 23) + _Dl = Dl_q + np.einsum("ijk,ijkl->l", Dl_go, Dgo_q) + return 1.0 - _l, -_Dl + + def create_pre_warmstart(self, model: RobotModel) -> None: + """Initializes the baseline constraints.""" + model.min_success_prob = self.min_success_prob + self._init_baseline_obj(model) diff --git a/frogger/baselines/wu.py b/frogger/baselines/wu.py new file mode 100644 index 0000000..ae2fcd4 --- /dev/null +++ b/frogger/baselines/wu.py @@ -0,0 +1,104 @@ +from dataclasses import dataclass +from typing import Tuple + +import numpy as np +import torch +from qpth.qp import QPFunction + +from frogger.baselines.base import BaselineConfig +from frogger.robots.robot_core import RobotModel + + +@dataclass(kw_only=True) +class WuBaselineConfig(BaselineConfig): + """Configuration for the Wu baseline solver. + + Note + ---- + All of the torch functions use the default device, which is CPU unless changed + elsewhere. In testing, the device did not have a large difference on run time. + """ + + n_g_extra: int = 0 + n_h_extra: int = 1 + + def _init_baseline_cons(self, model: RobotModel) -> None: + """Initializes constraints for the baseline. + + Equation (5) of the paper: + "Learning Diverse and Physically Feasible Dexterous Grasps with Generative + Model and Bilevel Optimization" + """ + # setting up the feasibility QP + # (i) friction cone constraint + Lambda_i = np.vstack( + ( + np.append(np.cos(2 * np.pi * np.arange(model.ns) / model.ns), 0.0), + np.append(np.sin(2 * np.pi * np.arange(model.ns) / model.ns), 0.0), + -np.append( + model.mu * np.cos(np.pi * np.ones(model.ns) / model.ns), 1.0 + ), + ) + ).T # pyramidal friction cone approx in contact frame + min normal force + + # Ain has shape((ns + 1) * nc, 3 * nc) + fn_min = 1.0 # hard code min normal force to 1, that's what they use + A_in = torch.tensor(np.kron(np.eye(model.nc), Lambda_i)) + b_in = torch.zeros((model.ns + 1) * model.nc).double() + b_in[model.ns :: model.ns + 1] = -fn_min + + A_eq = torch.Tensor().double() # empty + b_eq = torch.Tensor().double() + + # (ii) setting up QP constraint function + def bilevel_constraint_func(G: torch.Tensor) -> torch.Tensor: + """Constraint function for bilevel optimization. + + Takes in the grasp map and returns a cost. + """ + if G.dtype == torch.float32: + G = G.double() + Q = G.T @ G + 1e-7 * torch.eye(3 * model.nc).double() + f_opt = QPFunction(verbose=-1, check_Q_spd=False)( + Q, torch.zeros(3 * model.nc).double(), A_in, b_in, A_eq, b_eq + ).squeeze() + h = f_opt @ Q @ f_opt + return h + + # adding the bilevel constraint to the model + model._bilevel_cons = bilevel_constraint_func + + @staticmethod + def custom_compute_l(model: RobotModel) -> Tuple[np.ndarray, np.ndarray]: + """Cost function for Wu baseline. Since it's a feas program, does nothing.""" + return 0.0, np.zeros(model.n) + + @staticmethod + def custom_compute_h(model: RobotModel) -> Tuple[np.ndarray, np.ndarray]: + """Extra equality constraints for Wu baseline. This is the force closure QP. + + Warning + ------- + Requires model.DG to have been computed and cached already! + """ + # equality constraint + G = torch.tensor(model.G).double() + h = (model._bilevel_cons(G)).cpu().detach().numpy()[..., None] # (1,) + + # gradient + Dh_G = ( + torch.autograd.functional.jacobian( + model._bilevel_cons, G, create_graph=True, strict=True + ) + .cpu() + .detach() + .numpy() + ) + DG = model.DG + Dh = (Dh_G.reshape(-1) @ DG.reshape((-1, DG.shape[-1])))[None, ...] # (1, n) + + return h, Dh + + def create_pre_warmstart(self, model: RobotModel) -> None: + """Initializes the baseline constraints.""" + self._init_baseline_cons(model) diff --git a/frogger/robots/robot_core.py b/frogger/robots/robot_core.py index 0c4b963..03d427d 100644 --- a/frogger/robots/robot_core.py +++ b/frogger/robots/robot_core.py @@ -73,6 +73,7 @@ def __init__(self, cfg: "RobotModelConfig") -> None: ) # these will be class functions self.custom_compute_g = cfg.__class__.custom_compute_g self.custom_compute_h = cfg.__class__.custom_compute_h + self.finger_level_set = cfg.finger_level_set self.n_g_extra = cfg.n_g_extra self.n_h_extra = cfg.n_h_extra self.cfg = cfg @@ -172,6 +173,8 @@ def __init__(self, cfg: "RobotModelConfig") -> None: ) self.n_O = None self.n_W = None + self.R_O_cf = None # contact frames of each finger expressed in obj frame + self.DR_O_cf = None self.Ds_p = None # cached value of Ds evaluated at fingertips self.h = None # cached values of the eq constraint function and Jacobian self.Dh = None @@ -333,12 +336,13 @@ def set_q(self, q: np.ndarray) -> None: """Sets the robot state.""" assert len(q) == self.n self.plant.SetPositions(self.plant_context, self.robot_instance, q) + self.q = np.copy(q) # ######################## # # CACHED VALUE COMPUTATION # # ######################## # - def _process_collisions(self, q: np.ndarray) -> None: + def _process_collisions(self) -> None: """Computes all information related to collision constraints.""" # we initialize the inequality constraints here to allow derived RobotModels # to modify the collision geometries during initialization @@ -346,7 +350,7 @@ def _process_collisions(self, q: np.ndarray) -> None: self._init_ineq_cons() # update joint limit constraint values - self.g[: self.n_bounds] = self.A_box @ q + self.b_box + self.g[: self.n_bounds] = self.A_box @ self.q + self.b_box # collisions get computed conditionally after culling w/max_distance. # everything sufficiently far away we ignore and set the gradient to 0 @@ -476,7 +480,9 @@ def get_bf(gid): p_tips = [] J_tips = [] for _, v in sorted(self.hand_obj_cols.items()): - h.append(v[0]) + h.append( + v[0] - self.finger_level_set + ) # enforce that the tips lie on a level set Dh.append(v[1]) p_tips.append(v[2]) J_tips.append( @@ -505,7 +511,10 @@ def _finish_ineq_cons(self) -> None: else: g_extra, Dg_extra = self.custom_compute_g(self) - assert len(g_extra) == self.n_g_extra + if isinstance(g_extra, float): + assert self.n_g_extra == 1 + elif isinstance(g_extra, np.ndarray): + assert len(g_extra) == self.n_g_extra self.g[-self.n_g_extra :] = g_extra self.Dg[-self.n_g_extra :, :] = Dg_extra @@ -534,7 +543,7 @@ def _compute_DG_and_DW(self) -> None: Ds_O_ps = self.obj.Ds_O(self.P_OF.T, batched=True) D2s_O_ps = self.obj.D2s_O(self.P_OF.T, batched=True) - self.DG, self.DW = self._DG_DW_helper( + self.DG, self.DW, self.R_O_cf, self.DR_O_cf = self._DG_DW_helper( J_T, Ds_O_ps, D2s_O_ps, self.P_OF, self.n_O, R_OW, self.F ) @@ -579,6 +588,10 @@ def _DG_DW_helper( summing_matrix = np.kron(np.eye(nc), np.ones((1, 3))) gs_inners = summing_matrix @ (np.ascontiguousarray(Ds_O_ps).reshape(-1) ** 2) + # caching the contact frames and their Jacobians wrt q + R_O_cf = np.zeros((nc, 3, 3)) + DR_O_cf = np.zeros((nc, 3, 3, n)) + for i in range(nc): p = P_OF.T[i, :] # P_OF.T has shape (nc, 3), select ith row nrml = n_O.T[i, :] # n_O.T has shape (nc, 3), select ith row @@ -589,9 +602,10 @@ def _DG_DW_helper( zz = z @ z tx = z / np.sqrt(zz) ty = np.cross(nrml, tx) - R = np.stack((tx, ty, nrml)).T + R = np.stack((tx, ty, nrml)).T # contact frame in object frame + R_O_cf[i, ...] = R - # compute DR_p, Jacobian of rotation matrix wrt p + # compute DR_p, Jacobian of rotation matrix wrt p in object frame gs = Ds_O_ps[i] # compute this in the object frame gsgs = gs_inners[i] factor1 = (np.eye(3) - np.outer(gs, gs) / gsgs) / np.sqrt(gsgs) @@ -608,6 +622,10 @@ def _DG_DW_helper( DR_p = np.stack((Dtx_p, Dty_p, Dn_p), axis=1) # (3, 3, 3) + # computing the Jacobian of R wrt q - useful for nerf grasping + DR = (DR_p.reshape((9, -1)) @ R_OW_J).reshape((3, 3, n)) # (3, 3, n) + DR_O_cf[i, ...] = DR + # compute DphatR_p, Jacobian of skew(p) @ R # note that here p is in the object frame, so later, when we try to # differentiate wrt q, we need a factor that rotates to the world frame @@ -633,7 +651,8 @@ def _DG_DW_helper( DG[:, (3 * i) : (3 * (i + 1)), :] = DG_i DW[:, (ns * i) : (ns * (i + 1)), :] = DW_i - return DG, DW + + return DG, DW, R_O_cf, DR_O_cf def _compute_l(self) -> None: """Computes the min-weight metric and its gradient.""" @@ -649,11 +668,11 @@ def _compute_cost_func(self) -> None: self.f = -self.l self.Df = -self.Dl - def _compute_eq_cons(self, q: np.ndarray) -> None: + def _compute_eq_cons(self) -> None: """Computes the equality constraints.""" # computing coupling and contact constraints if self.n_couple != 0: - h_couple = self.A_couple @ q + self.b_couple + h_couple = self.A_couple @ self.q + self.b_couple Dh_couple = self.A_couple self.h[: self.n_couple + self.nc] = np.concatenate((self.h_tip, h_couple)) self.Dh[: self.n_couple + self.nc, :] = np.concatenate( @@ -681,18 +700,18 @@ def compute_all(self, q: np.ndarray) -> None: # updating plant context n = self.n assert q.shape == (n,) - self.set_q(q) + self.set_q(q) # also caches self.q # computing all cached values if self.h is None: self._init_eq_cons() - self._process_collisions(q) + self._process_collisions() self._compute_G_and_W() self._compute_DG_and_DW() self._compute_l() self._compute_cost_func() self._finish_ineq_cons() - self._compute_eq_cons(q) + self._compute_eq_cons() # ###################### # # CACHED VALUE RETRIEVAL # @@ -702,56 +721,60 @@ def compute_p_tips(self, q: np.ndarray) -> np.ndarray: """Computes the forward kinematics, p_tips.""" if self.p_tips is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.p_tips # (nc, 3) def compute_J_tips(self, q: np.ndarray) -> np.ndarray: """Computes the Jacobians of the fingertips, J_tips.""" if self.J_tips is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.J_tips # (nc, 3, n) def compute_n_O(self, q: np.ndarray) -> np.ndarray: """Computes the invward contact normals in the object frame, n_O.""" if self.n_O is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.n_O.T # (nc, 3) def compute_n_W(self, q: np.ndarray) -> np.ndarray: """Computes the inward contact normals in the world frame, n_W.""" if self.n_W is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.n_W.T # (nc, 3) + def compute_R_O_cf(self, q: np.ndarray) -> np.ndarray: + """Computes the contact frames of each finger expressed in the object frame.""" + if self.R_O_cf is None or np.any(q != self.q): + self.compute_all(q) + return self.R_O_cf + + def compute_DR_O_cf(self, q: np.ndarray) -> np.ndarray: + """Computes the Jacobian of the contact frames in the object frame.""" + if self.DR_O_cf is None or np.any(q != self.q): + self.compute_all(q) + return self.DR_O_cf + def compute_g(self, q: np.ndarray) -> np.ndarray: """Computes the inequality constraints g.""" if self.g is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.g # (n_ineq_cons,) def compute_Dg(self, q: np.ndarray) -> np.ndarray: """Computes the Jacobian of the inequality constraints, Dg.""" if self.Dg is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.Dg # (n_ineq_cons, n) def compute_h(self, q: np.ndarray) -> np.ndarray: """Computes the equality constraints h.""" if self.h is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.h # (n_eq_cons,) def compute_Dh(self, q: np.ndarray) -> np.ndarray: """Computes the Jacobian of the equality constraints, Dh.""" if self.Dh is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.Dh # (n_eq_cons, n) def compute_Ds(self, q: np.ndarray) -> np.ndarray: @@ -761,70 +784,60 @@ def compute_Ds(self, q: np.ndarray) -> np.ndarray: """ if self.Ds_p is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.Ds_p # (nc, 3) def compute_gOCs(self, q: np.ndarray) -> np.ndarray: """Computes the transformations from contacts to object frames.""" if self.gOCs is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.gOCs # (nc, 4, 4) def compute_G(self, q: np.ndarray) -> np.ndarray: """Computes the grasp map, G.""" if self.G is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.G # (6, 3 * nc) def compute_DG(self, q: np.ndarray) -> np.ndarray: """Computes the Jacobian of the grasp map, DG.""" if self.DG is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.DG # (6, 3 * nc, n) def compute_W(self, q: np.ndarray) -> np.ndarray: """Computes the wrench matrix whose columns are the primitive wrenches, W.""" if self.W is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.W # (6, ns * nc) def compute_DW(self, q: np.ndarray) -> np.ndarray: """Computes the Jacobian of the wrench matrix, Dw.""" if self.DW is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.DW # (6, ns * nc, n) def compute_l(self, q: np.ndarray) -> float: - """Computes the optimal minimum convex weight l.""" + """Computes the optimal minimum convex weight l (or other metric value).""" if self.l is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.l def compute_Dl(self, q: np.ndarray) -> np.ndarray: """Computes the Jacobian of l, Dl.""" if self.Dl is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.Dl # (n,) def compute_f(self, q: np.ndarray) -> float: - """Computes the cost function f.""" + """Computes the cost function f. Negative of the metric l.""" if self.f is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.f def compute_Df(self, q: np.ndarray) -> np.ndarray: """Computes the gradient of the cost, Df.""" if self.Df is None or np.any(q != self.q): self.compute_all(q) - self.q = np.copy(q) return self.Df # (n,) # ##### # @@ -896,6 +909,10 @@ class RobotModelConfig: The allowable penetration between the fingertips and the object. l_bar_cutoff : float, default=1e-6 The minimum allowable value of l_bar. + n_couple : int, default=0 + The number of coupling constraints. + finger_level_set : float, default=0.0 + The object level set that the fingertips should lie on. name : str | None, default=None The name of the robot. viz : bool, default=True @@ -934,6 +951,7 @@ class RobotModelConfig: d_pen: float = 0.001 l_bar_cutoff: float = 1e-6 n_couple: int = 0 + finger_level_set: float = 0.0 name: str | None = None viz: bool = True custom_compute_l: Callable[ diff --git a/models/fr3_algr_zed2i/fr3_algr_zed2i.urdf b/models/fr3_algr_zed2i/fr3_algr_zed2i.urdf new file mode 100644 index 0000000..7526d6d --- /dev/null +++ b/models/fr3_algr_zed2i/fr3_algr_zed2i.urdf @@ -0,0 +1,1067 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pyproject.toml b/pyproject.toml index 7f42621..45acdca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,6 +44,17 @@ dev = [ "pyglet<2", # for showing meshes in trimesh ] +# nerf grasping dependencies +ng = [ + "nerf_grasping@git+https://github.com/tylerlum/nerf_grasping", +] + +# all +all = [ + "frogger[dev]", + "frogger[ng]", +] + [options] dependency_links = [ "https://storage.googleapis.com/jax-releases/jax_releases.html", @@ -52,4 +63,4 @@ dependency_links = [ ] [tool.setuptools.packages.find] -include = ["frogger"] +include = ["frogger*"] diff --git a/scripts/test_nerf_grasping_solver.py b/scripts/test_nerf_grasping_solver.py new file mode 100644 index 0000000..ac5cca2 --- /dev/null +++ b/scripts/test_nerf_grasping_solver.py @@ -0,0 +1,72 @@ +import numpy as np +import torch +import trimesh +from nerf_grasping.config.grasp_metric_config import GraspMetricConfig +from nerf_grasping.optimizer_utils import GraspMetric +from pydrake.all import RigidTransform, RotationMatrix + +from frogger import ROOT +from frogger.baselines.ng import NerfGraspingBaselineConfig +from frogger.objects import MeshObjectConfig +from frogger.robots.robots import FR3AlgrZed2iModelConfig +from frogger.sampling import HeuristicFR3AlgrICSampler +from frogger.solvers import FroggerConfig + +# loading the object +mesh = trimesh.load(ROOT + "/data/test/bottle3/coacd/decomposed.obj") +mesh.apply_scale(0.0915) # scale down the size of the mesh +bounds = mesh.bounds +lb_O = bounds[0, :] +ub_O = bounds[1, :] +X_WO = RigidTransform( + RotationMatrix( + np.array( + [ + [1.0, 0.0, 0.0], + [0.0, 0.0, -1.0], + [0.0, 1.0, 0.0], + ] + ) + ), # make the bottle right side up + np.array([0.7, 0.0, -lb_O[-2]]), +) +obj = MeshObjectConfig( + X_WO=X_WO, + mesh=mesh, + name="bottle3", + clean=False, +).create() + +# loading the model +ModelConfig = NerfGraspingBaselineConfig.from_cfg(FR3AlgrZed2iModelConfig) +model = ModelConfig( + obj=obj, + ns=4, + mu=0.7, + d_min=0.001, + d_pen=0.005, + min_success_prob=0.05, + finger_level_set=0.01, + viz=True, +).create() + +# loading the sampler +sampler = HeuristicFR3AlgrICSampler( + model, + z_axis_fwd=True, +) +frogger = FroggerConfig( + model=model, + sampler=sampler, + tol_surf=1e-3, + tol_joint=1e-2, + tol_col=1e-3, + tol_fclosure=1e-5, + xtol_rel=1e-6, + xtol_abs=1e-6, + maxeval=1000, + maxtime=60.0, +).create() + +q_star = frogger.generate_grasp() +model.viz_config(q_star) diff --git a/scripts/timing.py b/scripts/timing.py index 1747042..c58f463 100644 --- a/scripts/timing.py +++ b/scripts/timing.py @@ -6,9 +6,9 @@ from pydrake.math import RigidTransform, RotationMatrix from frogger import ROOT -from frogger.baselines import WuBaselineConfig +from frogger.baselines.wu import WuBaselineConfig from frogger.metrics import ferrari_canny_L1, min_weight_metric -from frogger.objects import MeshObject, MeshObjectConfig +from frogger.objects import MeshObjectConfig from frogger.robots.robots import ( AlgrModelConfig, BH280ModelConfig, @@ -20,7 +20,7 @@ HeuristicBH280ICSampler, HeuristicFR3AlgrICSampler, ) -from frogger.solvers import Frogger, FroggerConfig +from frogger.solvers import FroggerConfig # [Feb. 22, 2024] suppress annoying torch warning about LUSolve from qpth warnings.filterwarnings("ignore", category=UserWarning)