Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
StructUtils = "ec057cc2-7a8d-4b58-b3b3-92acb9f63b42"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
Tar = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
TensorCast = "02d47bb6-7ce6-556a-be16-bb1710789e2b"
Expand Down Expand Up @@ -64,6 +65,7 @@ SHA = "0.7, 1"
SparseArrays = "1.11"
StaticArrays = "1"
Statistics = "1.11"
StructUtils = "2.6.0"
Tables = "1.11.1"
Tar = "1.9"
TensorCast = "0.3.3, 0.4"
Expand Down
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ makedocs(;
],
"Reference" => ["func_ref.md", "services_ref.md", "blob_ref.md"],
],
checkdocs = :public,
# warnonly=[:doctest],
# checkdocs=:none,
# html_prettyurls = !("local" in ARGS),
)

Expand Down
14 changes: 13 additions & 1 deletion docs/src/GraphData.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,19 @@ Labels are the principle identifier of a variable or factor.

#### Timestamps

Each variable or factor can have a timestamp associated with it.
Each variable or factor can have a timestamp associated with it representing when the physical event/observation occurred.

**Time Standard**: Timestamps use UTC-based time (Coordinated Universal Time) via the `TimeDateZone` type, not TAI (International Atomic Time). The key difference is that UTC includes leap seconds to keep synchronized with Earth's rotation, while TAI is a continuous monotonic time scale without leap seconds.

**Timezone Support**: While timestamps default to UTC (`tz"UTC"`), `TimeDateZone` supports any timezone (e.g., `tz"America/New_York"`, `tz"Europe/London"`). The timezone offset is preserved when stored and retrieved.

**Event Time vs Database Time**: The timestamp represents the physical event time (when a sensor measurement was taken, when a robot was at a pose, etc.), not when the variable was added to the database. Database metadata timestamps may be tracked separately by specific backend implementations.

**Temporal Uncertainty**: This single timestamp value is metadata and does not represent temporal uncertainty. For problems where time itself is a state variable requiring inference (e.g., using `SGal3` which includes temporal components), include time as part of your state type rather than relying on this metadata field. Furthermore, the concept of "ClockPriors" is also at play for the API design changes relating to v2.

**Future**: changing away from field name `timestamp` was deferred from v1.0 owing to resolution of older complexity of other fields being standardized; however, the desire for a better name exists and should be revisited in the v2 API. At time of writing, the best summary of the naming debate is captured here: https://github.com/JuliaRobotics/DistributedFactorGraphs.jl/issues/1087#issuecomment-3582252305. In the lead up to a new long term release (a.k.a semver major), a deprecation cycle will be used via semver minors to ensure users have an easy and macro-aided transition in the API.

Related functions:

- [`getTimestamp`](@ref)

Expand Down
17 changes: 15 additions & 2 deletions src/Common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,20 @@ function calcDeltatime(from::TimeDateZone, to::TimeDateZone)
end
calcDeltatime(from_node, to_node) = calcDeltatime(from_node.timestamp, to_node.timestamp)

function tdz_now(zone = tz"UTC") #TODO or default to slower localzone()?
Timestamp(args...) = TimeDateZone(args...)
Timestamp(t::Nanosecond, zone = tz"UTC") = Timestamp(Val(:unix), t, zone)
function Timestamp(epoch::Val{:unix}, t::Nanosecond, zone = tz"UTC")
return TimeDateZone(TimeDate(1970) + t, zone)
end
function Timestamp(epoch::Val{:unix}, t::Float64, zone = tz"UTC")
return Timestamp(epoch, Nanosecond(t * 10^9), zone)
end
Timestamp(t::Float64, zone = tz"UTC") = Timestamp(Val(:unix), t, zone)
function Timestamp(epoch::Val{:rata}, t::Float64, zone = tz"UTC")
return TimeDateZone(convert(DateTime, Millisecond(t*10^3)), zone)
end

function now_tdz(zone = tz"UTC")
t = time()
return TimeDateZone(TimeDate(1970) + Nanosecond(t * 10^9), zone)
return Timestamp(t, zone)
end
2 changes: 1 addition & 1 deletion src/DataBlobs/entities/BlobEntry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ StructUtils.@kwarg struct Blobentry
""" Storage for a couple of bytes directly in the graph. Use with caution and keep it small and simple."""
metadata::JSONText = JSONText("{}")
""" When the Blob itself was first created. Serialized as an ISO 8601 string."""
timestamp::TimeDateZone = tdz_now()
timestamp::TimeDateZone = now_tdz()
""" Type version of this Blobentry."""
version::VersionNumber = DFG.version(Blobentry)
end
Expand Down
Loading
Loading