Closed Alexbeast-CN closed 1 month ago
I found out that it was actually an issue with assimp. When it loads an OBJ file, it triples the number of points to match the number of triangles. But in reality, many points should be shared by triangles. Therefore, after manually processing the loading of the OBJ file with fstream, there were no problems.
I'm using hpp-fcl version 2.4.0 with ROS humble and ubuntu 22.04.
Both c++ version and python version are installed by apt with
apt install ros-humble-hpp-fcl
.I'm tring to test collision detection with a box and a convex shape load from .obj file.
This is my convex shape .obj:
You can download this file here
I firstly wrote a python program, and it works fine. I can move the box with "w, s, a, d, q, e" keys, and it prints "collision detected" when the box is inside the convex shape.
here is my python code
```py import numpy as np import trimesh import rclpy import hppfcl as fcl from pynput import keyboard from rclpy.node import Node from rclpy.qos import QoSProfile, DurabilityPolicy from visualization_msgs.msg import Marker class CollisionTest(Node): def __init__(self): super().__init__('collision_test') # config qos profile qos_profile = QoSProfile(depth=10) qos_profile.durability = DurabilityPolicy.TRANSIENT_LOCAL self.box_publisher = self.create_publisher(Marker, 'box', 10) self.env_publisher = self.create_publisher(Marker, 'env', qos_profile) self.timer = self.create_timer(0.1, self.timer_callback) self.box_position = np.array([0.0, 0.0, 0.0]) self.step = 0.03 self.init_box() self.init_env() # Setup keyboard listener self.listener = keyboard.Listener(on_press=self.on_press) self.listener.start() def init_box(self): # Initialize box collision object box_shape = fcl.Box(0.1, 0.1, 0.1) self.box_obj = fcl.CollisionObject(box_shape) # Initialize box marker self.box_marker = Marker() self.box_marker.header.frame_id = 'map' self.box_marker.ns = 'collision_test' self.box_marker.id = 0 self.box_marker.type = Marker.CUBE self.box_marker.action = Marker.ADD self.box_marker.scale.x = 0.1 self.box_marker.scale.y = 0.1 self.box_marker.scale.z = 0.1 self.box_marker.color.a = 1.0 self.box_marker.color.r = 0.0 self.box_marker.color.g = 1.0 self.box_marker.color.b = 0.0 def init_env(self): file_path = "/path/to/convex_hull.obj" scale = 1.0 # Publish markers env_marker = Marker() env_marker.header.frame_id = 'map' env_marker.ns = 'collision_test' env_marker.id = 0 env_marker.type = Marker.MESH_RESOURCE env_marker.mesh_resource = "file://" + file_path env_marker.action = Marker.ADD env_marker.scale.x = scale env_marker.scale.y = scale env_marker.scale.z = scale env_marker.color.r = 0.1 env_marker.color.g = 0.0 env_marker.color.b = 0.7 env_marker.color.a = 0.3 self.env_publisher.publish(env_marker) # Initialize environment collision object mesh = trimesh.load_mesh(file_path) mesh.apply_scale(scale) verts = fcl.StdVec_Vec3f() faces = fcl.StdVec_Triangle() verts.extend(mesh.vertices) for f in mesh.faces: faces.append(fcl.Triangle(int(f[0]), int(f[1]), int(f[2]))) convex = fcl.Convex(verts, faces) self.env_objs = [fcl.CollisionObject(convex)] def move_box(self): # Move the box marker self.box_marker.pose.position.x = self.box_position[0] self.box_marker.pose.position.y = self.box_position[1] self.box_marker.pose.position.z = self.box_position[2] self.box_publisher.publish(self.box_marker) # Move the box collision object transform = fcl.Transform3f() transform.setTranslation(self.box_position) self.box_obj.setTransform(transform) # Check collision for env_obj in self.env_objs: if self.check_collision(self.box_obj, env_obj): self.get_logger().info('Collision detected!') break def check_collision(self, obj1, obj2): request = fcl.CollisionRequest() result = fcl.CollisionResult() fcl.collide(obj1, obj2, request, result) return result.isCollision() def on_press(self, key): try: if key.char == 'w': self.box_position[1] += self.step elif key.char == 's': self.box_position[1] -= self.step elif key.char == 'a': self.box_position[0] -= self.step elif key.char == 'd': self.box_position[0] += self.step elif key.char == 'q': self.box_position[2] += self.step elif key.char == 'e': self.box_position[2] -= self.step except AttributeError: pass def timer_callback(self): self.move_box() def main(args=None): print(f"hpp-fcl version: {fcl.__version__}") rclpy.init(args=args) node = CollisionTest() rclpy.spin(node) rclpy.shutdown() if __name__ == '__main__': main() ```However, when I tried to rewrite the code in c++, things are getting wired. It prints "collision detection" in wrong space.
Here is a short video to show the problem:
https://github.com/humanoid-path-planner/hpp-fcl/assets/69784031/efc4783c-fbb8-4476-acb7-0e45e3930c60
here is my c++ code
```cpp #includeThe reseason why I write the
init_collision_objs()
function as a recursive function is because I will deal with a group of geometries in one .obj file in the future. The vertices of the convex shape are correct because the TRIANGLE_LIST visualization markers are working correctly.Thanks to anyone who can give a hand.