《最佳实践之》GPS NMEA-0183 协议, 解析 $GPRMC 协议

news2024/11/28 10:39:49

一,了解 GPS NMEA-0183 协议

需要基础物联网对接知识,需要对解析协议有一定认识。
如果不知道怎么连接硬件,请看我的另一篇博客:https://blog.csdn.net/Crazy_Cw/article/details/126613967
这篇文章只说明,如何解析协议。

在这里插入图片描述

NMEA 是 National Marine Electronics Association 的缩写,是美国国家海洋电子协会的简称,现在是 GPS 导航设备统一的 RTCM 标准协议。NMEA-0183 协议是目前 GPS 接收机上使用最广泛的协议,大多数常见的 GPS 接收机、GPS 数据处理软件、导航软件都遵守或者至少兼容这个协议。

如果你使用过 GPS 传感器,那么可能对从串口中冒出了大量以 GPGGA、GPGSA、GPRMC 等开头的数据有印象,它们就是 NMEA-0183 协议数据。
在这里插入图片描述


[14:31:01.842]收←◆$GPGGA,063100.00,3104.39321639,N,12125.30910133,E,5,41,0.5,22.8980,M,11.6136,M,10,9959*55
$GNGLL,3104.39321639,N,12125.30910133,E,063100.00,A,D*79
$GPZDA,063100.00,08,04,2024,,*6A
$GPRMC,063100.00,A,3104.39321639,N,12125.30910133,E,0.005,340.1,080424,6.3,W,D*25
$GPVTG,340.106,T,346.435,M,0.00461,N,0.00853,K,D*28
$GPHDT,337.0082,T*08
$GPGGA,063101.00,3104.39321864,N,12125.30910076,E,5,41,0.5,22.8981,M,11.6136,M,11,9959*52
$GNGLL,3104.39321864,N,12125.30910076,E,063101.00,A,D*7E
$GPZDA,063101.00,08,04,2024,,*6B
$GPRMC,063101.00,A,3104.39321864,N,12125.30910076,E,0.005,309.9,080424,6.3,W,D*27
$GPVTG,309.931,T,316.260,M,0.00521,N,0.00966,K,D*28
$GPHDT,337.0855,T*0A

在这些数据中,包含了位置、速度、时间等信息,通过解析这数据,就可以实时获取物体的位置信息,或者实现时间同步。

二、协议格式

NMEA 0183 通讯协议是以 ASCII 码为基础的,一般格式如下:

$aaaaa,df1,df2,…[CR][LF]

格式说明:
$ 为起始标志;
, 为域分隔符;

  • 为校验和识别符,其后两位数为校验和,代表了 $和 * 之间所有字符的按位异或值(不包括这两个字符);
    \r\n 为终止符(不可见),所有的语句必须以来结束,也就是 ASCII 字符的“回车”(十六进制的 0D)和“换行”(十六进制的 0A)。
    NMEA-0183 协议定义的语句非常多,但是常用的或者说兼容性最广的语句只有 GPGGA、GPGSA、GPGSV、GPRMC、GPVTG、GPGLL 等。下面给出这些常用 NMEA 0183 语句的字段定义解释。

2.1 GPGSA

GPS DOP and Active Satellites(GSA)当前卫星信息

$GPGSA,<1>,<2>,<3>,<3>,<3>,<3>,<3>,<4>,<5>,<6>,<7>

各字段描述如下:

  • 模式 :M = 手动, A = 自动。
  • 定位型式 1 = 未定位, 2 = 二维定位, 3 = 三维定位。
  • PRN 数字:01 至 32 表天空使用中的卫星编号,最多可接收 12 颗卫星信息。
  • PDOP 位置精度因子(0.5~99.9)
  • HDOP 水平精度因子(0.5~99.9)
  • VDOP 垂直精度因子(0.5~99.9)
  • Checksum(检查位)

2.2 GPGSV

GPS Satellites in View(GSV)可见卫星信息

$GPGSV, <1>,<2>,<3>,<4>,<5>,<6>,<7>,?<4>,<5>,<6>,<7>,<8>

