Browse Source

Add neutral hold mode (key 'n') for joint inspection

Bypasses NN output and commands default_angles directly at 500Hz.
Used for visual diagnosis of hardware joint offsets on new pelvis.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
main
Joe DiPrima 4 weeks ago
parent
commit
14cc19f213
  1. 12
      gear_sonic_deploy/src/g1/g1_deploy_onnx_ref/include/input_interface/gamepad_manager.hpp
  2. 12
      gear_sonic_deploy/src/g1/g1_deploy_onnx_ref/src/g1_deploy_onnx_ref.cpp

12
gear_sonic_deploy/src/g1/g1_deploy_onnx_ref/include/input_interface/gamepad_manager.hpp

@ -67,6 +67,10 @@ inline std::atomic<double> g_knee_offset_deg{0.0};
/// Applied post-NN to motor commands only (NN is blind to this adjustment). /// Applied post-NN to motor commands only (NN is blind to this adjustment).
inline std::atomic<double> g_hip_pitch_offset_deg{3.0}; inline std::atomic<double> g_hip_pitch_offset_deg{3.0};
/// Neutral hold mode: bypass NN, command default_angles directly. Key 'n' to toggle.
/// Used for visual joint inspection (diagnosing hardware offsets).
inline std::atomic<bool> g_neutral_hold_mode{false};
#if HAS_ROS2 #if HAS_ROS2
#include "ros2_input_handler.hpp" #include "ros2_input_handler.hpp"
#endif #endif
@ -198,6 +202,14 @@ class GamepadManager : public InputInterface {
is_manager_key = true; is_manager_key = true;
break; break;
} }
case 'n':
case 'N': {
bool cur = g_neutral_hold_mode.load();
g_neutral_hold_mode.store(!cur);
std::cout << "[NEUTRAL] Hold mode: " << (!cur ? "ON (default angles)" : "OFF (NN active)") << std::endl;
is_manager_key = true;
break;
}
case '1': { case '1': {
double val = g_hip_pitch_offset_deg.load() - 1.0; double val = g_hip_pitch_offset_deg.load() - 1.0;
g_hip_pitch_offset_deg.store(val); g_hip_pitch_offset_deg.store(val);

12
gear_sonic_deploy/src/g1/g1_deploy_onnx_ref/src/g1_deploy_onnx_ref.cpp

@ -2827,6 +2827,17 @@ class G1Deploy {
float* floatarr = action_buffer.data(); float* floatarr = action_buffer.data();
MotorCommand motor_command_tmp; MotorCommand motor_command_tmp;
// Neutral hold mode: bypass NN, command default angles directly (key 'n')
if (g_neutral_hold_mode.load()) {
for (int i = 0; i < G1_NUM_MOTOR; i++) {
motor_command_tmp.q_target.at(i) = static_cast<float>(default_angles[i]);
motor_command_tmp.tau_ff.at(i) = 0.0;
motor_command_tmp.kp.at(i) = kps[i];
motor_command_tmp.kd.at(i) = kds[i];
motor_command_tmp.dq_target.at(i) = 0.0;
}
} else {
for (int i = 0; i < G1_NUM_MOTOR; i++) { for (int i = 0; i < G1_NUM_MOTOR; i++) {
const double action_value = static_cast<double>(floatarr[isaaclab_to_mujoco[i]]) * g1_action_scale[i]; const double action_value = static_cast<double>(floatarr[isaaclab_to_mujoco[i]]) * g1_action_scale[i];
last_action[i] = static_cast<double>(floatarr[i]); last_action[i] = static_cast<double>(floatarr[i]);
@ -2836,6 +2847,7 @@ class G1Deploy {
motor_command_tmp.kd.at(i) = kds[i]; motor_command_tmp.kd.at(i) = kds[i];
motor_command_tmp.dq_target.at(i) = 0.0; motor_command_tmp.dq_target.at(i) = 0.0;
} }
}
// Optional waist pitch offset (keys 7/8). Default 0°. // Optional waist pitch offset (keys 7/8). Default 0°.
double waist_offset_rad = g_waist_pitch_offset_deg.load() * M_PI / 180.0; double waist_offset_rad = g_waist_pitch_offset_deg.load() * M_PI / 180.0;
if (waist_offset_rad != 0.0) { if (waist_offset_rad != 0.0) {

Loading…
Cancel
Save