Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial implementation for square up and walk-to-goal for CH process #694

Merged
merged 32 commits into from
Feb 27, 2025

Conversation

PotatoPeeler3000
Copy link
Contributor

@PotatoPeeler3000 PotatoPeeler3000 commented Feb 24, 2025

This is a Bhav level PR lol, a bunch of random changes that are grouped together. Most of the file changes come from refactoring things to different places. Here is a list of the changes:
-------------------------------- Package Change ------------------------------

  • Moved RapidHeightMapManager to ihmc-perception module
  • Moved ControllerQueueFootstepMonitor to ihmc-humanoid-robots module
    -------------------------------- Refactor Parameters ------------------------------
  • Movedd RapidHeightMapExtractor.getHeightMapParameters() to get called in the RapidHeightMapManager.getHeightMapParameters() which allows for only one set of parameters to be created.
  • Change ROS2Helper to ROS2Node for the height map pipeline.
    -------------------------------- Height Map Kernels -----------------------------------
  • Added a FilteredRapidHeightMapExtractor class that has a kernel that performs a weighted moving average on the height map as a filter. In this implementation its post-processing the height map. What should really be done is pre-processing the height map. (Change for the future if its a problem)
  • Tests for FilteredRapidHeightMapExtractor
  • Example CUDAExample3DKernel to show how to pass a 3D array into the kernels
    -------------------------------- RDX UI Changes -----------------------------
  • Added some better environments that reflect tested data. Cleaned up a couple of other environments
  • Removed a panel for the CUDA Height Map Parameters as its no longer needed
  • Removed bloat from CH panel, condensed dropdown parameters so they aren't visible by default
    -------------------------------- Continuous Hiking Changes -----------------------------
  • Created a square up message, its an empty message but in the CH process it handles the square up step required
  • Set squaring up to be the default and added an 'emergency stop' button to the UI (Esc Key).
  • Added a plan-to-goal feature for CH. This skips the CH pipeline and plans directly to a goal all at once. Takes a little but but the intent is to use it to rotate the robot in place.
  • Added a couple buttons on the UI to rotate the robot 90 degrees left or right. This uses the plan-to-goal feature to do this.
  • Reset graphics when the robot isn't walking.
  • Basically made the ContinuousHikingLogger useless by removing the usage from ControllerQueueFootstepMonitor so should come back to that but its not pressing.

PotatoPeeler3000 and others added 23 commits February 10, 2025 20:45
@PotatoPeeler3000 PotatoPeeler3000 changed the title Feature/new ch messages Initial implementation for square up and walk-to-goal for CH process Feb 24, 2025
@@ -18,6 +19,8 @@ public class ContinuousHikingAPI
public static final ROS2Topic<ContinuousHikingCommandMessage> CONTINUOUS_HIKING_COMMAND = IHMC_ROOT.withModule(moduleName).withType(ContinuousHikingCommandMessage.class).withSuffix("command");
public static final ROS2Topic<std_msgs.msg.dds.Empty> CLEAR_GOAL_FOOTSTEPS = IHMC_ROOT.withModule(moduleName).withType(std_msgs.msg.dds.Empty.class).withSuffix("clear_goal_footsteps");
public static final ROS2Topic<PoseListMessage> PLACED_GOAL_FOOTSTEPS = IHMC_ROOT.withModule(moduleName).withType(PoseListMessage.class).withSuffix("placed_goal_footsteps");
public static final ROS2Topic<PoseListMessage> ROTATE_GOAL_FOOTSTEPS = IHMC_ROOT.withModule(moduleName).withType(PoseListMessage.class).withSuffix("rotate_goal_footsteps");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New messages to walk the robot around with little user input

@@ -210,6 +213,11 @@ else if (dScroll < 0.0)
latestPickPoint.getOrientation().setYawPitchRoll(latestFootstepYaw + deltaYaw, 0.0, 0.0);
}
}
if (input.isWindowHovered() && input.mouseReleasedWithoutDrag(ImGuiMouseButton.Middle) && calculateStancePose.get() && selectionActive)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Middle click allows for this feature to plan-to-goal rather then add it to the CH goal queue

@@ -56,6 +56,7 @@ public void doAction(double timeInState)
message.setClearRemainingFootstepQueue(true);
continuousPlanner.setLatestFootstepPlan(null);
pauseWalkingPublisher.publish(message);
debugger.resetVisualizationForUIPublisher();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clear visuals when standing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new messages affect this state, this way I can skip the entire CH process when desired.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filtered height map class

@@ -34,10 +34,12 @@
*/
public class RapidHeightMapManager
{
static final HeightMapParameters heightMapParameters = new HeightMapParameters("GPU");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now we have one parameter set for the height map, not one each for the extractor type

setContactMap(other.contactMap);
setTerrainCostMap(other.terrainCostMap);

setSteppableRegionAssignmentMat(other.steppableRegionAssignmentMat);
setSteppableRegionRingMat(other.steppableRegionRingMat);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was missing some stuff in the copy constructor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty simple but could prove useful in the future

Copy link
Contributor

@TomaszTB TomaszTB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really feel like this PR should be split into four or so PRs... Maybe like this?

  1. ROS2Helper -> ROS2Node + ROS2Publisher changes (this one might be controversial)
  2. 3D CUDA kernel example + height map filter
  3. Cleanup + parameter changes
  4. Changes related to continuous hiking + UI

Otherwise I feel like getting this one merged will be difficult

Copy link
Contributor

@TomaszTB TomaszTB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll review this PR a bit slowly, one piece at a time (sorry this might take a while).

I added comments about the height map filter. Logic looks good, just some cleanup and memory freeing stuff I noticed.

#define LAYERS 0

__global__
void filterRapidHeightMap(unsigned short * matrixPointer, size_t pitchA,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you give a better name to matrixPointer? What sort of matrix is it? Seems like it holds some sort of history to me.

Comment on lines 30 to 33
// Create a 2x2 with 5 layers
int rows = 2;
int cols = 2;
int layers = 4;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment says 5 layers but layers = 4?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adresseed!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still looks the same to me

@@ -286,6 +287,9 @@ public void update(RigidBodyTransform sensorToWorldTransform, RigidBodyTransform
error = cudaStreamSynchronize(stream);
CUDATools.checkCUDAError(error);

if (heightMapParameters.getEnableAlphaFilter())
globalHeightMapImage = filteredRapidHeightMapExtractor.update(globalHeightMapImage);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should close the globalHeightMapImage between the call to update and the assignment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to free the CUDA memory of the globalHeightMapImage before you reassign it with a new GpuMat

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, it's actually gonna be a bit more complicated since you don't always return a new GpuMat. Sometimes you return the passed in one, then you don't want to free anything... Hmmm... Maybe just always return a new GpuMat? Or do it OpenCV style where you pass in the "destination" GpuMat as a parameter to the update method. That also leaves memory handling to whatever is calling update.

Copy link
Contributor

@TomaszTB TomaszTB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking pretty good with the height map filter. Just a few minor things I noticed.

{
MovingReferenceFrame midFeetZUpFrame = syncedRobotModel.getReferenceFrames().getMidFeetZUpFrame();
FramePose3D midFeetZUpPose = new FramePose3D(midFeetZUpFrame, midFeetZUpFrame.getTransformToWorldFrame());
SideDependentList<FramePose3D> goalPoses = new SideDependentList<>(new FramePose3D(syncedRobotModel.getReferenceFrames().getMidFeetZUpFrame()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like you're not getting anything out of this side dependent list. Why not just have two variables leftGoalPose and rightGoalPose?

FramePose3DReadOnly soleFramePose;
if (controllerQueueMonitor.getNumberOfIncompleteFootsteps() > 0)
{
LogTools.info("Yes this queue is not empty");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to keep this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatter, rip

Copy link
Contributor

@TomaszTB TomaszTB Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mean the formatting, I mean the logging
(although the formatting is awful too)

Comment on lines +99 to 105
ros2Node.createSubscription(HumanoidControllerAPI.getTopic(HighLevelStateChangeStatusMessage.class, robotName), message ->
{
if (message.takeNextData().getEndHighLevelControllerName() == HighLevelStateChangeStatusMessage.WALKING)
{
resetHeightMapRequested.set();
}
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ros2Node.createSubscription(HumanoidControllerAPI.getTopic(HighLevelStateChangeStatusMessage.class, robotName), message ->
{
if (message.takeNextData().getEndHighLevelControllerName() == HighLevelStateChangeStatusMessage.WALKING)
{
resetHeightMapRequested.set();
}
});
ros2Node.createSubscription2(HumanoidControllerAPI.getTopic(HighLevelStateChangeStatusMessage.class, robotName), message ->
{
if (message.getEndHighLevelControllerName() == HighLevelStateChangeStatusMessage.WALKING)
{
resetHeightMapRequested.set();
}
});

@PotatoPeeler3000 PotatoPeeler3000 merged commit 34baa22 into develop Feb 27, 2025
63 of 68 checks passed
@PotatoPeeler3000 PotatoPeeler3000 deleted the feature/new-ch-messages branch February 27, 2025 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants