diff --git a/c/include/libsbp/cpp/message_traits.h b/c/include/libsbp/cpp/message_traits.h index c9ad71a7eb..b499edffd6 100644 --- a/c/include/libsbp/cpp/message_traits.h +++ b/c/include/libsbp/cpp/message_traits.h @@ -1136,6 +1136,12 @@ struct MessageTraits { template<> struct MessageTraits { + static constexpr u16 id = 65294; +}; + + +template<> +struct MessageTraits { static constexpr u16 id = 65295; }; diff --git a/c/include/libsbp/solution_meta.h b/c/include/libsbp/solution_meta.h index 771b7c9b28..a4ffe8dfc1 100644 --- a/c/include/libsbp/solution_meta.h +++ b/c/include/libsbp/solution_meta.h @@ -44,28 +44,28 @@ typedef struct SBP_ATTR_PACKED { } solution_input_type_t; -/** Solution Sensors Metadata +/** Deprecated * * This message contains all metadata about the sensors received and/or used in computing the Fuzed Solution. * It focuses primarly, but not only, on GNSS metadata. */ -#define SBP_MSG_SOLN_META 0xFF0F -#define SBP_SOLN_META_ALIGNMENT_STATUS_MASK (0x7) -#define SBP_SOLN_META_ALIGNMENT_STATUS_SHIFT (0u) -#define SBP_SOLN_META_ALIGNMENT_STATUS_GET(flags) \ - (((flags) >> SBP_SOLN_META_ALIGNMENT_STATUS_SHIFT) \ - & SBP_SOLN_META_ALIGNMENT_STATUS_MASK) -#define SBP_SOLN_META_ALIGNMENT_STATUS_SET(flags, val) \ +#define SBP_MSG_SOLN_META_DEP_A 0xFF0F +#define SBP_SOLN_META_DEP_A_ALIGNMENT_STATUS_MASK (0x7) +#define SBP_SOLN_META_DEP_A_ALIGNMENT_STATUS_SHIFT (0u) +#define SBP_SOLN_META_DEP_A_ALIGNMENT_STATUS_GET(flags) \ + (((flags) >> SBP_SOLN_META_DEP_A_ALIGNMENT_STATUS_SHIFT) \ + & SBP_SOLN_META_DEP_A_ALIGNMENT_STATUS_MASK) +#define SBP_SOLN_META_DEP_A_ALIGNMENT_STATUS_SET(flags, val) \ do {((flags) |= \ - (((val) & (SBP_SOLN_META_ALIGNMENT_STATUS_MASK)) \ - << (SBP_SOLN_META_ALIGNMENT_STATUS_SHIFT)));} while(0) + (((val) & (SBP_SOLN_META_DEP_A_ALIGNMENT_STATUS_MASK)) \ + << (SBP_SOLN_META_DEP_A_ALIGNMENT_STATUS_SHIFT)));} while(0) -#define SBP_SOLN_META_ALIGNMENT_STATUS_UNKNOWN_REASON_OR_ALREADY_ALIGNED (0) -#define SBP_SOLN_META_ALIGNMENT_STATUS_SEED_VALUES_LOADED_AND_ALIGNMENT_IN_PROGRESS (1) -#define SBP_SOLN_META_ALIGNMENT_STATUS_NO_SEED_VALUES_AND_ALIGNMENT_IN_PROGRESS (2) -#define SBP_SOLN_META_ALIGNMENT_STATUS_SEED_VALUES_LOADED_BUT_NO_GNSS_MEASUREMENTS (3) -#define SBP_SOLN_META_ALIGNMENT_STATUS_NO_SEED_VALUES_NOR_GNSS_MEASUREMENTS (4) +#define SBP_SOLN_META_DEP_A_ALIGNMENT_STATUS_UNKNOWN_REASON_OR_ALREADY_ALIGNED (0) +#define SBP_SOLN_META_DEP_A_ALIGNMENT_STATUS_SEED_VALUES_LOADED_AND_ALIGNMENT_IN_PROGRESS (1) +#define SBP_SOLN_META_DEP_A_ALIGNMENT_STATUS_NO_SEED_VALUES_AND_ALIGNMENT_IN_PROGRESS (2) +#define SBP_SOLN_META_DEP_A_ALIGNMENT_STATUS_SEED_VALUES_LOADED_BUT_NO_GNSS_MEASUREMENTS (3) +#define SBP_SOLN_META_DEP_A_ALIGNMENT_STATUS_NO_SEED_VALUES_NOR_GNSS_MEASUREMENTS (4) typedef struct SBP_ATTR_PACKED { u16 pdop; /**< Position Dilution of Precision, as per last available DOPS from Starling GNSS engine [0.01] */ @@ -77,6 +77,24 @@ typedef struct SBP_ATTR_PACKED { u32 last_used_gnss_pos_tow; /**< Tow of last-used GNSS position measurement [ms] */ u32 last_used_gnss_vel_tow; /**< Tow of last-used GNSS velocity measurement [ms] */ solution_input_type_t sol_in[0]; /**< Array of Metadata describing the sensors potentially involved in the solution. Each element in the array represents a single sensor type and consists of flags containing (meta)data pertaining to that specific single sensor. Refer to each (XX)InputType descriptor in the present doc. */ +} msg_soln_meta_dep_a_t; + + +/** Solution Sensors Metadata + * + * This message contains all metadata about the sensors received and/or used in computing the sensorfusion solution. + * It focuses primarly, but not only, on GNSS metadata. + */ +#define SBP_MSG_SOLN_META 0xFF0E + +typedef struct SBP_ATTR_PACKED { + u32 tow; /**< GPS time of week rounded to the nearest millisecond [ms] */ + u16 pdop; /**< Position Dilution of Precision, as per last available DOPS from Starling GNSS engine [0.01] */ + u16 hdop; /**< Horizontal Dilution of Precision, as per last available DOPS from Starling GNSS engine [0.01] */ + u16 vdop; /**< Vertical Dilution of Precision, as per last available DOPS from Starling GNSS engine [0.01] */ + u16 age_corrections; /**< Age of the corrections (0xFFFF indicates invalid), as per last available AGE_CORRECTIONS from Starling GNSS engine [deciseconds] */ + u16 age_gnss; /**< Age of the last received valid GNSS solution (0xFFFF indicates invalid) [ms] */ + solution_input_type_t sol_in[0]; /**< Array of Metadata describing the sensors potentially involved in the solution. Each element in the array represents a single sensor type and consists of flags containing (meta)data pertaining to that specific single sensor. Refer to each (XX)InputType descriptor in the present doc. */ } msg_soln_meta_t; diff --git a/docs/sbp.pdf b/docs/sbp.pdf index 2c01f9e268..9ed75475a3 100644 Binary files a/docs/sbp.pdf and b/docs/sbp.pdf differ diff --git a/haskell/src/SwiftNav/SBP/Msg.hs b/haskell/src/SwiftNav/SBP/Msg.hs index dfb701ce4b..5c912787ef 100644 --- a/haskell/src/SwiftNav/SBP/Msg.hs +++ b/haskell/src/SwiftNav/SBP/Msg.hs @@ -202,6 +202,7 @@ data SBPMsg = | SBPMsgSettingsWrite MsgSettingsWrite Msg | SBPMsgSettingsWriteResp MsgSettingsWriteResp Msg | SBPMsgSolnMeta MsgSolnMeta Msg + | SBPMsgSolnMetaDepA MsgSolnMetaDepA Msg | SBPMsgSpecan MsgSpecan Msg | SBPMsgSpecanDep MsgSpecanDep Msg | SBPMsgSsrCodeBiases MsgSsrCodeBiases Msg @@ -408,6 +409,7 @@ instance Binary SBPMsg where | _msgSBPType == msgSettingsWrite = SBPMsgSettingsWrite (decode (fromStrict (unBytes _msgSBPPayload))) m | _msgSBPType == msgSettingsWriteResp = SBPMsgSettingsWriteResp (decode (fromStrict (unBytes _msgSBPPayload))) m | _msgSBPType == msgSolnMeta = SBPMsgSolnMeta (decode (fromStrict (unBytes _msgSBPPayload))) m + | _msgSBPType == msgSolnMetaDepA = SBPMsgSolnMetaDepA (decode (fromStrict (unBytes _msgSBPPayload))) m | _msgSBPType == msgSpecan = SBPMsgSpecan (decode (fromStrict (unBytes _msgSBPPayload))) m | _msgSBPType == msgSpecanDep = SBPMsgSpecanDep (decode (fromStrict (unBytes _msgSBPPayload))) m | _msgSBPType == msgSsrCodeBiases = SBPMsgSsrCodeBiases (decode (fromStrict (unBytes _msgSBPPayload))) m @@ -606,6 +608,7 @@ instance Binary SBPMsg where encoder (SBPMsgSettingsWrite _ m) = put m encoder (SBPMsgSettingsWriteResp _ m) = put m encoder (SBPMsgSolnMeta _ m) = put m + encoder (SBPMsgSolnMetaDepA _ m) = put m encoder (SBPMsgSpecan _ m) = put m encoder (SBPMsgSpecanDep _ m) = put m encoder (SBPMsgSsrCodeBiases _ m) = put m @@ -808,6 +811,7 @@ instance FromJSON SBPMsg where | msgType == msgSettingsWrite = SBPMsgSettingsWrite <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj | msgType == msgSettingsWriteResp = SBPMsgSettingsWriteResp <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj | msgType == msgSolnMeta = SBPMsgSolnMeta <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj + | msgType == msgSolnMetaDepA = SBPMsgSolnMetaDepA <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj | msgType == msgSpecan = SBPMsgSpecan <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj | msgType == msgSpecanDep = SBPMsgSpecanDep <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj | msgType == msgSsrCodeBiases = SBPMsgSsrCodeBiases <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj @@ -1011,6 +1015,7 @@ instance ToJSON SBPMsg where toJSON (SBPMsgSettingsWrite n m) = toJSON n <<>> toJSON m toJSON (SBPMsgSettingsWriteResp n m) = toJSON n <<>> toJSON m toJSON (SBPMsgSolnMeta n m) = toJSON n <<>> toJSON m + toJSON (SBPMsgSolnMetaDepA n m) = toJSON n <<>> toJSON m toJSON (SBPMsgSpecan n m) = toJSON n <<>> toJSON m toJSON (SBPMsgSpecanDep n m) = toJSON n <<>> toJSON m toJSON (SBPMsgSsrCodeBiases n m) = toJSON n <<>> toJSON m @@ -1208,6 +1213,7 @@ instance HasMsg SBPMsg where msg f (SBPMsgSettingsWrite n m) = SBPMsgSettingsWrite n <$> f m msg f (SBPMsgSettingsWriteResp n m) = SBPMsgSettingsWriteResp n <$> f m msg f (SBPMsgSolnMeta n m) = SBPMsgSolnMeta n <$> f m + msg f (SBPMsgSolnMetaDepA n m) = SBPMsgSolnMetaDepA n <$> f m msg f (SBPMsgSpecan n m) = SBPMsgSpecan n <$> f m msg f (SBPMsgSpecanDep n m) = SBPMsgSpecanDep n <$> f m msg f (SBPMsgSsrCodeBiases n m) = SBPMsgSsrCodeBiases n <$> f m diff --git a/haskell/src/SwiftNav/SBP/SolutionMeta.hs b/haskell/src/SwiftNav/SBP/SolutionMeta.hs index cee6163791..d1b5fdaa7f 100644 --- a/haskell/src/SwiftNav/SBP/SolutionMeta.hs +++ b/haskell/src/SwiftNav/SBP/SolutionMeta.hs @@ -64,37 +64,98 @@ instance Binary SolutionInputType where $(makeJSON "_solutionInputType_" ''SolutionInputType) $(makeLenses ''SolutionInputType) -msgSolnMeta :: Word16 -msgSolnMeta = 0xFF0F +msgSolnMetaDepA :: Word16 +msgSolnMetaDepA = 0xFF0F --- | SBP class for message MSG_SOLN_META (0xFF0F). +-- | SBP class for message MSG_SOLN_META_DEP_A (0xFF0F). -- -- This message contains all metadata about the sensors received and/or used in -- computing the Fuzed Solution. It focuses primarly, but not only, on GNSS -- metadata. -data MsgSolnMeta = MsgSolnMeta - { _msgSolnMeta_pdop :: !Word16 +data MsgSolnMetaDepA = MsgSolnMetaDepA + { _msgSolnMetaDepA_pdop :: !Word16 -- ^ Position Dilution of Precision, as per last available DOPS from Starling -- GNSS engine - , _msgSolnMeta_hdop :: !Word16 + , _msgSolnMetaDepA_hdop :: !Word16 -- ^ Horizontal Dilution of Precision, as per last available DOPS from -- Starling GNSS engine - , _msgSolnMeta_vdop :: !Word16 + , _msgSolnMetaDepA_vdop :: !Word16 -- ^ Vertical Dilution of Precision, as per last available DOPS from Starling -- GNSS engine - , _msgSolnMeta_n_sats :: !Word8 + , _msgSolnMetaDepA_n_sats :: !Word8 -- ^ Number of satellites, as per last available solution from Starling GNSS -- engine - , _msgSolnMeta_age_corrections :: !Word16 + , _msgSolnMetaDepA_age_corrections :: !Word16 -- ^ Age of the corrections (0xFFFF indicates invalid), as per last available -- AGE_CORRECTIONS from Starling GNSS engine - , _msgSolnMeta_alignment_status :: !Word8 + , _msgSolnMetaDepA_alignment_status :: !Word8 -- ^ State of alignment and the status and receipt of the alignment inputs - , _msgSolnMeta_last_used_gnss_pos_tow :: !Word32 + , _msgSolnMetaDepA_last_used_gnss_pos_tow :: !Word32 -- ^ Tow of last-used GNSS position measurement - , _msgSolnMeta_last_used_gnss_vel_tow :: !Word32 + , _msgSolnMetaDepA_last_used_gnss_vel_tow :: !Word32 -- ^ Tow of last-used GNSS velocity measurement - , _msgSolnMeta_sol_in :: ![SolutionInputType] + , _msgSolnMetaDepA_sol_in :: ![SolutionInputType] + -- ^ Array of Metadata describing the sensors potentially involved in the + -- solution. Each element in the array represents a single sensor type and + -- consists of flags containing (meta)data pertaining to that specific + -- single sensor. Refer to each (XX)InputType descriptor in the present + -- doc. + } deriving ( Show, Read, Eq ) + +instance Binary MsgSolnMetaDepA where + get = do + _msgSolnMetaDepA_pdop <- getWord16le + _msgSolnMetaDepA_hdop <- getWord16le + _msgSolnMetaDepA_vdop <- getWord16le + _msgSolnMetaDepA_n_sats <- getWord8 + _msgSolnMetaDepA_age_corrections <- getWord16le + _msgSolnMetaDepA_alignment_status <- getWord8 + _msgSolnMetaDepA_last_used_gnss_pos_tow <- getWord32le + _msgSolnMetaDepA_last_used_gnss_vel_tow <- getWord32le + _msgSolnMetaDepA_sol_in <- whileM (not <$> isEmpty) get + pure MsgSolnMetaDepA {..} + + put MsgSolnMetaDepA {..} = do + putWord16le _msgSolnMetaDepA_pdop + putWord16le _msgSolnMetaDepA_hdop + putWord16le _msgSolnMetaDepA_vdop + putWord8 _msgSolnMetaDepA_n_sats + putWord16le _msgSolnMetaDepA_age_corrections + putWord8 _msgSolnMetaDepA_alignment_status + putWord32le _msgSolnMetaDepA_last_used_gnss_pos_tow + putWord32le _msgSolnMetaDepA_last_used_gnss_vel_tow + mapM_ put _msgSolnMetaDepA_sol_in + +$(makeSBP 'msgSolnMetaDepA ''MsgSolnMetaDepA) +$(makeJSON "_msgSolnMetaDepA_" ''MsgSolnMetaDepA) +$(makeLenses ''MsgSolnMetaDepA) + +msgSolnMeta :: Word16 +msgSolnMeta = 0xFF0E + +-- | SBP class for message MSG_SOLN_META (0xFF0E). +-- +-- This message contains all metadata about the sensors received and/or used in +-- computing the sensorfusion solution. It focuses primarly, but not only, on +-- GNSS metadata. +data MsgSolnMeta = MsgSolnMeta + { _msgSolnMeta_tow :: !Word32 + -- ^ GPS time of week rounded to the nearest millisecond + , _msgSolnMeta_pdop :: !Word16 + -- ^ Position Dilution of Precision, as per last available DOPS from Starling + -- GNSS engine + , _msgSolnMeta_hdop :: !Word16 + -- ^ Horizontal Dilution of Precision, as per last available DOPS from + -- Starling GNSS engine + , _msgSolnMeta_vdop :: !Word16 + -- ^ Vertical Dilution of Precision, as per last available DOPS from Starling + -- GNSS engine + , _msgSolnMeta_age_corrections :: !Word16 + -- ^ Age of the corrections (0xFFFF indicates invalid), as per last available + -- AGE_CORRECTIONS from Starling GNSS engine + , _msgSolnMeta_age_gnss :: !Word16 + -- ^ Age of the last received valid GNSS solution (0xFFFF indicates invalid) + , _msgSolnMeta_sol_in :: ![SolutionInputType] -- ^ Array of Metadata describing the sensors potentially involved in the -- solution. Each element in the array represents a single sensor type and -- consists of flags containing (meta)data pertaining to that specific @@ -104,26 +165,22 @@ data MsgSolnMeta = MsgSolnMeta instance Binary MsgSolnMeta where get = do + _msgSolnMeta_tow <- getWord32le _msgSolnMeta_pdop <- getWord16le _msgSolnMeta_hdop <- getWord16le _msgSolnMeta_vdop <- getWord16le - _msgSolnMeta_n_sats <- getWord8 _msgSolnMeta_age_corrections <- getWord16le - _msgSolnMeta_alignment_status <- getWord8 - _msgSolnMeta_last_used_gnss_pos_tow <- getWord32le - _msgSolnMeta_last_used_gnss_vel_tow <- getWord32le + _msgSolnMeta_age_gnss <- getWord16le _msgSolnMeta_sol_in <- whileM (not <$> isEmpty) get pure MsgSolnMeta {..} put MsgSolnMeta {..} = do + putWord32le _msgSolnMeta_tow putWord16le _msgSolnMeta_pdop putWord16le _msgSolnMeta_hdop putWord16le _msgSolnMeta_vdop - putWord8 _msgSolnMeta_n_sats putWord16le _msgSolnMeta_age_corrections - putWord8 _msgSolnMeta_alignment_status - putWord32le _msgSolnMeta_last_used_gnss_pos_tow - putWord32le _msgSolnMeta_last_used_gnss_vel_tow + putWord16le _msgSolnMeta_age_gnss mapM_ put _msgSolnMeta_sol_in $(makeSBP 'msgSolnMeta ''MsgSolnMeta) diff --git a/java/src/com/swiftnav/sbp/client/MessageTable.java b/java/src/com/swiftnav/sbp/client/MessageTable.java index de5736deeb..c47b4a472d 100644 --- a/java/src/com/swiftnav/sbp/client/MessageTable.java +++ b/java/src/com/swiftnav/sbp/client/MessageTable.java @@ -175,6 +175,7 @@ import com.swiftnav.sbp.settings.MsgSettingsReadByIndexDone; import com.swiftnav.sbp.settings.MsgSettingsRegister; import com.swiftnav.sbp.settings.MsgSettingsRegisterResp; +import com.swiftnav.sbp.solution_meta.MsgSolnMetaDepA; import com.swiftnav.sbp.solution_meta.MsgSolnMeta; import com.swiftnav.sbp.ssr.MsgSsrOrbitClock; import com.swiftnav.sbp.ssr.MsgSsrCodeBiases; @@ -532,6 +533,8 @@ static SBPMessage dispatch(SBPMessage msg) throws SBPBinaryException { return new MsgSettingsRegister(msg); case MsgSettingsRegisterResp.TYPE: return new MsgSettingsRegisterResp(msg); + case MsgSolnMetaDepA.TYPE: + return new MsgSolnMetaDepA(msg); case MsgSolnMeta.TYPE: return new MsgSolnMeta(msg); case MsgSsrOrbitClock.TYPE: diff --git a/java/src/com/swiftnav/sbp/solution_meta/MsgSolnMeta.java b/java/src/com/swiftnav/sbp/solution_meta/MsgSolnMeta.java index c4a0150d66..27bd00e076 100644 --- a/java/src/com/swiftnav/sbp/solution_meta/MsgSolnMeta.java +++ b/java/src/com/swiftnav/sbp/solution_meta/MsgSolnMeta.java @@ -22,19 +22,22 @@ import org.json.JSONArray; -/** SBP class for message MSG_SOLN_META (0xFF0F). +/** SBP class for message MSG_SOLN_META (0xFF0E). * * You can have MSG_SOLN_META inherent its fields directly from * an inherited SBP object, or construct it inline using a dict of its * fields. * - * This message contains all metadata about the sensors received and/or used in computing the Fuzed Solution. + * This message contains all metadata about the sensors received and/or used in computing the sensorfusion solution. * It focuses primarly, but not only, on GNSS metadata. */ public class MsgSolnMeta extends SBPMessage { - public static final int TYPE = 0xFF0F; + public static final int TYPE = 0xFF0E; + /** GPS time of week rounded to the nearest millisecond */ + public long tow; + /** Position Dilution of Precision, as per last available DOPS from Starling GNSS engine */ public int pdop; @@ -44,20 +47,11 @@ public class MsgSolnMeta extends SBPMessage { /** Vertical Dilution of Precision, as per last available DOPS from Starling GNSS engine */ public int vdop; - /** Number of satellites, as per last available solution from Starling GNSS engine */ - public int n_sats; - /** Age of the corrections (0xFFFF indicates invalid), as per last available AGE_CORRECTIONS from Starling GNSS engine */ public int age_corrections; - /** State of alignment and the status and receipt of the alignment inputs */ - public int alignment_status; - - /** Tow of last-used GNSS position measurement */ - public long last_used_gnss_pos_tow; - - /** Tow of last-used GNSS velocity measurement */ - public long last_used_gnss_vel_tow; + /** Age of the last received valid GNSS solution (0xFFFF indicates invalid) */ + public int age_gnss; /** Array of Metadata describing the sensors potentially involved in the solution. Each element in the array represents a single sensor type and consists of flags containing (meta)data pertaining to that specific single sensor. Refer to each (XX)InputType descriptor in the present doc. */ public SolutionInputType[] sol_in; @@ -73,41 +67,35 @@ public MsgSolnMeta (SBPMessage msg) throws SBPBinaryException { @Override protected void parse(Parser parser) throws SBPBinaryException { /* Parse fields from binary */ + tow = parser.getU32(); pdop = parser.getU16(); hdop = parser.getU16(); vdop = parser.getU16(); - n_sats = parser.getU8(); age_corrections = parser.getU16(); - alignment_status = parser.getU8(); - last_used_gnss_pos_tow = parser.getU32(); - last_used_gnss_vel_tow = parser.getU32(); + age_gnss = parser.getU16(); sol_in = parser.getArray(SolutionInputType.class); } @Override protected void build(Builder builder) { + builder.putU32(tow); builder.putU16(pdop); builder.putU16(hdop); builder.putU16(vdop); - builder.putU8(n_sats); builder.putU16(age_corrections); - builder.putU8(alignment_status); - builder.putU32(last_used_gnss_pos_tow); - builder.putU32(last_used_gnss_vel_tow); + builder.putU16(age_gnss); builder.putArray(sol_in); } @Override public JSONObject toJSON() { JSONObject obj = super.toJSON(); + obj.put("tow", tow); obj.put("pdop", pdop); obj.put("hdop", hdop); obj.put("vdop", vdop); - obj.put("n_sats", n_sats); obj.put("age_corrections", age_corrections); - obj.put("alignment_status", alignment_status); - obj.put("last_used_gnss_pos_tow", last_used_gnss_pos_tow); - obj.put("last_used_gnss_vel_tow", last_used_gnss_vel_tow); + obj.put("age_gnss", age_gnss); obj.put("sol_in", SBPStruct.toJSONArray(sol_in)); return obj; } diff --git a/java/src/com/swiftnav/sbp/solution_meta/MsgSolnMetaDepA.java b/java/src/com/swiftnav/sbp/solution_meta/MsgSolnMetaDepA.java new file mode 100644 index 0000000000..fed0d31a70 --- /dev/null +++ b/java/src/com/swiftnav/sbp/solution_meta/MsgSolnMetaDepA.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2015-2018 Swift Navigation Inc. + * Contact: https://support.swiftnav.com + * + * This source is subject to the license found in the file 'LICENSE' which must + * be be distributed together with this source. All other rights reserved. + * + * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, + * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + */ + +package com.swiftnav.sbp.solution_meta; + +import java.math.BigInteger; + +import com.swiftnav.sbp.SBPMessage; +import com.swiftnav.sbp.SBPBinaryException; +import com.swiftnav.sbp.SBPStruct; + +import org.json.JSONObject; +import org.json.JSONArray; + + +/** SBP class for message MSG_SOLN_META_DEP_A (0xFF0F). + * + * You can have MSG_SOLN_META_DEP_A inherent its fields directly from + * an inherited SBP object, or construct it inline using a dict of its + * fields. + * + * This message contains all metadata about the sensors received and/or used in computing the Fuzed Solution. + * It focuses primarly, but not only, on GNSS metadata. */ + +public class MsgSolnMetaDepA extends SBPMessage { + public static final int TYPE = 0xFF0F; + + + /** Position Dilution of Precision, as per last available DOPS from Starling GNSS engine */ + public int pdop; + + /** Horizontal Dilution of Precision, as per last available DOPS from Starling GNSS engine */ + public int hdop; + + /** Vertical Dilution of Precision, as per last available DOPS from Starling GNSS engine */ + public int vdop; + + /** Number of satellites, as per last available solution from Starling GNSS engine */ + public int n_sats; + + /** Age of the corrections (0xFFFF indicates invalid), as per last available AGE_CORRECTIONS from Starling GNSS engine */ + public int age_corrections; + + /** State of alignment and the status and receipt of the alignment inputs */ + public int alignment_status; + + /** Tow of last-used GNSS position measurement */ + public long last_used_gnss_pos_tow; + + /** Tow of last-used GNSS velocity measurement */ + public long last_used_gnss_vel_tow; + + /** Array of Metadata describing the sensors potentially involved in the solution. Each element in the array represents a single sensor type and consists of flags containing (meta)data pertaining to that specific single sensor. Refer to each (XX)InputType descriptor in the present doc. */ + public SolutionInputType[] sol_in; + + + public MsgSolnMetaDepA (int sender) { super(sender, TYPE); } + public MsgSolnMetaDepA () { super(TYPE); } + public MsgSolnMetaDepA (SBPMessage msg) throws SBPBinaryException { + super(msg); + assert msg.type != TYPE; + } + + @Override + protected void parse(Parser parser) throws SBPBinaryException { + /* Parse fields from binary */ + pdop = parser.getU16(); + hdop = parser.getU16(); + vdop = parser.getU16(); + n_sats = parser.getU8(); + age_corrections = parser.getU16(); + alignment_status = parser.getU8(); + last_used_gnss_pos_tow = parser.getU32(); + last_used_gnss_vel_tow = parser.getU32(); + sol_in = parser.getArray(SolutionInputType.class); + } + + @Override + protected void build(Builder builder) { + builder.putU16(pdop); + builder.putU16(hdop); + builder.putU16(vdop); + builder.putU8(n_sats); + builder.putU16(age_corrections); + builder.putU8(alignment_status); + builder.putU32(last_used_gnss_pos_tow); + builder.putU32(last_used_gnss_vel_tow); + builder.putArray(sol_in); + } + + @Override + public JSONObject toJSON() { + JSONObject obj = super.toJSON(); + obj.put("pdop", pdop); + obj.put("hdop", hdop); + obj.put("vdop", vdop); + obj.put("n_sats", n_sats); + obj.put("age_corrections", age_corrections); + obj.put("alignment_status", alignment_status); + obj.put("last_used_gnss_pos_tow", last_used_gnss_pos_tow); + obj.put("last_used_gnss_vel_tow", last_used_gnss_vel_tow); + obj.put("sol_in", SBPStruct.toJSONArray(sol_in)); + return obj; + } +} \ No newline at end of file diff --git a/javascript/sbp/solution_meta.js b/javascript/sbp/solution_meta.js index 247170b09b..67435004ee 100644 --- a/javascript/sbp/solution_meta.js +++ b/javascript/sbp/solution_meta.js @@ -58,7 +58,7 @@ SolutionInputType.prototype.fieldSpec.push(['sensor_type', 'writeUInt8', 1]); SolutionInputType.prototype.fieldSpec.push(['flags', 'writeUInt8', 1]); /** - * SBP class for message MSG_SOLN_META (0xFF0F). + * SBP class for message MSG_SOLN_META_DEP_A (0xFF0F). * * This message contains all metadata about the sensors received and/or used in * computing the Fuzed Solution. It focuses primarly, but not only, on GNSS @@ -84,6 +84,64 @@ SolutionInputType.prototype.fieldSpec.push(['flags', 'writeUInt8', 1]); * * @param sbp An SBP object with a payload to be decoded. */ +var MsgSolnMetaDepA = function (sbp, fields) { + SBP.call(this, sbp); + this.messageType = "MSG_SOLN_META_DEP_A"; + this.fields = (fields || this.parser.parse(sbp.payload)); + + return this; +}; +MsgSolnMetaDepA.prototype = Object.create(SBP.prototype); +MsgSolnMetaDepA.prototype.messageType = "MSG_SOLN_META_DEP_A"; +MsgSolnMetaDepA.prototype.msg_type = 0xFF0F; +MsgSolnMetaDepA.prototype.constructor = MsgSolnMetaDepA; +MsgSolnMetaDepA.prototype.parser = new Parser() + .endianess('little') + .uint16('pdop') + .uint16('hdop') + .uint16('vdop') + .uint8('n_sats') + .uint16('age_corrections') + .uint8('alignment_status') + .uint32('last_used_gnss_pos_tow') + .uint32('last_used_gnss_vel_tow') + .array('sol_in', { type: SolutionInputType.prototype.parser, readUntil: 'eof' }); +MsgSolnMetaDepA.prototype.fieldSpec = []; +MsgSolnMetaDepA.prototype.fieldSpec.push(['pdop', 'writeUInt16LE', 2]); +MsgSolnMetaDepA.prototype.fieldSpec.push(['hdop', 'writeUInt16LE', 2]); +MsgSolnMetaDepA.prototype.fieldSpec.push(['vdop', 'writeUInt16LE', 2]); +MsgSolnMetaDepA.prototype.fieldSpec.push(['n_sats', 'writeUInt8', 1]); +MsgSolnMetaDepA.prototype.fieldSpec.push(['age_corrections', 'writeUInt16LE', 2]); +MsgSolnMetaDepA.prototype.fieldSpec.push(['alignment_status', 'writeUInt8', 1]); +MsgSolnMetaDepA.prototype.fieldSpec.push(['last_used_gnss_pos_tow', 'writeUInt32LE', 4]); +MsgSolnMetaDepA.prototype.fieldSpec.push(['last_used_gnss_vel_tow', 'writeUInt32LE', 4]); +MsgSolnMetaDepA.prototype.fieldSpec.push(['sol_in', 'array', SolutionInputType.prototype.fieldSpec, function () { return this.fields.array.length; }, null]); + +/** + * SBP class for message MSG_SOLN_META (0xFF0E). + * + * This message contains all metadata about the sensors received and/or used in + * computing the sensorfusion solution. It focuses primarly, but not only, on GNSS + * metadata. + * + * Fields in the SBP payload (`sbp.payload`): + * @field tow number (unsigned 32-bit int, 4 bytes) GPS time of week rounded to the nearest millisecond + * @field pdop number (unsigned 16-bit int, 2 bytes) Position Dilution of Precision, as per last available DOPS from Starling GNSS + * engine + * @field hdop number (unsigned 16-bit int, 2 bytes) Horizontal Dilution of Precision, as per last available DOPS from Starling GNSS + * engine + * @field vdop number (unsigned 16-bit int, 2 bytes) Vertical Dilution of Precision, as per last available DOPS from Starling GNSS + * engine + * @field age_corrections number (unsigned 16-bit int, 2 bytes) Age of the corrections (0xFFFF indicates invalid), as per last available + * AGE_CORRECTIONS from Starling GNSS engine + * @field age_gnss number (unsigned 16-bit int, 2 bytes) Age of the last received valid GNSS solution (0xFFFF indicates invalid) + * @field sol_in array Array of Metadata describing the sensors potentially involved in the solution. + * Each element in the array represents a single sensor type and consists of flags + * containing (meta)data pertaining to that specific single sensor. Refer to each + * (XX)InputType descriptor in the present doc. + * + * @param sbp An SBP object with a payload to be decoded. + */ var MsgSolnMeta = function (sbp, fields) { SBP.call(this, sbp); this.messageType = "MSG_SOLN_META"; @@ -93,28 +151,24 @@ var MsgSolnMeta = function (sbp, fields) { }; MsgSolnMeta.prototype = Object.create(SBP.prototype); MsgSolnMeta.prototype.messageType = "MSG_SOLN_META"; -MsgSolnMeta.prototype.msg_type = 0xFF0F; +MsgSolnMeta.prototype.msg_type = 0xFF0E; MsgSolnMeta.prototype.constructor = MsgSolnMeta; MsgSolnMeta.prototype.parser = new Parser() .endianess('little') + .uint32('tow') .uint16('pdop') .uint16('hdop') .uint16('vdop') - .uint8('n_sats') .uint16('age_corrections') - .uint8('alignment_status') - .uint32('last_used_gnss_pos_tow') - .uint32('last_used_gnss_vel_tow') + .uint16('age_gnss') .array('sol_in', { type: SolutionInputType.prototype.parser, readUntil: 'eof' }); MsgSolnMeta.prototype.fieldSpec = []; +MsgSolnMeta.prototype.fieldSpec.push(['tow', 'writeUInt32LE', 4]); MsgSolnMeta.prototype.fieldSpec.push(['pdop', 'writeUInt16LE', 2]); MsgSolnMeta.prototype.fieldSpec.push(['hdop', 'writeUInt16LE', 2]); MsgSolnMeta.prototype.fieldSpec.push(['vdop', 'writeUInt16LE', 2]); -MsgSolnMeta.prototype.fieldSpec.push(['n_sats', 'writeUInt8', 1]); MsgSolnMeta.prototype.fieldSpec.push(['age_corrections', 'writeUInt16LE', 2]); -MsgSolnMeta.prototype.fieldSpec.push(['alignment_status', 'writeUInt8', 1]); -MsgSolnMeta.prototype.fieldSpec.push(['last_used_gnss_pos_tow', 'writeUInt32LE', 4]); -MsgSolnMeta.prototype.fieldSpec.push(['last_used_gnss_vel_tow', 'writeUInt32LE', 4]); +MsgSolnMeta.prototype.fieldSpec.push(['age_gnss', 'writeUInt16LE', 2]); MsgSolnMeta.prototype.fieldSpec.push(['sol_in', 'array', SolutionInputType.prototype.fieldSpec, function () { return this.fields.array.length; }, null]); /** @@ -200,7 +254,9 @@ OdoInputType.prototype.fieldSpec.push(['flags', 'writeUInt8', 1]); module.exports = { SolutionInputType: SolutionInputType, - 0xFF0F: MsgSolnMeta, + 0xFF0F: MsgSolnMetaDepA, + MsgSolnMetaDepA: MsgSolnMetaDepA, + 0xFF0E: MsgSolnMeta, MsgSolnMeta: MsgSolnMeta, GNSSInputType: GNSSInputType, IMUInputType: IMUInputType, diff --git a/jsonschema/MsgSolnMeta.json b/jsonschema/MsgSolnMeta.json index bbd5648e50..91dcb7591d 100644 --- a/jsonschema/MsgSolnMeta.json +++ b/jsonschema/MsgSolnMeta.json @@ -13,28 +13,24 @@ "$schema": "http://json-schema.org/draft-06/schema#", "$id": "#MsgSolnMeta", "title":"MsgSolnMeta", - "description":"This message contains all metadata about the sensors received and/or used in computing the Fuzed Solution.,\nIt focuses primarly, but not only, on GNSS metadata.\n", + "description":"This message contains all metadata about the sensors received and/or used in computing the sensorfusion solution.,\nIt focuses primarly, but not only, on GNSS metadata.\n", "type": "object", "properties": { + "tow": {"type": "integer"}, "pdop": {"type": "integer"}, "hdop": {"type": "integer"}, "vdop": {"type": "integer"}, - "n_sats": {"type": "integer"}, "age_corrections": {"type": "integer"}, - "alignment_status": {"type": "integer"}, - "last_used_gnss_pos_tow": {"type": "integer"}, - "last_used_gnss_vel_tow": {"type": "integer"}, + "age_gnss": {"type": "integer"}, "sol_in": {"type": "array", "items": {"$ref": "SolutionInputType.json"}} }, "required": [ + "tow", "pdop", "hdop", "vdop", - "n_sats", "age_corrections", - "alignment_status", - "last_used_gnss_pos_tow", - "last_used_gnss_vel_tow", + "age_gnss", "sol_in" ] } \ No newline at end of file diff --git a/proto/solution_meta.proto b/proto/solution_meta.proto index e7c6aafad1..02dcab0fd5 100644 --- a/proto/solution_meta.proto +++ b/proto/solution_meta.proto @@ -36,19 +36,17 @@ message SolutionInputType { /** Solution Sensors Metadata * - * This message contains all metadata about the sensors received and/or used in computing the Fuzed Solution. + * This message contains all metadata about the sensors received and/or used in computing the sensorfusion solution. * It focuses primarly, but not only, on GNSS metadata. */ message MsgSolnMeta { - uint32 pdop = 1; - uint32 hdop = 2; - uint32 vdop = 3; - uint32 n_sats = 4; + uint32 tow = 1; + uint32 pdop = 2; + uint32 hdop = 3; + uint32 vdop = 4; uint32 age_corrections = 5; - uint32 alignment_status = 6; - uint32 last_used_gnss_pos_tow = 7; - uint32 last_used_gnss_vel_tow = 8; - repeated SolutionInputType sol_in = 9; + uint32 age_gnss = 6; + repeated SolutionInputType sol_in = 7; } /** Instruments the physical type of GNSS sensor input to the fuzed solution. diff --git a/python/sbp/RELEASE-VERSION b/python/sbp/RELEASE-VERSION index 4d9d11cf50..a423d4217b 100644 --- a/python/sbp/RELEASE-VERSION +++ b/python/sbp/RELEASE-VERSION @@ -1 +1 @@ -3.4.2 +3.4.2 \ No newline at end of file diff --git a/python/sbp/jit/solution_meta.py b/python/sbp/jit/solution_meta.py index c1d04a0766..d7691e1015 100644 --- a/python/sbp/jit/solution_meta.py +++ b/python/sbp/jit/solution_meta.py @@ -65,11 +65,11 @@ def _unpack_members(self, buf, offset, length): return res, off, length -SBP_MSG_SOLN_META = 0xFF0F -class MsgSolnMeta(SBP): - """SBP class for message MSG_SOLN_META (0xFF0F). +SBP_MSG_SOLN_META_DEP_A = 0xFF0F +class MsgSolnMetaDepA(SBP): + """SBP class for message MSG_SOLN_META_DEP_A (0xFF0F). - You can have MSG_SOLN_META inherit its fields directly + You can have MSG_SOLN_META_DEP_A inherit its fields directly from an inherited SBP object, or construct it inline using a dict of its fields. @@ -128,6 +128,61 @@ def _unpack_members(self, buf, offset, length): return res, off, length +SBP_MSG_SOLN_META = 0xFF0E +class MsgSolnMeta(SBP): + """SBP class for message MSG_SOLN_META (0xFF0E). + + You can have MSG_SOLN_META inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message contains all metadata about the sensors received and/or used in computing the sensorfusion solution. +It focuses primarly, but not only, on GNSS metadata. + + + """ + __slots__ = ['tow', + 'pdop', + 'hdop', + 'vdop', + 'age_corrections', + 'age_gnss', + 'sol_in', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__pdop, offset, length) = get_u16(buf, offset, length) + ret['pdop'] = __pdop + (__hdop, offset, length) = get_u16(buf, offset, length) + ret['hdop'] = __hdop + (__vdop, offset, length) = get_u16(buf, offset, length) + ret['vdop'] = __vdop + (__age_corrections, offset, length) = get_u16(buf, offset, length) + ret['age_corrections'] = __age_corrections + (__age_gnss, offset, length) = get_u16(buf, offset, length) + ret['age_gnss'] = __age_gnss + (__sol_in, offset, length) = get_array(SolutionInputType.parse_members)(buf, offset, length) + ret['sol_in'] = __sol_in + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.pdop = res['pdop'] + self.hdop = res['hdop'] + self.vdop = res['vdop'] + self.age_corrections = res['age_corrections'] + self.age_gnss = res['age_gnss'] + self.sol_in = res['sol_in'] + return res, off, length + + class GNSSInputType(object): """SBP class for message GNSSInputType @@ -220,5 +275,6 @@ def _unpack_members(self, buf, offset, length): msg_classes = { - 0xFF0F: MsgSolnMeta, + 0xFF0F: MsgSolnMetaDepA, + 0xFF0E: MsgSolnMeta, } \ No newline at end of file diff --git a/python/sbp/solution_meta.py b/python/sbp/solution_meta.py index 8f2ddf41da..d3d199de8f 100644 --- a/python/sbp/solution_meta.py +++ b/python/sbp/solution_meta.py @@ -182,11 +182,11 @@ def to_binary(self): d = dict([(k, getattr(obj, k)) for k in self.__slots__]) return OdoInputType.build(d) -SBP_MSG_SOLN_META = 0xFF0F -class MsgSolnMeta(SBP): - """SBP class for message MSG_SOLN_META (0xFF0F). +SBP_MSG_SOLN_META_DEP_A = 0xFF0F +class MsgSolnMetaDepA(SBP): + """SBP class for message MSG_SOLN_META_DEP_A (0xFF0F). - You can have MSG_SOLN_META inherit its fields directly + You can have MSG_SOLN_META_DEP_A inherit its fields directly from an inherited SBP object, or construct it inline using a dict of its fields. @@ -245,13 +245,13 @@ class MsgSolnMeta(SBP): def __init__(self, sbp=None, **kwargs): if sbp: - super( MsgSolnMeta, + super( MsgSolnMetaDepA, self).__init__(sbp.msg_type, sbp.sender, sbp.length, sbp.payload, sbp.crc) self.from_binary(sbp.payload) else: - super( MsgSolnMeta, self).__init__() - self.msg_type = SBP_MSG_SOLN_META + super( MsgSolnMetaDepA, self).__init__() + self.msg_type = SBP_MSG_SOLN_META_DEP_A self.sender = kwargs.pop('sender', SENDER_ID) self.pdop = kwargs.pop('pdop') self.hdop = kwargs.pop('hdop') @@ -266,6 +266,127 @@ def __init__(self, sbp=None, **kwargs): def __repr__(self): return fmt_repr(self) + @staticmethod + def from_json(s): + """Given a JSON-encoded string s, build a message object. + + """ + d = json.loads(s) + return MsgSolnMetaDepA.from_json_dict(d) + + @staticmethod + def from_json_dict(d): + sbp = SBP.from_json_dict(d) + return MsgSolnMetaDepA(sbp, **d) + + + def from_binary(self, d): + """Given a binary payload d, update the appropriate payload fields of + the message. + + """ + p = MsgSolnMetaDepA._parser.parse(d) + for n in self.__class__.__slots__: + setattr(self, n, getattr(p, n)) + + def to_binary(self): + """Produce a framed/packed SBP message. + + """ + c = containerize(exclude_fields(self)) + self.payload = MsgSolnMetaDepA._parser.build(c) + return self.pack() + + def into_buffer(self, buf, offset): + """Produce a framed/packed SBP message into the provided buffer and offset. + + """ + self.payload = containerize(exclude_fields(self)) + self.parser = MsgSolnMetaDepA._parser + self.stream_payload.reset(buf, offset) + return self.pack_into(buf, offset, self._build_payload) + + def to_json_dict(self): + self.to_binary() + d = super( MsgSolnMetaDepA, self).to_json_dict() + j = walk_json_dict(exclude_fields(self)) + d.update(j) + return d + +SBP_MSG_SOLN_META = 0xFF0E +class MsgSolnMeta(SBP): + """SBP class for message MSG_SOLN_META (0xFF0E). + + You can have MSG_SOLN_META inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message contains all metadata about the sensors received and/or used in computing the sensorfusion solution. +It focuses primarly, but not only, on GNSS metadata. + + + Parameters + ---------- + sbp : SBP + SBP parent object to inherit from. + tow : int + GPS time of week rounded to the nearest millisecond + pdop : int + Position Dilution of Precision, as per last available DOPS from Starling GNSS engine + hdop : int + Horizontal Dilution of Precision, as per last available DOPS from Starling GNSS engine + vdop : int + Vertical Dilution of Precision, as per last available DOPS from Starling GNSS engine + age_corrections : int + Age of the corrections (0xFFFF indicates invalid), as per last available AGE_CORRECTIONS from Starling GNSS engine + age_gnss : int + Age of the last received valid GNSS solution (0xFFFF indicates invalid) + sol_in : array + Array of Metadata describing the sensors potentially involved in the solution. Each element in the array represents a single sensor type and consists of flags containing (meta)data pertaining to that specific single sensor. Refer to each (XX)InputType descriptor in the present doc. + sender : int + Optional sender ID, defaults to SENDER_ID (see sbp/msg.py). + + """ + _parser = construct.Struct( + 'tow' / construct.Int32ul, + 'pdop' / construct.Int16ul, + 'hdop' / construct.Int16ul, + 'vdop' / construct.Int16ul, + 'age_corrections' / construct.Int16ul, + 'age_gnss' / construct.Int16ul, + construct.GreedyRange('sol_in' / construct.Struct(SolutionInputType._parser)),) + __slots__ = [ + 'tow', + 'pdop', + 'hdop', + 'vdop', + 'age_corrections', + 'age_gnss', + 'sol_in', + ] + + def __init__(self, sbp=None, **kwargs): + if sbp: + super( MsgSolnMeta, + self).__init__(sbp.msg_type, sbp.sender, sbp.length, + sbp.payload, sbp.crc) + self.from_binary(sbp.payload) + else: + super( MsgSolnMeta, self).__init__() + self.msg_type = SBP_MSG_SOLN_META + self.sender = kwargs.pop('sender', SENDER_ID) + self.tow = kwargs.pop('tow') + self.pdop = kwargs.pop('pdop') + self.hdop = kwargs.pop('hdop') + self.vdop = kwargs.pop('vdop') + self.age_corrections = kwargs.pop('age_corrections') + self.age_gnss = kwargs.pop('age_gnss') + self.sol_in = kwargs.pop('sol_in') + + def __repr__(self): + return fmt_repr(self) + @staticmethod def from_json(s): """Given a JSON-encoded string s, build a message object. @@ -315,5 +436,6 @@ def to_json_dict(self): msg_classes = { - 0xFF0F: MsgSolnMeta, + 0xFF0F: MsgSolnMetaDepA, + 0xFF0E: MsgSolnMeta, } \ No newline at end of file diff --git a/python/tests/sbp/test_table.py b/python/tests/sbp/test_table.py index 1ad4c86ebe..a06146f3a7 100644 --- a/python/tests/sbp/test_table.py +++ b/python/tests/sbp/test_table.py @@ -44,7 +44,7 @@ def test_table_count(): Test number of available messages to deserialize. """ - number_of_messages = 193 + number_of_messages = 194 assert len(_SBP_TABLE) == number_of_messages def test_table_unqiue_count(): diff --git a/rust/sbp/src/messages/mod.rs b/rust/sbp/src/messages/mod.rs index 8c23b229c8..eaeb44b2d5 100644 --- a/rust/sbp/src/messages/mod.rs +++ b/rust/sbp/src/messages/mod.rs @@ -192,6 +192,7 @@ use self::settings::MsgSettingsSave; use self::settings::MsgSettingsWrite; use self::settings::MsgSettingsWriteResp; use self::solution_meta::MsgSolnMeta; +use self::solution_meta::MsgSolnMetaDepA; use self::ssr::MsgSsrCodeBiases; use self::ssr::MsgSsrGridDefinitionDepA; use self::ssr::MsgSsrGriddedCorrection; @@ -433,6 +434,7 @@ pub enum SBP { MsgGnssTimeOffset(MsgGnssTimeOffset), MsgGroupMeta(MsgGroupMeta), MsgSolnMeta(MsgSolnMeta), + MsgSolnMetaDepA(MsgSolnMetaDepA), MsgHeartbeat(MsgHeartbeat), Unknown(Unknown), } @@ -1395,11 +1397,16 @@ impl SBP { msg.set_sender_id(sender_id); Ok(SBP::MsgGroupMeta(msg)) } - 65295 => { + 65294 => { let mut msg = MsgSolnMeta::parse(payload)?; msg.set_sender_id(sender_id); Ok(SBP::MsgSolnMeta(msg)) } + 65295 => { + let mut msg = MsgSolnMetaDepA::parse(payload)?; + msg.set_sender_id(sender_id); + Ok(SBP::MsgSolnMetaDepA(msg)) + } 65535 => { let mut msg = MsgHeartbeat::parse(payload)?; msg.set_sender_id(sender_id); @@ -1611,6 +1618,7 @@ impl SBP { SBP::MsgGnssTimeOffset(msg) => msg, SBP::MsgGroupMeta(msg) => msg, SBP::MsgSolnMeta(msg) => msg, + SBP::MsgSolnMetaDepA(msg) => msg, SBP::MsgHeartbeat(msg) => msg, SBP::Unknown(msg) => msg, } diff --git a/rust/sbp/src/messages/solution_meta.rs b/rust/sbp/src/messages/solution_meta.rs index 4c0a4cb672..81bc112118 100644 --- a/rust/sbp/src/messages/solution_meta.rs +++ b/rust/sbp/src/messages/solution_meta.rs @@ -128,13 +128,106 @@ impl crate::serialize::SbpSerialize for IMUInputType { /// Solution Sensors Metadata /// -/// This message contains all metadata about the sensors received and/or used in computing the Fuzed Solution. +/// This message contains all metadata about the sensors received and/or used in computing the sensorfusion solution. /// It focuses primarly, but not only, on GNSS metadata. /// #[cfg_attr(feature = "sbp_serde", derive(Serialize, Deserialize))] #[derive(Debug, Clone)] #[allow(non_snake_case)] pub struct MsgSolnMeta { + pub sender_id: Option, + /// GPS time of week rounded to the nearest millisecond + pub tow: u32, + /// Position Dilution of Precision, as per last available DOPS from Starling + /// GNSS engine + pub pdop: u16, + /// Horizontal Dilution of Precision, as per last available DOPS from + /// Starling GNSS engine + pub hdop: u16, + /// Vertical Dilution of Precision, as per last available DOPS from Starling + /// GNSS engine + pub vdop: u16, + /// Age of the corrections (0xFFFF indicates invalid), as per last available + /// AGE_CORRECTIONS from Starling GNSS engine + pub age_corrections: u16, + /// Age of the last received valid GNSS solution (0xFFFF indicates invalid) + pub age_gnss: u16, + /// Array of Metadata describing the sensors potentially involved in the + /// solution. Each element in the array represents a single sensor type and + /// consists of flags containing (meta)data pertaining to that specific + /// single sensor. Refer to each (XX)InputType descriptor in the present + /// doc. + pub sol_in: Vec, +} + +impl MsgSolnMeta { + #[rustfmt::skip] + pub fn parse(_buf: &mut &[u8]) -> Result { + Ok( MsgSolnMeta{ + sender_id: None, + tow: _buf.read_u32::()?, + pdop: _buf.read_u16::()?, + hdop: _buf.read_u16::()?, + vdop: _buf.read_u16::()?, + age_corrections: _buf.read_u16::()?, + age_gnss: _buf.read_u16::()?, + sol_in: SolutionInputType::parse_array(_buf)?, + } ) + } +} +impl super::SBPMessage for MsgSolnMeta { + fn get_message_type(&self) -> u16 { + 65294 + } + + fn get_sender_id(&self) -> Option { + self.sender_id + } + + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + + fn to_frame(&self) -> std::result::Result, crate::framer::FramerError> { + let trait_object = self as &dyn super::SBPMessage; + crate::framer::to_frame(trait_object) + } +} + +impl crate::serialize::SbpSerialize for MsgSolnMeta { + #[allow(unused_variables)] + fn append_to_sbp_buffer(&self, buf: &mut Vec) { + self.tow.append_to_sbp_buffer(buf); + self.pdop.append_to_sbp_buffer(buf); + self.hdop.append_to_sbp_buffer(buf); + self.vdop.append_to_sbp_buffer(buf); + self.age_corrections.append_to_sbp_buffer(buf); + self.age_gnss.append_to_sbp_buffer(buf); + self.sol_in.append_to_sbp_buffer(buf); + } + + fn sbp_size(&self) -> usize { + let mut size = 0; + size += self.tow.sbp_size(); + size += self.pdop.sbp_size(); + size += self.hdop.sbp_size(); + size += self.vdop.sbp_size(); + size += self.age_corrections.sbp_size(); + size += self.age_gnss.sbp_size(); + size += self.sol_in.sbp_size(); + size + } +} + +/// Deprecated +/// +/// This message contains all metadata about the sensors received and/or used in computing the Fuzed Solution. +/// It focuses primarly, but not only, on GNSS metadata. +/// +#[cfg_attr(feature = "sbp_serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone)] +#[allow(non_snake_case)] +pub struct MsgSolnMetaDepA { pub sender_id: Option, /// Position Dilution of Precision, as per last available DOPS from Starling /// GNSS engine @@ -165,10 +258,10 @@ pub struct MsgSolnMeta { pub sol_in: Vec, } -impl MsgSolnMeta { +impl MsgSolnMetaDepA { #[rustfmt::skip] - pub fn parse(_buf: &mut &[u8]) -> Result { - Ok( MsgSolnMeta{ + pub fn parse(_buf: &mut &[u8]) -> Result { + Ok( MsgSolnMetaDepA{ sender_id: None, pdop: _buf.read_u16::()?, hdop: _buf.read_u16::()?, @@ -182,7 +275,7 @@ impl MsgSolnMeta { } ) } } -impl super::SBPMessage for MsgSolnMeta { +impl super::SBPMessage for MsgSolnMetaDepA { fn get_message_type(&self) -> u16 { 65295 } @@ -201,7 +294,7 @@ impl super::SBPMessage for MsgSolnMeta { } } -impl crate::serialize::SbpSerialize for MsgSolnMeta { +impl crate::serialize::SbpSerialize for MsgSolnMetaDepA { #[allow(unused_variables)] fn append_to_sbp_buffer(&self, buf: &mut Vec) { self.pdop.append_to_sbp_buffer(buf); diff --git a/spec/yaml/swiftnav/sbp/solution_meta.yaml b/spec/yaml/swiftnav/sbp/solution_meta.yaml index 64bf5401d3..dfd1c314d7 100644 --- a/spec/yaml/swiftnav/sbp/solution_meta.yaml +++ b/spec/yaml/swiftnav/sbp/solution_meta.yaml @@ -56,10 +56,11 @@ definitions: units: (XX)InputType desc: Refer to each InputType description - - MSG_SOLN_META: + - MSG_SOLN_META_DEP_A: id: 0xFF0F - short_desc: Solution Sensors Metadata - public: true + short_desc: Deprecated + desc: Deprecated. + public: False desc: | This message contains all metadata about the sensors received and/or used in computing the Fuzed Solution. It focuses primarly, but not only, on GNSS metadata. @@ -115,6 +116,45 @@ definitions: Each element in the array represents a single sensor type and consists of flags containing (meta)data pertaining to that specific single sensor. Refer to each (XX)InputType descriptor in the present doc. + - MSG_SOLN_META: + id: 0xFF0E + short_desc: Solution Sensors Metadata + public: true + desc: | + This message contains all metadata about the sensors received and/or used in computing the sensorfusion solution. + It focuses primarly, but not only, on GNSS metadata. + fields: + - tow: + type: u32 + units: ms + desc: GPS time of week rounded to the nearest millisecond + - pdop: + type: u16 + units: 0.01 + desc: Position Dilution of Precision, as per last available DOPS from Starling GNSS engine + - hdop: + type: u16 + units: 0.01 + desc: Horizontal Dilution of Precision, as per last available DOPS from Starling GNSS engine + - vdop: + type: u16 + units: 0.01 + desc: Vertical Dilution of Precision, as per last available DOPS from Starling GNSS engine + - age_corrections: + type: u16 + units: deciseconds + desc: Age of the corrections (0xFFFF indicates invalid), as per last available AGE_CORRECTIONS from Starling GNSS engine + - age_gnss: + type: u16 + units: ms + desc: Age of the last received valid GNSS solution (0xFFFF indicates invalid) + - sol_in: + type: array + fill: SolutionInputType + desc: Array of Metadata describing the sensors potentially involved in the solution. + Each element in the array represents a single sensor type and consists of flags containing (meta)data + pertaining to that specific single sensor. Refer to each (XX)InputType descriptor in the present doc. + ############################################# # One structure definition per sensor class # Feel free to add more sensor Classes.