diff --git a/README.md b/README.md index 96cf5b87..0c25ec77 100644 --- a/README.md +++ b/README.md @@ -182,3 +182,160 @@ If you find **LIBERO** to be useful in your own research, please consider citing |------------------|-------------------------------------------------------------------------------------------------------------------------------------| | Codebase | [MIT License](LICENSE) | | Datasets | [Creative Commons Attribution 4.0 International (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/legalcode) | + +# Dataset +key list: +📊 data/demo_0/actions +📊 data/demo_0/dones +📊 data/demo_0/obs/agentview_rgb +📊 data/demo_0/obs/ee_ori +📊 data/demo_0/obs/ee_pos +📊 data/demo_0/obs/ee_states +📊 data/demo_0/obs/eye_in_hand_rgb +📊 data/demo_0/obs/gripper_states +📊 data/demo_0/obs/joint_states +📊 data/demo_0/rewards +📊 data/demo_0/robot_states +📊 data/demo_0/states +📊 data/demo_1/actions +📊 data/demo_1/dones +📊 data/demo_1/obs/agentview_rgb +📊 data/demo_1/obs/ee_ori +📊 data/demo_1/obs/ee_pos +📊 data/demo_1/obs/ee_states +📊 data/demo_1/obs/eye_in_hand_rgb +📊 data/demo_1/obs/gripper_states +📊 data/demo_1/obs/joint_states +📊 data/demo_1/rewards +📊 data/demo_1/robot_states +📊 data/demo_1/states + +detail: +📊 数据集: data/demo_0/actions + Shape: (148, 7) ✅ + Dtype: float64 ✅ + Data (first 1 elements): [[ 0.24642857 -0.51696429 0.01607143 0. 0.01821429 -0. + -1. ]] 📈 + +📊 指定key对应的数据集: data/demo_0/dones + Shape: (148,) ✅ + Dtype: uint8 ✅ + Data (first 1 elements): [0] 📈 + +📊 指定key对应的数据集: data/demo_0/obs/agentview_rgb + Shape: (148, 128, 128, 3) ✅ + Dtype: uint8 ✅ + Data (first 1 elements): [[[[172 164 159] + [176 167 163] + [175 167 160] + ... + [199 191 182] + [198 189 180] + [199 191 182]] + + [[135 132 128] + [134 132 128] + [134 132 128] + ... + [138 136 131] + [138 136 131] + [138 136 132]]]] 📈 + +📊 指定key对应的数据集: data/demo_0/obs/ee_ori + Shape: (148, 3) ✅ + Dtype: float64 ✅ + Data (first 1 elements): [[ 3.13415876 -0.04464834 -0.06500138]] + +📊 指定key对应的数据集: data/demo_0/obs/ee_pos + Shape: (148, 3) ✅ + Dtype: float64 ✅ + Data (first 1 elements): [[-0.13461222 -0.03159367 0.26087246]] + +📊 指定key对应的数据集: data/demo_0/obs/ee_states + Shape: (148, 6) ✅ + Dtype: float64 ✅ + Data (first 1 elements): [[-0.13461222 -0.03159367 0.26087246 3.13415876 -0.04464834 -0.06500138]] 📈 + +📊 指定key对应的数据集: data/demo_0/obs/eye_in_hand_rgb + Shape: (148, 128, 128, 3) ✅ + Dtype: uint8 ✅ + Data (first 1 elements): [[[[ 57 57 57] + [ 57 57 57] + [ 57 57 57] + ... + [ 56 56 56] + [ 56 56 56] + [ 56 56 56]] + + [[192 182 172] + [195 185 175] + [203 193 183] + ... + [102 63 55] + [103 85 82] + [103 86 84]]]] 📈 + +📊 指定key对应的数据集: data/demo_0/obs/gripper_states + Shape: (148, 2) ✅ + Dtype: float64 ✅ + Data (first 1 elements): [[ 0.03610362 -0.03629859]] 📈 + +📊 指定key对应的数据集: data/demo_0/obs/joint_states + Shape: (148, 7) ✅ + Dtype: float64 ✅ + Data (first 1 elements): [[-0.01647415 -0.12439009 -0.04895048 -2.40863181 -0.01870208 2.24320355 + 0.7614374 ]] 📈 + +📊 指定key对应的数据集: data/demo_0/rewards + Shape: (148,) ✅ + Dtype: uint8 ✅ + Data (first 1 elements): [0] 📈 + +只有抓到时会奖励: +📊 指定key对应的数据集: data/demo_0/rewards + Shape: (148,) ✅ + Dtype: uint8 ✅ + Data (first 1 elements): [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] 📈 + +📊 指定key对应的数据集: data/demo_0/robot_states + Shape: (148, 9) ✅ + Dtype: float64 ✅ + Data (first 1 elements): [[ 0.03610362 -0.03629859 -0.13461222 -0.03159367 0.26087246 0.99967843 + -0.01424114 -0.02073299 0.00322098]] 📈 + +0.99967843 -0.01424114 -0.02073299 0.00322098 ❗不清楚对应的是哪里 + +📊 指定key对应的数据集: data/demo_0/states + Shape: (148, 110) ✅ + Dtype: float64 ✅ + Data (first 1 elements): [[ 2.50000000e-01 -1.39058727e-02 -1.32895206e-01 -3.95190726e-02 + -2.41748166e+00 -1.56499662e-02 2.24342081e+00 7.70441485e-01 + 3.39412254e-02 -3.41246158e-02 -1.19341153e-01 -2.39844686e-01 + 3.83793457e-02 -2.26022130e-03 2.27541573e-03 7.07695320e-01 + 7.06510473e-01 -1.43712746e-02 2.45927217e-01 -4.58262675e-03 + 7.07104752e-01 -1.69384343e-03 1.69371900e-03 7.07104753e-01 + 4.99867361e-02 -9.99780001e-02 9.14421729e-02 5.00114670e-01 + 4.99884733e-01 5.00043808e-01 4.99956758e-01 -1.51981690e-01 + 5.50623211e-02 8.92147605e-03 1.60411515e-10 -3.16300943e-07 + -1.06977855e-06 1.00000000e+00 9.55577769e-02 -1.98123762e-01 + 6.69983663e-02 4.99972463e-01 5.00027595e-01 4.99983556e-01 + 5.00016384e-01 1.50242278e-01 3.00555488e-02 3.83998685e-02 + -2.29096800e-03 2.29130000e-03 7.07626522e-01 7.06579229e-01 + -1.99379192e-01 -7.87157716e-02 8.69543094e-03 8.87495516e-10 + -4.17292295e-07 -2.42161980e-06 1.00000000e+00 -4.50482326e-02 + 1.55016014e-01 -1.65641087e-01 1.61861455e-01 -5.95531864e-02 + -1.20304390e-02 -1.56137187e-01 5.76449863e-02 -5.71816273e-02 + -3.19849468e-05 3.20957564e-06 9.09489769e-04 8.99028765e-05 + -2.15092962e-06 -8.43101306e-04 8.81460714e-11 -7.43320061e-08 + 1.86903244e-05 -1.93300596e-08 1.62516811e-05 -8.34625155e-11 + -4.66691074e-05 7.71475538e-05 -9.80411604e-01 -1.91370102e-04 + 2.94757962e-06 -3.58290715e-04 -3.41173844e-12 -3.28112589e-12 + 9.13729709e-08 -4.48594712e-10 4.05903512e-10 1.04577420e-13 + -8.44980612e-06 5.70231207e-05 -3.45229732e-01 -1.41749996e-04 + 1.01964102e-08 -9.34021809e-04 1.53355879e-09 3.00852655e-09 + 4.82651896e-08 7.90797893e-08 -4.52425251e-10 4.04379947e-08 + -9.63592933e-11 -1.90983833e-11 3.10686229e-06 -1.10637040e-08 + 1.20000589e-08 8.78974798e-12]] 📈 \ No newline at end of file diff --git a/custom/LIBERO_output_video_test.mp4 b/custom/LIBERO_output_video_test.mp4 new file mode 100644 index 00000000..0fefbdb5 Binary files /dev/null and b/custom/LIBERO_output_video_test.mp4 differ diff --git a/custom/check_dataset_format_test.py b/custom/check_dataset_format_test.py new file mode 100644 index 00000000..7bbb80f7 --- /dev/null +++ b/custom/check_dataset_format_test.py @@ -0,0 +1,117 @@ +import h5py +import numpy as np + +def explore_hdf5(file_path): + """ + 查看HDF5文件的结构和数据集内容 + """ + try: + # ✅ 打开HDF5文件,'r'表示只读模式 + with h5py.File(file_path, 'r') as f: + print("📂 HDF5文件结构:") + + # ✅ 递归函数,用于打印文件中的组和数据集 + def print_structure(name, obj): + indent = ' ' * name.count('/') + if isinstance(obj, h5py.Group): + print(f"{indent}📁 Group: {name}") + elif isinstance(obj, h5py.Dataset): + print(f"{indent}📊 Dataset: {name}") + print(f"{indent} Shape: {obj.shape}") + print(f"{indent} Dtype: {obj.dtype}") + # 如果数据集较小,打印部分数据 + if obj.size < 10: + print(f"{indent} Data: {obj[()]}") + else: + print(f"{indent} Data (first 1 elements): {obj[:1]}") + + # ✅ 遍历文件结构 + f.visititems(print_structure) + + except FileNotFoundError: + print("❌ 文件不存在,请检查文件路径!") + except Exception as e: + print(f"❌ 发生错误: {str(e)}") + + +def print_dataset_keys(file_path): + """ + 打印HDF5文件中所有数据集的key(名称路径) + """ + try: + # ✅ 打开HDF5文件,'r'表示只读模式 + with h5py.File(file_path, 'r') as f: + print("📂 数据集的key列表:") + + # ✅ 递归函数,仅收集数据集的key + def collect_dataset_keys(name, obj): + if isinstance(obj, h5py.Dataset): + print(f"📊 {name}") + + # ✅ 遍历文件结构,打印数据集key + f.visititems(collect_dataset_keys) + + if not any(isinstance(obj, h5py.Dataset) for _, obj in f.items()): + print("⚠️ 文件中没有数据集!") + + except FileNotFoundError: + print("❌ 文件不存在,请检查文件路径!") + except Exception as e: + print(f"❌ 发生错误: {str(e)}") + + +def print_dataset_content(file_path, dataset_key): + """ + 打印HDF5文件中指定数据集key的内容 + :param file_path: HDF5文件路径 + :param dataset_key: 数据集的key(名称路径,如 'demo_1/data') + """ + try: + # ✅ 打开HDF5文件,'r'表示只读模式 + with h5py.File(file_path, 'r') as f: + # ✅ 检查指定key是否存在 + if dataset_key not in f: + print(f"❌ 数据集 '{dataset_key}' 不存在!") + return + + # ✅ 获取数据集 + dataset = f[dataset_key] + if not isinstance(dataset, h5py.Dataset): + print(f"❌ '{dataset_key}' 不是一个数据集!") + return + + # ✅ 打印数据集信息 + print(f"📊 指定key对应的数据集: {dataset_key}") + print(f" Shape: {dataset.shape} ✅") + print(f" Dtype: {dataset.dtype} ✅") + + # ✅ 打印数据内容 + if dataset.size < 10: + print(f" Data: {dataset[()]} 📈") + else: + print(f" Data (first 1 elements): {dataset[:1]} 📈") + + except FileNotFoundError: + print("❌ 文件不存在,请检查文件路径!") + except Exception as e: + print(f"❌ 发生错误: {str(e)}") + +# # 示例用法 +# if __name__ == "__main__": +# # 使用你提供的HDF5文件路径 +# file_path = "/home/sythoid_01/文档/Huangwenlong/LIBERO/libero/datasets/libero_object/pick_up_the_alphabet_soup_and_place_it_in_the_basket_demo.hdf5" +# # 替换为你想查看的数据集key +# dataset_key = "data/demo_0/states" # 示例key,需替换为实际的key +# print_dataset_content(file_path, dataset_key) + +# # 示例用法 +# if __name__ == "__main__": +# # 使用你提供的HDF5文件路径 +# file_path = "/home/sythoid_01/文档/Huangwenlong/LIBERO/libero/datasets/libero_object/pick_up_the_alphabet_soup_and_place_it_in_the_basket_demo.hdf5" +# print_dataset_keys(file_path) + +# 示例用法 +if __name__ == "__main__": + # 替换为你自己的HDF5文件路径 + file_path = "/home/sythoid_01/文档/Huangwenlong/LIBERO/libero/datasets/libero_object/pick_up_the_alphabet_soup_and_place_it_in_the_basket_demo.hdf5" + explore_hdf5(file_path) \ No newline at end of file diff --git a/custom/demo_array_convert_to_video_test.py b/custom/demo_array_convert_to_video_test.py new file mode 100644 index 00000000..7f299fb7 --- /dev/null +++ b/custom/demo_array_convert_to_video_test.py @@ -0,0 +1,80 @@ +import h5py +import numpy as np +import cv2 + +def create_side_by_side_video(file_path, output_video_path, agent_key="data/demo_0/obs/agentview_rgb", eye_key="data/demo_0/obs/eye_in_hand_rgb"): + """ + 从HDF5文件中提取agentview_rgb和eye_in_hand_rgbd,生成左右拼接的视频并保存 + :param file_path: HDF5文件路径 + :param output_video_path: 输出视频路径(.mp4) + :param agent_key: agentview_rgb数据集的key + :param eye_key: eye_in_hand_rgbd数据集的key + """ + try: + # ✅ 打开HDF5文件 + with h5py.File(file_path, 'r') as f: + # ✅ 检查数据集是否存在 + if agent_key not in f or eye_key not in f: + print(f"❌ 数据集 '{agent_key}' 或 '{eye_key}' 不存在!") + return + + # ✅ 读取数据集 + agent_data = f[agent_key][()] + eye_data = f[eye_key][()] + + # ✅ 检查数据形状 + if agent_data.shape[0] != eye_data.shape[0]: + print(f"❌ 两数据集帧数不一致!agentview_rgb: {agent_data.shape[0]}, eye_in_hand_rgbd: {eye_data.shape[0]}") + return + + # ✅ 处理RGB和RGBD数据 + if len(agent_data.shape) != 4 or agent_data.shape[3] != 3: + print(f"❌ agentview_rgb 数据形状异常: {agent_data.shape},期望 (T, H, W, 3)") + return + + # 如果eye_in_hand_rgbd是RGBD(4通道),提取RGB部分 + if len(eye_data.shape) == 4 and eye_data.shape[3] == 4: + print("📌 检测到eye_in_hand_rgbd为RGBD,提取RGB通道") + eye_data = eye_data[:, :, :, :3] # 取前3个通道(RGB) + elif len(eye_data.shape) != 4 or eye_data.shape[3] != 3: + print(f"❌ eye_in_hand_rgbd 数据形状异常: {eye_data.shape},期望 (T, H, W, 3) 或 (T, H, W, 4)") + return + + # ✅ 确保数据类型为uint8 + if agent_data.dtype != np.uint8: + agent_data = agent_data.astype(np.uint8) + if eye_data.dtype != np.uint8: + eye_data = eye_data.astype(np.uint8) + + # ✅ 获取视频参数 + num_frames, height, width, _ = agent_data.shape + fps = 30 # 可根据需要调整帧率 + output_size = (width * 2, height) # 左右拼接,宽度翻倍 + + # ✅ 初始化视频写入器 + fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 使用mp4v编码 + out = cv2.VideoWriter(output_video_path, fourcc, fps, output_size) + + # ✅ 逐帧拼接并写入视频 + for i in range(num_frames): + # 左右拼接图像 + combined_frame = np.hstack((agent_data[i], eye_data[i])) + # OpenCV使用BGR格式,需转换RGB到BGR + combined_frame = cv2.cvtColor(combined_frame, cv2.COLOR_RGB2BGR) + out.write(combined_frame) + print(f"📽️ 已处理帧 {i+1}/{num_frames}") + + # ✅ 释放视频写入器 + out.release() + print(f"🎉 视频已保存到: {output_video_path}") + + except FileNotFoundError: + print("❌ 文件不存在,请检查文件路径!") + except Exception as e: + print(f"❌ 发生错误: {str(e)}") + +# 示例用法 +if __name__ == "__main__": + file_path = "/home/sythoid_01/文档/Huangwenlong/LIBERO/libero/datasets/libero_object/pick_up_the_alphabet_soup_and_place_it_in_the_basket_demo.hdf5" + output_video_path = "/home/sythoid_01/文档/Huangwenlong/LIBERO/custom/output_video.mp4" # 输出视频文件名 + create_side_by_side_video(file_path, output_video_path) \ No newline at end of file diff --git a/custom/getting_started_test.py b/custom/getting_started_test.py new file mode 100644 index 00000000..a8902428 --- /dev/null +++ b/custom/getting_started_test.py @@ -0,0 +1,40 @@ +from libero.libero import benchmark +from libero.libero.envs import OffScreenRenderEnv +import os +from libero.libero import get_libero_path +import torch + +benchmark_dict = benchmark.get_benchmark_dict() +task_suite_name = "libero_object" # can also choose libero_spatial, libero_object, etc. +task_suite = benchmark_dict[task_suite_name]() + +# retrieve a specific task +task_id = 0 +task = task_suite.get_task(task_id) +task_name = task.name +task_description = task.language +task_bddl_file = os.path.join(get_libero_path("bddl_files"), task.problem_folder, task.bddl_file) +print(f"[info] retrieving task {task_id} from suite {task_suite_name}, the " + \ + f"language instruction is {task_description}, and the bddl file is {task_bddl_file}") + +# step over the environment +env_args = { + "bddl_file_name": task_bddl_file, + "camera_heights": 128, + "camera_widths": 128 +} +env = OffScreenRenderEnv(**env_args) +env.seed(0) +env.reset() + +# ! Fix torch.load error by adding NumPy to safe globals +torch.serialization.add_safe_globals(['numpy.core.multiarray._reconstruct']) + +init_states = task_suite.get_task_init_states(task_id) # for benchmarking purpose, we fix the a set of initial states +init_state_id = 0 +env.set_init_state(init_states[init_state_id]) + +dummy_action = [0.] * 7 +for step in range(10): + obs, reward, done, info = env.step(dummy_action) +env.close() \ No newline at end of file