From 0d59c8514bd045bc61897252ab3247e4b2e9ae3a Mon Sep 17 00:00:00 2001 From: nuknal Date: Fri, 17 May 2024 21:46:38 +0800 Subject: [PATCH] get raw data --- aux/attitude.go | 10 ++++ aux/aux.go | 114 ++++++++++++++++++++++++++++++++++++++++ aux/orbit.go | 1 + cmd/extract.go | 13 ++--- cmd/parse.go | 7 +-- extract/aos.go | 8 +-- extract/aux.go | 96 +++++++++++++++++++++++---------- extract/aux_ebox.go | 84 +++++++++++++++++++++++++++++ extract/aux_platform.go | 68 +++++++++++++++++++++++- extract/trans_frame.go | 9 ++-- go.mod | 2 +- 11 files changed, 365 insertions(+), 47 deletions(-) create mode 100644 aux/attitude.go create mode 100644 aux/aux.go create mode 100644 aux/orbit.go diff --git a/aux/attitude.go b/aux/attitude.go new file mode 100644 index 0000000..4d07cc3 --- /dev/null +++ b/aux/attitude.go @@ -0,0 +1,10 @@ +package aux + +/* + 将欧拉角 (yaw, pitch, roll) 转换为旋转矩阵 + + 参数: + - yaw: 偏航角(绕Z轴旋转) + - pitch: 俯仰角(绕Y轴旋转) + - roll: 滚转角(绕X轴旋转) +*/ diff --git a/aux/aux.go b/aux/aux.go new file mode 100644 index 0000000..ab23db7 --- /dev/null +++ b/aux/aux.go @@ -0,0 +1,114 @@ +package aux + +import ( + "fmt" + "math" +) + +// 定义常数 +const ( + GM = 3.986004418e14 // 地球引力常数(m^3/s^2) + Re = 6378137.0 // 地球半径(m) +) + +// 四元数 +type Quaternion struct { + w, x, y, z float64 +} + +// 矢量 +type Vector3 struct { + x, y, z float64 +} + +// 计算轨道参数 +func calculateOrbitalParameters(position, velocity Vector3) (float64, float64, float64, float64, float64) { + r := math.Sqrt(position.x*position.x + position.y*position.y + position.z*position.z) + v := math.Sqrt(velocity.x*velocity.x + velocity.y*velocity.y + velocity.z*velocity.z) + + // 计算轨道参数 + energy := 0.5*v*v - GM/r // 比能 + a := -GM / (2 * energy) // 轨道半长轴 + e := math.Sqrt(1 - (math.Pow(math.Sqrt(math.Pow(position.x*velocity.y-position.y*velocity.x, 2)+ + math.Pow(position.y*velocity.z-position.z*velocity.y, 2)+ + math.Pow(position.z*velocity.x-position.x*velocity.z, 2)), 2) / (GM * a))) + i := math.Acos(position.z / r) // 轨道倾角 + Omega := math.Atan2(position.x, -position.y) // 升交点赤经 + omega := math.Atan2(position.z*velocity.x-position.x*velocity.z, position.x*velocity.y-position.y*velocity.x) // 升交点赤纬 + return a, e, i * 180 / math.Pi, Omega * 180 / math.Pi, omega * 180 / math.Pi +} + +// 四元数到旋转矩阵 +func quaternionToRotationMatrix(q Quaternion) [3][3]float64 { + w, x, y, z := q.w, q.x, q.y, q.z + return [3][3]float64{ + {1 - 2*y*y - 2*z*z, 2*x*y - 2*z*w, 2*x*z + 2*y*w}, + {2*x*y + 2*z*w, 1 - 2*x*x - 2*z*z, 2*y*z - 2*x*w}, + {2*x*z - 2*y*w, 2*y*z + 2*x*w, 1 - 2*x*x - 2*y*y}, + } +} + +// 向量加法 +func add(v1, v2 Vector3) Vector3 { + return Vector3{v1.x + v2.x, v1.y + v2.y, v1.z + v2.z} +} + +// 向量数乘 +func scale(v Vector3, c float64) Vector3 { + return Vector3{v.x * c, v.y * c, v.z * c} +} + +// 矩阵乘法 +func matrixMult(m [3][3]float64, v Vector3) Vector3 { + return Vector3{ + m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z, + m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z, + m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z, + } +} + +// 计算图像位置 +func calculateImagePosition(roll, pitch, yaw float64, quat Quaternion, satellitePos, satelliteVel Vector3) (float64, float64) { + // 将角度转换为弧度 + roll = roll * math.Pi / 180 + pitch = pitch * math.Pi / 180 + yaw = yaw * math.Pi / 180 + + // 构造旋转矩阵 + R := quaternionToRotationMatrix(quat) + // 传感器坐标系中的Z轴向量 + sensorZ := Vector3{0, 0, 1} + // 将Z轴向量通过旋转矩阵转换到卫星坐标系中 + lineOfSight := matrixMult(R, sensorZ) + + // 计算交点经纬度 + lat := math.Asin(lineOfSight.z) * 180 / math.Pi + lon := math.Atan2(lineOfSight.y, lineOfSight.x) * 180 / math.Pi + + return lat, lon +} + +func Calculate() { + // 假设一些已知数据 + satellitePos := Vector3{x: 7000e3, y: 0, z: 0} // 假设一个简单的地心坐标位置 + satelliteVel := Vector3{x: 0, y: 7.5e3, z: 0} // 假设一个简单的速度 + quat := Quaternion{w: 0.7071, x: 0.7071, y: 0, z: 0} // 假设一个简单的四元数 + roll := 0.0 + pitch := 0.0 + yaw := 0.0 + + // 计算轨道参数 + a, e, i, Omega, omega := calculateOrbitalParameters(satellitePos, satelliteVel) + + // 打印轨道参数 + fmt.Println("轨道参数:") + fmt.Printf("轨道半长轴 (a): %.2f m\n", a) + fmt.Printf("偏心率 (e): %.6f\n", e) + fmt.Printf("轨道倾角 (i): %.2f 度\n", i) + fmt.Printf("升交点赤经 (Ω): %.2f 度\n", Omega) + fmt.Printf("近地点幅角 (ω): %.2f 度\n", omega) + + // 计算图像位置 + lat, lon := calculateImagePosition(roll, pitch, yaw, quat, satellitePos, satelliteVel) + fmt.Printf("\n图像位置:\n纬度: %.6f\n经度: %.6f\n", lat, lon) +} diff --git a/aux/orbit.go b/aux/orbit.go new file mode 100644 index 0000000..2ef1d9f --- /dev/null +++ b/aux/orbit.go @@ -0,0 +1 @@ +package aux diff --git a/cmd/extract.go b/cmd/extract.go index 057f3e6..0fbdadb 100644 --- a/cmd/extract.go +++ b/cmd/extract.go @@ -17,16 +17,17 @@ var extractCmd = &cobra.Command{ Long: `Extract data from raw data files`, Run: func(cmd *cobra.Command, args []string) { params := extract.Params{ - InputData: fmt.Sprintf("demo/%s.dat", dataId), + InputData: fmt.Sprintf("demo/data/%s.dat", dataId), OutputPath: "demo/output", TempPath: "demo/temp", DataId: dataId, + Satellite: "SJY01", } p := extract.NewExtractor(¶ms) - p.ExtractAosData() - dats, _ := p.ExtractOriginalImageData() - for _, d := range dats { - p.SeprateAuxAndImgData(d) + aos, _ := p.ExtractAosData() + dats, _ := p.ExtractOriginalImageData(aos) + for i, d := range dats { + p.SeprateAuxAndImgData(d, i) } }, } @@ -34,5 +35,5 @@ var extractCmd = &cobra.Command{ func init() { rootCmd.AddCommand(extractCmd) - extractCmd.Flags().StringVarP(&dataId, "data id", "d", "051513", "051513") + extractCmd.Flags().StringVarP(&dataId, "data-id", "d", "051513", "051513") } diff --git a/cmd/parse.go b/cmd/parse.go index db23a87..6810c21 100644 --- a/cmd/parse.go +++ b/cmd/parse.go @@ -14,15 +14,16 @@ var parseCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { params := extract.Params{ - InputData: "demo/051513.dat", + InputData: "demo/data/051513.dat", OutputPath: "demo/output", TempPath: "demo/temp", DataId: "051513", + Satellite: "SJY01", } p := extract.NewExtractor(¶ms) - // p.ParseAuxPlatform("demo/output/051513_S46_AUX1.dat") + p.ParseAuxPlatformWithHead("demo/ref/辅助数据.dat") fmt.Println("Reference Time: 2000-01-01 12:00:00 UTC, seconds:", extract.Time2000UTCSec()) - p.SeprateAuxAndImgData("demo/temp/051513_S46.dat") + // p.SeprateAuxAndImgData("demo/temp/051513_S46.dat", 1) }, } diff --git a/extract/aos.go b/extract/aos.go index 8c6f12c..eaabf6d 100644 --- a/extract/aos.go +++ b/extract/aos.go @@ -19,12 +19,12 @@ var AOSSyncWord = []byte{0x1A, 0xCF, 0xFC, 0x1D} type AOSFrame struct { } -func (p *Extractor) ExtractAosData() error { +func (p *Extractor) ExtractAosData() (string, error) { // 打开传输帧文件 - 一次读入内存 rawData, err := os.ReadFile(p.params.InputData) if err != nil { log.Println("read data from", p.params.InputData, "error:", err.Error()) - return err + return "", err } name := filepath.Base(p.params.InputData) @@ -33,7 +33,7 @@ func (p *Extractor) ExtractAosData() error { os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777) if err != nil { fmt.Println("create data err", err.Error()) - return err + return "", err } defer foData.Close() wData := bufio.NewWriter(foData) @@ -74,7 +74,7 @@ func (p *Extractor) ExtractAosData() error { log.Println("valid AOS frame cnt:", validFrameCnt) log.Println("error AOS frame cnt:", errFrameCnt) - return nil + return aosDataFile, nil } func LDPCCheck(frame []byte) error { diff --git a/extract/aux.go b/extract/aux.go index 8c43b0f..e0ed508 100644 --- a/extract/aux.go +++ b/extract/aux.go @@ -5,6 +5,7 @@ import ( "encoding/binary" "errors" "fmt" + "io" "os" "path/filepath" "sort" @@ -62,7 +63,7 @@ func (afh *AuxFrameHead) Decode(data []byte) error { afh.IsLinerMatrix = (afh.ImgMode&(1<<5) == 0x0 && afh.ImgMode&(1<<6) == 0x0 && afh.ImgMode&(1<<7) == 0x0) afh.SerialNo = binary.BigEndian.Uint32(data[12:16]) afh.TimeSec = binary.BigEndian.Uint32(data[16:20]) - afh.TimeSecFrac = uint32(uint32(data[20])<<16 | uint32(data[21])<<8 | uint32(data[22])) //binary.BigEndian.Uint32(data[20:23]) + afh.TimeSecFrac = uint32(uint32(data[20])<<16 | uint32(data[21])<<8 | uint32(data[22])) afh.FileNo = data[23] afh.RowLength = afh.LengthOfRow() @@ -112,7 +113,7 @@ type Record struct { } // 从传输帧文件中分离辅助数据,分别存储到辅助数据文件 _AUX.dat 和图像数据文件 _IMG_{波谱}.dat 中 -func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error { +func (p *Extractor) SeprateAuxAndImgData(sDataFile string, segmentIndex int) error { // 打开传输帧文件 - 一次读入内存 sData, err := os.ReadFile(sDataFile) if err != nil { @@ -127,6 +128,8 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error { defer fimg.Close() fimg.WriteString("字节数 帧头流水号 文件号 帧头时间 中心辅助数据前4字节(行33-36)\n") var qmap []*Record + var startAuxLine bool + var preSN uint32 for i := 0; i < len(sData); { // 解析帧 if i+24 > len(sData) { @@ -148,22 +151,22 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error { if !afh.IsValidFrmHead { log.Debugf("[%d] invalid frame head of original raw data %v", i, afh.FrmHead) i += 1 + continue + } + + r := &Record{index: i, frmHead: afh} + qmap = append(qmap, r) + + utcTime := binary.BigEndian.Uint32(sData[i+32 : i+36]) + + t := time.Unix(int64(afh.TimeSec+uint32(ReferenceTime2000)), int64(afh.TimeSecFrac)*1000) + tAux := time.Unix(int64(utcTime+uint32(ReferenceTime2000)), 0) + + startAuxLine = tAux.Year() == t.Year() && tAux.Month() == t.Month() && tAux.Day() == t.Day() && + tAux.Hour() == t.Hour() && tAux.Minute() == t.Minute() + if !startAuxLine { + // fimg.WriteString(fmt.Sprintf("-----%d not AUX Start -----\n", afh.SerialNo)) } else { - r := &Record{index: i, frmHead: afh} - qmap = append(qmap, r) - i += 24 - - utcTime := binary.BigEndian.Uint32(sData[i+32 : i+36]) - - t := time.Unix(int64(afh.TimeSec+uint32(ReferenceTime2000)), 0) - tAux := time.Unix(int64(utcTime), 0) - startAuxLine := tAux.Year() == t.Year() && tAux.Month() == t.Month() && tAux.Day() == t.Day() && - tAux.Hour() == t.Hour() && tAux.Minute() == t.Minute() - - if startAuxLine { - fimg.WriteString("----- AUX Start -----\n") - } - fimg.WriteString(fmt.Sprintf("%d %d %d %s %s\n", i, afh.SerialNo, @@ -171,7 +174,14 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error { t.String(), tAux.String(), )) + + if afh.SerialNo-preSN != 16 { + fmt.Println("serial number not continuous", afh.SerialNo, preSN) + } + preSN = afh.SerialNo } + + i += afh.RowLength } sort.Slice(qmap, func(i, j int) bool { @@ -196,31 +206,34 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error { defer waux1.Flush() defer faux1.Close() - pan := outputDir + "/" + name + "_IMG_PAN.RAW" + pan := outputDir + "/" + name + "_PAN.RAW" os.Remove(pan) fpan, _ := os.OpenFile(pan, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777) wpan := bufio.NewWriter(fpan) defer wpan.Flush() defer fpan.Close() panEnviHdr := EnviHdr{} - wpanHdr, _ := NewBSQWriter(outputDir+"/"+name+"_IMG_PAN.HDR", &panEnviHdr) + wpanHdr, _ := NewBSQWriter(outputDir+"/"+name+"_PAN.HDR", &panEnviHdr) defer wpanHdr.Close() // 先按单波段存储,再按波段组合存储为 BSQ 格式的 MSS - mss := outputDir + "/" + name + "_IMG_MSS.RAW" + mss := outputDir + "/" + name + "_MSS.RAW" os.Remove(mss) fmss, _ := os.OpenFile(mss, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777) wmss := bufio.NewWriter(fmss) defer wmss.Flush() defer fmss.Close() mssEnviHdr := EnviHdr{} - wmssHdr, _ := NewBSQWriter(outputDir+"/"+name+"_IMG_MSS.HDR", &mssEnviHdr) + wmssHdr, _ := NewBSQWriter(outputDir+"/"+name+"_MSS.HDR", &mssEnviHdr) defer wmssHdr.Close() var afh AuxFrameHead dataLen := len(sData) mssData := make([][]byte, 4) + var firstLineFound bool + var totalLines int + var pancount int for i := 0; i < dataLen; { if i+4 > dataLen { logrus.Println("end of data, dataLen:", dataLen, "i:", i) @@ -262,6 +275,21 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error { break } + // 通过中心辅助时间判断是否第一行数据 + if !firstLineFound { + utcTime := binary.BigEndian.Uint32(sData[i+32 : i+36]) + t := time.Unix(int64(afh.TimeSec+uint32(ReferenceTime2000)), int64(afh.TimeSecFrac)*1000) + tAux := time.Unix(int64(utcTime+uint32(ReferenceTime2000)), 0) + firstLineFound = tAux.Year() == t.Year() && tAux.Month() == t.Month() && tAux.Day() == t.Day() && + tAux.Hour() == t.Hour() && tAux.Minute() == t.Minute() + if !firstLineFound { + log.Info("did not find first line of aux data, skip this frame: ", afh.SerialNo) + i += afh.RowLength + continue + } + } + totalLines += 1 + // 存储辅助数据到临时文件 dataIndex := i + 24 waux0.Write(sData[dataIndex : dataIndex+8]) // 8字节焦面电箱辅助数据 @@ -271,29 +299,31 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error { // 存储图像数据到临时文件 - 以 ENVI BSQ 格式存储,同时提供 HDR 描述文件 if afh.B0 { - wpan.Write(sData[dataIndex : dataIndex+19040]) + // wpan.Write(sData[dataIndex : dataIndex+19040]) + write16bPixelLittleEndian(wpan, sData[dataIndex:dataIndex+19040]) dataIndex += 19040 panEnviHdr.Lines += 1 + pancount += 19040 } if afh.B1 { - // wmss.Write(sData[dataIndex : dataIndex+1192]) + // write16bPixelLittleEndian(wmss, sData[dataIndex:dataIndex+1192]) mssData[0] = append(mssData[0], sData[dataIndex:dataIndex+1192]...) dataIndex += 1192 mssEnviHdr.Lines += 1 } if afh.B2 { - // wmss.Write(sData[dataIndex : dataIndex+1192]) + // write16bPixelLittleEndian(wmss, sData[dataIndex:dataIndex+1192]) mssData[1] = append(mssData[1], sData[dataIndex:dataIndex+1192]...) dataIndex += 1192 } if afh.B3 { - // wmss.Write(sData[dataIndex : dataIndex+1192]) + // write16bPixelLittleEndian(wmss, sData[dataIndex:dataIndex+1192]) mssData[2] = append(mssData[2], sData[dataIndex:dataIndex+1192]...) dataIndex += 1192 } if afh.B4 { - // wmss.Write(sData[dataIndex : dataIndex+1192]) + // write16bPixelLittleEndian(wmss, sData[dataIndex:dataIndex+1192]) mssData[3] = append(mssData[3], sData[dataIndex:dataIndex+1192]...) dataIndex += 1192 } @@ -304,7 +334,7 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error { for i := 0; i < 4; i++ { if len(mssData[i]) > 0 { log.Println("write mss data of band B", i+1) - _, err := wmss.Write(mssData[i]) + // _, err := write16bPixelLittleEndian(wmss, mssData[i]) if err != nil { log.Error("write mss data error:", err.Error()) } @@ -312,14 +342,24 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error { } } + write16bPixelLittleEndian(wmss, mssData[2]) + panEnviHdr.Samples = 9520 panEnviHdr.Bands = 1 wpanHdr.Write([]byte(panEnviHdr.String())) mssEnviHdr.Lines = mssEnviHdr.Lines / 4 // 多光谱波段分别在 4 行中传输 mssEnviHdr.Samples = 2384 - mssEnviHdr.Bands = bands + mssEnviHdr.Bands = 1 wmssHdr.Write([]byte(mssEnviHdr.String())) return nil } + +// 写入 16 位像素值,小端序 +func write16bPixelLittleEndian(w io.Writer, data []byte) (int, error) { + for i := 0; i < len(data)-1; i += 2 { + data[i], data[i+1] = data[i+1], data[i] + } + return w.Write(data) +} diff --git a/extract/aux_ebox.go b/extract/aux_ebox.go index 489607f..4f25529 100644 --- a/extract/aux_ebox.go +++ b/extract/aux_ebox.go @@ -1,5 +1,7 @@ package extract +import "fmt" + // 卫星时间起点 北京时间 2000-01-01 20:00:00 var ( ReferenceTime2000 = 946728000 @@ -7,4 +9,86 @@ var ( // 焦面电箱辅助数据 128 字节 (每 16 行原始图像数据为一组) type AuxFocalBox struct { + TransferTime float32 // 执行转移时间 0.5us/bit + TrainingDone byte // 1B成功;0B失败 + WorkMode byte // 工作模式 0B正常;1B故障 + IntegralDirection byte // 积分方向 1B正向;0B反向 + PGAGain byte // PGA增益 +} + +func (ab *AuxFocalBox) Decode(data []byte) error { + byte0 := data[0] & 0b00111111 + ab.TransferTime = float32(uint32(byte0)<<16|uint32(data[1])<<8|uint32(data[2])) * 0.5 + ab.TrainingDone = data[3] & 0b10000000 + ab.WorkMode = data[3] & 0b01000000 + ab.IntegralDirection = data[3] & 0b00100000 + ab.PGAGain = data[3] & 0b00011111 + return nil +} + +func (ab AuxFocalBox) String() string { + return fmt.Sprintf( + `执行转移时间:%f us\n + TrainingDone:%x\n + 工作模式:%x\n + 积分方向:%x\n + PGA增益:%s + `, + ab.TransferTime, + ab.TrainingDone, + ab.WorkMode, + ab.IntegralDirection, + ab.PGAGainValue(), + ) +} + +func (ab AuxFocalBox) PGAGainValue() string { + switch ab.PGAGain { + case 0b0000: + return "0.75x" + case 0b0001: + return "1.25x" + case 0b0010: + return "1.75x" + case 0b0011: + return "2.25x" + case 0b0100: + return "2.75x" + case 0b0101: + return "3.25x" + case 0b0110: + return "3.75x" + case 0b0111: + return "4.25x" + case 0b1000: + return "4.75x" + case 0b1001: + return "5.25x" + case 0b1010: + return "5.75x" + case 0b10000: + return "1x" + case 0b10001: + return "1.5x" + case 0b10010: + return "2x" + case 0b10011: + return "2.5x" + case 0b10100: + return "3x" + case 0b10101: + return "3.5x" + case 0b10110: + return "4x" + case 0b10111: + return "4.5x" + case 0b11000: + return "5x" + case 0b11001: + return "5.5x" + case 0b11010: + return "6x" + default: + return "unknown" + } } diff --git a/extract/aux_platform.go b/extract/aux_platform.go index 05cef91..194f86e 100644 --- a/extract/aux_platform.go +++ b/extract/aux_platform.go @@ -7,6 +7,7 @@ import ( "time" "github.com/sirupsen/logrus" + log "github.com/sirupsen/logrus" ) const AuxPlatformFrmSize = 512 // 512 bytes @@ -90,7 +91,8 @@ type AuxPlatform struct { Reserved1 [4]byte // 预留字节 Reserved2 [2]byte // 预留字节 Reserved3 [2]byte // 预留字节 - // 241 - 311 暂不解析 + // 241.0 - 311.0 波道1参数 + // 241.1 - 311.1 波道2参数 WGS84PosX float64 // [312-315]计算当前WGS 84位置X 单位:0.01米 WGS84PosY float64 // [316-319] WGS84PosZ float64 // [320-323] @@ -191,6 +193,70 @@ func (e *Extractor) ParseAuxPlatform(auxfile string) ([]*AuxPlatform, error) { return aps, nil } +func (e *Extractor) ParseAuxPlatformWithHead(auxfile string) ([]*AuxPlatform, error) { + data, err := os.ReadFile(auxfile) + if err != nil { + logrus.Println("read aux data from", auxfile, "error:", err.Error()) + return nil, err + } + + fimg, _ := os.Create("demo/temp/ref_051622_aux_img.txt") + defer fimg.Close() + fimg.WriteString("index 流水号 文件号 时间秒 秒小数 utcTime\n") + + var aps []*AuxPlatform + rows := 0 + for i := 0; i < len(data); { + if data[i] == 0xD1 && data[i+1] == 0x5B && data[i+2] == 0xD1 && data[i+3] == 0x5B { + log.Debug("find package head: 0xD15BD15B") + } else { + i++ + // log.Println(i,"not find package head: 0xD15BD15B, skip 1 byte") + continue + } + afh := &AuxFrameHead{} + afh.Decode(data[i : i+24]) + + if !afh.IsValidFrmHead { + log.Debugf("[%d] invalid frame head of original raw data %v", i, afh.FrmHead) + i += 1 + continue + } + + if (afh.SerialNo-1)%16 == 0 { + + ab := &AuxFocalBox{} + ab.Decode(data[i+24 : i+32]) + fmt.Println(ab.String()) + + utcTime := binary.BigEndian.Uint32(data[i+32 : i+36]) + + // t := time.Unix(int64(afh.TimeSec+uint32(ReferenceTime2000)), int64(afh.TimeSecFrac)*1000) + taux := time.Unix(int64(utcTime+uint32(ReferenceTime2000)), 0) + + fimg.WriteString( + fmt.Sprintf("%d %d %d %d %d %d %s\n", + i, + afh.SerialNo, + afh.FileNo, + afh.TimeSec, + afh.TimeSecFrac, + utcTime, + taux.String(), + )) + + rows++ + // if rows > 32 { + // break + // } + } + + i += 64 + + } + return aps, nil +} + func Time2000UTCSec() int64 { t, _ := time.ParseInLocation("2006-01-02 15:04:05", "2000-01-01 12:00:00", time.UTC) return t.Unix() diff --git a/extract/trans_frame.go b/extract/trans_frame.go index dd0c4c1..e246d5e 100644 --- a/extract/trans_frame.go +++ b/extract/trans_frame.go @@ -46,10 +46,8 @@ func (t *TransFrame) Decode(frame []byte) { } // 提取图像传输帧中的原始图像数据 -func (p *Extractor) ExtractOriginalImageData() ([]string, error) { +func (p *Extractor) ExtractOriginalImageData(aosDataFile string) ([]string, error) { var sData []string - name := filepath.Base(p.params.InputData) - aosDataFile := filepath.Join(p.params.TempPath, AOSTempDataPrefix+name) nullFrmCnt := 0 aosData, err := os.ReadFile(aosDataFile) @@ -116,7 +114,10 @@ func (p *Extractor) ExtractOriginalImageData() ([]string, error) { continue } - s01 := filepath.Join(p.params.TempPath, fmt.Sprintf("%s_S%d.dat", p.params.DataId, k)) + s01 := filepath.Join(p.params.TempPath, fmt.Sprintf("%s_%s_S%d.dat", + p.params.Satellite, + p.params.DataId, + k)) fo, err := os.OpenFile(s01, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777) if err != nil { diff --git a/go.mod b/go.mod index a88e65b..42f41e9 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module starwiz.cn/sjy01/preprocessing -go 1.21.0 +go 1.19 require github.com/k0kubun/pp v3.0.1+incompatible