各字段描述如下:

  • GSV语句的总数
  • 本句GSV的编号
  • 可见卫星的总数,00 至 12。
  • 卫星编号, 01 至 32。
  • 卫星仰角, 00 至 90 度。
  • 卫星方位角, 000 至 359 度。实际值。
  • 讯号噪声比(C/No), 00 至 99 dB;无表未接收到讯号。
  • Checksum(检查位)
    注意:第 <4>,<5>,<6>,<7> 项个别卫星会重复出现,每行最多有四颗卫星。其余卫星信息会于次一行出现,若未使用,这些字段会空白。

2.3 GPGGA

Global Positioning System Fix Data(GGA)GPS定位信息

$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*hh

各字段描述如下:

  • UTC 时间,hhmmss(时分秒)格式
  • 纬度 ddmm.mmmm(度分)格式(前面的 0 也将被传输)
  • 纬度半球 N(北纬)或 S(南纬)
  • 经度 dddmm.mmmm(度分)格式(前面的 0 也将被传输)
  • 经度半球 E(东经)或 W(西经)
  • GPS 状态:0=未定位,1=非差分定位,2=差分定位,6=正在估算
  • 正在使用解算位置的卫星数量(00~12)(前面的 0 也将被传输)
  • HDOP 水平精度因子(0.5~99.9)
  • 海拔高度(-9999.9~99999.9)
  • 地球椭球面相对大地水准面的高度
  • 差分时间(从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空)
  • 差分站 ID 号 0000~1023(前面的 0 也将被传输,如果不是差分定位将为空)

2.4 GPRMC

Recommended Minimum Specific GPS/TRANSIT Data(RMC)推荐定位信息

$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh

各字段描述如下:

  • UTC 时间,格式 hhmmss.ssss,代表时分秒.毫秒
  • 定位状态,A=有效定位,V=无效定位
  • 纬度 ddmm.mmmm(度分)格式(前面的 0 也将被传输)
  • 纬度半球 N(北纬)或 S(南纬)
  • 经度 dddmm.mmmm(度分)格式(前面的 0 也将被传输)
  • 经度半球 E(东经)或 W(西经)
  • 地面速率(000.0~999.9 节,前面的 0 也将被传输)
  • 地面航向(方位角),等效于二维罗盘(000.0~359.9 度,以真北为参考基准,前面的 0 也将被传输)
  • UTC 日期,DDMMYY(日月年)格式
  • 磁偏角(000.0~180.0 度,前面的 0 也将被传输)
  • 磁偏角方向,E(东)或 W(西)
  • 模式指示(仅 NMEA0183 3.0 版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
    最后两个字节是校验和
    注意:

如果字段 4 的值等于 N,则字段 3 的值等于 ddmm.mmmmmm
如果字段 4 的值等于 S,则字段 3 的值等于 -ddmm.mmmmmm
如果字段 6 的值等于 E,则字段 5 的值等于 ddmm.mmmmmm
如果字段 6 的值等于 W,则字段 5 的值等于 -ddmm.mmmmmm
十进制北纬度数 = dd + mm.mmmmmm/60
十进制南纬度数 = -(dd + mm.mmmmmm/60)
十进制东经度数 = ddd + mm.mmmmmm/60
十进制西经度数 = -(ddd + mm.mmmmmm/60)

2.5 GPVTG

Track Made Good and Ground Speed(VTG)地面速度信息

$GPVTG,<1>,T,<2>,M,<3>,N,<4>,K,<5>*hh

各字段描述如下:

  • 以真北为参考基准的地面航向(000~359 度,前面的 0 也将被传输)
  • 以磁北为参考基准的地面航向(000~359 度,前面的 0 也将被传输)
  • 地面速率(000.0~999.9 节,前面的 0 也将被传输)
  • 地面速率(0000.0~1851.8 公里/小时,前面的0也将被传输)
  • 模式指示(仅 NMEA 0183 3.0 版本输出,A=自主定位,D=差分,E=估算,N=数据无效)

三、实践解析DEMO

解析GPRMC,实践

3.1 创建一个接收对象

package com.joyaiot.vehiclemonitor.netty.handler.carprotocol.entiy;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.sql.Time;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;

/**
* 功能描述: TODO 方法描述
*
* @Author keLe
* @Date 2024/4/8
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class GPRMCData {

  /**UTC时间*/
  private Time utcTime;

  /**
   * GPS状态
   * A=有效,V=无效
   */
  private  String status;

  /**
   * 纬度,DDDMM.MMMMM
   */
  private  double latitude;

  /**
   * 纬度,DDDMM.MMMMM
  */
  private  double longitude;

  /**
   * 速度,Knots
   */
  private  double speedKnots;

  /**
   * 地面速度,节(nautical miles per hour)
   */
  private  double courseDegrees;

  /**日期*/
  private  Date date;

  /**
   * 磁偏角
   */
  private  double magneticVariation;

  /**
   * 磁变方向,W=西变,E=东变
   */
  private  String magneticVariationDir;

  /**
   * 模式,A=自主定位,D=差分,E=估算,N=数据无效
   * */
  private  String modeIndicator;

}


