| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -176,17 +176,32 @@ class Laikad: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      return position_estimate, position_std, velocity_estimate, velocity_std | 
					 | 
					 | 
					 | 
					      return position_estimate, position_std, velocity_estimate, velocity_std | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def gps_time_from_qcom_report(self, gnss_msg): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    report = gnss_msg.drMeasurementReport | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    if report.source == log.QcomGnss.MeasurementSource.gps: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      report_time = GPSTime(report.gpsWeek, report.gpsMilliseconds / 1000.0) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    elif report.source == log.QcomGnss.MeasurementSource.sbas: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      report_time = GPSTime(report.gpsWeek, report.gpsMilliseconds / 1000.0) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    elif report.source == log.QcomGnss.MeasurementSource.glonass: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      report_time = GPSTime.from_glonass(report.glonassYear, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                                            report.glonassDay, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                                            report.glonassMilliseconds / 1000.0) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    else: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      raise NotImplementedError(f'Unknownconstellation {report.source}') | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return report_time | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def is_good_report(self, gnss_msg): | 
					 | 
					 | 
					 | 
					  def is_good_report(self, gnss_msg): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if gnss_msg.which() == 'drMeasurementReport' and self.use_qcom: | 
					 | 
					 | 
					 | 
					    if gnss_msg.which() == 'drMeasurementReport' and self.use_qcom: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      constellation_id = ConstellationId.from_qcom_source(gnss_msg.drMeasurementReport.source) | 
					 | 
					 | 
					 | 
					      constellation_id = ConstellationId.from_qcom_source(gnss_msg.drMeasurementReport.source) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      # TODO: Understand and use remaining unknown constellations | 
					 | 
					 | 
					 | 
					      # TODO: Understand and use remaining unknown constellations | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      try: | 
					 | 
					 | 
					 | 
					      try: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        good_constellation = constellation_id in [ConstellationId.GPS, ConstellationId.SBAS] | 
					 | 
					 | 
					 | 
					        good_constellation = constellation_id in [ConstellationId.GPS, ConstellationId.SBAS, ConstellationId.GLONASS] | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      except NotImplementedError: | 
					 | 
					 | 
					 | 
					      except NotImplementedError: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        good_constellation = False | 
					 | 
					 | 
					 | 
					        good_constellation = False | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      # gpsWeek 65535 is received rarely from quectel, this cannot be | 
					 | 
					 | 
					 | 
					      # Garbage timestamps with week > 32767 are sometimes sent by module. | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      # passed to GnssMeasurements's gpsWeek (Int16) | 
					 | 
					 | 
					 | 
					      # This is an issue with gpsTime and GLONASS time. | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      good_week = not getattr(gnss_msg, gnss_msg.which()).gpsWeek > np.iinfo(np.int16).max | 
					 | 
					 | 
					 | 
					      report_time = self.gps_time_from_qcom_report(gnss_msg) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      good_week = report_time.week < np.iinfo(np.int16).max | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      return good_constellation and good_week | 
					 | 
					 | 
					 | 
					      return good_constellation and good_week | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    elif gnss_msg.which() == 'measurementReport' and not self.use_qcom: | 
					 | 
					 | 
					 | 
					    elif gnss_msg.which() == 'measurementReport' and not self.use_qcom: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      return True | 
					 | 
					 | 
					 | 
					      return True | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -195,17 +210,26 @@ class Laikad: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def read_report(self, gnss_msg): | 
					 | 
					 | 
					 | 
					  def read_report(self, gnss_msg): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if self.use_qcom: | 
					 | 
					 | 
					 | 
					    if self.use_qcom: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      # QCOM reports are per constellation, should always send 3 reports | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      report = gnss_msg.drMeasurementReport | 
					 | 
					 | 
					 | 
					      report = gnss_msg.drMeasurementReport | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      week = report.gpsWeek | 
					 | 
					 | 
					 | 
					      report_time = self.gps_time_from_qcom_report(gnss_msg) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      tow = report.gpsMilliseconds / 1000.0 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      new_meas = read_raw_qcom(report) | 
					 | 
					 | 
					 | 
					      if report_time - self.last_report_time > 0: | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        self.qcom_reports = [report] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      else: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        self.qcom_reports.append(report) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      self.last_report_time = report_time | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      new_meas = [] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      if len(self.qcom_reports) == 3: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        for report in self.qcom_reports: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          new_meas.extend(read_raw_qcom(report)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    else: | 
					 | 
					 | 
					 | 
					    else: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      report = gnss_msg.measurementReport | 
					 | 
					 | 
					 | 
					      report = gnss_msg.measurementReport | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      week = report.gpsWeek | 
					 | 
					 | 
					 | 
					      self.last_report_time = GPSTime(report.gpsWeek, report.rcvTow) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      tow = report.rcvTow | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      new_meas = read_raw_ublox(report) | 
					 | 
					 | 
					 | 
					      new_meas = read_raw_ublox(report) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.last_report_time = GPSTime(week, tow) | 
					 | 
					 | 
					 | 
					    return self.last_report_time, new_meas | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return week, tow, new_meas | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def is_ephemeris(self, gnss_msg): | 
					 | 
					 | 
					 | 
					  def is_ephemeris(self, gnss_msg): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if self.use_qcom: | 
					 | 
					 | 
					 | 
					    if self.use_qcom: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -279,12 +303,11 @@ class Laikad: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if self.is_ephemeris(gnss_msg): | 
					 | 
					 | 
					 | 
					    if self.is_ephemeris(gnss_msg): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      self.read_ephemeris(gnss_msg) | 
					 | 
					 | 
					 | 
					      self.read_ephemeris(gnss_msg) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    elif self.is_good_report(gnss_msg): | 
					 | 
					 | 
					 | 
					    elif self.is_good_report(gnss_msg): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      week, tow, new_meas = self.read_report(gnss_msg) | 
					 | 
					 | 
					 | 
					      report_t, new_meas = self.read_report(gnss_msg) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      self.gps_week = week | 
					 | 
					 | 
					 | 
					      self.gps_week = report_t.week | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if week > 0: | 
					 | 
					 | 
					 | 
					      if report_t.week > 0: | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        latest_msg_t = GPSTime(week, tow) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if self.auto_fetch_navs: | 
					 | 
					 | 
					 | 
					        if self.auto_fetch_navs: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          self.fetch_navs(latest_msg_t, block) | 
					 | 
					 | 
					 | 
					          self.fetch_navs(report_t, block) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      corrected_measurements = self.process_report(new_meas, t) | 
					 | 
					 | 
					 | 
					      corrected_measurements = self.process_report(new_meas, t) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      msg_dict['correctedMeasurements'] = [create_measurement_msg(m) for m in corrected_measurements] | 
					 | 
					 | 
					 | 
					      msg_dict['correctedMeasurements'] = [create_measurement_msg(m) for m in corrected_measurements] | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |