sensor_interface.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #!/usr/bin/env python
  2. # This work is licensed under the terms of the MIT license.
  3. # For a copy, see <https://opensource.org/licenses/MIT>.
  4. """
  5. This file containts CallBack class and SensorInterface, responsible of
  6. handling the use of sensors for the agents
  7. """
  8. import copy
  9. import logging
  10. try:
  11. from queue import Queue
  12. from queue import Empty
  13. except ImportError:
  14. from Queue import Queue
  15. from Queue import Empty
  16. import numpy as np
  17. import carla
  18. class SensorReceivedNoData(Exception):
  19. """
  20. Exceptions thrown when the sensors used by the agent take too long to receive data
  21. """
  22. class CallBack(object):
  23. """
  24. Class the sensors listen to in order to receive their data each frame
  25. """
  26. def __init__(self, tag, sensor, data_provider):
  27. """
  28. Initializes the call back
  29. """
  30. self._tag = tag
  31. self._data_provider = data_provider
  32. self._data_provider.register_sensor(tag, sensor)
  33. def __call__(self, data):
  34. """
  35. call function
  36. """
  37. if isinstance(data, carla.Image):
  38. self._parse_image_cb(data, self._tag)
  39. elif isinstance(data, carla.LidarMeasurement):
  40. self._parse_lidar_cb(data, self._tag)
  41. elif isinstance(data, carla.RadarMeasurement):
  42. self._parse_radar_cb(data, self._tag)
  43. elif isinstance(data, carla.GnssMeasurement):
  44. self._parse_gnss_cb(data, self._tag)
  45. elif isinstance(data, carla.IMUMeasurement):
  46. self._parse_imu_cb(data, self._tag)
  47. else:
  48. logging.error('No callback method for this sensor.')
  49. # Parsing CARLA physical Sensors
  50. def _parse_image_cb(self, image, tag):
  51. """
  52. parses cameras
  53. """
  54. array = np.frombuffer(image.raw_data, dtype=np.dtype("uint8"))
  55. array = copy.deepcopy(array)
  56. array = np.reshape(array, (image.height, image.width, 4))
  57. self._data_provider.update_sensor(tag, array, image.frame)
  58. def _parse_lidar_cb(self, lidar_data, tag):
  59. """
  60. parses lidar sensors
  61. """
  62. points = np.frombuffer(lidar_data.raw_data, dtype=np.dtype('f4'))
  63. points = copy.deepcopy(points)
  64. points = np.reshape(points, (int(points.shape[0] / 4), 4))
  65. self._data_provider.update_sensor(tag, points, lidar_data.frame)
  66. def _parse_radar_cb(self, radar_data, tag):
  67. """
  68. parses radar sensors
  69. """
  70. # [depth, azimuth, altitute, velocity]
  71. points = np.frombuffer(radar_data.raw_data, dtype=np.dtype('f4'))
  72. points = copy.deepcopy(points)
  73. points = np.reshape(points, (int(points.shape[0] / 4), 4))
  74. points = np.flip(points, 1)
  75. self._data_provider.update_sensor(tag, points, radar_data.frame)
  76. def _parse_gnss_cb(self, gnss_data, tag):
  77. """
  78. parses gnss sensors
  79. """
  80. array = np.array([gnss_data.latitude,
  81. gnss_data.longitude,
  82. gnss_data.altitude], dtype=np.float64)
  83. self._data_provider.update_sensor(tag, array, gnss_data.frame)
  84. def _parse_imu_cb(self, imu_data, tag):
  85. """
  86. parses IMU sensors
  87. """
  88. array = np.array([imu_data.accelerometer.x,
  89. imu_data.accelerometer.y,
  90. imu_data.accelerometer.z,
  91. imu_data.gyroscope.x,
  92. imu_data.gyroscope.y,
  93. imu_data.gyroscope.z,
  94. imu_data.compass,
  95. ], dtype=np.float64)
  96. self._data_provider.update_sensor(tag, array, imu_data.frame)
  97. class SensorInterface(object):
  98. """
  99. Class that contains all sensor data
  100. """
  101. def __init__(self):
  102. """
  103. Initializes the class
  104. """
  105. self._sensors_objects = {}
  106. self._new_data_buffers = Queue()
  107. self._queue_timeout = 10
  108. def register_sensor(self, tag, sensor):
  109. """
  110. Registers the sensors
  111. """
  112. if tag in self._sensors_objects:
  113. raise ValueError("Duplicated sensor tag [{}]".format(tag))
  114. self._sensors_objects[tag] = sensor
  115. def update_sensor(self, tag, data, timestamp):
  116. """
  117. Updates the sensor
  118. """
  119. if tag not in self._sensors_objects:
  120. raise ValueError("The sensor with tag [{}] has not been created!".format(tag))
  121. self._new_data_buffers.put((tag, timestamp, data))
  122. def get_data(self):
  123. """
  124. Returns the data of a sensor
  125. """
  126. try:
  127. data_dict = {}
  128. while len(data_dict.keys()) < len(self._sensors_objects.keys()):
  129. sensor_data = self._new_data_buffers.get(True, self._queue_timeout)
  130. data_dict[sensor_data[0]] = ((sensor_data[1], sensor_data[2]))
  131. except Empty:
  132. raise SensorReceivedNoData("A sensor took too long to send its data")
  133. return data_dict