@@ -66,6 +66,22 @@ def __init__(self, zmq_url=None):
66
66
self .primitive_geometries_names = []
67
67
self .arrow_names = []
68
68
self .link_visuals = dict ()
69
+ self ._animation = None
70
+ self ._current_frame = 0
71
+
72
+ def start_recording_animation (self ):
73
+ from meshcat .animation import Animation
74
+ self ._animation = Animation ()
75
+
76
+ def stop_recording_animation (self ):
77
+ self ._animation = None
78
+
79
+ def set_animation_frame (self , frame_number ):
80
+ self ._current_frame = frame_number
81
+
82
+ def publish_animation (self ):
83
+ if self ._animation is not None :
84
+ self .viewer .set_animation (self ._animation )
69
85
70
86
@staticmethod
71
87
def __is_mesh (geometry_object : idyn .SolidShape ) -> bool :
@@ -174,7 +190,11 @@ def __apply_transform_to_primitive_geomety(
174
190
world_H_geometry_scaled = np .array (world_H_geometry )
175
191
176
192
# Update viewer configuration.
177
- self .viewer [viewer_name ].set_transform (world_H_geometry_scaled )
193
+ if self ._animation is None :
194
+ self .viewer [viewer_name ].set_transform (world_H_geometry_scaled )
195
+ else :
196
+ with self ._animation .at_frame (self .viewer , self ._current_frame ) as frame :
197
+ frame [viewer_name ].set_transform (world_H_geometry_scaled )
178
198
179
199
def __apply_transform (self , world_H_frame , solid_shape , viewer_name ):
180
200
world_H_geometry = (
@@ -187,7 +207,11 @@ def __apply_transform(self, world_H_frame, solid_shape, viewer_name):
187
207
world_H_geometry_scaled = np .array (world_H_geometry ).dot (extended_scale )
188
208
189
209
# Update viewer configuration.
190
- self .viewer [viewer_name ].set_transform (world_H_geometry_scaled )
210
+ if self ._animation is None :
211
+ self .viewer [viewer_name ].set_transform (world_H_geometry_scaled )
212
+ else :
213
+ with self ._animation .at_frame (self .viewer , self ._current_frame ) as frame :
214
+ frame [viewer_name ].set_transform (world_H_geometry_scaled )
191
215
192
216
def __model_exists (self , model_name ):
193
217
return (
@@ -509,7 +533,11 @@ def set_primitive_geometry_transform(
509
533
transform [0 :3 , 0 :3 ] = rotation
510
534
transform [0 :3 , 3 ] = position
511
535
transform [3 , 3 ] = 1
512
- self .viewer [shape_name ].set_transform (transform )
536
+ if self ._animation is None :
537
+ self .viewer [shape_name ].set_transform (transform )
538
+ else :
539
+ with self ._animation .at_frame (self .viewer , self ._current_frame ) as frame :
540
+ frame [shape_name ].set_transform (transform )
513
541
514
542
def set_arrow_transform (self , origin , vector , shape_name = "iDynTree" ):
515
543
if not self .__arrow_exists (shape_name ):
@@ -523,7 +551,11 @@ def set_arrow_transform(self, origin, vector, shape_name="iDynTree"):
523
551
transform [3 , 3 ] = 1
524
552
525
553
if np .linalg .norm (vector ) < 1e-6 :
526
- self .viewer [shape_name ].set_transform (transform )
554
+ if self ._animation is None :
555
+ self .viewer [shape_name ].set_transform (transform )
556
+ else :
557
+ with self ._animation .at_frame (self .viewer , self ._current_frame ) as frame :
558
+ frame [shape_name ].set_transform (transform )
527
559
return
528
560
529
561
# extract rotation matrix from a normalized vector
@@ -543,7 +575,11 @@ def set_arrow_transform(self, origin, vector, shape_name="iDynTree"):
543
575
R = np .eye (3 ) + skew_symmetric_matrix + np .dot (skew_symmetric_matrix , skew_symmetric_matrix ) * ((1 - c ) / (s ** 2 ))
544
576
545
577
transform [0 :3 , 0 :3 ] = R @ S
546
- self .viewer [shape_name ].set_transform (transform )
578
+ if self ._animation is None :
579
+ self .viewer [shape_name ].set_transform (transform )
580
+ else :
581
+ with self ._animation .at_frame (self .viewer , self ._current_frame ) as frame :
582
+ frame [shape_name ].set_transform (transform )
547
583
548
584
def load_model_from_file (
549
585
self , model_path : str , considered_joints = None , model_name = "iDynTree" , color = None
0 commit comments