3.2 解析协议工具类

package com.joyaiot.vehiclemonitor.netty.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.fast.api.base.util.StringUtil;
import com.joyaiot.vehiclemonitor.netty.handler.carprotocol.entiy.GPRMCData;
import com.joyaiot.vehiclemonitor.utils.DecimalUtils;
import lombok.extern.slf4j.Slf4j;

import java.sql.Time;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 功能描述: GPRMC协议解析
 * 协议格式:$GPRMC,075704.00,A,3104.39326987,N,12125.30904175,E,0.007,286.4,070424,6.3,W,D*29
 * @see  <p>https://blog.csdn.net/Crazy_Cw/article/details/137515699</p>
 *
 * @Author keLe
 * @Date 2024/4/8
 */
@Slf4j
public class GPRMCParser {

    /**
     * 正则表达式
     *  验证协议 $GPRMC,075704.00,A,3104.39326987,N,12125.30904175,E,0.007,286.4,070424,6.3,W,D*29
     */
    private static final Pattern GPRMC_PATTERN = Pattern.compile(
            "\\$GPRMC,(\\d+\\.?\\d*),([AV]),(\\d+\\.\\d+),(N|S),(\\d+\\.\\d+),(E|W)," +
                    "(\\d+\\.\\d+),(\\d+\\.\\d+)?,(\\d+)?,(\\d+\\.\\d+)?,(E|W)?,(A|D|E|N)\\*\\w+");

    /**
     * 1节等于1.852公里/小时(km/h) (单位换算)
     */
    private static final double KNOTS_TO_KILOMETERS_PER_HOUR = 1.852;

    /**
     * 1km = 1000m (单位换算)
     */
    private static final double KILOMETERS_TO_METERS = 1000;

    /**
     * 1小时等于3600秒 (单位换算)
     */
    private static final double HOURS_TO_SECONDS = 3600.0;

    /**
     * 功能描述: 协议解析
     * @Author keLe
     * @Date 2024/4/8
     * @param  gprmcString 协议字符串
     * @return com.joyaiot.vehiclemonitor.netty.handler.carprotocol.entiy.GPRMCData 协议解析结果
     */
    public static GPRMCData parse(String gprmcString) {
        GPRMCData data = new GPRMCData();
        Matcher matcher = isValidGPRMCFormat(gprmcString);
        // 校验GPRMC格式
        if (null == matcher) {
            log.error("Invalid GPRMC format");
            return null;
        }

        try {
            // 解析UTC时间
            String utcTime = parseUTCTime(matcher,gprmcString);
            data.setUtcTime(parseUTCTimeToDate(utcTime));

            // 解析状态
            data.setStatus(parseStatus(matcher,gprmcString));

            // 解析纬度
            double latitude = parseLatitude(matcher,gprmcString);
            data.setLatitude(latitude);

            // 解析经度
            double longitude = parseLongitude(matcher,gprmcString);
            data.setLongitude(longitude);

            // 解析速度
            double speedKnots = parseSpeed(matcher,gprmcString);
            data.setSpeedKnots(convertKnotsToMetersPerSecond(speedKnots));

            // 解析航向
            data.setCourseDegrees(parseCourse(matcher,gprmcString));

            // 解析日期
            data.setDate(parseDate(matcher,gprmcString, utcTime));

            // 解析磁偏角
            data.setMagneticVariation(parseMagneticVariation(matcher,gprmcString));

            // 解析磁偏角方向
            data.setMagneticVariationDir(parseMagneticVariationDir(matcher,gprmcString));

            // 解析模式指示
            data.setModeIndicator(parseModeIndicator(matcher,gprmcString));
        }catch (Exception e){
            log.error("GPRMC parse error:{}", e.getMessage());
            return null;
        }

        return data;
    }

    /**
     * 校验GPRMC格式是否有效
     * @Author keLe
     * @Date 2024/4/8
     * @param gprmcString GPRMC字符串
     * @return Matcher 匹配器
     */
    private static Matcher isValidGPRMCFormat(String gprmcString) {
        Matcher matcher = GPRMC_PATTERN.matcher(gprmcString);
        return matcher.matches() ? matcher : null;
    }

    /**
     * 解析UTC时间
     * @Author keLe
     * @Date 2024/4/8
     * @param gprmcString GPRMC字符串
     * @return String UTC时间
     */
    private static String parseUTCTime(Matcher matcher,String gprmcString) {
        String utcTimeStr = matcher.group(1);
        int hours = Integer.parseInt(utcTimeStr.substring(0, 2));
        int minutes = Integer.parseInt(utcTimeStr.substring(2, 4));
        String seconds = utcTimeStr.substring(4);
        String[] split = seconds.split("\\.");
        return hours + ":" + minutes + ":" + split[0] + "." + split[1];
    }

    /**
     * 将UTC时间字符串转换为Date对象
     * @Author keLe
     * @Date 2024/4/8
     * @param utcTimeStr UTC时间字符串
     * @return Date UTC时间对应的Date对象
     */
    private static Time parseUTCTimeToDate(String utcTimeStr) {
        try {
            DateTime parse = DateUtil.parse(utcTimeStr, "HH:mm:ss.ssss");
            return new Time(parse.getTime());
        } catch (Exception e) {
            log.error("Failed to parse UTC time:{}, 报错原因:{}", utcTimeStr, e.toString());
            return null;
        }
    }

    /**
     * 解析状态
     * @Author keLe
     * @Date 2024/4/8
     * @param gprmcString GPRMC字符串
     * @return String 状态
     */
    private static String parseStatus(Matcher matcher,String gprmcString) {
        return matcher.group(4).equals("A") ? "有效" : "无效";
    }

    /**
     * 解析纬度
     * @Author keLe
     * @Date 2024/4/8
     * @param gprmcString GPRMC字符串
     * @return double 纬度
     */
    private static double parseLatitude(Matcher matcher,String gprmcString) {
        return parseCoordinate(matcher.group(3), matcher.group(4), 2);
    }

    /**
     * 解析经度
     * @Author keLe
     * @Date 2024/4/8
     * @param gprmcString GPRMC字符串
     * @return double 经度
     */
    private static double parseLongitude(Matcher matcher,String gprmcString) {
        return parseCoordinate(matcher.group(5), matcher.group(6), 3);
    }

    /**
     * 功能描述: 解析速度
     * @Author keLe
     * @Date 2024/4/8
     * @param  matcher  匹配器
     * @param  gprmcString  GPRMC字符串
     * @return java.lang.String
     */
    private static double parseSpeed(Matcher matcher,String gprmcString) {
        return parseOptionalDouble(matcher.group(7));
    }

    /**
     * 功能描述: 解析时间
     * @Author keLe
     * @Date 2024/4/8
     * @param  matcher  匹配器
     * @param  gprmcString  GPRMC字符串
     * @return java.lang.String
     */
    private static double parseCourse(Matcher matcher,String gprmcString) {
        return parseOptionalDouble(matcher.group(8));
    }

    /**
     * 功能描述: 解析时间
     * @Author keLe
     * @Date 2024/4/8
     * @param  matcher  匹配器
     * @param  gprmcString  GPRMC字符串
     * @return java.lang.String
     */
    private static Date parseDate(Matcher matcher,String gprmcString, String utcTime) {
        String yyyy = 2000 + Integer.parseInt(matcher.group(9).substring(4)) + "";
        String MM = matcher.group(9).substring(2, 4);
        String dd = matcher.group(9).substring(0, 2);
        try {
            return DateUtil.parse(yyyy + "-" + MM + "-" + dd + " " + utcTime, DatePattern.NORM_DATETIME_PATTERN);
        } catch (Exception e) {
            log.error("Failed to parse  YYMMDD :{}, 报错原因:{}", matcher.group(9), e.toString());
            return null;
        }
    }

    /**
     * 功能描述: 解析磁偏角
     * @Author keLe
     * @Date 2024/4/8
     * @param  matcher  匹配器
     * @param  gprmcString  GPRMC字符串
     * @return java.lang.String
     */
    private static double parseMagneticVariation(Matcher matcher,String gprmcString) {
        return parseOptionalDouble(matcher.group(10));
    }

    /**
     * 功能描述: 解析磁偏角方向
     * @Author keLe
     * @Date 2024/4/8
     * @param  matcher  匹配器
     * @param  gprmcString  GPRMC字符串
     * @return java.lang.String
     */
    private static String parseMagneticVariationDir(Matcher matcher,String gprmcString) {
        return parseDir(matcher.group(11));
    }

    /**
     * 功能描述: parse Mode
     * @Author keLe
     * @Date 2024/4/8
     * @param  matcher  匹配器
     * @param  gprmcString  GPRMC字符串
     * @return java.lang.String
     */
    private static String parseModeIndicator(Matcher matcher,String gprmcString) {
        return parseModel(matcher.group(12));
    }

    /**
     * 功能描述: parse Coordinate
     * @Author keLe
     * @Date 2024/4/8
     * @param  degrees 经纬度
     * @param  direction 方向
     * @param  index 截取下标位置
     * @return java.lang.String
     */
    private static double parseCoordinate(String degrees, String direction, int index) {
        double coord = Double.parseDouble(degrees.substring(0, index)) + Double.parseDouble(degrees.substring(index)) / 60.0;
        if (direction.startsWith("S") || direction.startsWith("W")) {
            coord *= -1;
        }
        return coord;
    }

    /**
     * 功能描述: parse Double
     * @Author keLe
     * @Date 2024/4/8
     * @param  value 字符串
     */
    private static double parseOptionalDouble(String value) {
        if (value == null || value.isEmpty()) {
            return Double.NaN;
        }
        return Double.parseDouble(value);
    }


    /**
     * Converts speed from knots to meters per second.
     *
     * @param speedInKnots The speed in knots.
     * @return The speed in meters per second.
     */
    public static double convertKnotsToMetersPerSecond(double speedInKnots) {
        if (speedInKnots == 0) {
            return speedInKnots;
        }
        double speedInKilometersPerHour = speedInKnots * KNOTS_TO_KILOMETERS_PER_HOUR * KILOMETERS_TO_METERS;
        return DecimalUtils.preserveDecimal(speedInKilometersPerHour / HOURS_TO_SECONDS, 3);
    }

    /**
     * 功能描述: Mode indication (NMEA0183 version 3.0 output only, A=autonomous positioning,
     *   D=differential, E=estimate, N=invalid data)
     * @Author keLe
     * @Date 2024/4/8
     * @param  charStr 模式指示
     * @return java.lang.String
     */
    public static String parseModel(String charStr) {
        String str = "数据无效";
        if (StringUtil.isBlank(charStr)) {
            return str;
        }
        switch (charStr) {
            case "A":
                str = "自主定位";
                break;
            case "D":
                str = "差分";
                break;
            case "E":
                str = "估算";
                break;
            default:
                str = "数据无效";
                break;
        }
        return str;
    }

    /**
     * 功能描述: Magnetic declination direction, E (east) or W (west)
     * @Author keLe
     * @Date 2024/4/8
     * @param  group 磁偏角方向
     * @return java.lang.String
     */
    private static String parseDir(String group) {
        if (StringUtil.isBlank(group)) {
            return "数据无效";
        }
        return group.equals("E") ? "东" : "西";
    }


