Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions PythonClient/airsim/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# unit tests
52 changes: 52 additions & 0 deletions PythonClient/airsim/tests/test_utils_reshape.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Offline tests for list_to_2d_float_array guards."""
import importlib.util
import os
import sys
import types as pytypes
import unittest

import numpy as np

_HERE = os.path.dirname(os.path.abspath(__file__))
_UTILS = os.path.join(os.path.dirname(_HERE), "utils.py")


def _load_utils():
pkg = pytypes.ModuleType("airsim")
pkg.__path__ = [os.path.dirname(_HERE)]
sys.modules["airsim"] = pkg
stub = pytypes.ModuleType("airsim.types")
sys.modules["airsim.types"] = stub
uspec = importlib.util.spec_from_file_location("airsim.utils", _UTILS)
umod = importlib.util.module_from_spec(uspec)
sys.modules["airsim.utils"] = umod
uspec.loader.exec_module(umod)
return umod


_u = _load_utils()


class TestListTo2d(unittest.TestCase):
def test_happy_path(self):
out = _u.list_to_2d_float_array([1, 2, 3, 4], 2, 2)
self.assertEqual(out.shape, (2, 2))
self.assertEqual(out.dtype, np.float32)
self.assertAlmostEqual(float(out[0, 0]), 1.0)

def test_empty_zero_by_zero(self):
out = _u.list_to_2d_float_array([], 0, 0)
self.assertEqual(out.shape, (0, 0))

def test_length_mismatch(self):
with self.assertRaises(ValueError) as ctx:
_u.list_to_2d_float_array([1, 2, 3], 2, 2)
self.assertIn("flat length", str(ctx.exception))

def test_negative_dim(self):
with self.assertRaises(ValueError):
_u.list_to_2d_float_array([], -1, 1)


if __name__ == "__main__":
unittest.main()
24 changes: 23 additions & 1 deletion PythonClient/airsim/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,29 @@ def string_to_float_array(bstr):
return np.fromstring(bstr, np.float32)

def list_to_2d_float_array(flst, width, height):
return np.reshape(np.asarray(flst, np.float32), (height, width))
"""Reshape a flat float list into a height x width float32 array.

Raises ValueError with a clear message when dimensions are invalid so
empty or truncated depth buffers fail closed instead of cascading
opaque numpy reshape errors.
"""
try:
w = int(width)
h = int(height)
except (TypeError, ValueError) as exc:
raise ValueError("width and height must be integers") from exc
if w < 0 or h < 0:
raise ValueError("width and height must be non-negative, got width=%r height=%r" % (w, h))
arr = np.asarray(flst, np.float32).reshape(-1)
expected = w * h
if arr.size != expected:
raise ValueError(
"flat length %d does not match width*height (%d*%d=%d)"
% (arr.size, w, h, expected)
)
if expected == 0:
return np.zeros((h, w), dtype=np.float32)
return np.reshape(arr, (h, w))

def get_pfm_array(response):
return list_to_2d_float_array(response.image_data_float, response.width, response.height)
Expand Down