Exclude log record in data collection

This commit is contained in:
Saberlve 2026-08-17 15:06:02 +00:00
parent 172bec5fe6
commit 99546165ec
17 changed files with 117 additions and 63 deletions

View File

@ -84,6 +84,7 @@ Predefined configs are provided under `config/`:
- `robot.teach_sensitivity` — teaching sensitivity, valid range 15 - `robot.teach_sensitivity` — teaching sensitivity, valid range 15
- `robot.manual_gripper_speed` — gripper velocity in normalized position per second (default `0.5`) - `robot.manual_gripper_speed` — gripper velocity in normalized position per second (default `0.5`)
- `robot.observe_joint_vel` — record joint velocities in observations (`false` by default) - `robot.observe_joint_vel` — record joint velocities in observations (`false` by default)
- `robot.enable_logs` — enable optional per-cycle timing/diagnostic logs (`false` by default)
- `robot.cameras.camera` — Intel RealSense camera (`serial_number_or_name`, resolution, fps) - `robot.cameras.camera` — Intel RealSense camera (`serial_number_or_name`, resolution, fps)
- `dataset.root` / `dataset.repo_id` / `single_task` / `fps` / `episode_time_s` / `reset_time_s` / `num_episodes` — dataset settings - `dataset.root` / `dataset.repo_id` / `single_task` / `fps` / `episode_time_s` / `reset_time_s` / `num_episodes` — dataset settings
@ -134,6 +135,7 @@ records the loop period, GELLO read, safety guard, ServoJ, and complete
```bash ```bash
uv run uf-robot-teleop \ uv run uf-robot-teleop \
--config_path config/gello/xarm7_gello_record_config.yaml \ --config_path config/gello/xarm7_gello_record_config.yaml \
--robot.enable_logs=true \
--fps 60 \ --fps 60 \
--guard_latency_experiment=true \ --guard_latency_experiment=true \
--experiment_duration_s 60 --experiment_duration_s 60

View File

@ -84,6 +84,7 @@ ls /dev/serial/by-id/
- `robot.teach_sensitivity` — 示教灵敏度,有效范围 15 - `robot.teach_sensitivity` — 示教灵敏度,有效范围 15
- `robot.manual_gripper_speed` — 夹爪速度(每秒归一化位置变化,默认 `0.5` - `robot.manual_gripper_speed` — 夹爪速度(每秒归一化位置变化,默认 `0.5`
- `robot.observe_joint_vel` — 是否在观测中记录关节速度(默认 `false` - `robot.observe_joint_vel` — 是否在观测中记录关节速度(默认 `false`
- `robot.enable_logs` — 是否启用每帧耗时和诊断日志(默认 `false`
- `robot.cameras.camera` — Intel RealSense 相机配置(`serial_number_or_name`、分辨率、fps - `robot.cameras.camera` — Intel RealSense 相机配置(`serial_number_or_name`、分辨率、fps
- `dataset.root` / `dataset.repo_id` / `single_task` / `fps` / `episode_time_s` / `reset_time_s` / `num_episodes` — 数据集配置 - `dataset.root` / `dataset.repo_id` / `single_task` / `fps` / `episode_time_s` / `reset_time_s` / `num_episodes` — 数据集配置
@ -124,6 +125,7 @@ GELLO 读取、安全检测、ServoJ 和完整 `send_action` 耗时:
```bash ```bash
uv run uf-robot-teleop \ uv run uf-robot-teleop \
--config_path config/gello/xarm7_gello_record_config.yaml \ --config_path config/gello/xarm7_gello_record_config.yaml \
--robot.enable_logs=true \
--fps 60 \ --fps 60 \
--guard_latency_experiment=true \ --guard_latency_experiment=true \
--experiment_duration_s 60 --experiment_duration_s 60

View File

@ -5,6 +5,7 @@ robot:
control_space: "joint" control_space: "joint"
robot_ip: "192.168.1.245" robot_ip: "192.168.1.245"
gripper_type: 1 gripper_type: 1
enable_logs: false
# make sure to edit with your correct configurations! # make sure to edit with your correct configurations!
teleop: teleop:

View File

@ -5,6 +5,7 @@ robot:
control_space: "joint" control_space: "joint"
robot_ip: "192.168.1.245" robot_ip: "192.168.1.245"
gripper_type: 1 gripper_type: 1
enable_logs: false
# make sure to edit with your correct configurations! # make sure to edit with your correct configurations!
teleop: teleop:

View File

@ -5,6 +5,7 @@ robot:
control_space: "cartesian" control_space: "cartesian"
robot_ip: "192.168.1.245" robot_ip: "192.168.1.245"
gripper_type: 1 gripper_type: 1
enable_logs: false
max_linear_velocity: 200 max_linear_velocity: 200
min_tcp_z_mm: 50 min_tcp_z_mm: 50
gripper_error_log_path: "logs/xarm7_gripper_errors.log" gripper_error_log_path: "logs/xarm7_gripper_errors.log"

View File

@ -5,6 +5,7 @@ robot:
control_space: "joint" control_space: "joint"
robot_ip: "192.168.1.245" robot_ip: "192.168.1.245"
gripper_type: 1 gripper_type: 1
enable_logs: false
# Up to 60 Hz goal updates; the first command after idle is immediate. # Up to 60 Hz goal updates; the first command after idle is immediate.
# Keeping the gripper below its 5000 maximum speed avoids C19 in testing. # Keeping the gripper below its 5000 maximum speed avoids C19 in testing.
gripper_command_interval_s: 0.0166667 gripper_command_interval_s: 0.0166667

View File

@ -7,6 +7,7 @@ robot:
robot_ip: "192.168.1.245" robot_ip: "192.168.1.245"
# Gripper type: 1 is the xArm gripper. # Gripper type: 1 is the xArm gripper.
gripper_type: 1 gripper_type: 1
enable_logs: false
manual_mode: true manual_mode: true
# Normalized gripper position change per second while holding C/O. # Normalized gripper position change per second while holding C/O.
manual_gripper_speed: 0.5 manual_gripper_speed: 0.5

View File

@ -5,6 +5,7 @@ robot:
control_space: "cartesian" control_space: "cartesian"
robot_ip: "192.168.1.85" robot_ip: "192.168.1.85"
gripper_type: 10 gripper_type: 10
enable_logs: false
max_linear_velocity: 200 max_linear_velocity: 200
cameras: cameras:
fisheye: fisheye:

View File

@ -5,6 +5,7 @@ robot:
control_space: "cartesian" control_space: "cartesian"
robot_ip: "192.168.1.127" robot_ip: "192.168.1.127"
gripper_type: 0 gripper_type: 0
enable_logs: false
cameras: cameras:
overhead: overhead:

View File

@ -12,6 +12,7 @@ robot:
control_space: "cartesian" control_space: "cartesian"
robot_ip: "192.168.1.29" robot_ip: "192.168.1.29"
gripper_type: 2 gripper_type: 2
enable_logs: false
max_linear_velocity: 200 max_linear_velocity: 200
cameras: cameras:
fisheye: fisheye:
@ -28,6 +29,7 @@ robot:
control_space: "cartesian" control_space: "cartesian"
robot_ip: "192.168.1.83" robot_ip: "192.168.1.83"
gripper_type: 2 gripper_type: 2
enable_logs: false
max_linear_velocity: 200 max_linear_velocity: 200
cameras: cameras:
fisheye: fisheye:

View File

@ -5,6 +5,7 @@ robot:
control_space: "cartesian" control_space: "cartesian"
robot_ip: "192.168.1.83" robot_ip: "192.168.1.83"
gripper_type: 2 gripper_type: 2
enable_logs: false
max_linear_velocity: 250 max_linear_velocity: 250
cameras: cameras:
fisheye: fisheye:

View File

@ -55,6 +55,7 @@ GELLO get_action
```bash ```bash
uv run uf-robot-teleop \ uv run uf-robot-teleop \
--config_path config/gello/xarm7_gello_record_config.yaml \ --config_path config/gello/xarm7_gello_record_config.yaml \
--robot.enable_logs=true \
--fps 60 \ --fps 60 \
--experiment_1_baseline=true \ --experiment_1_baseline=true \
--experiment_duration_s 60 --experiment_duration_s 60

View File

@ -107,6 +107,7 @@ class UFRobot(Robot, Thread):
self._is_connected = False self._is_connected = False
self._is_calibrated =True self._is_calibrated =True
self.enable_logs = bool(getattr(config, "enable_logs", False))
self.logs = {} self.logs = {}
self._cmd_cnt = 0 self._cmd_cnt = 0
@ -539,6 +540,7 @@ class UFRobot(Robot, Thread):
local = self._local_kinematics.tcp_position(joints) local = self._local_kinematics.tcp_position(joints)
error_mm = float(np.linalg.norm(local - reported)) error_mm = float(np.linalg.norm(local - reported))
limit = float(self.config.local_kinematics_max_error_mm) limit = float(self.config.local_kinematics_max_error_mm)
if getattr(self, "enable_logs", True):
self.logs["local_kinematics_error_mm"] = error_mm self.logs["local_kinematics_error_mm"] = error_mm
if math.isfinite(error_mm) and error_mm <= limit: if math.isfinite(error_mm) and error_mm <= limit:
self._local_model_fault_count = 0 self._local_model_fault_count = 0
@ -820,9 +822,10 @@ class UFRobot(Robot, Thread):
def get_observation(self) -> dict[str, np.ndarray]: def get_observation(self) -> dict[str, np.ndarray]:
obs_dict = {} obs_dict = {}
self._log_controller_error_if_changed("get_observation") self._log_controller_error_if_changed("get_observation")
logs_enabled = bool(getattr(self, "enable_logs", True))
# Read Stretch state # Read robot state
before_read_t = time.perf_counter() before_read_t = time.perf_counter() if logs_enabled else None
if self._control_space == "joint": if self._control_space == "joint":
code, states = self.real_arm.get_joint_states(is_radian=True, num=3) code, states = self.real_arm.get_joint_states(is_radian=True, num=3)
pos_list = states[0].copy() pos_list = states[0].copy()
@ -867,12 +870,13 @@ class UFRobot(Robot, Thread):
self.real_arm.robotiq_get_status(number_of_registers=3) self.real_arm.robotiq_get_status(number_of_registers=3)
grippos = self.real_arm.robotiq_status['gPO'] # 0..255 grippos = self.real_arm.robotiq_status['gPO'] # 0..255
grippos_norm = self._gripper_param.get_gripper_norm(grippos) # 0=open, 1=closed grippos_norm = self._gripper_param.get_gripper_norm(grippos) # 0=open, 1=closed
if logs_enabled:
self.logs["read_pos_dt_s"] = time.perf_counter() - before_read_t self.logs["read_pos_dt_s"] = time.perf_counter() - before_read_t
obs_dict[f"{self.prefix}gripper.pos"] = grippos_norm obs_dict[f"{self.prefix}gripper.pos"] = grippos_norm
# Capture images from cameras # Capture images from cameras
for cam_key, cam in self.cameras.items(): for cam_key, cam in self.cameras.items():
before_camread_t = time.perf_counter() before_camread_t = time.perf_counter() if logs_enabled else None
frame = cam.async_read() frame = cam.async_read()
shape = frame.shape shape = frame.shape
if (self.camera_height > 0 and self.camera_height != shape[0]) or (self.camera_width > 0 and self.camera_width != shape[1]): if (self.camera_height > 0 and self.camera_height != shape[0]) or (self.camera_width > 0 and self.camera_width != shape[1]):
@ -881,7 +885,10 @@ class UFRobot(Robot, Thread):
import cv2 import cv2
frame = cv2.resize(frame, (camera_height, camera_width), interpolation=cv2.INTER_AREA) frame = cv2.resize(frame, (camera_height, camera_width), interpolation=cv2.INTER_AREA)
obs_dict[f"{self.prefix}{cam_key}"] = frame obs_dict[f"{self.prefix}{cam_key}"] = frame
self.logs[f"async_read_camera_{cam_key}_dt_s"] = time.perf_counter() - before_camread_t if logs_enabled:
self.logs[f"async_read_camera_{cam_key}_dt_s"] = (
time.perf_counter() - before_camread_t
)
return obs_dict return obs_dict
@ -896,6 +903,7 @@ class UFRobot(Robot, Thread):
return self.get_observation() return self.get_observation()
if not self._rt_report_normal: if not self._rt_report_normal:
raise ConnectionError("RT Report for target robot NOT READY!") raise ConnectionError("RT Report for target robot NOT READY!")
logs_enabled = bool(getattr(self, "enable_logs", True))
with self._update_lock: with self._update_lock:
positions = self.rt_actual_joint_pos.copy() positions = self.rt_actual_joint_pos.copy()
velocities = self.rt_actual_joint_speed.copy() velocities = self.rt_actual_joint_speed.copy()
@ -919,9 +927,9 @@ class UFRobot(Robot, Thread):
obs_dict[f"{self.prefix}gripper.pos"] = float(gripper) obs_dict[f"{self.prefix}gripper.pos"] = float(gripper)
for camera_key, camera in self.cameras.items(): for camera_key, camera in self.cameras.items():
before_camera_t = time.perf_counter() before_camera_t = time.perf_counter() if logs_enabled else None
frame = camera.async_read() frame = camera.async_read()
after_camera_t = time.perf_counter() after_camera_t = time.perf_counter() if logs_enabled else None
shape = frame.shape shape = frame.shape
if ( if (
self.camera_height > 0 self.camera_height > 0
@ -935,6 +943,7 @@ class UFRobot(Robot, Thread):
height = self.camera_height if self.camera_height != 0 else shape[0] height = self.camera_height if self.camera_height != 0 else shape[0]
frame = cv2.resize(frame, (width, height), interpolation=cv2.INTER_AREA) frame = cv2.resize(frame, (width, height), interpolation=cv2.INTER_AREA)
obs_dict[f"{self.prefix}{camera_key}"] = frame obs_dict[f"{self.prefix}{camera_key}"] = frame
if logs_enabled:
self.logs[f"async_read_camera_{camera_key}_dt_s"] = ( self.logs[f"async_read_camera_{camera_key}_dt_s"] = (
after_camera_t - before_camera_t after_camera_t - before_camera_t
) )
@ -944,11 +953,13 @@ class UFRobot(Robot, Thread):
before_camera_t, before_camera_t,
after_camera_t, after_camera_t,
) )
if logs_enabled:
self._last_realtime_observation_end_monotonic_s = time.perf_counter() self._last_realtime_observation_end_monotonic_s = time.perf_counter()
return obs_dict return obs_dict
def _send_gripper_action(self, gripper_norm: float) -> None: def _send_gripper_action(self, gripper_norm: float) -> None:
gripper_norm = min(max(float(gripper_norm), 0.0), 1.0) gripper_norm = min(max(float(gripper_norm), 0.0), 1.0)
logs_enabled = bool(getattr(self, "enable_logs", True))
if ( if (
self._last_gripper_command is not None self._last_gripper_command is not None
and abs(gripper_norm - self._last_gripper_command) and abs(gripper_norm - self._last_gripper_command)
@ -964,7 +975,7 @@ class UFRobot(Robot, Thread):
if now - self._last_gripper_command_attempt_s < self.config.gripper_command_interval_s: if now - self._last_gripper_command_attempt_s < self.config.gripper_command_interval_s:
return return
self._last_gripper_command_attempt_s = now self._last_gripper_command_attempt_s = now
command_start_s = now command_start_s = now if logs_enabled else None
if self._gripper_type == GripperType.xArmGripper: if self._gripper_type == GripperType.xArmGripper:
grippos = self._gripper_param.get_grippos(gripper_norm) grippos = self._gripper_param.get_grippos(gripper_norm)
@ -1005,14 +1016,22 @@ class UFRobot(Robot, Thread):
result = self.real_arm.getset_tgpio_modbus_data(modbus_datas) result = self.real_arm.getset_tgpio_modbus_data(modbus_datas)
code = result[0] if isinstance(result, (tuple, list)) else result code = result[0] if isinstance(result, (tuple, list)) else result
command_dt_ms = (time.perf_counter() - command_start_s) * 1000 command_dt_ms = (
(time.perf_counter() - command_start_s) * 1000
if logs_enabled
else None
)
if code not in (None, 0): if code not in (None, 0):
detail = f"target={gripper_norm:.6f}, pulse={grippos}"
if command_dt_ms is not None:
detail += f", dt_ms={command_dt_ms:.3f}"
self._log_gripper_error( self._log_gripper_error(
"send_gripper_action", "send_gripper_action",
code, code,
f"target={gripper_norm:.6f}, pulse={grippos}, dt_ms={command_dt_ms:.3f}", detail,
) )
return return
if logs_enabled:
self._log_gripper_command(gripper_norm, grippos, command_dt_ms) self._log_gripper_command(gripper_norm, grippos, command_dt_ms)
self._last_gripper_command = gripper_norm self._last_gripper_command = gripper_norm
@ -1139,10 +1158,8 @@ class UFRobot(Robot, Thread):
if self.config.no_action: if self.config.no_action:
return action return action
before_write_t = time.perf_counter() logs_enabled = bool(getattr(self, "enable_logs", True))
self.logs["safety_guard_dt_s"] = 0.0 before_write_t = time.perf_counter() if logs_enabled else None
self.logs["servo_j_dt_s"] = 0.0
self.logs["safety_guard_path"] = "not_run"
safe_action = dict(action) safe_action = dict(action)
if self._control_space == "joint": if self._control_space == "joint":
# first sync with gello or other control device SLOWLY! # first sync with gello or other control device SLOWLY!
@ -1152,8 +1169,9 @@ class UFRobot(Robot, Thread):
cmd_list = [0]*(self._dof) cmd_list = [0]*(self._dof)
for i in range(self._dof): for i in range(self._dof):
cmd_list[i] = action[f"{self.prefix}J{i+1}.pos"] cmd_list[i] = action[f"{self.prefix}J{i+1}.pos"]
guard_start_t = time.perf_counter() guard_start_t = time.perf_counter() if logs_enabled else None
safe_cmd = self._guard_joint_target(cmd_list) safe_cmd = self._guard_joint_target(cmd_list)
if logs_enabled:
self.logs["safety_guard_dt_s"] = time.perf_counter() - guard_start_t self.logs["safety_guard_dt_s"] = time.perf_counter() - guard_start_t
self.logs["safety_guard_path"] = self._last_guard_path self.logs["safety_guard_path"] = self._last_guard_path
if safe_cmd is None: if safe_cmd is None:
@ -1174,10 +1192,11 @@ class UFRobot(Robot, Thread):
code = self.real_arm.set_state(0) code = self.real_arm.set_state(0)
self._check_motion_code("set_state(0)", code) self._check_motion_code("set_state(0)", code)
time.sleep(0.1) time.sleep(0.1)
servo_j_start_t = time.perf_counter() servo_j_start_t = time.perf_counter() if logs_enabled else None
code = self.real_arm.set_servo_angle_j( code = self.real_arm.set_servo_angle_j(
safe_cmd[:self._dof].tolist(), speed=jnt_spd, is_radian=True safe_cmd[:self._dof].tolist(), speed=jnt_spd, is_radian=True
) )
if logs_enabled:
self.logs["servo_j_dt_s"] = time.perf_counter() - servo_j_start_t self.logs["servo_j_dt_s"] = time.perf_counter() - servo_j_start_t
self._check_motion_code("set_servo_angle_j", code) self._check_motion_code("set_servo_angle_j", code)
elif safe_cmd is not None: elif safe_cmd is not None:
@ -1222,6 +1241,7 @@ class UFRobot(Robot, Thread):
if self._gripper_type > GripperType.NoGripper: if self._gripper_type > GripperType.NoGripper:
self._send_gripper_action(safe_action[f"{self.prefix}gripper.pos"]) self._send_gripper_action(safe_action[f"{self.prefix}gripper.pos"])
if logs_enabled:
self.logs["write_pos_dt_s"] = time.perf_counter() - before_write_t self.logs["write_pos_dt_s"] = time.perf_counter() - before_write_t
return safe_action return safe_action

View File

@ -20,6 +20,7 @@ class UFRobotConfig(RobotConfig):
gripper_command_threshold: float = 0.01 # normalized change required before sending a new command gripper_command_threshold: float = 0.01 # normalized change required before sending a new command
gripper_command_interval_s: float = 0.1 # minimum interval between tool RS485 goals gripper_command_interval_s: float = 0.1 # minimum interval between tool RS485 goals
gripper_error_log_path: str | None = "logs/xarm_gripper_errors.log" gripper_error_log_path: str | None = "logs/xarm_gripper_errors.log"
enable_logs: bool = False # optional per-cycle timing and diagnostic logs
observe_joint_vel: bool = False # only effective in joint control mode observe_joint_vel: bool = False # only effective in joint control mode
manual_mode: bool = False # xArm joint teaching mode; records state and optional gripper actions manual_mode: bool = False # xArm joint teaching mode; records state and optional gripper actions
manual_gripper_speed: float = 0.5 # normalized gripper position per second in manual mode manual_gripper_speed: float = 0.5 # normalized gripper position per second in manual mode

View File

@ -102,6 +102,18 @@ def _manual_gripper_action_key(action_features):
return next((key for key in action_features if key.endswith("gripper.pos")), None) return next((key for key in action_features if key.endswith("gripper.pos")), None)
def _diagnostic_logs_enabled(robot) -> bool:
"""Return whether optional per-cycle diagnostics are enabled for a robot."""
config = getattr(robot, "config", None)
if config is not None and hasattr(config, "enable_logs"):
return bool(config.enable_logs)
child_robots = getattr(robot, "robots", None)
if child_robots:
return any(_diagnostic_logs_enabled(child) for child in child_robots.values())
return False
def _manual_action_from_observation(observation, action_features, gripper_target=None): def _manual_action_from_observation(observation, action_features, gripper_target=None):
"""Keep only robot action fields when mirroring manual-mode state.""" """Keep only robot action fields when mirroring manual-mode state."""
action = {key: value for key, value in observation.items() if key in action_features} action = {key: value for key, value in observation.items() if key in action_features}
@ -353,6 +365,7 @@ def record_loop(
manual_gripper_action_key = _manual_gripper_action_key(robot.action_features) manual_gripper_action_key = _manual_gripper_action_key(robot.action_features)
realtime_controller = None realtime_controller = None
diagnostic_logs_enabled = _diagnostic_logs_enabled(robot)
sync_log_file = None sync_log_file = None
sync_log_writer = None sync_log_writer = None
sync_frame_index = 0 sync_frame_index = 0
@ -371,10 +384,12 @@ def record_loop(
initial_observation=last_robot_cmd, initial_observation=last_robot_cmd,
) )
realtime_controller.start() realtime_controller.start()
if diagnostic_logs_enabled:
sync_log_dir = Path("logs") sync_log_dir = Path("logs")
sync_log_dir.mkdir(parents=True, exist_ok=True) sync_log_dir.mkdir(parents=True, exist_ok=True)
sync_log_path = sync_log_dir / ( sync_log_path = sync_log_dir / (
f"gello_record_sync_{time.strftime('%Y%m%d_%H%M%S')}_{time.time_ns() % 1_000_000:06d}.csv" f"gello_record_sync_{time.strftime('%Y%m%d_%H%M%S')}_"
f"{time.time_ns() % 1_000_000:06d}.csv"
) )
sync_log_file = sync_log_path.open("w", newline="", buffering=1) sync_log_file = sync_log_path.open("w", newline="", buffering=1)
sync_log_writer = csv.DictWriter( sync_log_writer = csv.DictWriter(
@ -405,13 +420,16 @@ def record_loop(
# Get robot observation # Get robot observation
if realtime_controller is not None: if realtime_controller is not None:
obs = robot.get_realtime_observation() obs = robot.get_realtime_observation()
observation_monotonic_s = getattr( observation_monotonic_s = getattr(robot, "_last_realtime_observation_monotonic_s", None)
robot, "_last_realtime_observation_monotonic_s", time.perf_counter() if observation_monotonic_s is None:
) observation_monotonic_s = time.perf_counter()
realtime_controller.update_observation(obs) realtime_controller.update_observation(obs)
if diagnostic_logs_enabled:
matched_action, matched_action_sent_s = realtime_controller.action_sample_at( matched_action, matched_action_sent_s = realtime_controller.action_sample_at(
observation_monotonic_s observation_monotonic_s
) )
else:
matched_action = realtime_controller.action_at(observation_monotonic_s)
else: else:
obs = robot.get_observation() obs = robot.get_observation()

View File

@ -162,6 +162,10 @@ def teleop_loop(cfg: TeleopConfig):
if cfg.guard_latency_experiment: if cfg.guard_latency_experiment:
_validate_guard_latency_config(cfg) _validate_guard_latency_config(cfg)
if hasattr(cfg.robot, "enable_logs") and not cfg.robot.enable_logs:
raise ValueError(
"Guard latency experiment requires robot.enable_logs=true"
)
logging.warning( logging.warning(
"Guard latency experiment enabled: measuring GELLO, safety guard, ServoJ, " "Guard latency experiment enabled: measuring GELLO, safety guard, ServoJ, "
"and total send latency for %.1f active seconds", "and total send latency for %.1f active seconds",

View File

@ -1,6 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
import logging import logging
import time
import numpy as np import numpy as np
from lerobot.utils.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError from lerobot.utils.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError
from ..base_teleop import UFBaseTeleop from ..base_teleop import UFBaseTeleop
@ -170,11 +169,8 @@ class GelloTeleop(UFBaseTeleop):
def get_action(self) -> dict[str, np.ndarray]: def get_action(self) -> dict[str, np.ndarray]:
if not self._teleop_enabled: if not self._teleop_enabled:
raise RuntimeError("Gello teleop is disabled") raise RuntimeError("Gello teleop is disabled")
start = time.perf_counter()
fake_obs = dict({"joint_state": np.array([0.0]*(self.dof+1))}) # for agent.act() argument, actually no use fake_obs = dict({"joint_state": np.array([0.0]*(self.dof+1))}) # for agent.act() argument, actually no use
action_array = self.gello_agent.act(fake_obs) # current gello joint pos as np.ndarray action_array = self.gello_agent.act(fake_obs) # current gello joint pos as np.ndarray
dt_ms = (time.perf_counter() - start) * 1e3
logger.debug(f"{self} read action: {dt_ms:.1f}ms")
action = {} action = {}
for i in range(self.dof): for i in range(self.dof):