| 762 | |
| 763 | |
| 764 | class CameraManager(object): |
| 765 | def __init__(self, parent_actor, hud): |
| 766 | self.sensor = None |
| 767 | self.surface = None |
| 768 | self._parent = parent_actor |
| 769 | self.hud = hud |
| 770 | self.recording = False |
| 771 | bound_y = 0.5 + self._parent.bounding_box.extent.y |
| 772 | Attachment = carla.AttachmentType |
| 773 | self._camera_transforms = [ |
| 774 | (carla.Transform(carla.Location(x=-5.5, z=2.5), carla.Rotation(pitch=8.0)), Attachment.SpringArm), |
| 775 | (carla.Transform(carla.Location(x=1.6, z=1.7)), Attachment.Rigid), |
| 776 | (carla.Transform(carla.Location(x=5.5, y=1.5, z=1.5)), Attachment.SpringArm), |
| 777 | (carla.Transform(carla.Location(x=-8.0, z=6.0), carla.Rotation(pitch=6.0)), Attachment.SpringArm), |
| 778 | (carla.Transform(carla.Location(x=-1, y=-bound_y, z=0.5)), Attachment.Rigid)] |
| 779 | self.transform_index = 1 |
| 780 | self.sensors = [ |
| 781 | ['sensor.camera.rgb', cc.Raw, 'Camera RGB'], |
| 782 | ['sensor.camera.depth', cc.Raw, 'Camera Depth (Raw)'], |
| 783 | ['sensor.camera.depth', cc.Depth, 'Camera Depth (Gray Scale)'], |
| 784 | ['sensor.camera.depth', cc.LogarithmicDepth, 'Camera Depth (Logarithmic Gray Scale)'], |
| 785 | ['sensor.camera.semantic_segmentation', cc.Raw, 'Camera Semantic Segmentation (Raw)'], |
| 786 | ['sensor.camera.semantic_segmentation', cc.CityScapesPalette, |
| 787 | 'Camera Semantic Segmentation (CityScapes Palette)'], |
| 788 | ['sensor.lidar.ray_cast', None, 'Lidar (Ray-Cast)']] |
| 789 | world = self._parent.get_world() |
| 790 | bp_library = world.get_blueprint_library() |
| 791 | for item in self.sensors: |
| 792 | bp = bp_library.find(item[0]) |
| 793 | if item[0].startswith('sensor.camera'): |
| 794 | bp.set_attribute('image_size_x', str(hud.dim[0])) |
| 795 | bp.set_attribute('image_size_y', str(hud.dim[1])) |
| 796 | elif item[0].startswith('sensor.lidar'): |
| 797 | bp.set_attribute('range', '5000') |
| 798 | item.append(bp) |
| 799 | self.index = None |
| 800 | |
| 801 | def toggle_camera(self): |
| 802 | self.transform_index = (self.transform_index + 1) % len(self._camera_transforms) |
| 803 | self.set_sensor(self.index, notify=False, force_respawn=True) |
| 804 | |
| 805 | def set_sensor(self, index, notify=True, force_respawn=False): |
| 806 | index = index % len(self.sensors) |
| 807 | needs_respawn = True if self.index is None else \ |
| 808 | (force_respawn or (self.sensors[index][0] != self.sensors[self.index][0])) |
| 809 | if needs_respawn: |
| 810 | if self.sensor is not None: |
| 811 | self.sensor.destroy() |
| 812 | self.surface = None |
| 813 | self.sensor = self._parent.get_world().spawn_actor( |
| 814 | self.sensors[index][-1], |
| 815 | self._camera_transforms[self.transform_index][0], |
| 816 | attach_to=self._parent, |
| 817 | attachment_type=self._camera_transforms[self.transform_index][1]) |
| 818 | # We need to pass the lambda a weak reference to self to avoid |
| 819 | # circular reference. |
| 820 | weak_self = weakref.ref(self) |
| 821 | self.sensor.listen(lambda image: CameraManager._parse_image(weak_self, image)) |