|
| 1 | +""" |
| 2 | +VFH integration test. |
| 3 | +""" |
| 4 | + |
| 5 | +import multiprocessing as mp |
| 6 | +import queue |
| 7 | +import numpy as np |
| 8 | + |
| 9 | +from modules import lidar_detection |
| 10 | +from modules import lidar_oscillation |
| 11 | +from modules.vfh import vfh |
| 12 | +from worker import queue_wrapper |
| 13 | +from worker import worker_controller |
| 14 | + |
| 15 | +# Constants |
| 16 | +QUEUE_MAX_SIZE = 10 |
| 17 | +SECTOR_WIDTH = 5.0 |
| 18 | +MAX_VECTOR_MAGNITUDE = 1.0 |
| 19 | +LINEAR_DECAY_RATE = 0.05 |
| 20 | +CONFIDENCE_VALUE = 1.0 |
| 21 | +START_ANGLE = -90.0 |
| 22 | +END_ANGLE = 90.0 |
| 23 | +THRESHOLD = 0.5 |
| 24 | + |
| 25 | +# pylint: disable=duplicate-code |
| 26 | + |
| 27 | + |
| 28 | +def simulate_oscillation_worker(in_queue: queue_wrapper.QueueWrapper) -> None: |
| 29 | + """ |
| 30 | + Simulate LidarOscillation and push it to the queue. |
| 31 | + """ |
| 32 | + readings = [] |
| 33 | + |
| 34 | + for angle in np.arange(-90, -30, SECTOR_WIDTH): |
| 35 | + result, detection = lidar_detection.LidarDetection.create(angle=angle, distance=5.0) |
| 36 | + assert result, "Failed to create LidarDetection" |
| 37 | + readings.append(detection) |
| 38 | + |
| 39 | + for angle in np.arange(-30, 30, SECTOR_WIDTH): |
| 40 | + result, detection = lidar_detection.LidarDetection.create(angle=angle, distance=100.0) |
| 41 | + assert result, "Failed to create LidarDetection" |
| 42 | + readings.append(detection) |
| 43 | + |
| 44 | + for angle in np.arange(30, 90, SECTOR_WIDTH): |
| 45 | + result, detection = lidar_detection.LidarDetection.create(angle=angle, distance=5.0) |
| 46 | + assert result, "Failed to create LidarDetection" |
| 47 | + readings.append(detection) |
| 48 | + |
| 49 | + result, oscillation = lidar_oscillation.LidarOscillation.create(readings) |
| 50 | + assert result, "Failed to create LidarOscillation" |
| 51 | + assert oscillation is not None |
| 52 | + |
| 53 | + in_queue.queue.put(oscillation) |
| 54 | + |
| 55 | + result, populated_oscillation = lidar_oscillation.LidarOscillation.create( |
| 56 | + [ |
| 57 | + lidar_detection.LidarDetection.create(angle=angle, distance=50.0)[1] |
| 58 | + for angle in range(-90, 95, 5) |
| 59 | + ] |
| 60 | + ) |
| 61 | + assert result, "Failed to create a blank LidarOscillation" |
| 62 | + assert populated_oscillation is not None |
| 63 | + |
| 64 | + in_queue.queue.put(populated_oscillation) |
| 65 | + |
| 66 | + |
| 67 | +def main() -> int: |
| 68 | + """ |
| 69 | + Main function for the VFH integration test. |
| 70 | + """ |
| 71 | + # Setup |
| 72 | + controller = worker_controller.WorkerController() |
| 73 | + mp_manager = mp.Manager() |
| 74 | + |
| 75 | + oscillation_in_queue = queue_wrapper.QueueWrapper(mp_manager, QUEUE_MAX_SIZE) |
| 76 | + |
| 77 | + vfh_instance = vfh.VectorFieldHistogram( |
| 78 | + sector_width=SECTOR_WIDTH, |
| 79 | + max_vector_magnitude=MAX_VECTOR_MAGNITUDE, |
| 80 | + linear_decay_rate=LINEAR_DECAY_RATE, |
| 81 | + confidence_value=CONFIDENCE_VALUE, |
| 82 | + start_angle=START_ANGLE, |
| 83 | + end_angle=END_ANGLE, |
| 84 | + ) |
| 85 | + |
| 86 | + # Simulate LidarOscillation data |
| 87 | + simulate_oscillation_worker(oscillation_in_queue) |
| 88 | + |
| 89 | + # Test |
| 90 | + density_count = 0 |
| 91 | + while True: |
| 92 | + try: |
| 93 | + input_data: lidar_oscillation.LidarOscillation = oscillation_in_queue.queue.get_nowait() |
| 94 | + assert input_data is not None |
| 95 | + |
| 96 | + result, output_data = vfh_instance.run(input_data) |
| 97 | + assert result, "VFH computation failed" |
| 98 | + assert output_data is not None |
| 99 | + |
| 100 | + # Print detailed debug information |
| 101 | + print(f"PolarObstacleDensity {density_count + 1}:") |
| 102 | + print(f" Sectors: {len(output_data.sector_densities)}") |
| 103 | + print( |
| 104 | + f" Sector Densities: {[sector.density for sector in output_data.sector_densities]}" |
| 105 | + ) |
| 106 | + print(f" Angles: {[sector.angle_start for sector in output_data.sector_densities]}") |
| 107 | + |
| 108 | + density_count += 1 |
| 109 | + |
| 110 | + except queue.Empty: |
| 111 | + break |
| 112 | + |
| 113 | + assert density_count > 0, "No PolarObstacleDensity objects were processed" |
| 114 | + print(f"Total PolarObstacleDensities processed: {density_count}") |
| 115 | + |
| 116 | + # Teardown |
| 117 | + controller.request_exit() |
| 118 | + oscillation_in_queue.fill_and_drain_queue() |
| 119 | + |
| 120 | + return 0 |
| 121 | + |
| 122 | + |
| 123 | +if __name__ == "__main__": |
| 124 | + result_main = main() |
| 125 | + if result_main < 0: |
| 126 | + print(f"ERROR: Status code: {result_main}") |
| 127 | + |
| 128 | + print("Done!") |
0 commit comments