test_aircraft.py 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. from types import SimpleNamespace
  2. import unittest
  3. from motian_bridge import Config
  4. from motian_bridge.aircraft import ParamEntry, ParamTable
  5. from motian_bridge.dialects.v20 import VKFly
  6. from motian_bridge.telemetry import Telemetry
  7. def cfg(**kwargs):
  8. fields = dict(system_id="UAV000001", uav_type=7, serial_port="loop://",
  9. serial_baudrate=57600, mqtt_host="localhost")
  10. fields.update(kwargs)
  11. return Config(**fields)
  12. def sender(system=1, component=1):
  13. return VKFly.MAVLink(None, srcSystem=system, srcComponent=component)
  14. def heartbeat(mav, armed=False, mode=4):
  15. return mav.heartbeat_encode(
  16. VKFly.MAV_TYPE_QUADROTOR, VKFly.MAV_AUTOPILOT_GENERIC,
  17. VKFly.MAV_MODE_FLAG_SAFETY_ARMED if armed else 0,
  18. mode, VKFly.MAV_STATE_ACTIVE).pack(mav)
  19. def param_value_frame(mav, param_id, value, index=0, count=1,
  20. type_=VKFly.MAV_PARAM_TYPE_REAL32):
  21. return mav.param_value_encode(param_id, value, type_, count, index).pack(mav)
  22. class AircraftTests(unittest.TestCase):
  23. def test_aircraft_created_from_heartbeat(self):
  24. telemetry = Telemetry(cfg())
  25. self.assertIsNone(telemetry.aircraft)
  26. self.assertIsNone(telemetry.source)
  27. telemetry.feed(heartbeat(sender(4, 1)), now=0)
  28. aircraft = telemetry.aircraft
  29. self.assertIsNotNone(aircraft)
  30. self.assertEqual(aircraft.source, (4, 1))
  31. self.assertEqual(telemetry.source, (4, 1))
  32. self.assertEqual(aircraft.uav_type, VKFly.MAV_TYPE_QUADROTOR)
  33. def test_param_table_accumulates_and_completes(self):
  34. telemetry = Telemetry(cfg())
  35. mav = sender()
  36. telemetry.feed(heartbeat(mav), now=0)
  37. table = telemetry.aircraft.params
  38. self.assertFalse(table.complete())
  39. telemetry.feed(param_value_frame(mav, b"FS_CONF_A", 4660, index=0, count=2), now=0)
  40. self.assertFalse(table.complete())
  41. telemetry.feed(param_value_frame(mav, b"ALT_LIM_UP1", 120, index=1, count=2), now=0)
  42. self.assertTrue(table.complete())
  43. self.assertEqual(table.get("FS_CONF_A"), 4660)
  44. self.assertEqual(table.get("ALT_LIM_UP1"), 120)
  45. self.assertEqual(telemetry.param_value("FS_CONF_A"), 4660)
  46. self.assertIsNone(telemetry.param_value("MISSING"))
  47. self.assertIn("FS_CONF_A", table)
  48. def test_duplicate_index_and_unknown_index_do_not_complete(self):
  49. table = ParamTable()
  50. known = SimpleNamespace(param_id=b"P", param_value=1.0, param_type=9,
  51. param_count=2, param_index=0)
  52. table.update(known)
  53. table.update(known)
  54. self.assertEqual(len(table.received), 1)
  55. self.assertEqual(len(table), 1)
  56. unknown = SimpleNamespace(param_id=b"Q", param_value=2.0, param_type=9,
  57. param_count=2, param_index=0xFFFF)
  58. table.update(unknown)
  59. self.assertEqual(table.received, {0})
  60. self.assertFalse(table.complete())
  61. def test_param_table_setitem_accepts_values_and_entries(self):
  62. table = ParamTable()
  63. table["X"] = 5.0
  64. table["Y"] = ParamEntry(3.0, VKFly.MAV_PARAM_TYPE_UINT8, 1)
  65. self.assertEqual(table.get("X"), 5.0)
  66. self.assertEqual(table.get("Y"), 3.0)
  67. self.assertEqual(table.entries["Y"].param_type, VKFly.MAV_PARAM_TYPE_UINT8)
  68. if __name__ == "__main__":
  69. unittest.main()