| 384 | |
| 385 | |
| 386 | class CollisionSensor(object): |
| 387 | def __init__(self, parent_actor, hud): |
| 388 | self.sensor = None |
| 389 | self.history = [] |
| 390 | self._parent = parent_actor |
| 391 | self.hud = hud |
| 392 | world = self._parent.get_world() |
| 393 | bp = world.get_blueprint_library().find('sensor.other.collision') |
| 394 | self.sensor = world.spawn_actor(bp, carla.Transform(), attach_to=self._parent) |
| 395 | # We need to pass the lambda a weak reference to self to avoid circular |
| 396 | # reference. |
| 397 | weak_self = weakref.ref(self) |
| 398 | self.sensor.listen(lambda event: CollisionSensor._on_collision(weak_self, event)) |
| 399 | |
| 400 | def get_collision_history(self): |
| 401 | history = collections.defaultdict(int) |
| 402 | for frame, intensity in self.history: |
| 403 | history[frame] += intensity |
| 404 | return history |
| 405 | |
| 406 | @staticmethod |
| 407 | def _on_collision(weak_self, event): |
| 408 | self = weak_self() |
| 409 | if not self: |
| 410 | return |
| 411 | actor_type = get_actor_display_name(event.other_actor) |
| 412 | self.hud.notification('Collision with %r' % actor_type) |
| 413 | impulse = event.normal_impulse |
| 414 | intensity = math.sqrt(impulse.x ** 2 + impulse.y ** 2 + impulse.z ** 2) |
| 415 | self.history.append((event.frame, intensity)) |
| 416 | if len(self.history) > 4000: |
| 417 | self.history.pop(0) |
| 418 | |
| 419 | # ============================================================================== |
| 420 | # -- LaneInvasionSensor -------------------------------------------------------- |