Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4ee5c9f
alex teleop
LuigiPenco93 Sep 4, 2025
cc86d62
ghost robot
LuigiPenco93 Sep 4, 2025
fb7de0b
Merge branch 'develop' into feature/alex-teleop
reesep5 Sep 17, 2025
a2ec97d
fixed a weird constructor in OpenAlexanderRobotModel
reesep5 Sep 18, 2025
7b3f938
Merge branch 'develop' into feature/alex-teleop-2
LuigiPenco93 Sep 22, 2025
a9b01d4
Merge remote-tracking branch 'origin/develop' into feature/alex-teleop-2
LuigiPenco93 Oct 28, 2025
d3217fd
tracker roles
LuigiPenco93 Oct 28, 2025
5f0e860
disable kst server
LuigiPenco93 Oct 29, 2025
9a50011
Merge branch 'develop' into feature/alex-teleop-2
Oct 30, 2025
60aa9ed
Got local logging working and tuned the realsense and height map for …
PotatoPeeler3000 Oct 30, 2025
3e2708e
Setup behavior tree scene. (#1065)
calvertdw Oct 30, 2025
d80337a
added a getter (#1069)
rjgriffin42 Oct 30, 2025
e3b0623
Fix sync feedback loop bug with footstep plan action interactables. (…
calvertdw Oct 30, 2025
36c1266
minor null check in multi thread factory
Oct 30, 2025
7402c42
Merge branch 'develop' into feature/alex-teleop-2
Nov 7, 2025
6becff2
undo robot model stuff
Nov 7, 2025
ca073ed
remove artifcats from merge
Nov 7, 2025
30a70bf
remove artifcats
Nov 7, 2025
aaf4047
tuned kst
Nov 7, 2025
ed742ed
fixes pr
LuigiPenco93 Nov 12, 2025
69a4f80
Merge branch 'develop' into feature/alex-teleop-2
LuigiPenco93 Nov 12, 2025
b28b98b
Revert "remove artifcats from merge"
LuigiPenco93 Nov 13, 2025
d10b9da
fix with develop
LuigiPenco93 Nov 13, 2025
a51932b
Update OpenAlexanderMomentumOptimizationSettings.java
LuigiPenco93 Nov 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ public void update()
{
areHandTaskspaceOutputsEnabled.get(robotSide).set(configurationCommand.isHandTaskspaceEnabled(robotSide));
areArmJointspaceOutputsEnabled.get(robotSide).set(configurationCommand.isArmJointspaceEnabled(robotSide));
areLegJointspaceOutputsEnabled.get(robotSide).set(configurationCommand.isLegJointspaceEnabled(robotSide));
areLegJointspaceOutputsEnabled.get(robotSide).set(configurationCommand.isLegJointspaceEnabled(robotSide) && !isFootInSupport.get(robotSide));
}

if (commandInputManager.isNewCommandAvailable(KinematicsStreamingToolboxInitialConfigurationCommand.class))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,6 @@ private void updateGhostPoseWithJoystick()
private void updateGhostPitchBasedOnFeet()
{
miniGhostFullRobotModel.getElevator().updateFramesRecursively();
miniGhostFullRobotModel.getRootJoint().getJointPose().getRotation();
miniGhostFullRobotModel.getSoleFrame(RobotSide.RIGHT).getTransformToWorldFrame().getRotation();
miniGhostFullRobotModel.getSoleFrame(RobotSide.LEFT).getTransformToWorldFrame().getRotation();

Quaternion rootJointInitialOrientation = new Quaternion(miniGhostFrame.getTransformToRoot().getRotation());
// Get the rotations of the sole frames.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import us.ihmc.euclid.referenceFrame.FramePose3D;
import us.ihmc.euclid.referenceFrame.ReferenceFrame;
import us.ihmc.euclid.tuple3D.Point3D;
import us.ihmc.euclid.tuple3D.interfaces.Point3DReadOnly;
import us.ihmc.mecano.multiBodySystem.interfaces.OneDoFJointBasics;
import us.ihmc.mecano.multiBodySystem.interfaces.RigidBodyBasics;
import us.ihmc.motionRetargeting.RetargetingParameters;
Expand Down Expand Up @@ -43,7 +44,19 @@
import java.util.Collection;
import java.util.List;
import java.util.Set;

/**
* Manages the various VR modes and associated state for immersive humanoid control in the RDX UI.
* <p>
* Responsible for switching between modes such as whole-body IK streaming, footstep placement,
* joystick-based walking, and footstep streaming; maintaining their corresponding input logic,
* GUIs, and visualizations in the VR context.
* </p>
* <p>
* Handles creation and update of VR panels, occlusion and perception visualizers, hand managers, and robot
* streaming helpers; integrates robot-side per-arm and hand tracking, stereo panel occlusion for rendering,
* and dynamic control panel presentation.
* </p>
*/
public class RDXVRModeManager
{
private final ImGuiUniqueLabelMap labels = new ImGuiUniqueLabelMap(getClass());
Expand Down Expand Up @@ -71,6 +84,7 @@ public class RDXVRModeManager
private final Throttler panelOcclusionRateLimiter = new Throttler();
private final SideDependentList<List<RigidBodyBasics>> syncedRobotArmRigidBodies = new SideDependentList<>(new ArrayList<>(), new ArrayList<>());
private final SideDependentList<List<RigidBodyBasics>> ghostIKRobotArmRigidBodies = new SideDependentList<>(new ArrayList<>(), new ArrayList<>());
private final SideDependentList<Point3D> tempHandPoints = new SideDependentList<>(new Point3D(), new Point3D());

public void create(RDXBaseUI baseUI,
ROS2SyncedRobotModel syncedRobot,
Expand Down Expand Up @@ -219,8 +233,6 @@ private void processVRInput(RDXVRContext vrContext)
public void update()
{
vrManager.getTeleporter().setBButtonEnabled(mode != RDXVRMode.WHOLE_BODY_IK_STREAMING);
if (mode != RDXVRMode.INPUTS_DISABLED)
interactablesEnabled.set(false);

switch (mode)
{
Expand Down Expand Up @@ -250,15 +262,54 @@ public void update()
for (RobotSide side : RobotSide.values)
{
checkStereoPanelOcclusions(syncedRobotArmRigidBodies.get(side), perceptionVisualizers.getRobotVisualizer().getMultiBodyGraphic());
Point3D tempPoint = tempHandPoints.get(side);
tempPoint.set(syncedRobot.getFullRobotModel().getHandControlFrame(side).getTransformToRoot().getTranslation());
checkStereoPanelOcclusionWithHandControlFrames(tempPoint, syncedRobotArmRigidBodies.get(side), perceptionVisualizers.getRobotVisualizer().getMultiBodyGraphic());
if (mode == RDXVRMode.WHOLE_BODY_IK_STREAMING && kinematicsStreaming != null)
{
checkStereoPanelOcclusions(ghostIKRobotArmRigidBodies.get(side), kinematicsStreaming.getGhostRobotGraphic());
tempPoint.set(kinematicsStreaming.getGhostFullRobotModel().getHandControlFrame(side).getTransformToRoot().getTranslation());
checkStereoPanelOcclusionWithHandControlFrames(tempPoint, ghostIKRobotArmRigidBodies.get(side), kinematicsStreaming.getGhostRobotGraphic());
}
}
}
}
}

/**
* Checks if the specified hand control frame point is occluded by the stereo panel's view.
* <p>
* If it is occluded, hides the last rigid body in the provided list, which is closest to the hand control frame.
* If it is not occluded, ensures that rigid body is visible.
* </p>
*
* @param handPoint the hand control frame point to check for occlusion
* @param rigidBodyList the ordered list of rigid bodies for the arm; last entry is closest to hand
* @param robotGraphics the graphics object whose visibility set should be updated
*/
private void checkStereoPanelOcclusionWithHandControlFrames(Point3DReadOnly handPoint, List<RigidBodyBasics> rigidBodyList, RDXMultiBodyGraphic robotGraphics)
{
if (stereoPanel.isOccludingView(handPoint))
{
robotGraphics.getMultiBody().getRigidBodiesToHide().add(rigidBodyList.get(rigidBodyList.size() - 1).getName());
}
else
{
robotGraphics.getMultiBody().getRigidBodiesToHide().remove(rigidBodyList.get(rigidBodyList.size() - 1).getName());
}
}

/**
* Checks occlusion of the origins of a list of robot rigid bodies against the stereo panel's view.
* <p>
* For each {@link RigidBodyBasics} in the list, this method tests if its origin (expressed as a {@link Point3D})
* is currently occluded by the stereo panel. If occluded, the rigid body's name is added to the
* set of hidden bodies in the provided {@code robotGraphics}. If not occluded, its name is removed from the set.
* </p>
*
* @param rigidBodyList the list of rigid bodies to test for occlusion by the stereo panel
* @param robotGraphics the graphics instance whose hidden body set is updated for visualization
*/
private void checkStereoPanelOcclusions(List<RigidBodyBasics> rigidBodyList, RDXMultiBodyGraphic robotGraphics)
{
for (RigidBodyBasics rigidBody : rigidBodyList)
Expand All @@ -280,23 +331,22 @@ public void renderImGuiWidgets()
if (ImGui.radioButton(labels.get(RDXVRMode.INPUTS_DISABLED.getReadableName()), mode == RDXVRMode.INPUTS_DISABLED))
{
mode = RDXVRMode.INPUTS_DISABLED;
if (kinematicsStreaming != null)
kinematicsStreaming.setKSTEnabled(false);
disableKinematicsStreaming();
footstepPlacer.reset();
footstepStreaming.reset();
}
if (ImGui.radioButton(labels.get(RDXVRMode.FOOTSTEP_PLACEMENT.getReadableName()), mode == RDXVRMode.FOOTSTEP_PLACEMENT))
{
mode = RDXVRMode.FOOTSTEP_PLACEMENT;
if (kinematicsStreaming != null)
kinematicsStreaming.setKSTEnabled(false);
disableKinematicsStreaming();
interactablesEnabled.set(false);
}
if (ImGui.radioButton(labels.get(RDXVRMode.FOOTSTEP_STREAMING.getReadableName()), mode == RDXVRMode.FOOTSTEP_STREAMING))
{
mode = RDXVRMode.FOOTSTEP_STREAMING;
if (kinematicsStreaming != null)
kinematicsStreaming.setKSTEnabled(false);
disableKinematicsStreaming();
footstepStreaming.reset();
interactablesEnabled.set(false);
}
if (kinematicsStreaming == null)
{
Expand All @@ -307,6 +357,7 @@ public void renderImGuiWidgets()
mode = RDXVRMode.WHOLE_BODY_IK_STREAMING;
footstepPlacer.reset();
footstepStreaming.reset();
interactablesEnabled.set(false);
}
if (kinematicsStreaming == null)
{
Expand All @@ -315,12 +366,18 @@ public void renderImGuiWidgets()
if (ImGui.radioButton(labels.get(RDXVRMode.JOYSTICK_WALKING.getReadableName()), mode == RDXVRMode.JOYSTICK_WALKING))
{
mode = RDXVRMode.JOYSTICK_WALKING;
if (kinematicsStreaming != null)
kinematicsStreaming.setKSTEnabled(false);
disableKinematicsStreaming();
footstepPlacer.reset();
interactablesEnabled.set(false);
}
}

private void disableKinematicsStreaming()
{
if (kinematicsStreaming != null)
kinematicsStreaming.setKSTEnabled(false);
}

private void getRenderables(Array<Renderable> renderables, Pool<Renderable> pool, Set<RDXSceneLevel> sceneLevels)
{
if (sceneLevels.contains(RDXSceneLevel.VIRTUAL))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ public void processVRInput()
KinematicsStreamingToolboxInputMessage toolboxInputMessage = new KinematicsStreamingToolboxInputMessage();
processControllers(toolboxInputMessage);
processTrackers(toolboxInputMessage);
processHeadset(toolboxInputMessage);
retargetMotion(toolboxInputMessage);
multiContact.doCoMControl(toolboxInputMessage);

Expand Down Expand Up @@ -530,6 +531,29 @@ private void processTrackers(KinematicsStreamingToolboxInputMessage messageToPac
}
}

private void processHeadset(KinematicsStreamingToolboxInputMessage messageToPack)
{
vrContext.getHeadset().runIfConnected(headset->
{
RigidBodyBasics controlledSegment = getControlledSegment(HEAD);
if (controlledSegment != null)
{
FramePose3D desiredPose = new FramePose3D();
desiredPose.setToZero(headset.getXForwardZUpHeadsetFrame());
desiredPose.changeFrame(ReferenceFrame.getWorldFrame());
KinematicsToolboxRigidBodyMessage message = createRigidBodyMessage(controlledSegment,
desiredPose,
headset.getAngularVelocity(),
headset.getLinearVelocity(),
retargetingParameters.getPositionWeight(HEAD),
retargetingParameters.getOrientationWeight(HEAD),
retargetingParameters.getLinearRateLimitation(HEAD),
retargetingParameters.getAngularRateLimitation(HEAD));
messageToPack.getInputs().add().set(message);
}
});
}

private void retargetMotion(KinematicsStreamingToolboxInputMessage messageToPack)
{
if (armScaling.get())
Expand Down Expand Up @@ -608,6 +632,7 @@ private RigidBodyBasics getControlledSegment(VRTrackedSegmentType segmentType)
case LEFT_HAND, RIGHT_HAND -> ghostFullRobotModel.getHand(segmentType.getSegmentSide());
case LEFT_ANKLE, RIGHT_ANKLE -> ghostFullRobotModel.getFoot(segmentType.getSegmentSide());
case LEFT_WRIST, RIGHT_WRIST -> ghostFullRobotModel.getForearm(segmentType.getSegmentSide());
case HEAD -> ghostFullRobotModel.getHead();
case CHEST -> ghostFullRobotModel.getChest();
case WAIST -> ghostFullRobotModel.getPelvis();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public enum VRTrackedSegmentType
RIGHT_HAND("Right Hand", RobotSide.RIGHT),
LEFT_WRIST("Left Wrist", RobotSide.LEFT),
RIGHT_WRIST("Right Wrist", RobotSide.RIGHT),
HEAD("Head", null),
CHEST("Chest", null),
WAIST("Waist", null),
LEFT_ANKLE("Left Ankle", RobotSide.LEFT),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ public class OpenAlexanderMomentumOptimizationSettings extends MomentumOptimizat
// TODO Needs tune up.
private final Vector2D copRateHighWeight = new Vector2D(0.00008, 0.00032);

// TODO Needs tune up.
private final double neckJointspaceWeight = 0.0;
private final double neckJointspaceWeight = 50.0;
// TODO Needs tune up.
private final double spineJointspaceWeight = 10.0;
// TODO Needs tune up.
Expand Down
Loading