Skip to content

Conversation

@ShrutheeshIR
Copy link
Contributor

@ShrutheeshIR ShrutheeshIR commented Oct 18, 2025

Add support for multiple end effectors. This PR is in tandem with CoMMALab/cricket#4.
Major changes callout

  • Each robot has an array of EEFs instead of a single EEF.
    • To support getting FKs, we have a new function, to_isometries(), that returns an array of EEF FKs. This is nice, as it can directly be fed into std::map for attachment (as follows)
  • Instead of attachments being std::optional, it is now a std::map<eef_id, attachment e>. This has some effects
    • To add an attachment, we must specify the eef_id (in py and cpp). As a follow up, we could default this to 0 perhaps.
    • Instead of checking if attachment exists, we just check if its size is non-zero.
    • In addition to env-attachment, robot-attachment, we also need to check for attachment-attachment collisions. This is now done within env-attachment collision check itself, but could be moved out if needed.
  • Modified all robot files to reflect the changes. (there are only two changes per robot file -- eef_name -> eef_names, to_isometry -> to_isometries
    • Also added bimanual_franka.hh
  • Also pulled in Viser visualization Example Python #76 for viser viz

TODO

  • Test if it actually works :(

output

inline constexpr auto less_than(typename S::ScalarT s) const noexcept -> D
{
return greater_than(broadcast_scalar(s));
return less_than(broadcast_scalar(s));
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 has been annoying me for a while

}

template <size_t N, typename DataT>
inline static auto to_isometries(const DataT *buf) -> std::array<Eigen::Transform<DataT, 3, Eigen::Isometry>, N>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

if there are multiple EEFs, then each FK is a 12 ele array

e.attachments->pose(p_tf);
for(auto i=0U; i < N; i++){
if(e.attachments.find(i) != e.attachments.end())
e.attachments.at(i).pose(p_tfs[i]);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

at() to modify in place

}
}

// now treat the other attachments also as potential collision objects
Copy link
Contributor Author

Choose a reason for hiding this comment

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

seems pretty clunky to me, but idk if there's a better way

@ShrutheeshIR
Copy link
Contributor Author

Disabled clang-format for now. It modifies too many files

@ShrutheeshIR
Copy link
Contributor Author

Well looking at other PRs, I should probably remove fr3.hh

namespace vamp::collision
{
template <typename DataT>
struct EEFAttachment {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

for attachments, we need to keep track of both the attachment object, and the end effector it is attached to. custom struct to support it

Copy link
Member

Choose a reason for hiding this comment

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

I think this might not actually be the right approach -- actually, including attachment state in the environment is almost certainly "wrong," since environments should ideally be immutable in the planning process.

Instead, would it make sense to refactor into having an AttachedRobot<R> that stores the poses for attachment frames? I did this in my own Rust reimplementation and it worked very well.

Copy link
Collaborator

@zkingston zkingston left a comment

Choose a reason for hiding this comment

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

LGTM overall, some notes:

  • Does BimanualPanda work with the random_dance.py script? If not we may need to change the logic so it can find the URDF/SRDF for Bullet rendering.
  • Does the current attachment.py script still work?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Lots of commented code here, please clean up.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you remove and keep only with the Viser add PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you review that PR -- #76?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Same, remove and keep only with Viser PR.

return ;
}
eef_attachments.emplace_back(eef_idx, a);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Spacing between functions? Surprised clang-format didn't catch this.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually, a number of formatting things, please update.

// TODO: Fix the sphere representation to allow to store float radii even with vector
// centers
if (sphere_environment_in_collision(e, s.x, s.y, s.z, s.r[{0, 0}]))
for (const auto &eef_attachment: e.eef_attachments){
Copy link
Collaborator

Choose a reason for hiding this comment

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

As the EEs are indexed, may be better to just do i=0...N and j=i+1...N rather than the != iter check.

const std::size_t n = std::max(std::ceil(distance / static_cast<float>(rake) * resolution), 1.F);

bool valid = (environment.attachments) ? Robot::template fkcc_attach<rake>(environment, block) :
bool valid = (environment.eef_attachments.size()) ? Robot::template fkcc_attach<rake>(environment, block) :
Copy link
Collaborator

Choose a reason for hiding this comment

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

can also use ! empty()

Copy link
Collaborator

Choose a reason for hiding this comment

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

Did you add multiple EEs to baxter?

option(VAMP_INSTALL_CPP_LIBRARY "Install VAMP C++ library (disable for Python wheel builds)" ON)

option(VAMP_BUILD_CPP_DEMO "Build VAMP C++ Demo Scripts" OFF)
option(VAMP_BUILD_CPP_DEMO "Build VAMP C++ Demo Scripts" ON)
Copy link
Collaborator

Choose a reason for hiding this comment

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

this should be off by default for python wheels

@wbthomason wbthomason linked an issue Dec 12, 2025 that may be closed by this pull request
@zkingston zkingston changed the title Multi eef vamp Support multiple attachment frames Dec 12, 2025
Copy link
Member

@claytonwramsey claytonwramsey left a comment

Choose a reason for hiding this comment

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

main thoughts:

  • factor out changes not related to bimanual manipulation
  • make sure to not bust up the formatting to keep the diff small
  • bimanual panda should probably not be a robot

namespace vamp::collision
{
template <typename DataT>
struct EEFAttachment {
Copy link
Member

Choose a reason for hiding this comment

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

I think this might not actually be the right approach -- actually, including attachment state in the environment is almost certainly "wrong," since environments should ideally be immutable in the planning process.

Instead, would it make sense to refactor into having an AttachedRobot<R> that stores the poses for attachment frames? I did this in my own Rust reimplementation and it worked very well.

std::vector<HeightField<DataT>> heightfields;
std::vector<CAPT> pointclouds;
std::optional<Attachment<DataT>> attachments;
std::vector<EEFAttachment<DataT>> eef_attachments; // eef_id to attachment
Copy link
Member

Choose a reason for hiding this comment

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

should eef_attachments instead be a std::vector<std::optional<EEFAttachment<DataT>>> as our key set is fixed when the robot is fixed? this means the attachment also doesn't need to track its own index.

if (eef_attachment.eef_idx == i)
eef_attachment.attachment.pose(p_tfs[i]);
}
}
Copy link
Member

Choose a reason for hiding this comment

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

see my comment on changing the structure of eef_attachments

}

// now treat the other attachments also as potential collision objects
// This is probably expensive, find a more efficient way.
Copy link
Member

Choose a reason for hiding this comment

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

Attachment collision checking is comparatively cheap; I think it is ok to stay.
Maybe adding a coarse phase check would be an improvement to perf but generally I think it is not going to be a big issue.

Copy link
Member

Choose a reason for hiding this comment

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

It is probably not the best idea to add a bimanual panda robot, since it's a lot to support and doesn't really reflect areal robot. Instead maybe we use Baxter as our demo for a bimanual robot?

Copy link
Member

Choose a reason for hiding this comment

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

did clang-format do something to this poor beast?

Copy link
Member

Choose a reason for hiding this comment

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

cherry-pick this out maybe since it belongs in its own PR

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.

Allow Multiple Frames for Attachments

3 participants