j2000-w84
This commit is contained in:
9
calculator/const.go
Normal file
9
calculator/const.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package calculator
|
||||||
|
|
||||||
|
// WGS84 ellipsoid constants
|
||||||
|
const (
|
||||||
|
a = 6378137.0 // semi-major axis in meters
|
||||||
|
f = 1 / 298.257223563 // flattening
|
||||||
|
e2 = 2*f - f*f // square of eccentricity
|
||||||
|
J2000Epoch = 2451545.0 // Julian date of J2000 epoch
|
||||||
|
)
|
||||||
78
calculator/j2000.go
Normal file
78
calculator/j2000.go
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package calculator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Function to convert current J2000 position to WGS84
|
||||||
|
func J2000ToWGS84(j2000X, j2000Y, j2000Z float64, utc time.Time) (float64, float64, float64) {
|
||||||
|
julianDate := UTCToJulianDate(utc)
|
||||||
|
gast := CalculateGAST(julianDate, utc)
|
||||||
|
|
||||||
|
// Calculate rotation matrix from J2000 to ITRS
|
||||||
|
rotationMatrix := CreateRotationMatrix(gast)
|
||||||
|
|
||||||
|
// Rotate J2000 position to ITRS
|
||||||
|
itrsX := rotationMatrix[0][0]*j2000X + rotationMatrix[0][1]*j2000Y + rotationMatrix[0][2]*j2000Z
|
||||||
|
itrsY := rotationMatrix[1][0]*j2000X + rotationMatrix[1][1]*j2000Y + rotationMatrix[1][2]*j2000Z
|
||||||
|
itrsZ := rotationMatrix[2][0]*j2000X + rotationMatrix[2][1]*j2000Y + rotationMatrix[2][2]*j2000Z
|
||||||
|
|
||||||
|
// Convert ITRS to geodetic coordinates (WGS84)
|
||||||
|
latitude, longitude, height := ECEFToGeodetic(itrsX, itrsY, itrsZ)
|
||||||
|
return latitude, longitude, height
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to convert UTC to Julian Date
|
||||||
|
func UTCToJulianDate(t time.Time) float64 {
|
||||||
|
year, month, day := t.Date()
|
||||||
|
hour, minute, second := t.Clock()
|
||||||
|
fracOfDay := float64(hour)/24 + float64(minute)/(24*60) + float64(second)/(24*60*60)
|
||||||
|
|
||||||
|
if month <= 2 {
|
||||||
|
year -= 1
|
||||||
|
month += 12
|
||||||
|
}
|
||||||
|
|
||||||
|
A := year / 100
|
||||||
|
B := 2 - A + A/4
|
||||||
|
julianDate := float64(int(365.25*float64(year))) + float64(int(30.6001*float64(month+1))) + float64(day) + 1720994.5 + fracOfDay + float64(B)
|
||||||
|
return julianDate
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to calculate GAST (Greenwich Apparent Sidereal Time)
|
||||||
|
func CalculateGAST(julianDate float64, utc time.Time) float64 {
|
||||||
|
// Calculate Julian centuries since J2000.0
|
||||||
|
T := (julianDate - J2000Epoch) / 36525.0
|
||||||
|
|
||||||
|
// Calculate Greenwich Mean Sidereal Time (GMST) in degrees
|
||||||
|
GMST := 280.46061837 + 360.98564736629*(julianDate-J2000Epoch) + 0.000387933*T*T - T*T*T/38710000
|
||||||
|
GMST = math.Mod(GMST, 360.0)
|
||||||
|
if GMST < 0 {
|
||||||
|
GMST += 360.0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the equation of the equinoxes (simplified)
|
||||||
|
omega := 125.04 - 0.052954*T
|
||||||
|
L := 280.47 + 0.98565*T
|
||||||
|
epsilon := 23.4393 - 0.0000004*T
|
||||||
|
deltaPsi := -0.000319*math.Sin(math.Pi/180.0*omega) - 0.000024*math.Sin(math.Pi/180.0*2*L)
|
||||||
|
|
||||||
|
// Greenwich Apparent Sidereal Time (GAST)
|
||||||
|
GAST := GMST + deltaPsi*math.Cos(math.Pi/180.0*epsilon)
|
||||||
|
GAST = math.Mod(GAST, 360.0)
|
||||||
|
if GAST < 0 {
|
||||||
|
GAST += 360.0
|
||||||
|
}
|
||||||
|
|
||||||
|
return GAST * math.Pi / 180.0 // Convert to radians
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to create the rotation matrix for the given GAST
|
||||||
|
func CreateRotationMatrix(gast float64) [3][3]float64 {
|
||||||
|
return [3][3]float64{
|
||||||
|
{math.Cos(gast), math.Sin(gast), 0},
|
||||||
|
{-math.Sin(gast), math.Cos(gast), 0},
|
||||||
|
{0, 0, 1},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package calculator
|
|
||||||
|
|
||||||
import "github.com/twpayne/go-proj/v10"
|
|
||||||
|
|
||||||
func J2000ToLngLat(x, y, z float64) []float64 {
|
|
||||||
var lng, lat float64
|
|
||||||
return []float64{lng, lat}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WGS84XYZtoLngLat(x, y, z float64) []float64 {
|
|
||||||
var lng, lat float64
|
|
||||||
pj, err := proj.NewCRSToCRS("EPSG:3857", "EPSG:4326", nil)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
coor := proj.NewCoord(x, y, z, 0)
|
|
||||||
coor, err = pj.Forward(coor)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
lng = coor.X()
|
|
||||||
lat = coor.Y()
|
|
||||||
return []float64{lng, lat}
|
|
||||||
}
|
|
||||||
31
calculator/wgs84.go
Normal file
31
calculator/wgs84.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package calculator
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
func WGS84XYZtoLatLngH(X, Y, Z float64) (float64, float64, float64) {
|
||||||
|
return ECEFToGeodetic(X, Y, Z)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to convert ECEF (ITRS) coordinates to geodetic coordinates (latitude, longitude, height)
|
||||||
|
func ECEFToGeodetic(X, Y, Z float64) (float64, float64, float64) {
|
||||||
|
b := a * (1 - f)
|
||||||
|
e2Prime := e2 * (a * a) / (b * b)
|
||||||
|
p := math.Sqrt(X*X + Y*Y)
|
||||||
|
theta := math.Atan2(Z*a, p*b)
|
||||||
|
|
||||||
|
// Calculate Longitude
|
||||||
|
longitude := math.Atan2(Y, X)
|
||||||
|
|
||||||
|
// Calculate Latitude
|
||||||
|
latitude := math.Atan2(Z+e2Prime*b*math.Pow(math.Sin(theta), 3), p-e2*a*math.Pow(math.Cos(theta), 3))
|
||||||
|
|
||||||
|
// Calculate Height
|
||||||
|
N := a / math.Sqrt(1-e2*math.Pow(math.Sin(latitude), 2))
|
||||||
|
height := p/math.Cos(latitude) - N
|
||||||
|
|
||||||
|
// Convert radians to degrees for latitude and longitude
|
||||||
|
latitudeDeg := latitude * 180 / math.Pi
|
||||||
|
longitudeDeg := longitude * 180 / math.Pi
|
||||||
|
|
||||||
|
return latitudeDeg, longitudeDeg, height
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ var parseCmd = &cobra.Command{
|
|||||||
logrus.Error(err)
|
logrus.Error(err)
|
||||||
}
|
}
|
||||||
// p.ParseAuxEBox("demo/output/SJY01_PMS_20240516_101236_051622_096_EB.AUX")
|
// p.ParseAuxEBox("demo/output/SJY01_PMS_20240516_101236_051622_096_EB.AUX")
|
||||||
|
e.ParseAuxPlatform("demo/output/Q052100/SJY01_PMS_20240519_121433_Q052100_102.AUX")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/k0kubun/pp/v3"
|
"github.com/k0kubun/pp/v3"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"starwiz.cn/sjy01/preprocessing/calculator"
|
||||||
)
|
)
|
||||||
|
|
||||||
const AuxPlatformFrmSize = 512 // 512 bytes
|
const AuxPlatformFrmSize = 512 // 512 bytes
|
||||||
@@ -29,9 +30,9 @@ type AuxPlatform struct {
|
|||||||
QuatOrbJQ1 float64 // [37-40]轨道相对惯性系四元数矢部 的 Q1 值,量纲 1/0x40000000
|
QuatOrbJQ1 float64 // [37-40]轨道相对惯性系四元数矢部 的 Q1 值,量纲 1/0x40000000
|
||||||
QuatOrbJQ2 float64 // [41-44]Q2 值
|
QuatOrbJQ2 float64 // [41-44]Q2 值
|
||||||
QuatOrbJQ3 float64 // [45-48]Q3 值
|
QuatOrbJQ3 float64 // [45-48]Q3 值
|
||||||
Eular1 float64 // [49-52]本体相对轨道姿态角,量纲:1/1000000 单位:rad
|
Eular1 float64 // [49-52]本体相对轨道姿态角,[Z]Yaw 测摆角,量纲:1/1000000 单位:rad
|
||||||
Eular2 float64 // [53-56]
|
Eular2 float64 // [53-56] Pitch [Y]
|
||||||
Eular3 float64 // [57-60]
|
Eular3 float64 // [57-60] Roll [X]
|
||||||
DotEular1 float64 // [61-62]本体相对轨道角速度,量纲:1/100000 单位:rad
|
DotEular1 float64 // [61-62]本体相对轨道角速度,量纲:1/100000 单位:rad
|
||||||
DotEular2 float64 // [63-64]
|
DotEular2 float64 // [63-64]
|
||||||
DotEular3 float64 // [65-66]
|
DotEular3 float64 // [65-66]
|
||||||
@@ -353,23 +354,32 @@ func (e *Extractor) ParseAuxPlatform(auxfile string) ([]*AuxPlatform, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
aps = append(aps, &ap)
|
aps = append(aps, &ap)
|
||||||
ap.Print()
|
// ap.Print()
|
||||||
// Calculate(
|
// Calculate(
|
||||||
// Vector3{ap.J2000Pos_X, ap.J2000Pos_Y, ap.J2000Pos_Y},
|
// Vector3{ap.J2000Pos_X, ap.J2000Pos_Y, ap.J2000Pos_Y},
|
||||||
// Vector3{ap.J2000Vel_X, ap.J2000Vel_Y, ap.J2000Vel_Z},
|
// Vector3{ap.J2000Vel_X, ap.J2000Vel_Y, ap.J2000Vel_Z},
|
||||||
// Quaternion{ap.SS1_Q1, ap.SS1_Q2, ap.SS1_Q3, ap.SS1_Q4},
|
// Quaternion{ap.SS1_Q1, ap.SS1_Q2, ap.SS1_Q3, ap.SS1_Q4},
|
||||||
// )
|
// )
|
||||||
|
|
||||||
// pp.Println(calculator.WGS84XYZtoLngLat(ap.W84PosX, ap.W84PosY, ap.W84PosZ))
|
pp.Println(calculator.WGS84XYZtoLatLngH(ap.W84PosX, ap.W84PosY, ap.W84PosZ))
|
||||||
// pp.Println(calculator.WGS84XYZtoLngLat(ap.WGS84PosX, ap.WGS84PosY, ap.WGS84PosZ))
|
pp.Println(calculator.WGS84XYZtoLatLngH(ap.WGS84PosX, ap.WGS84PosY, ap.WGS84PosZ))
|
||||||
|
|
||||||
|
pp.Println(calculator.J2000ToWGS84(
|
||||||
|
ap.J2000PosX,
|
||||||
|
ap.J2000PosY,
|
||||||
|
ap.J2000PosZ,
|
||||||
|
time.Unix(
|
||||||
|
int64(ap.UTCTimeSec+uint32(ReferenceTime2000)),
|
||||||
|
int64(ap.Microsecond)*1000).UTC()))
|
||||||
|
|
||||||
|
pp.Println(calculator.J2000ToWGS84(
|
||||||
|
ap.J2000Pos_X,
|
||||||
|
ap.J2000Pos_Y,
|
||||||
|
ap.J2000Pos_Z,
|
||||||
|
time.Unix(
|
||||||
|
int64(ap.UTCTimeSec+uint32(ReferenceTime2000)),
|
||||||
|
int64(ap.Microsecond)*1000).UTC()))
|
||||||
break
|
break
|
||||||
|
|
||||||
if i+AuxPlatformFrmSize > len(data) {
|
|
||||||
logrus.Info("rest of aux data length is not enough", len(data)-i)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return aps, nil
|
return aps, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user