1
+ import argparse
2
+ import copy
3
+ import numpy as np
4
+ from src .env import PickPlaceEnv
5
+ from src .LMP import LMP , LMP_wrapper , LMPFGen
6
+ from src .configs import cfg_tabletop , lmp_tabletop_coords
7
+ from src .key import projectkey
8
+ from openai import OpenAI
9
+ import shapely
10
+ from shapely .geometry import *
11
+ from shapely .affinity import *
12
+ from moviepy .editor import ImageSequenceClip , concatenate_videoclips
13
+
14
+ def setup_LMP (env , cfg_tabletop , openai_client ):
15
+ # LMP env wrapper
16
+ cfg_tabletop = copy .deepcopy (cfg_tabletop )
17
+ cfg_tabletop ["env" ] = dict ()
18
+ cfg_tabletop ["env" ]["init_objs" ] = list (env .obj_name_to_id .keys ())
19
+ cfg_tabletop ["env" ]["coords" ] = lmp_tabletop_coords
20
+ LMP_env = LMP_wrapper (env , cfg_tabletop )
21
+ # creating APIs that the LMPs can interact with
22
+ fixed_vars = {"np" : np }
23
+ fixed_vars .update (
24
+ {
25
+ name : eval (name )
26
+ for name in shapely .geometry .__all__ + shapely .affinity .__all__
27
+ }
28
+ )
29
+ variable_vars = {
30
+ k : getattr (LMP_env , k )
31
+ for k in [
32
+ "get_bbox" ,
33
+ "get_obj_pos" ,
34
+ "get_color" ,
35
+ "is_obj_visible" ,
36
+ "denormalize_xy" ,
37
+ "put_first_on_second" ,
38
+ "get_obj_names" ,
39
+ "get_corner_name" ,
40
+ "get_side_name" ,
41
+ ]
42
+ }
43
+ variable_vars ["say" ] = lambda msg : print (f"robot says: { msg } " )
44
+
45
+ # creating the function-generating LMP
46
+ lmp_fgen = LMPFGen (openai_client , cfg_tabletop ["lmps" ]["fgen" ], fixed_vars , variable_vars )
47
+
48
+ # creating other low-level LMPs
49
+ variable_vars .update (
50
+ {
51
+ k : LMP (openai_client , k , cfg_tabletop ["lmps" ][k ], lmp_fgen , fixed_vars , variable_vars )
52
+ for k in [
53
+ "parse_obj_name" ,
54
+ "parse_position" ,
55
+ "parse_question" ,
56
+ "transform_shape_pts" ,
57
+ ]
58
+ }
59
+ )
60
+
61
+ # creating the LMP that deals w/ high-level language commands
62
+ lmp_tabletop_ui = LMP (
63
+ openai_client ,
64
+ "tabletop_ui" ,
65
+ cfg_tabletop ["lmps" ]["tabletop_ui" ],
66
+ lmp_fgen ,
67
+ fixed_vars ,
68
+ variable_vars ,
69
+ )
70
+
71
+ return lmp_tabletop_ui
72
+
73
+ def execute_actions (action_list , obj_list , env , lmp_tabletop_ui , output_path ):
74
+ # Split action_list into individual tasks
75
+ tasks = action_list .split ("and then" )
76
+
77
+ # List to hold all video clips
78
+ video_clips = []
79
+
80
+ # Process each task separately
81
+ for task in tasks :
82
+ env .cache_video = [] # Clear the cache for the new task
83
+ print (f"Running task: { task .strip ()} and recording video..." )
84
+ lmp_tabletop_ui (task .strip (), f'objects = { env .object_list } ' )
85
+
86
+ # Render the video for the task
87
+ if env .cache_video :
88
+ task_clip = ImageSequenceClip (env .cache_video , fps = 30 )
89
+ video_clips .append (task_clip )
90
+
91
+ # Concatenate all the task videos into one final video
92
+ if video_clips :
93
+ final_clip = concatenate_videoclips (video_clips , method = "compose" )
94
+ final_clip .write_videofile (output_path , codec = 'libx264' , bitrate = "5000k" , fps = 30 )
95
+ print (f"Final video saved at { output_path } " )
96
+
97
+ def main (args ):
98
+ client = OpenAI (api_key = projectkey )
99
+ # Initialize environment and LMP with passed arguments
100
+ obj_list = args .obj_list
101
+ action_list = args .action_list
102
+ output_path = args .output # Output path for final video
103
+
104
+ # Initialize environment
105
+ env = PickPlaceEnv (render = True , high_res = True , high_frame_rate = False )
106
+ _ = env .reset (obj_list )
107
+ lmp_tabletop_ui = setup_LMP (env , cfg_tabletop , client )
108
+
109
+ # Execute actions and save video
110
+ execute_actions (action_list , obj_list , env , lmp_tabletop_ui , output_path )
111
+
112
+ if __name__ == "__main__" :
113
+ # Parse arguments
114
+ parser = argparse .ArgumentParser (description = "Run PickPlaceEnv with LMP based on action list." )
115
+ parser .add_argument ('--action_list' , type = str , required = True , help = 'String of actions separated by "and then"' )
116
+ parser .add_argument ('--obj_list' , nargs = '+' , required = True , help = 'List of object names in the environment' )
117
+ parser .add_argument ('--output' , type = str , required = True , help = 'Path to save the final video' )
118
+
119
+ args = parser .parse_args ()
120
+
121
+ main (args )
0 commit comments