Skip to content

Commit

Permalink
feat: Update log/pub time from the ROS header time
Browse files Browse the repository at this point in the history
  • Loading branch information
mrkbac committed Oct 9, 2023
1 parent 3017650 commit 776a799
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 27 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ Kappe is an efficient data migration tool designed to seamlessly convert and spl
- [Topic](#topic)
- [Rename a topic](#rename-a-topic)
- [Remove a topic](#remove-a-topic)
- [Update the ROS header time](#update-the-ros-header-time)
- [Change ROS Timestamp to publish time](#change-ros-timestamp-to-publish-time)
- [Change MCAP pub/log time from ROS header](#change-mcap-publog-time-from-ros-header)
- [Add a time offset to ROS Timestamp](#add-a-time-offset-to-ros-timestamp)
- [Pointcloud](#pointcloud)
- [Remove zero points from PointCloud2](#remove-zero-points-from-pointcloud2)
Expand Down Expand Up @@ -91,6 +93,17 @@ topic:
- /points
```

#### Update the ROS header time

Adds 8 second and 300 nanosec to the ROS header.

```yaml
time_offset:
/sensor/points:
sec: 8
nanosec: 300
```

#### Change ROS Timestamp to publish time

Change the time of the ROS Timestamp to the time the message was published.
Expand All @@ -101,6 +114,19 @@ time_offset:
pub_time: True
```

#### Change MCAP pub/log time from ROS header

Update the log/pub time from the ROS header.
If `pub_time` is set, pub time will be used as source.
If `sec` and/or `nanosec` is set, the offset is used.

```yaml
time_offset:
/sensor/points:
update_publish_time: True
update_log_time: True
```

#### Add a time offset to ROS Timestamp

Add 15 seconds to the ROS Timestamp.
Expand Down
55 changes: 28 additions & 27 deletions src/kappe/module/timing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import Any

from mcap.reader import DecodedMessageTuple
from mcap.records import Message
from mcap_ros1._vendor.genpy.rostime import Duration as ROS1Duration
from mcap_ros1._vendor.genpy.rostime import Time as ROS1Time
from pydantic import BaseModel, Extra
Expand All @@ -28,40 +29,40 @@ class SettingTimeOffset(BaseModel, extra=Extra.forbid):
:ivar nanosec: Nanoseconds to add to the timestamp.
:ivar pub_time: Use the publish time instead of the message time. If set sec and nanosec
will be added to the publish time.
:ivar update_log_time: Updates the log_time of the MCAP message.
:ivar update_publish_time: Updates the publish_time of the MCAP message.
"""

sec: int = 0
nanosec: int = 0
pub_time: bool | None = None
pub_time: bool = False
update_log_time: bool = False
update_publish_time: bool = False


def time_offset_stamp(cfg: SettingTimeOffset, publish_time_ns: int, stamp: TimeMsg):
pub_time = cfg.pub_time
off_sec = cfg.sec
off_nanosec = cfg.nanosec

if pub_time is True:
header_sec = publish_time_ns // 1e9
header_nanosec = publish_time_ns % int(1e9)
def time_offset_stamp(cfg: SettingTimeOffset, message: Message, stamp: TimeMsg):
if cfg.pub_time:
stamp_nano = message.publish_time
else:
header_sec = int(stamp.sec)
header_nanosec = int(stamp.nanosec)
stamp_nano = int(stamp.sec * 1e9) + int(stamp.nanosec)

stamp_nano += cfg.sec
stamp_nano += int(cfg.nanosec * 1e9)

sec = int(stamp_nano // 1e9)
nanosec = stamp_nano - (sec * 1e9)

header_nanosec += off_nanosec
stamp.sec = sec
stamp.nanosec = nanosec

# handle nanosec under & overflow
if header_nanosec < 0:
header_nanosec += int(1e9)
header_sec -= 1
elif header_nanosec >= int(1e9):
header_nanosec -= int(1e9)
header_sec += 1
if cfg.update_publish_time:
message.publish_time = stamp_nano

stamp.nanosec = header_nanosec
stamp.sec = header_sec + off_sec
if cfg.update_log_time:
message.log_time = stamp_nano


def time_offset_rec(cfg: SettingTimeOffset, publish_time_ns: int, msg: Any):
def time_offset_rec(cfg: SettingTimeOffset, message: Message, msg: Any):
if not hasattr(msg, '__slots__'):
return

Expand All @@ -70,20 +71,20 @@ def time_offset_rec(cfg: SettingTimeOffset, publish_time_ns: int, msg: Any):

if isinstance(attr, list):
for i in attr:
time_offset_rec(cfg, publish_time_ns, i)
time_offset_rec(cfg, message, i)

if 'mcap_ros2._dynamic.Time' in str(type(attr)):
time_offset_stamp(cfg, publish_time_ns, attr)
time_offset_stamp(cfg, message, attr)
else:
time_offset_rec(cfg, publish_time_ns, attr)
time_offset_rec(cfg, message, attr)


def time_offset(cfg: SettingTimeOffset, msg: DecodedMessageTuple):
"""Apply time offset to the message."""
schema, channel, message, ros_msg = msg
ros_msg = msg.decoded_message
if not hasattr(msg, '__slots__'):
return
time_offset_rec(cfg, message.publish_time_ns, ros_msg)
time_offset_rec(cfg, msg.message, ros_msg)


def fix_ros1_time(msg: Any):
Expand Down

0 comments on commit 776a799

Please sign in to comment.