    public static void main(String[] args) {
        String gprmcString = "$GPRMC,075704.00,A,3104.39326987,N,12125.30904175,E,0.007,286.4,070424,6.3,W,D*29";

        System.out.println("原始报文:" + gprmcString);

        System.out.println("解析报文结果:" + parse(gprmcString));
    }
}



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1577800.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI编程案例002/ 根据草图设计小红书封面

之前看OpenAI发布会&#xff0c;给个草图能设计个网站。 今天试了一下&#xff0c;给ChatGpt一个封面的设计草图&#xff0c;让ChatGpt编程实现一个拼图封面。 需求如下&#xff1a; 上传四张图片图片按草图排列成不同的布局&#xff0c;每一种布局是一个封面。下面草图的布…

Godot 常用UI+布局容器简单介绍

文章目录 前言相关链接Canvasitem&#xff1a;画布Control&#xff1a;UI布局基类Container&#xff1a;布局容器基类AspectRatioContainer&#xff1a;伸缩居中布局BoxContainer&#xff1a;盒子布局ColorPicker:取色器 CenterContainer&#xff1a;不伸缩居中FlowContainer&a…

软件设计师:下午题(试题三)历年真题

2021年下半年 2021年上半年 2020年下半年 2019年下半年 2019年上半年 2018年下半年 2018年上半年 2017年下半年 后续知识引入 2017年上半年 2016年下半年 2016年上半年 2015年下半年 2015年上半年 2014年下半年 2014年上半年 2013年下半年 2013年上半年 2012年下半年 2012年…

Flink运行机制相关概念介绍

Flink运行机制相关概念介绍 1. 流式计算和批处理2. 流式计算的状态与容错3. Flink简介及其在业务系统中的位置4. Flink模型5. Flink的架构6. Flink的重要概念7. Flink的状态、状态分区、状态缩放&#xff08;rescale&#xff09;和Key Group8. Flink数据交换9. 时间语义10. 水位…

给他个卖票的机会,他能卖出负数票. 多线程安全问题演示

文章目录 1.1 线程安全产生的原因注意 : 以上代码是有问题 , 接下来继续改进通过上述代码的执行结果 , 发现了出现了负号票 , 和相同的票 . 说明数据出现安全问题 1.2 线程的同步1.3 同步代码块1.4 同步方法1.5 Lock锁 1.1 线程安全产生的原因 多个线程在对共享数据进行读改写…

关系(三)利用python绘制相关矩阵图

关系&#xff08;三&#xff09;利用python绘制相关矩阵图 相关矩阵图&#xff08;Correlogram&#xff09;简介 相关矩阵图既可以分析每对变量之间的相关性&#xff0c;也可以分析单变量的分布情况。相关性以散点图的形式可视化&#xff0c;对角线用直方图/密度图表示每个变量…

MySQL 底层数据结构 聚簇索引以及二级索引 Explain的使用

数据结构 我们知道MySQL的存储引擎Innodb默认底层是使用B树的变种来存储数据的 下面我们来复习一下B树存储 B树存储 哈希存储的区别 哈希存储,只能使用等值查询 B树与B树存储 我们知道B树实际上就是B树的变种 那么为啥使用B树而不是使用B树呢? 我们知道效率的高低主要取决于…

【JavaScript】作用域和闭包

作用域 作用域是程序源代码中定义的范围。JavaScript采用词法作用域&#xff0c;也就是静态作用域。所谓词法作用域就是在函数定义的时候就已经确定了。 let value 1 function foo(){console.log(value) } function bar(){let value 2foo() } bar() // 1变量对象是当前代码…

2.基础乐理-唱名的来历,简谱的构造

前置内容&#xff1a;1.唱名与记住唱名的方法 唱名的来历&#xff1a; 很久很久以前&#xff08;公元前&#xff09;各个文明开始诞生和慢慢发展&#xff0c;随着文明的发展&#xff0c;各个文明都开始出现自己的音乐&#xff0c;根据考古学家的发现在 公元前1800年&#xff…

【随笔】Git 高级篇 -- 整理提交记录(下)rebase(十六)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

