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 __init__(self, speed=0.15, lane_offset=140, wait_period=10, hard_coded_turns=True): self.hard_coded_turns = hard_coded_turns self.speed = speed self.pid = SteeringPid(lane_offset, kp=0.1, ki=0.006, kd=1.2) self.intersections_pid = SteeringPid(1, kp=0.1, ki=0.006, kd=1.2) self.current_turn = None self.current_turn_direction = None self.handling_intersection = False self.inter_start_time = time.time() self.go_straight = False self.angle = 0 self.waypoint = Waypoint() self.car = Car_Control() self.detector = Image_Process() self.vs = cv2.VideoCapture( "/dev/video2", cv2.CAP_V4L) # TODO: figure out a good way to do this self.intersections = Intersections(wait_period=wait_period) self.pipeline = rs.pipeline() self.config = rs.config() self.config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30) self.pipeline.start(self.config)
def test_with_multiple_obstacles(self): grid = np.zeros((20, 20)).astype(np.bool) grid[3:4, 0:15] = True grid[13:14, 5:20] = True queries = [[Waypoint(0, 0, 0), Waypoint(19, 19, 3)]] self._run_test(grid, queries)
def add_waypoint(self, waypoint: Waypoint) -> None: with self.waypoints_lock: orig_pos = Position(lat=waypoint.lat, lon=waypoint.lon) adjusted_position, path = self.map.closest_point(orig_pos) waypoint.path = path waypoint.lat = adjusted_position.lat waypoint.lon = adjusted_position.lon self.waypoints.append(waypoint) self.on_waypoint_change()
def test_with_no_solution(self): grid = np.zeros((20, 20)).astype(np.bool) grid[15:16, 0:10] = True grid[15:20, 10:11] = True queries = [ [Waypoint(0, 0, 0), Waypoint(19, 2, 3)] ] self._run_test_with_no_solution(grid, queries)
def __init__(self, filename=None, data_path=None): # Based in Django's approach -> http://code.djangoproject.com/svn/django/trunk/django/__init__.py self.version = __import__('pytrainer').get_version() #Process command line options self.startup_options = self.get_options() #Setup logging self.environment = Environment(platform.get_platform(), self.startup_options.conf_dir) self.environment.create_directories() self.set_logging(self.startup_options.log_level, self.startup_options.log_type) logging.debug('>>') logging.debug("pytrainer version %s" % (self.version)) self.data_path = data_path self.date = Date() self.ddbb = None # Checking profile logging.debug('Checking configuration and profile...') self.profile = Profile(self.environment, self.data_path, self) self.uc = UC() self.windowmain = None self.ddbb = DDBB(self.profile, self) logging.debug('connecting to DDBB') self.ddbb.connect() initialize_data(self.ddbb, self.environment.conf_dir) self._sport_service = SportService(self.ddbb) self.record = Record(self._sport_service, data_path, self) self.athlete = Athlete(data_path, self) self.stats = Stats(self._sport_service, self) pool_size = self.profile.getIntValue("pytraining", "activitypool_size", default=1) self.activitypool = ActivityPool(self, size=pool_size) #preparamos la ventana principal self.windowmain = Main(self._sport_service, data_path, self, self.version, gpxDir=self.profile.gpxdir) self.date = Date(self.windowmain.calendar) self.waypoint = Waypoint(data_path, self) self.extension = Extension(data_path, self) self.plugins = Plugins(data_path, self) self.importdata = Importdata(self._sport_service, data_path, self, self.profile) self.loadPlugins() self.loadExtensions() self.windowmain.setup() self.windowmain.on_calendar_selected(None) self.refreshMainSportList() self.windowmain.run() logging.debug('<<')
def test_should_navigate_to_the_next_waypoint_when_a_waypoint_is_reached( self): self.listen(EventName.navigate) waypoint1 = Waypoint(Position(1, 1), 5) waypoint2 = Waypoint(Position(2, 2), 5) follower = Follower(self.exchange, [waypoint1, waypoint2], self.mock_logger) self.exchange.publish(Event(EventName.start)) self.exchange.publish(Event(EventName.arrived, waypoint1)) self.assertEqual(self.last_event.waypoint, waypoint2)
def receiveMissionItem(self, msg): self.numberOfonboardWP += 1 wp = Waypoint(msg.seq, msg.x, msg.y, msg.z) wp.waypointType = msg.command self.onboardWP.append(wp) if self.numberOfonboardWP < self.onboardWPCount: self.connection.waypoint_request_send( self.numberOfonboardWP) # read next one else: self.newTextMessageSignal.emit( 'Total {} waypoint(s) onboard'.format(len(self.onboardWP))) self.onboardWaypointsReceivedSignal.emit( self.onboardWP) # all done, send signal
def load_persistent(self): try: file = open(os.path.join(self.settingsdir,'persist.xml'), 'r') doc = xml.parse(file) if doc.documentElement.tagName == 'session': waypoint_list = doc.getElementsByTagName('waypoints')[0] sources = waypoint_list.getElementsByTagName('source') for source in sources: currentSource = Source(source.getAttribute('type')) if currentSource.name == "Manual Waypoints": self.manualSource = currentSource sourceIter = self.wpList.append(None,(currentSource,)) waypoints=source.getElementsByTagName('wp') for waypoint in waypoints: wp=Waypoint() name_element = \ waypoint.getElementsByTagName('name')[0] lat_element = \ waypoint.getElementsByTagName('latitude')[0] lon_element = \ waypoint.getElementsByTagName('longitude')[0] alt_element = \ waypoint.getElementsByTagName('altitude')[0] wp.name = string.strip(name_element.firstChild.data) wp.lat=float(lat_element.firstChild.data) wp.lon=float(lon_element.firstChild.data) wp.alt=float(alt_element.firstChild.data) #print '---'+wp.name #Append Waypoint to correct Source Object self.wpList.append(sourceIter,(wp,)) #if document is empty or contains garbage raise IOError after cleaning up else: doc.unlink() file.close() raise IOError doc.unlink() file.close() return True except(IOError): #The File is not available for reading so insert standard Source into the list currentSource = Source('Manual Waypoints') self.manualSource = currentSource self.wpList.append(None,(currentSource,)) return False
def test_with_complex_obstacles(self): grid = np.zeros((20, 20)).astype(np.bool) grid[3:4, 5:20] = True grid[7:8, 0:15] = True grid[13:14, 5:20] = True grid[11:14, 4:5] = True grid[14:17, 7:8] = True grid[15:20, 12:13] = True queries = [ [Waypoint(0, 0, 0), Waypoint(19, 19, 3)] ] self._run_test(grid, queries)
def compute_man2(data): glob = ["E", "N", "S", "W"] loc = ["L", "R"] ship = Ship() waypoint = Waypoint() for dire in data: print(f"Waypoint Position: {waypoint.get_x()},{waypoint.get_y()}") if dire[0] in glob: waypoint.shift(dire[0], dire[1]) elif dire[0] in loc: waypoint.rotate(dire[0], dire[1]) elif dire[0] == "F": x = waypoint.get_x() * dire[1] y = waypoint.get_y() * dire[1] ship.alter_global("E", x) ship.alter_global("N", y) print(ship.compute_man())
def test_with_random_obstacle(self): grid = np.zeros((20, 20)).astype(np.bool) for variable in range(1,4): rand_a = random.randint(1, 10) rand_b = random.randint(0, 5) rand_c = random.randint(5, 10) rand_d = random.randint(0, 5) grid[rand_a:rand_a + rand_b, rand_c:rand_c + rand_d] = True queries = [ [Waypoint(0, 0, 0), Waypoint(19, 19, 3)], ] self._run_test(grid, queries)
def load_from_msg(self, msg): """[Load from PoseArray] Args: msg ([type]): [description] """ self.clearall() frame_id = msg.header.frame_id wp_pose = PoseStamped() wp_pose.header.frame_id = frame_id for pose in msg.poses: wp = Waypoint() wp_pose.pose = pose wp.load_from_msg(deepcopy(wp_pose)) self.append(wp)
def __init__(self, file): try: self.filename = file.name except AttributeError: self.filename = '(unknown)' element = parse(file) namespace = re.match('\{(.*)\}', element.getroot().tag).group(1) ele_tag_name = '{%s}ele' % namespace name_tag_name = '{%s}name' % namespace time_tag_name = '{%s}time' % namespace self.coords = [] for trkpt in element.findall('/{%s}trk/{%s}trkseg/{%s}trkpt' % (namespace, namespace, namespace)): lat = math.pi * float(trkpt.get('lat')) / 180.0 lon = math.pi * float(trkpt.get('lon')) / 180.0 ele_tag = trkpt.find(ele_tag_name) ele = 0 if ele_tag is None else float(ele_tag.text) time = trkpt.find(time_tag_name) if time is None: continue dt = datetime.strptime(time.text, GPX_DATETIME_FORMAT) coord = Coord(lat, lon, ele, dt) self.coords.append(coord) self.waypoints = [] for wpt in element.findall('/{%s}wpt' % namespace): name = wpt.find(name_tag_name).text lat = math.pi * float(wpt.get('lat')) / 180.0 lon = math.pi * float(wpt.get('lon')) / 180.0 ele_tag = wpt.find(ele_tag_name) ele = 0 if ele_tag is None else float(ele_tag.text) waypoint = Waypoint(name, lat, lon, ele) self.waypoints.append(waypoint)
def test_should_steer_repeatedly_during_navigation(self): logger = Mock() destination = Waypoint(Position(10.0003, 10.0003), 10) gps = FakeMovingGPS([ Position(10, 10), Position(10.0001, 10.00015), Position(10.00025, 10.0002), Position(10.0003, 10.0003) ]) sensors = FakeSensors(gps, 1, 45) steerer = Steerer(self.servo, logger, CONFIG['steerer']) helm = Helm(self.exchange, sensors, steerer, logger, CONFIG['helm']) navigator = Navigator(sensors, Globe(), self.exchange, logger, CONFIG['navigator']) self.exchange.publish(Event(EventName.navigate, waypoint=destination)) self.ticks(number=7, duration=20) logger.debug.assert_has_calls([ call( 'Navigator, distance from waypoint +46.819018, combined tolerance +10.000000' ), call( 'Navigator, distance from waypoint +27.647432, combined tolerance +10.000000' ), call( 'Steerer, steering 36.4, heading 45.0, rate of turn +1.0, rudder +0.0, new rudder +4.6' ), call( 'Steerer, steering 36.4, heading 45.0, rate of turn +1.0, rudder +4.6, new rudder +9.2' ), call( 'Navigator, distance from waypoint +12.281099, combined tolerance +10.000000' ), call( 'Steerer, steering 63.1, heading 45.0, rate of turn +1.0, rudder +9.2, new rudder +0.4' ), call( 'Navigator, distance from waypoint +0.000000, combined tolerance +10.000000' ), call( 'Steerer, steering 63.1, heading 45.0, rate of turn +1.0, rudder +0.4, new rudder -8.3' ), call( 'Steerer, steering 63.1, heading 45.0, rate of turn +1.0, rudder -8.3, new rudder -17.1' ) ]) logger.info.assert_has_calls([ call( 'Navigator, steering to +10.000300,+10.000300, bearing 44.6, distance 46.8m, review after 23s' ), call( 'Navigator, steering to +10.000300,+10.000300, bearing 36.4, distance 27.6m, review after 13s' ), call( 'Navigator, steering to +10.000300,+10.000300, bearing 63.1, distance 12.3m, review after 6s' ), call('Navigator, arrived at +10.000300,+10.000300') ])
def test_should_navigate_to_next_waypoint_with_kink_in_route(self): destination = Waypoint(Position(10.03, 10.03), 10) gps = FakeMovingGPS([ Position(10, 10), Position(10.01, 10.01), Position(10.025, 10.015), Position(10.03, 10.03) ]) sensors = FakeSensors(gps, 1, 45) steerer = Steerer(self.servo, self.logger, CONFIG['steerer']) helm = Helm(self.exchange, sensors, steerer, self.logger, CONFIG['helm']) navigator = Navigator(sensors, Globe(), self.exchange, self.logger, CONFIG['navigator']) self.exchange.publish(Event(EventName.navigate, waypoint=destination)) self.ticks(number=14, duration=200) self.logger.info.assert_has_calls([ call( 'Navigator, steering to +10.030000,+10.030000, bearing 44.6, distance 4681.8m, review after 600s' ), call( 'Navigator, steering to +10.030000,+10.030000, bearing 44.6, distance 3121.2m, review after 600s' ), call( 'Navigator, steering to +10.030000,+10.030000, bearing 71.3, distance 1734.0m, review after 600s' ), call('Navigator, arrived at +10.030000,+10.030000') ])
def iact31(self): self.write('ACT_31_00\r\n') line = self.readline() if line == 'No Data\r\n': return while True: if line == ' Done\r\n': break m = re.match( r'\A(.*?);([NS])\s+(\d+)\'(\d+\.\d+);([EW])\s+(\d+)\'(\d+\.\d+);\s*(\d+);\s*(\d+)\r\n', line) if m: name = m.group(1) lat = int(m.group(3)) + float(m.group(4)) / 60.0 if m.group(2) == 'S': lat = -lat lon = int(m.group(6)) + float(m.group(7)) / 60.0 if m.group(5) == 'W': lon = -lon alt = int(m.group(8)) radius = int(m.group(9)) yield Waypoint(name, lat, lon, alt, radius=radius) else: raise ProtocolError('unexpected response %r' % line) line = self.readline()
def generate_circle(self, radius, center, num_points, max_forward_speed, theta_offset=0.0, heading_offset=0.0, append=False): if radius <= 0: print 'Invalid radius, value=', radius return False if num_points <= 0: print 'Invalid number of samples, value=', num_points return False if max_forward_speed <= 0: print 'Invalid absolute maximum velocity, value=', max_forward_speed return False if not append: # Clear current list self.clear_waypoints() step_theta = 2 * np.pi / num_points for i in range(num_points): angle = i * step_theta + theta_offset x = np.cos(angle) * radius + center.x y = np.sin(angle) * radius + center.y z = center.z wp = Waypoint(x, y, z, max_forward_speed, heading_offset) self.add_waypoint(wp) return True
def __init__(self, ORB): self.ORB = ORB logger.info('Drone Type:{}'.format(config.drone['UAV'])) logger.info('MainController:{}'.format(config.drone['MainController'])) self._model = config.drone['Model'] # Aileron :[No.ch, low ,mid, high ,var, sign, rate] self.AIL = config.channels['AIL'] # Elevator:[No.ch, low ,mid, high ,var, sign, rate] self.ELE = config.channels['ELE'] # Throttle:[No.ch, low ,mid, high ,var, sign, rate] self.THR = config.channels['THR'] # Rudder :[No.ch, low ,mid, high ,var, sign, rate] self.RUD = config.channels['RUD'] # Mode :[No.ch , low , Loiter, high] self.mode = config.channels['Mode'] if config.drone['Model'] == 'HELI': # GYRO Rate :[No.ch , 0 , pwm] self.Rate = config.channels['Rate'] # PITCH :[No.ch , 0 , pwm] self.PIT = config.channels['PIT'] else: # Aux1 :[No.ch , 0 , pwm] self.Aux1 = config.channels['Aux1'] # Aux2 :[No.ch , 0 , pwm] self.Aux2 = config.channels['Aux2'] # Switch :[No.ch , 0 , pwm] self.Switch = config.channels['Switch'] self.wp = Waypoint(ORB) self.update_home() self.init_altitude()
def test_should_signal_a_navigate_event_using_the_first_waypoint(self): self.listen(EventName.navigate) firstwaypoint = Waypoint(Position(1, 1), 5) follower = Follower(self.exchange, [firstwaypoint], self.mock_logger) self.exchange.publish(Event(EventName.start)) self.assertEqual(self.last_event.name, EventName.navigate) self.assertEqual(self.last_event.waypoint, firstwaypoint)
def post_waypoint() -> str: post = request.get_json() if request.is_json else json.loads( request.get_data()) position = post['position'] lat = position['latitude'] lon = position['longitude'] controller.add_waypoint(Waypoint(x=lon, y=lat)) return '{"status": "success"}'
def test_should_steer_to_waypoint_if_outside_tolerance(self): self.listen(EventName.set_course) waypoint = Waypoint(Position(53.0001,-1.9999),5) expected_bearing = self.globe.bearing(self.current_position,waypoint.position) navigator = self.new_navigator(self.mock_gps) self.exchange.publish(Event(EventName.navigate,waypoint)) self.assertEqual(self.event_count(EventName.set_course),1,"expected set course event following navigate") self.assertEqual(self.last_event.heading,expected_bearing)
def get_valid_neighbours(self,current, grid): valid_neighbours = [] for i in [0,1,-1]: for j in [0,1,-1]: for k in [0,1,2,3]: new_waypoint = Waypoint(current.x + i, current.y + j, (current.orientation + k) % 4) if pv.is_valid_waypoint(new_waypoint, grid) and pv.is_valid_transition(current, new_waypoint): valid_neighbours.append(new_waypoint) return valid_neighbours
def test_should_not_steer_and_log_arrival_if_arrived(self): self.listen(EventName.arrived) self.listen(EventName.set_course) navigator = self.new_navigator(self.mock_gps) self.exchange.publish(Event(EventName.navigate,Waypoint(self.current_position,0))) self.assertEqual(self.event_count(EventName.set_course),0,"expected no event to set course if we have arrived") self.assertEqual(self.event_count(EventName.arrived),1,"expected arrived event if we have arrived") self.mock_logger.info.assert_called_with('Navigator, arrived at {:+f},{:+f}'.format(self.current_position.latitude,self.current_position.longitude))
def test_should_allow_a_tolerance_and_consider_errors_when_calculating_if_we_have_reached_waypoint(self): self.listen(EventName.arrived) self.listen(EventName.set_course) waypoint = Waypoint(Position(53.0001,-1.9999),10) navigator = self.new_navigator(self.mock_gps) self.exchange.publish(Event(EventName.navigate,waypoint)) self.assertEqual(self.event_count(EventName.arrived),1,"expected arrived event if we have arrived") self.mock_logger.info.assert_called_with('Navigator, arrived at {:+f},{:+f}'.format(waypoint.latitude,waypoint.longitude))
def test_should_use_minimum_steer_time_if_time_calculation_returns_small_value(self): self.listen(EventName.after) waypoint = Waypoint(Position(53.0001,-1.9999),5) fake_gps = FakeMovingGPS([self.current_position, waypoint.position]) fake_gps.speed = 100 navigator = self.new_navigator(fake_gps) self.exchange.publish(Event(EventName.navigate,waypoint)) self.assertEqual(self.last_event.seconds,MIN_TIME_TO_STEER)
def load_from_file(self, filename): try: file = open(filename, 'r') doc = xml.parse(file) currentSource = Source(os.path.basename(filename)) sourceIter = self.wpList.append(None,(currentSource,)) if doc.documentElement.tagName == 'gpx': waypoints = doc.getElementsByTagName('wpt') for waypoint in waypoints: wp=Waypoint() wp.lat=float(waypoint.getAttribute('lat')) wp.lon=float(waypoint.getAttribute('lon')) alt_element = \ waypoint.getElementsByTagName('ele') if alt_element.length > 0: wp.alt=float(alt_element[0].firstChild.data) name_element = \ waypoint.getElementsByTagName('name') if name_element.length > 0: wp.name = string.strip(name_element[0].firstChild.data) #Append Waypoint to correct Source Object self.wpList.append(sourceIter,(wp,)) #if document is empty or contains garbage raise IOError after cleaning up else: doc.unlink() file.close() raise IOError doc.unlink() file.close() return True except(IOError): return False
def test_should_use_a_minimum_speed_for_calculation_preventing_divide_by_zero_error(self): self.listen(EventName.after) waypoint = Waypoint(Position(53.001,-2.001),5) fake_gps = FakeMovingGPS([self.current_position, waypoint.position]) fake_gps.speed = 0 expected_time = expected_time_to_steer(self.current_position,waypoint.position,0.01) navigator = self.new_navigator(fake_gps) self.exchange.publish(Event(EventName.navigate,waypoint)) self.assertEqual(self.last_event.seconds,expected_time)
def test_should_use_maximum_steer_time_if_its_a_long_way_to_go(self): self.listen(EventName.after) waypoint = Waypoint(Position(60.0001,10),5) fake_gps = FakeMovingGPS([self.current_position, waypoint.position]) fake_gps.speed = 1 expected_bearing = self.globe.bearing(self.current_position,waypoint.position) navigator = self.new_navigator(fake_gps) self.exchange.publish(Event(EventName.navigate,waypoint)) self.assertEqual(self.last_event.seconds,MAX_TIME_TO_STEER)
def poll_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: raise InterruptedError('Program closed by user') elif event.type == pygame.KEYDOWN and event.key == pygame.K_a: self.draw_adjusted = not self.draw_adjusted elif event.type == pygame.KEYDOWN and event.key == pygame.K_s: self.draw_exact = not self.draw_exact elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: x, y = pygame.mouse.get_pos() x, y = self.cart_to_coords(x, y) self.add_waypoint(Waypoint(x, y))
def _create_waypoints_collection(self): waypoints = [self.start_waypoint()] if isinstance(self.primitive(), Path): lane = self.start_waypoint().lane() road_node = self.start_waypoint().road_node() for element in self.primitive(): new_waypoint = Waypoint(lane, element.end_point(), element.end_heading(), road_node) waypoints.append(new_waypoint) waypoints.pop(-1) waypoints.append(self.end_waypoint()) return waypoints
def ipbrwps(self): for m in self.ieach('PBRWPS,', PBRWPS_RE): lat = int(m.group(1)) + float(m.group(2)) / 60 if m.group(3) == 'S': lat *= -1 lon = int(m.group(4)) + float(m.group(5)) / 60 if m.group(6) == 'W': lon *= -1 id = m.group(7) name = m.group(8) alt = int(m.group(9)) yield Waypoint(name, lat, lon, alt, id=id)
def __init__(self,filename = None, data_path = None): #Version constants self.version ="1.10.0-dev" #Process command line options self.startup_options = self.get_options() #Setup logging self.environment = Environment(platform.get_platform(), self.startup_options.conf_dir) self.environment.create_directories() self.set_logging(self.startup_options.log_level, self.startup_options.log_type) logging.debug('>>') logging.debug("PyTrainer version %s" % (self.version)) self.data_path = data_path self.date = Date() self.ddbb = None # Checking profile logging.debug('Checking configuration and profile...') self.profile = Profile(self.environment, self.data_path,self) self.uc = UC() self.windowmain = None self.ddbb = DDBB(self.profile, self) logging.debug('connecting to DDBB') self.ddbb.connect() initialize_data(self.ddbb, self.environment.conf_dir) self._sport_service = SportService(self.ddbb) self.record = Record(self._sport_service, data_path, self) self.athlete = Athlete(data_path,self) self.stats = Stats(self._sport_service, self) pool_size = self.profile.getIntValue("pytraining","activitypool_size", default=1) self.activitypool = ActivityPool(self, size=pool_size) #preparamos la ventana principal self.windowmain = Main(self._sport_service, data_path,self,self.version, gpxDir=self.profile.gpxdir) self.date = Date(self.windowmain.calendar) self.waypoint = Waypoint(data_path,self) self.extension = Extension(data_path, self) self.plugins = Plugins(data_path, self) self.importdata = Importdata(self._sport_service, data_path, self, self.profile) self.loadPlugins() self.loadExtensions() self.windowmain.setup() self.windowmain.on_calendar_selected(None) self.refreshMainSportList() self.windowmain.run() logging.debug('<<')
def add_waypoint_from_msg(self, msg): waypoint = Waypoint() waypoint.from_message(msg) return self.add_waypoint(waypoint)
class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants self.version ="1.10.0-dev" #Process command line options self.startup_options = self.get_options() #Setup logging self.environment = Environment(platform.get_platform(), self.startup_options.conf_dir) self.environment.create_directories() self.set_logging(self.startup_options.log_level, self.startup_options.log_type) logging.debug('>>') logging.debug("PyTrainer version %s" % (self.version)) self.data_path = data_path self.date = Date() self.ddbb = None # Checking profile logging.debug('Checking configuration and profile...') self.profile = Profile(self.environment, self.data_path,self) self.uc = UC() self.windowmain = None self.ddbb = DDBB(self.profile, self) logging.debug('connecting to DDBB') self.ddbb.connect() initialize_data(self.ddbb, self.environment.conf_dir) self._sport_service = SportService(self.ddbb) self.record = Record(self._sport_service, data_path, self) self.athlete = Athlete(data_path,self) self.stats = Stats(self._sport_service, self) pool_size = self.profile.getIntValue("pytraining","activitypool_size", default=1) self.activitypool = ActivityPool(self, size=pool_size) #preparamos la ventana principal self.windowmain = Main(self._sport_service, data_path,self,self.version, gpxDir=self.profile.gpxdir) self.date = Date(self.windowmain.calendar) self.waypoint = Waypoint(data_path,self) self.extension = Extension(data_path, self) self.plugins = Plugins(data_path, self) self.importdata = Importdata(self._sport_service, data_path, self, self.profile) self.loadPlugins() self.loadExtensions() self.windowmain.setup() self.windowmain.on_calendar_selected(None) self.refreshMainSportList() self.windowmain.run() logging.debug('<<') def get_options(self): ''' Define usage and accepted options for command line startup returns: options - dict with option: value pairs ''' usage = '''usage: %prog [options] For more help on valid options try: %prog -h ''' parser = OptionParser(usage=usage) parser.set_defaults(log_level=logging.ERROR, validate=False, equip=False, newgraph=True, conf_dir=None, log_type="file") parser.add_option("-d", "--debug", action="store_const", const=logging.DEBUG, dest="log_level", help="enable logging at debug level") parser.add_option("-i", "--info", action="store_const", const=logging.INFO, dest="log_level", help="enable logging at info level") parser.add_option("-w", "--warn", action="store_const", const=logging.WARNING, dest="log_level", help="enable logging at warning level") parser.add_option("--valid", action="store_true", dest="validate", help="enable validation of files imported by plugins (details at info or debug logging level) - note plugin must support validation") parser.add_option("--oldgraph", action="store_false", dest="newgraph", help="Turn off new graphing approach") parser.add_option("--newgraph", action="store_true", dest="newgraph", help="Deprecated Option: Turn on new graphing approach") parser.add_option("--confdir", dest="conf_dir", help="Specify the directory where application configuration will be stored.") parser.add_option("--logtype", dest="log_type", metavar="TYPE", type="choice" , choices=["file", "console"], help="Specify where logging should be output to. TYPE is one of 'file' (default), or 'console'.") (options, args) = parser.parse_args() return options def set_logging(self, level, log_type): '''Setup rotating log file with customized format''' if("console" == log_type): handler = logging.StreamHandler(sys.stdout) else: handler = logging.handlers.RotatingFileHandler(self.environment.log_file, maxBytes=100000, backupCount=5) formatter = logging.Formatter('%(asctime)s|%(levelname)s|%(module)s|%(funcName)s|%(message)s') handler.setFormatter(formatter) logging.getLogger('').addHandler(handler) self.set_logging_level(self.startup_options.log_level) def set_logging_level(self, level): '''Set level of information written to log''' logging.debug("Setting logger to level: "+ str(level)) logging.getLogger('').setLevel(level) def quit(self): logging.debug('--') logging.info("Exit!") #self.webservice.stop() self.windowmain.gtk_main_quit() logging.shutdown() sys.exit() # Any nonzero value is considered "abnormal termination" by shells and the like def loadPlugins(self): logging.debug('>>') activeplugins = self.plugins.getActivePlugins() if (len(activeplugins)<1): logging.info("No active plugins") else: for plugin in activeplugins: txtbutton = self.plugins.loadPlugin(plugin) self.windowmain.addImportPlugin(txtbutton) logging.debug('<<') def loadExtensions(self): logging.debug('>>') activeextensions = self.extension.getActiveExtensions() if (len(activeextensions)<1): logging.info("No active extensions") else: for extension in activeextensions: txtbutton = self.extension.loadExtension(extension) self.windowmain.addExtension(txtbutton) logging.debug('<<') def runPlugin(self,widget,pathPlugin): logging.debug('>>') self.pluginClass = self.plugins.importClass(pathPlugin) pluginFiles = self.pluginClass.run() if pluginFiles is not None: logging.debug("Plugin returned %d files" % (len(pluginFiles)) ) #process returned GPX files for (pluginFile, sport) in pluginFiles: if os.path.isfile(pluginFile): logging.info('File exists. Size: %d. Sport: %s' % (os.path.getsize(pluginFile), sport)) if self.record.importFromGPX(pluginFile, sport) is None: logging.error("Error importing file "+pluginFile) else: logging.error('File '+pluginFile+' not valid') else: logging.debug("No files returned from Plugin") self.refreshListRecords() self.refreshGraphView("day") logging.debug('<<') def runExtension(self,extension,id): logging.debug('>>') #print("Extension id: %s" % str(id)) activity = self.activitypool.get_activity(id) txtbutton,pathExtension,type = extension self.extensionClass = self.extension.importClass(pathExtension) self.extensionClass.run(id, activity) #if type == "record": # #Si es record le tenemos que crear el googlemaps, el gpx y darle el id de la bbdd # alert = self.extension.runExtension(pathExtension,id) logging.debug('<<') def refreshMainSportList(self): logging.debug('>>') sports = self._sport_service.get_all_sports() self.windowmain.updateSportList(sports) logging.debug('<<') def refreshGraphView(self, view, sport=None): logging.debug('>>') if self.windowmain is None: logging.debug("First call to refreshGraphView") logging.debug('<<') return date_selected = self.date.getDate() if view=="record": logging.debug('record view') if self.windowmain.recordview.get_current_page()==0: self.refreshRecordGraphView("info") elif self.windowmain.recordview.get_current_page()==1: self.refreshRecordGraphView("graphs") elif self.windowmain.recordview.get_current_page()==2: self.refreshRecordGraphView("map") elif self.windowmain.recordview.get_current_page()==3: self.refreshRecordGraphView("heartrate") elif self.windowmain.recordview.get_current_page()==4: self.refreshRecordGraphView("analytics") elif view=="day": logging.debug('day view') sport = self.windowmain.activeSport sport_id = self.record.getSportId(sport) record_list = self.record.getrecordList(date_selected, sport_id) self.windowmain.actualize_dayview(record_list=record_list) #selected,iter = self.windowmain.recordTreeView.get_selection().get_selected() elif view=="week": logging.debug('week view') date_range = DateRange.for_week_containing(date_selected) sport = self.windowmain.activeSport sport_id = self.record.getSportId(sport) record_list = self.record.getrecordPeriod(date_range, sport_id) self.windowmain.actualize_weekview(record_list, date_range) elif view=="month": logging.debug('month view') date_range = DateRange.for_month_containing(date_selected) sport = self.windowmain.activeSport sport_id = self.record.getSportId(sport) record_list = self.record.getrecordPeriod(date_range, sport_id) nameMonth, daysInMonth = self.date.getNameMonth(date_selected) self.windowmain.actualize_monthview(record_list, nameMonth) self.windowmain.actualize_monthgraph(record_list, daysInMonth) elif view=="year": logging.debug('year view') date_range = DateRange.for_year_containing(date_selected) sport = self.windowmain.activeSport sport_id = self.record.getSportId(sport) record_list = self.record.getrecordPeriod(date_range, sport_id) self.windowmain.actualize_yearview(record_list, date_selected.year) self.windowmain.actualize_yeargraph(record_list) elif view=="listview": logging.debug('list view') self.refreshListView() elif view=="athlete": logging.debug('athlete view') self.windowmain.on_athleteview_activate() elif view=="stats": logging.debug('stats view') self.windowmain.on_statsview_activate() else: print "Unknown view %s" % view logging.debug('<<') def refreshRecordGraphView(self, view, id_record=None): logging.debug('>>') logging.info('Working on '+view+' graph') if id_record is not None: #Refresh called for a specific record #Select correct record in treeview model = self.windowmain.recordTreeView.get_model() #Loop through all records in treeview looking for the correct one to highlight for i,row in enumerate(model): if row[0] == id_record: self.windowmain.recordTreeView.set_cursor(i) else: selected,iter = self.windowmain.recordTreeView.get_selection().get_selected() if iter: id_record = selected.get_value(iter,0) else: id_record = None view="info" activity = self.activitypool.get_activity(id_record) if view=="info": self.windowmain.actualize_recordview(activity) if view=="graphs": self.windowmain.actualize_recordgraph(activity) if view=="map": self.refreshMapView() if view=="heartrate": self.windowmain.actualize_heartrategraph(activity) self.windowmain.actualize_hrview(activity) if view=="analytics": self.windowmain.actualize_analytics(activity) logging.debug('<<') def refreshMapView(self, full_screen=False): logging.debug('>>') if self.windowmain is None: logging.debug('Called before windowmain initialisation') logging.debug('<<') return selected,iter = self.windowmain.recordTreeView.get_selection().get_selected() id_record = selected.get_value(iter,0) activity = self.activitypool.get_activity(id_record) logging.debug('Trying to show map for record '+str(id_record)) self.windowmain.actualize_map(activity, full_screen) logging.debug('<<') def refreshListRecords(self): logging.debug('>>') #Refresh list view #self.refreshListView() # old variant self.refreshListView(self.windowmain.listsearch.condition) #Refresh list records date = self.date.getDate() sport = self.windowmain.activeSport id_sport = self.record.getSportId(sport) record_ids = self.record.getrecordList(date, id_sport) self.windowmain.actualize_recordTreeView(record_ids) #Mark the monthly calendar to show which days have activity? record_list = self.record.getRecordDayList(date, id_sport) self.windowmain.actualize_calendar(record_list) logging.debug('<<') def refreshAthleteView(self): logging.debug('>>') self.athlete.refresh() self.windowmain.actualize_athleteview(self.athlete) logging.debug('<<') def refreshStatsView(self): logging.debug('>>') self.stats.refresh() self.windowmain.actualize_statsview(self.stats, self.record.getAllRecordList()) logging.debug('<<') def refreshListView(self,condition=None): logging.debug('>>') record_list = self.record.getRecordListByCondition(condition) self.windowmain.actualize_listview(record_list) logging.debug('<<') def refreshWaypointView(self,default_waypoint=None,redrawmap=1): logging.debug('>>') waypoint_list = self.waypoint.getAllWaypoints() self.windowmain.actualize_waypointview(waypoint_list,default_waypoint,redrawmap) logging.debug('<<') def editExtensions(self): logging.debug('>>') before = self.extension.getActiveExtensions() self.extension.manageExtensions() after = self.extension.getActiveExtensions() self.setExtensions(before, after) logging.debug('<<') def importData(self): logging.debug('>>') activeplugins_before = self.plugins.getActivePlugins() self.importdata.runImportdata() activeplugins_after = self.plugins.getActivePlugins() #Need to check for plugins that have been disabled (were active and now are not) self.setMenuPlugins(activeplugins_before, activeplugins_after) self.refreshListRecords() self.refreshGraphView(self.windowmain.selected_view) logging.debug('<<') def editGpsPlugins(self): logging.debug('>>') activeplugins_before = self.plugins.getActivePlugins() self.plugins.managePlugins() activeplugins_after = self.plugins.getActivePlugins() #Need to check for plugins that have been disabled (were active and now are not) self.setMenuPlugins(activeplugins_before, activeplugins_after) logging.debug('<<') def setMenuPlugins(self, activeplugins_before, activeplugins_after): logging.debug('>>') #Need to check for plugins that have been disabled (were active and now are not) for plugin in activeplugins_before: if plugin not in activeplugins_after: #disabled plugin -> need to unload plugin txtbutton = self.plugins.loadPlugin(plugin) self.windowmain.removeImportPlugin(txtbutton) #Need to check for plugins that have been enabled (were not active and now are) for plugin in activeplugins_after: if plugin not in activeplugins_before: #new active plugin -> need to load plugin txtbutton = self.plugins.loadPlugin(plugin) self.windowmain.addImportPlugin(txtbutton) logging.debug('<<') def setExtensions(self, before, after): logging.debug('>>') #Need to check for extensions that have been disabled (were active and now are not) for extension in before: if extension not in after: #disabled extension -> need to unload extension print "Need to disable extension %s " % extension txtbutton = self.extension.loadExtension(extension) self.windowmain.removeExtension(txtbutton) #Need to check for plugins that have been enabled (were not active and now are) for extension in after: if extension not in before: #new active extension -> need to load extension logging.debug("Enabling extension %s " % extension) txtbutton = self.extension.loadExtension(extension) self.windowmain.addExtension(txtbutton) logging.debug('<<') def newRecord(self,title=None,distance=None,time=None,upositive=None,unegative=None,bpm=None,calories=None,comment=None,view=None): logging.debug('>>') date = self.date.getDate() self.record.newRecord(date, title, distance, time, upositive, unegative, bpm, calories, comment) self.refreshListRecords() if view is not None: self.refreshGraphView(view) logging.debug('<<') def editRecord(self, id_record, view=None): logging.debug("Editing record with id: '%s'", id_record) self.record.editRecord(id_record) self.refreshListRecords() if view is not None: self.refreshGraphView(view) logging.debug('<<') def removeRecord(self, id_record, confirm = False, view=None): logging.debug('>>') if confirm: self.record.removeRecord(id_record) else: msg = _("Delete this database entry?") params = [id_record,True] warning = Warning(self.data_path,self.removeRecord,params) warning.set_text(msg) warning.run() self.refreshListRecords() if view is not None: self.refreshGraphView(view) logging.debug('<<') def removeWaypoint(self,id_waypoint, confirm = False): logging.debug('>>') if confirm: self.waypoint.removeWaypoint(id_waypoint) self.refreshWaypointView() else: msg = _("Delete this waypoint?") params = [id_waypoint,True] warning = Warning(self.data_path,self.removeWaypoint,params) warning.set_text(msg) warning.run() logging.debug('<<') def updateWaypoint(self,id_waypoint,lat,lon,name,desc,sym): logging.debug('>>') self.waypoint.updateWaypoint(id_waypoint,lat,lon,name,desc,sym) self.refreshWaypointView(id_waypoint) logging.debug('<<') def exportCsv(self): logging.debug('>>') from save import Save save = Save(self.data_path, self.record) save.run() logging.debug('<<') def editProfile(self): logging.debug('>>') self.profile.editProfile(self._sport_service) self.activitypool.clear_pool() self.windowmain.setup() logging.debug('<<')