CARLA Simulator: Difference between revisions

Line 53: Line 53:


To convert depth values to euclidean distance, you need to divide by \(\cos(\theta)\) where \(\theta\) is the angle to the center of the image.
To convert depth values to euclidean distance, you need to divide by \(\cos(\theta)\) where \(\theta\) is the angle to the center of the image.
{{hidden | Z-depth to Euclidean depth |
<syntaxhighlight lang="python">
theta, phi = np.meshgrid((np.arange(width) + 0.5) * (2 * np.pi / width),
                        (np.arange(height) + 0.5) * (np.pi / height))
uvs, uv_sides = my_helpers.spherical_to_cubemap(theta.reshape(-1),
                                              phi.reshape(-1))
cubemap_uvs = uvs.reshape(height, width, 2)
# cubemap_uv_sides = uv_sides.reshape(height, width)
world_coords = my_helpers.spherical_to_cartesian(
  cubemap_uvs[:, :, 0] * np.pi / 2 + np.pi / 4,
  cubemap_uvs[:, :, 1] * np.pi / 2 + np.pi / 4)
cos_angle = world_coords @ np.array([0, 0, 1], dtype=np.float32)
return depth_image / cos_angle[np.newaxis, :, :, np.newaxis]
</syntaxhighlight>
* Here <code>cubemap_uvs</code> are the UVs of each equirectangular pixel within the cubemap.
Spherical to cubemap is defined as follows:
<syntaxhighlight lang="python">
def spherical_to_cubemap(theta, phi):
  """Converts spherical coordinates to cubemap coordinates.
  Args:
    theta: Longitude (azimuthal angle) in radians. [0, 2pi]
    phi: Latitude (altitude angle) in radians. [0, pi]
  Returns:
    uv: UVS in channel_last format
    idx: Side of the cubemap
  """
  u = np.zeros(theta.shape, dtype=np.float32)
  v = np.zeros(theta.shape, dtype=np.float32)
  side = np.zeros(theta.shape, dtype=np.float32)
  side[:] = -1
  for i in range(0, 4):
    indices = np.logical_or(
        np.logical_and(theta >= i * np.pi / 2 - np.pi / 4, theta <=
                      (i + 1) * np.pi / 2 - np.pi / 4),
        np.logical_and(theta >= i * np.pi / 2 - np.pi / 4 + 2 * np.pi, theta <=
                      (i + 1) * np.pi / 2 - np.pi / 4 + 2 * np.pi))
    u[indices] = np.tan(theta[indices] - i * np.pi / 2)
    v[indices] = 1 / (
        np.tan(phi[indices]) * np.cos(theta[indices] - i * np.pi / 2))
    side[indices] = i + 1
  top_indices = np.logical_or(phi < np.pi / 4, v >= 1)
  u[top_indices] = -np.tan(phi[top_indices]) * np.sin(theta[top_indices] -
                                                      np.pi)
  v[top_indices] = np.tan(phi[top_indices]) * np.cos(theta[top_indices] - np.pi)
  side[top_indices] = 0
  bottom_indices = np.logical_or(phi >= 3 * np.pi / 4, v <= -1)
  u[bottom_indices] = -np.tan(phi[bottom_indices]) * np.sin(
      theta[bottom_indices])
  v[bottom_indices] = -np.tan(phi[bottom_indices]) * np.cos(
      theta[bottom_indices])
  side[bottom_indices] = 5
  assert not np.any(side < 0), "Side less than 0"
  return np.stack(((u + 1) / 2, (-v + 1) / 2), axis=-1), side
</syntaxhighlight>
}}


==Fixed time step==
==Fixed time step==