每日汇评:地缘冲突休战会阻碍黄金创纪录的涨势吗?

尽管以色列与哈马斯的地缘政治紧张局势有所缓和&#xff0c;金价仍冲破 2350 美元&#xff0c;创下新高&#xff1b; 对央行黄金购买量激增的预期抵消了美国非农就业数据主导的美联储强硬押注&#xff1b; 在美国CPI数据公布之前&#xff0c;由于 RSI 极度超买&#xff0c;金价…

YOLOV8注意力改进方法: CoTAttention(Visual Question Answering,VQA)附改进代码)

原论文地址&#xff1a;原论文下载地址 论文相关内容介绍&#xff1a; 论文摘要翻译&#xff1a; 具有自关注的Transformer导致了自然语言处理领域的革命&#xff0c;并且最近在许多计算机视觉任务中激发了具有竞争性结果的Transformer风格架构设计的出现。然而&#xff0c;大…

day02php环境和编译器—我耀学IT

一、环境介绍 1、web 环境 使用 PHP 需要先安装环境&#xff0c;安装环境比较麻烦&#xff0c;需要安装Web服务、PHP应用服务器、MySQL管理系统。 Web服务&#xff1a;apache 和 nginx PHP&#xff1a;多版本 MySQL&#xff1a;多版本 2、环境集成包 因为多环境、多版本、多系…

查看Linux系统相关信息

注&#xff1a; 本文只是博主学习记录分享&#xff0c;仅供参考。如有错误肯定是博主理解有问题&#xff0c;谢谢&#xff01; 一、查看当前操作系统的内核信息 命令&#xff1a;uname -a 二、查看当前操作系统版本信息 命令&#xff1a;cat /proc/version 这条命令可以查看到…

什么是电子邮件加密?电子邮件加密有几种类型?

在当今数字时代&#xff0c;电子邮件已经成为人们日常生活中不可或缺的沟通工具&#xff0c;据相关数据统计&#xff0c;全球每天发送的电子邮件数以亿计&#xff0c;而这些邮件里面通常包含了姓名、地址、个人身份信息 (PII)、登录凭证、财务信息、法律合同、知识产权等有价值…

Python学习从0到1 day22 第二阶段 面向对象 ⑤ 多态

诋毁本身就是一种仰望 —— 24.4.8 学习目标 1.理解多态的概念 2.理解抽象类&#xff08;接口的编程思想&#xff09; 多态 多态&#xff0c;指的是&#xff1a;多种状态&#xff0c;即完成某个行为时&#xff0c;使用不同的对象会得到不同的状态 多态常用在继承关系上 比如&am…

从事「音视频领域」开发工作有前途吗?

据我所知&#xff0c;做音视频的也分算法和工程&#xff0c;这两者都比普通开发高出不少&#xff0c;音视频工程开发的薪资大概比普通web开发高出30%。在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「音视频开发的资料从专业入门到高级教程」&#xff0…

使用 AI 生成正则表达式,告别正则烦恼

如果你有处理正则表达式的需求&#xff0c;那么这个网站&#xff08;autoregex.xyz&#xff09;一定要收藏好。 可以根据文字描述生成正则表达式。 默认是从文字到正则&#xff0c;不用选择。 输入框中输入描述&#xff0c;点击 ”GO“ 按钮。 等待一会儿&#xff0c;即可生…

计算 Hermitian 矩阵的特征值和特征向量 cusolver 示例 DnCheevj

1&#xff0c;原理 计算Hermitian 矩阵的特征值&#xff0c;使用Jacobi 旋转法&#xff0c;每次调整两个对称元素为0&#xff0c;通过迭代&#xff0c;使得非对角线上的值总体越来越趋近于0. 示例扩展了 nv 的 cusolverDsyevj 的示例 由于特征向量是正交的&#xff0c;故V*V…

预训练任务

预训练任务 - Mask Language Model jieba预分词长度小于4的词直接mask&#xff08;mask_ids就是input_ids&#xff09; if rands > self.mask_rate and len(word) < 4:word word_list[i]word_encode tokenizer.encode(word, add_special_tokensFalse)for token in wo…