class SimWiring(): def __init__(self): self.globe = Globe() self.console_logger = self._console_logger() self.exchange = Exchange(self.console_logger) self.gps = SimulatedGPS(CHORLTON.position,0,0.1) self.vehicle = SimulatedVehicle(self.gps, self.globe,self.console_logger,single_step=False) self.timeshift = TimeShift(self.exchange,self.vehicle.timer.time) self.event_source = EventSource(self.exchange,self.vehicle.timer,self.console_logger,CONFIG['event source']) self.sensors = Sensors(self.vehicle.gps, self.vehicle.windsensor,self.vehicle.compass,self.vehicle.timer.time,self.exchange,self.console_logger,CONFIG['sensors']) self.steerer = Steerer(self.vehicle.rudder,self.console_logger,CONFIG['steerer']) self.helm = Helm(self.exchange, self.sensors, self.steerer, self.console_logger, CONFIG['helm']) self.course_steerer = CourseSteerer(self.sensors,self.helm,self.vehicle.timer, CONFIG['course steerer']) self.navigator_simulator = Navigator(self.sensors,self.globe,self.exchange,self.console_logger,CONFIG['navigator']) self.tracking_timer = Timer() self.tracker_simulator = Tracker(self.console_logger,self.sensors,self.tracking_timer) def _console_logger(self): logging.basicConfig(format=LOGGING_FORMAT, level=CONFIG['wiring']['logging level']) return logging.getLogger("simulate") def _follower(self,waypoints): self.follower_simulator = Follower(self.exchange,waypoints,self.console_logger) return self.follower_simulator def follow(self,waypoints): self.gps.set_position(waypoints[0].position,0,0.8,True) self.vehicle.position = waypoints[0].position self.follower_simulator = self._follower(waypoints) self.event_source.start()
class TestFollower(unittest.TestCase): def setUp(self): self.mock_logger = Mock() self.mock_logger.error = Mock(side_effect=print_msg) self.exchange = Exchange(self.mock_logger) self.timer = StubTimer() self.timeshift = TimeShift(self.exchange, self.timer.time) self.event_source = EventSource(self.exchange,self.timer,self.mock_logger,{'tick interval':0.2}) gps = FakeMovingGPS([Position(10,10),Position(11,11),Position(12,12),Position(13,13)]) self.navigator = Navigator(gps,Globe(),self.exchange,self.mock_logger, {'min time to steer': 5,'max time to steer': 20}) def test_should_navigate_along_list_of_waypoints_with_logging(self): waypoint1 = Waypoint(Position(11,11),10) waypoint2 = Waypoint(Position(13,13),10) follower = Follower(self.exchange,[waypoint1,waypoint2],self.mock_logger) self.event_source.start() self.mock_logger.info.assert_has_calls( [call('Follower, next waypoint +11.000000,+11.000000'), call('Navigator, steering to +11.000000,+11.000000, bearing 44.4, distance 155941.2m, review after 20s'), call('Navigator, arrived at +11.000000,+11.000000'), call('Follower, next waypoint +13.000000,+13.000000'), call('Navigator, steering to +13.000000,+13.000000, bearing 44.2, distance 155399.6m, review after 20s'), call('Navigator, arrived at +13.000000,+13.000000'), call('**************************************************************'), call('Follower, all waypoints reached, navigation complete'), call('**************************************************************')])
def test_should_publish_a_tick_event(self): self.listen(EventName.tick) self.timer.wait_for = Mock(side_effect=self.finish) event_source = EventSource(self.exchange, self.timer, self.mock_logger, CONFIG) event_source.start() self.assertEqual(self.last_listened_event.name,EventName.tick)
def test_should_publish_a_tick_event(self): self.listen(EventName.tick) self.timer.wait_for = Mock(side_effect=self.finish) event_source = EventSource(self.exchange, self.timer, self.mock_logger, CONFIG) event_source.start() self.assertEqual(self.last_listened_event.name, EventName.tick)
def test_should_publish_multiple_events_until_nav_complete(self): self.listen(EventName.tick) self.after(5,EventName.end) self.timer.wait_for = Mock(side_effect=self.count_down_ticks) event_source = EventSource(self.exchange,self.timer, self.mock_logger,CONFIG) event_source.start() self.assertEqual(self.event_count,5)
def test_should_publish_multiple_events_until_nav_complete(self): self.listen(EventName.tick) self.after(5, EventName.end) self.timer.wait_for = Mock(side_effect=self.count_down_ticks) event_source = EventSource(self.exchange, self.timer, self.mock_logger, CONFIG) event_source.start() self.assertEqual(self.event_count, 5)
def test_errors_should_be_logged_and_events_continue(self): self.listen(EventName.tick) self.after(2,EventName.end) self.timer.wait_for = Mock(side_effect=self.count_down_ticks) self.exchange.original_publish = self.exchange.publish self.exchange.publish = self.intercept_publish event_source = EventSource(self.exchange,self.timer, self.mock_logger,CONFIG) event_source.start() self.mock_logger.error.assert_has_calls([call('EventSource, RuntimeError: oops')]) self.assertEqual(self.event_count,2)
class TestFollower(unittest.TestCase): def setUp(self): self.mock_logger = Mock() self.mock_logger.error = Mock(side_effect=print_msg) self.exchange = Exchange(self.mock_logger) self.timer = StubTimer() self.timeshift = TimeShift(self.exchange, self.timer.time) self.event_source = EventSource(self.exchange, self.timer, self.mock_logger, {'tick interval': 0.2}) gps = FakeMovingGPS([ Position(10, 10), Position(11, 11), Position(12, 12), Position(13, 13) ]) self.navigator = Navigator(gps, Globe(), self.exchange, self.mock_logger, { 'min time to steer': 5, 'max time to steer': 20 }) def test_should_navigate_along_list_of_waypoints_with_logging(self): waypoint1 = Waypoint(Position(11, 11), 10) waypoint2 = Waypoint(Position(13, 13), 10) follower = Follower(self.exchange, [waypoint1, waypoint2], self.mock_logger) self.event_source.start() self.mock_logger.info.assert_has_calls([ call('Follower, next waypoint +11.000000,+11.000000'), call( 'Navigator, steering to +11.000000,+11.000000, bearing 44.4, distance 155941.2m, review after 20s' ), call('Navigator, arrived at +11.000000,+11.000000'), call('Follower, next waypoint +13.000000,+13.000000'), call( 'Navigator, steering to +13.000000,+13.000000, bearing 44.2, distance 155399.6m, review after 20s' ), call('Navigator, arrived at +13.000000,+13.000000'), call( '**************************************************************' ), call('Follower, all waypoints reached, navigation complete'), call( '**************************************************************' ) ])
def test_errors_should_be_logged_and_events_continue(self): self.listen(EventName.tick) self.after(2, EventName.end) self.timer.wait_for = Mock(side_effect=self.count_down_ticks) self.exchange.original_publish = self.exchange.publish self.exchange.publish = self.intercept_publish event_source = EventSource(self.exchange, self.timer, self.mock_logger, CONFIG) event_source.start() self.mock_logger.error.assert_has_calls( [call('EventSource, RuntimeError: oops')]) self.assertEqual(self.event_count, 2)
def test_errors_during_logging_should_be_ignored_and_event_processing_continues(self): failing_logger = Mock() failing_logger.configure_mock(**{'error.side_effect': RuntimeError}) self.listen(EventName.tick) self.after(2,EventName.end) self.timer.wait_for = Mock(side_effect=self.count_down_ticks) self.exchange.original_publish = self.exchange.publish self.exchange.publish = self.intercept_publish event_source = EventSource(self.exchange,self.timer, failing_logger,CONFIG) event_source.start() failing_logger.error.assert_has_calls([call('EventSource, RuntimeError: oops')]) self.assertEqual(self.event_count,2)
def test_errors_during_logging_should_be_ignored_and_event_processing_continues( self): failing_logger = Mock() failing_logger.configure_mock(**{'error.side_effect': RuntimeError}) self.listen(EventName.tick) self.after(2, EventName.end) self.timer.wait_for = Mock(side_effect=self.count_down_ticks) self.exchange.original_publish = self.exchange.publish self.exchange.publish = self.intercept_publish event_source = EventSource(self.exchange, self.timer, failing_logger, CONFIG) event_source.start() failing_logger.error.assert_has_calls( [call('EventSource, RuntimeError: oops')]) self.assertEqual(self.event_count, 2)
class Wiring(): def __init__(self, gps=False, servo_port=SERVO_PORT): # devices self._gps = gps self.windsensor = WindSensor(I2C(WINDSENSOR_I2C_ADDRESS)) self.compass = Compass(I2C(COMPASS_I2C_ADDRESS), I2C(ACCELEROMETER_I2C_ADDRESS)) self.red_led = GpioWriter(17, os) self.green_led = GpioWriter(18, os) # Navigation self.globe = Globe() self.timer = Timer() self.application_logger = self._rotating_logger(APPLICATION_NAME) self.position_logger = self._rotating_logger("position") self.exchange = Exchange(self.application_logger) self.timeshift = TimeShift(self.exchange, self.timer.time) self.event_source = EventSource(self.exchange, self.timer, self.application_logger, CONFIG['event source']) self.sensors = Sensors(self.gps, self.windsensor, self.compass, self.timer.time, self.exchange, self.position_logger, CONFIG['sensors']) self.gps_console_writer = GpsConsoleWriter(self.gps) self.rudder_servo = Servo(serial.Serial(servo_port), RUDDER_SERVO_CHANNEL, RUDDER_MIN_PULSE, RUDDER_MIN_ANGLE, RUDDER_MAX_PULSE, RUDDER_MAX_ANGLE) self.steerer = Steerer(self.rudder_servo, self.application_logger, CONFIG['steerer']) self.helm = Helm(self.exchange, self.sensors, self.steerer, self.application_logger, CONFIG['helm']) self.course_steerer = CourseSteerer(self.sensors, self.helm, self.timer, CONFIG['course steerer']) self.navigator = Navigator(self.sensors, self.globe, self.exchange, self.application_logger, CONFIG['navigator']) self.self_test = SelfTest(self.red_led, self.green_led, self.timer, self.rudder_servo, RUDDER_MIN_ANGLE, RUDDER_MAX_ANGLE) # Tracking self.tracking_logger = self._rotating_logger("track") self.tracking_sensors = Sensors(self.gps, self.windsensor, self.compass, self.timer.time, self.exchange, self.tracking_logger, CONFIG['sensors']) self.tracker = Tracker(self.tracking_logger, self.tracking_sensors, self.timer) def _rotating_logger(self, appname): logHandler = TimedRotatingFileHandler("/var/log/pi-nav/" + appname, when="midnight", backupCount=30) logHandler.setFormatter(logging.Formatter(LOGGING_FORMAT)) logger = logging.getLogger(appname) logger.addHandler(logHandler) logger.setLevel(CONFIG['wiring']['logging level']) return logger @property def gps(self): if not self._gps: self._gps = GpsReader() self._gps.setDaemon(True) self._gps.start() return self._gps def showgps(self): try: self.timer.call(self.gps_console_writer.write).every(5) except (KeyboardInterrupt, SystemExit): self.gps.running = False self.gps.join() def follow(self, waypoints): self.application_logger.info( '**************************************************************') self.application_logger.info( '*** Pi-Nav starting navigation: ' + datetime.datetime.now().strftime("%Y-%m-%d")) self.application_logger.info( '**************************************************************') self.self_test.run() self.rudder_servo.set_position(0) self.follower = Follower(self.exchange, waypoints, self.application_logger) self.event_source.start() def track(self): self.self_test.run() self.tracker.track(10)
class Wiring(): def __init__(self,gps=False,servo_port=SERVO_PORT): # devices self._gps = gps self.windsensor = WindSensor(I2C(WINDSENSOR_I2C_ADDRESS)) self.compass = Compass(I2C(COMPASS_I2C_ADDRESS),I2C(ACCELEROMETER_I2C_ADDRESS)) self.red_led = GpioWriter(17,os) self.green_led = GpioWriter(18,os) # Navigation self.globe = Globe() self.timer = Timer() self.application_logger = self._rotating_logger(APPLICATION_NAME) self.position_logger = self._rotating_logger("position") self.exchange = Exchange(self.application_logger) self.timeshift = TimeShift(self.exchange,self.timer.time) self.event_source = EventSource(self.exchange,self.timer,self.application_logger,CONFIG['event source']) self.sensors = Sensors(self.gps,self.windsensor,self.compass,self.timer.time,self.exchange,self.position_logger,CONFIG['sensors']) self.gps_console_writer = GpsConsoleWriter(self.gps) self.rudder_servo = Servo(serial.Serial(servo_port),RUDDER_SERVO_CHANNEL,RUDDER_MIN_PULSE,RUDDER_MIN_ANGLE,RUDDER_MAX_PULSE,RUDDER_MAX_ANGLE) self.steerer = Steerer(self.rudder_servo,self.application_logger,CONFIG['steerer']) self.helm = Helm(self.exchange,self.sensors,self.steerer,self.application_logger,CONFIG['helm']) self.course_steerer = CourseSteerer(self.sensors,self.helm,self.timer,CONFIG['course steerer']) self.navigator = Navigator(self.sensors,self.globe,self.exchange,self.application_logger,CONFIG['navigator']) self.self_test = SelfTest(self.red_led,self.green_led,self.timer,self.rudder_servo,RUDDER_MIN_ANGLE,RUDDER_MAX_ANGLE) # Tracking self.tracking_logger = self._rotating_logger("track") self.tracking_sensors = Sensors(self.gps,self.windsensor,self.compass,self.timer.time,self.exchange,self.tracking_logger,CONFIG['sensors']) self.tracker = Tracker(self.tracking_logger,self.tracking_sensors,self.timer) def _rotating_logger(self,appname): logHandler = TimedRotatingFileHandler("/var/log/pi-nav/" + appname,when="midnight",backupCount=30) logHandler.setFormatter(logging.Formatter(LOGGING_FORMAT)) logger = logging.getLogger(appname) logger.addHandler( logHandler ) logger.setLevel( CONFIG['wiring']['logging level']) return logger @property def gps(self): if not self._gps: self._gps = GpsReader() self._gps.setDaemon(True) self._gps.start() return self._gps def showgps(self): try: self.timer.call(self.gps_console_writer.write).every(5) except (KeyboardInterrupt, SystemExit): self.gps.running = False self.gps.join() def follow(self,waypoints): self.application_logger.info('**************************************************************') self.application_logger.info('*** Pi-Nav starting navigation: ' + datetime.datetime.now().strftime("%Y-%m-%d")) self.application_logger.info('**************************************************************') self.self_test.run() self.rudder_servo.set_position(0) self.follower = Follower(self.exchange,waypoints,self.application_logger) self.event_source.start() def track(self): self.self_test.run() self.tracker.track(10)