在线时间56 小时
UID3297826
注册时间2016-7-27
NXP金币0
TA的每日心情 | 开心 2017-1-13 17:13 |
---|
签到天数: 12 天 [LV.3]偶尔看看II
中级会员
- 积分
- 494
- 最后登录
- 2018-1-6
|
本帖最后由 191925882 于 2016-12-20 01:34 编辑
一.团队介绍 学校:汕头大学 队员:2人
二.项目
模块图:
这是电路连接图,接LPC824lite的p0-0端口作为主控板的GPS信号的Rx端 P0-4作为。供电供地。
由于室内没GPS信号,完全一颗星都搜索不到,故引了一根长天线到外面,这样才会收到3颗以上的星,此时才能正常定位。
最后测得的经纬度,如下图:
附一:
NEO-M8
u-blox M8 concurrent GNSS modules
u-blox M8 并行GNSS模块
亮点:
1)并行的GNSS引擎,可以用于GPS、GLONASS、BeiDou和QZSS
2)工业标准:167dBm导航精度
3)产品种类繁多来满足性能和消费的需求
4)低功耗与高性能的结合
5)u-blox无线模块的简单集成
6)与NEO-7,NEO-6以及NEO-5系列向下兼容。
1.功能描述
1.1 概览
NEO-M8系列的独立并行处理GNSS模块是建立u-blox M8 GNSS引擎的高效性能之上的,u-blox M8 GNSS包括GPS、GLONASS、Galileo、BeiDou、QZSS和SBAS,并且拥有经过工业证明的NEO形式要素。
NEO-M8系列提供了高灵敏度和低电压供应下的最小反应时间,NEO-M8M为价格敏感的应用做了优化,并且NEO-M8N则提供了最好的性能和更简单的RF射频集成。NEO形式要素允许从NEO前几代的简单移植。精致的RF架构和干扰抑制可以保证芯片在反GNSS环境下依然有良好的性能。NEO-M8系列芯片将高水平的鲁棒性和灵活的连接方式的集成性组合在一起,NEO-M8N的未来可用性的证据是一个内部的Flash闪存,该闪存可以允许firmware固件的简单更新来支持传统的GNSS系统。这个特性可以使得NEO-M8特别适合工业和自动化应用。
DDC(I2C兼容)接口提供了和大多数的u-bloxSARA、LEON和LISA无线模块的连接和协同使能。对于RF优化,NEO-M8N/M8Q拥有自己独自的特性,该特性包括一个传统的前端LNA(low-noise amplifier,低噪音放大器),这是为了更容易地集成天线,以及一个SAW(surface acoustic wave,声表面波)滤波器来应付增长的干扰免疫。
u-blox M8模块使用了GNSS芯片,该芯片经过AEC-Q100的认证,在ISO/TS 16949认证体系下生产,在系统层进行了完全测试。质量测试符合ISO 16750标准:“道路车辆----环境状况和电气、电子设备的测试”。
u-blox的AssistNow协助提供了附加的信息,例如日历、年历、粗略的上次位置和时间,减少第一次精准定位所需要的时间,提高获得数据的精度,u-blox M8的AssistNow数据支持GPS和GLONASS的集成,这比只用GPS提供帮助要更快速地获得数据。在长时间离线之后,
扩展的AssistNow离线有效数据(保存35天以上)和AssistNow自发有效数据(保存6天以上)依然可以快速获得数据。
模块: 1.5 GNSS NEO-M8 GNSS模块是并发的GNSS接收器,并且接收和跟踪多GNSS系统(例如:GPS、GLONASS、GALILEO、BeiDou和QZSS信号)。因为双频率RF前端架构,三个信号(GPS L1C/A,GLONASS L1OF和BeiDou B1)中的两个能够被接收和并行处理。默认情况下M8接收器被配置为接收并行GPS(包括SBAS和QZSS)和GLONASS。如果电力消耗是主要的因素,那么接收器应该被配置为单GNSS操作,使用GPS或者GLONASS或者BeiDou并且禁止使用QZSS和SBAS。 注意:Galileo、QZSS和SBAS和GPS分享相同的频率,并且总是能和GPS一块处理。 1.5.1 GPS NEO-M8 定位模块被设计来接收和跟踪GPS提供的1575.42MHz的L1C/A信号。NEO-M8系列可以并行接收和处理GPS和GLONASS或者并行接收和处理GPS和BeiDou。 1.5.2 GLONASS NEO-M8系列可以并行接收和处理GLONASS和GPS或者并行接收和处理GLONASS和BeiDou。 俄国的GLONASS卫星系统是美国基本全球定位系统(GPS)的可替换系统。U-blox NEO-M8定位模块被设计来接收和跟踪GLONASS提供的 1602MHz+ k*562.5kHz的L1OF信号
代码:- //From Baseflight-master
- static void gpsNewData(uint16_t c)
- {
- int axis;
- static uint32_t nav_loopTimer;
- int32_t dist;
- int32_t dir;
- int16_t speed;
- if (gpsNewFrameNMEA(c)) {
- // new data received and parsed, we're in business
- lastLastMessage = lastMessage;
- lastMessage=time_nowMs();
- if (GPS_update == 1) //Ö»Òª½øÈë´Ëº¯ÊýÒ»´Î¾Í·×ªÒ»Ï¡£Í»È»ÆæÏë¿ÉÒÔÓô˱êÖ¾×öLEDµÄ¿ØÖƱêÖ¾¡£
- { GPS_update = 0;
- led_set(0xff);
- }
- else
- { GPS_update = 1;
- led_set(0x00);
- }
- if (f.GPS_FIX && GPS_numSat >= 5) {
- if (!altHoldMode) //ÈôÊÇû½âËø£¬»°ËµÉÏËø½âËøµ½µ×ÊÇʲôÒâ˼£¿
- f.GPS_FIX_HOME = 0;
- if (!f.GPS_FIX_HOME && altHoldMode) //GPS_FIX_HOME=0£¨ÆðʼλÖñêÖ¾£©²¢ÇÒ ARMED=1;£¨½âËø£©Ê±
- GPS_reset_home_position();
-
- // Apply moving average filter to GPS data
- //»¬¶¯Æ½¾ùÂ˲¨¾ÍÊǼÓÉϺóÃæµÄ¼õȥǰÃæµÄ£¬È»ºóÔÙÓóý·¨¼´¿É³ýµô4¡£
- #if defined(GPS_FILTERING)
- GPS_filter_index = (GPS_filter_index + 1) % GPS_FILTER_VECTOR_LENGTH;
- for (axis = 0; axis < 2; axis++) {
- GPS_read[axis] = GPS_coord[axis]; // latest unfiltered data is in GPS_latitude and GPS_longitude
- GPS_degree[axis] = GPS_read[axis] / 10000000; // get the degree to assure the sum fits to the int32_t
- // How close we are to a degree line ? its the first three digits from the fractions of degree
- // later we use it to Check if we are close to a degree line, if yes, disable averaging,
- fraction3[axis] = (GPS_read[axis] - GPS_degree[axis] * 10000000) / 10000;
- GPS_filter_sum[axis] -= GPS_filter[axis][GPS_filter_index];
- GPS_filter[axis][GPS_filter_index] = GPS_read[axis] - (GPS_degree[axis] * 10000000);
- GPS_filter_sum[axis] += GPS_filter[axis][GPS_filter_index];
- GPS_filtered[axis] = GPS_filter_sum[axis] / GPS_FILTER_VECTOR_LENGTH + (GPS_degree[axis] * 10000000);
- if (nav_mode == NAV_MODE_POSHOLD) { // we use gps averaging only in poshold mode...
- if (fraction3[axis] > 1 && fraction3[axis] < 999)
- GPS_coord[axis] = GPS_filtered[axis];
- }
- }
- #endif
- // dTnav calculation
- // Time for calculating x,y speed and navigation pids
- dTnav = (float)(time_nowMs() - nav_loopTimer) / 1000.0f; //´ËʱµÄµ¥Î»ÎªÎ¢Ãë
- nav_loopTimer = time_nowMs();
- // prevent runup from bad GPS
- dTnav = min(dTnav, 1.0f); //ÏÞÖÆ
- // calculate distance and bearings for gui and other stuff continously - From home to copter
- GPS_distance_cm_bearing(&GPS_coord[LAT], &GPS_coord[LON], &GPS_home[LAT], &GPS_home[LON], &dist, &dir);
- GPS_distanceToHome = dist / 100; // ¼Òµ½·ÉÐÐÆ÷µÄ¾àÀë
- GPS_directionToHome = dir / 100; // ¼Òµ½·ÉÐÐÆ÷µÄ·½Î»
- if (!f.GPS_FIX_HOME) { // If we don't have home set, do not display anything
- GPS_distanceToHome = 0;
- GPS_directionToHome = 0;
- }
- // calculate the current velocity based on gps coordinates continously to get a valid speed at the moment when we start navigating
- GPS_calc_velocity();
- if (f.GPS_HOLD_MODE || f.GPS_HOME_MODE) { // ok we are navigating //10ÔÂ24ÈÕ homeºÍhold·Ö±ðÊÇÔÚÖ÷º¯ÊýÖÐʹÓÃÈ¥±ê¼ÇÒ£¿ØÆ÷µÄ·µº½Ä£Ê½ºÍ¶¨µãģʽ
- // do gps nav calculations here, these are common for nav and poshold
- GPS_distance_cm_bearing(&GPS_coord[LAT], &GPS_coord[LON], &GPS_WP[LAT], &GPS_WP[LON], &wp_distance, &target_bearing);
- GPS_calc_location_error(&GPS_WP[LAT], &GPS_WP[LON], &GPS_coord[LAT], &GPS_coord[LON]);
- switch (nav_mode) { //nav_mode µÄ¸³ÖµÊÇÔÚÖ÷º¯ÊýÖиøÕâ¸ö±äÁ¿¸³ÏÂÃæµÄÖµ
- case NAV_MODE_POSHOLD:
- // Desired output is in nav_lat and nav_lon where 1deg inclination is 100
- GPS_calc_poshold();
- break;
- case NAV_MODE_WP:
- speed = GPS_calc_desired_speed(cfg.nav_speed_max, NAV_SLOW_NAV); // slow navigation
- // use error as the desired rate towards the target
- // Desired output is in nav_lat and nav_lon where 1deg inclination is 100
- GPS_calc_nav_rate(speed); //ÕâÀïµÄspeedÊÇÉÏÃ溯ÊýÀï´«¹ýÀ´µÄ
- // Tail control
- if (cfg.nav_controls_heading) { //ÄѵÀÊÇ¿ØÖÆ·½ÏòµÄ²ÎÁ¿£¿//nav_controls_heading //10ÔÂ24ÈÕÕâ¸öº¯Êý¸³0»¹ÊǸ³1È¡¾öÓë»úÉíµÄ³¯Ïò£¬¹Ê´Ëʱû¸øËü¸³Öµ
- if (NAV_TAIL_FIRST) { //Í·Ïȵ½
- magHold = wrap_18000(nav_bearing - 18000) / 100; //¶ÔÓÚmagholdÕâ¸ö´ÊÎÒ»¹Ã»ÓкúÃÑо¿
- } else { //·ñÔòβÏȵ½
- magHold = nav_bearing / 100;
- }
- }
- // Are we there yet ?(within x meters of the destination)
- if ((wp_distance <= cfg.gps_wp_radius) || check_missed_wp()) { // if yes switch to poshold mode
- nav_mode = NAV_MODE_POSHOLD; //10ÔÂ24ÈÕ ÔÚÖ÷º¯ÊýÖÐÃ÷Ìì×Ô¼ºÌí¼ÓÖ÷º¯Êý
- if (NAV_SET_TAKEOFF_HEADING) {
- magHold = nav_takeoff_bearing;
- }
- }
- break;
- }
- } //end of gps calcs
- }
- }
- }
-
复制代码- static bool gpsNewFrameNMEA(char c)
- {
- uint8_t frameOK = 0;
- static uint8_t param = 0, offset = 0, parity = 0;
- static char string[15];
- static uint8_t checksum_param, gps_frame = NO_FRAME;
- static gpsMessage_t gps_msg;
- switch (c) {
- case '
- :
- param = 0;
- offset = 0;
- parity = 0;
- break;
- case ',': //Óöµ½ÕâÁ½¸ö²Å½øÈë´Ëº¯Êý
- case '*':
- string[offset] = 0;
- if (param == 0) { // frame identification
- gps_frame = NO_FRAME;
- if (string[0] == 'G' && string[1] == 'N' && string[2] == 'G' && string[3] == 'G' && string[4] == 'A')
- gps_frame = FRAME_GGA;
- if (string[0] == 'G' && string[1] == 'N' && string[2] == 'R' && string[3] == 'M' && string[4] == 'C')
- gps_frame = FRAME_RMC;
- }
- switch (gps_frame) {
- case FRAME_GGA: // ************* GPGGA FRAME parsing
- switch (param) {
- case 2:
- gps_msg.latitude = GPS_coord_to_degrees(string); // 10ÔÂ24ÈÕ°ÑÕâ¸öº¯Êý¼ÌÐøÓÅ»¯ÏÂ,okÒÑ×ö
- break;
- case 3:
- if (string[0] == 'S')
- gps_msg.latitude *= -1;
- break;
- case 4:
- gps_msg.longitude = GPS_coord_to_degrees(string); // 10ÔÂ24ÈÕ°ÑÕâ¸öº¯Êý¼ÌÐøÓÅ»¯ÏÂ,okÒÑ×ö
- break;
- case 5:
- if (string[0] == 'W')
- gps_msg.longitude *= -1;
- break;
- case 6:
- f.GPS_FIX = string[0] > '0';
- break;
- case 7:
- gps_msg.numSat = grab_fields(string, 0); // 10ÔÂ24ÈÕ°ÑÕâ¸öº¯Êý¼ÌÐøÓÅ»¯ÏÂ,okÒÑ×ö
- break;
- case 9:
- gps_msg.altitude = grab_fields(string, 0); // altitude in meters added by Mis
- break;
- }
- break;
- case FRAME_RMC: // ************* GPRMC FRAME parsing
- switch (param) {
- case 7:
- gps_msg.speed = ((grab_fields(string, 1) * 5144L) / 1000L); // speed in cm/s added by Mis
- break;
- case 8:
- gps_msg.ground_course = (grab_fields(string, 1)); // ground course deg * 10
- break;
- }
- break;
- }
- param++;
- offset = 0;
- if (c == '*')
- checksum_param = 1;
- else
- parity ^= c;
- break;
- case '\r': //µ±½ÓÊÕµ½»»Ðзû
- case '\n':
- if (checksum_param) { //parity checksum
- uint8_t checksum = 16 * ((string[0] >= 'A') ? string[0] - 'A' + 10 : string[0] - '0') + ((string[1] >= 'A') ? string[1] - 'A' + 10 : string[1] - '0');
- if (checksum == parity) {
- switch (gps_frame) {
- case FRAME_GGA:
- frameOK = 1;
- if (f.GPS_FIX) { //´Ëʱ²ÅʱµÃµ½ÎÒÃÇÏëÒªµÄÊý¾Ý
- GPS_coord[LAT] = gps_msg.latitude;
- GPS_coord[LON] = gps_msg.longitude;
- GPS_numSat = gps_msg.numSat;
- GPS_altitude = gps_msg.altitude;
- }
- break;
- case FRAME_RMC:
- GPS_speed = gps_msg.speed;
- GPS_ground_course = gps_msg.ground_course;
- // if (!sensors(SENSOR_MAG) && GPS_speed > 100) { //ÒªÊÇûÓдŴ«¸ÐÆ÷
- // GPS_ground_course = wrap_18000(GPS_ground_course * 10) / 10;
- // heading = GPS_ground_course / 10; // Use values Based on GPS if we are moving.
- // }
- break;
- }
- }
- }
- checksum_param = 0;
- break;
- default: //ÒªÊÇ ²»ÊÇÉÏÃæcaseÀïÃæµÄÄǾÍÊÇÊý¾ÝÀ²£¬°ÑÊý¾ÝÌîÈëÊý×éÖÐÈ¥¡£
- if (offset < 15)
- string[offset++] = c;
- if (!checksum_param)
- parity ^= c;
- break;
- }
- return frameOK;
- }
复制代码
|
|