Skip to content

deploy_policy.py: current_state_norm is computed from stat.json but never used in inference #32

Description

@Vincia-Jun

Title

deploy_policy.py: current_state_norm is computed from stat.json but never used in inference

Summary

In the RoboTwin evaluation pipeline, deploy_policy.py computes a normalized version of the 14-dim current_state using stat.json, but this normalized state does not seem to be used anywhere in the actual inference path. As a result, stat.json appears to have no effect on the qpos evaluation behavior.

I would like to confirm whether this is intentional, or whether some normalization / denormalization logic is missing.

Location

Relevant code:

  • inference/robotwin/Motus/deploy_policy.py
  • around update_obs() and get_action()

What I observed

In update_obs(), the code loads the robot state from:

state = observation['joint_action']['vector']

Then it stores:

self.current_state = state_tensor.to(self.device)
self.current_state_norm = self._normalize_actions(self.current_state).to(self.device)

So current_state_norm is indeed computed from the min/max statistics in utils/stat.json. [code]

However, in get_action(), the actual model call uses:

predicted_frames, predicted_actions = self.model.inference_step(
    first_frame=current_frame,
    state=self.current_state,
    ...
)

instead of self.current_state_norm. Also, after inference, predicted_actions are returned directly, without any call to _denormalize_actions().

Why this is confusing

From reading the code, the intended workflow seems to be:

  1. load normalization statistics from stat.json
  2. normalize the 14-dim qpos state
  3. feed normalized state into the model
  4. possibly denormalize the output actions before execution

But the current implementation appears to do:

  1. load normalization statistics from stat.json
  2. compute self.current_state_norm
  3. never use it
  4. run inference with self.current_state
  5. execute predicted actions directly with action_type='qpos'

So it is unclear whether:

  • stat.json is just legacy / unused code,
  • the model was intentionally trained on raw qpos states,
  • or the normalized state should actually be passed into inference_step().

Question

Could you clarify which of the following is correct?

  1. stat.json is currently unused in RoboTwin evaluation and can be ignored.
  2. current_state_norm should be used in inference_step(), and this is a bug.
  3. The model expects raw current_state, but the normalization code was kept from an earlier implementation.
  4. Output actions are expected to be normalized / denormalized somewhere else, and I missed that part.

Additional context

I am trying to adapt this evaluation code from qpos mode to end-effector mode, so understanding whether stat.json is semantically important here would be very helpful. Right now it looks like the actual qpos behavior is determined mainly by:

state = observation['joint_action']['vector']
...
state=self.current_state
...
TASK_ENV.take_action(action, action_type='qpos')

rather than by stat.json itself.

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions