Follow Mobility
The Follow Mobility plugin implements a leader/follower pattern where one or more leader nodes broadcast their position and follower nodes autonomously track and move towards them.
How It Works
The plugin is split into two independent components, a leader and a follower, that communicate through the simulation's broadcast messaging system via the Dispatcher plugin.
Leader (MobilityLeaderPlugin)
The leader periodically broadcasts its current position and orientation to all nodes in range. It does not control the node's movement, your protocol is free to move the leader however you like (e.g., via a mission mobility plugin or manual commands). The leader also tracks which followers are currently connected by listening for acknowledgment messages.
Key behaviors:
- Broadcasts position + orientation at a configurable interval (
broadcast_interval). - Automatically tracks its own position via telemetry updates.
- Culls followers that haven't responded within
follower_timeoutseconds. - Exposes a
followersproperty to query currently connected followers.
Follower (MobilityFollowerPlugin)
The follower listens for leader broadcasts and moves to maintain a configurable relative position offset from the followed leader. It periodically scans for available leaders and handles leader disconnections.
Key behaviors:
- Maintains a list of available leaders based on received broadcasts.
- By default, auto-follows the first available leader (
auto_follow=True). This can be disabled to require explicit calls tofollow_leader(). - Moves to
leader_position + relative_positionon each leader broadcast. - Sends an acknowledgment message back to the leader on each update.
- Detects leader disconnection after
leader_timeoutseconds of silence.
Orientation Support
The leader has a configurable orientation (in degrees, counter-clockwise from the +X axis)
that is included in every broadcast. When orientation-aware following is enabled
(follow_orientation=True, the default), the follower's relative position offset is rotated
by the leader's orientation before being applied.
This means the follower formation rotates together with the leader's heading. For example, a
follower at relative position (10, 0, 0) (10 units ahead) will always stay 10 units ahead
of the leader in the direction the leader is facing, rather than always staying at a fixed
world-coordinate offset.
The leader's orientation can be changed at any time via set_orientation().
Mobility Control
The follower plugin controls your protocol's mobility. You should not use any other mobility plugin alongside it or implement custom mobility behavior in a follower protocol. The leader plugin does not affect movement and is safe to combine with other mobility plugins.
Quick Usage Example
from gradysim.protocol.interface import IProtocol
from gradysim.protocol.plugin.follow_mobility import (
MobilityLeaderPlugin,
MobilityLeaderConfiguration,
MobilityFollowerPlugin,
MobilityFollowerConfiguration,
)
class LeaderProtocol(IProtocol):
def initialize(self):
self.leader = MobilityLeaderPlugin(
self,
MobilityLeaderConfiguration(
broadcast_interval=0.1,
initial_orientation=90.0, # facing +Y
),
)
def handle_timer(self, timer):
pass
def handle_packet(self, message):
pass
def handle_telemetry(self, telemetry):
pass
def finish(self):
pass
class FollowerProtocol(IProtocol):
def initialize(self):
self.follower = MobilityFollowerPlugin(
self,
MobilityFollowerConfiguration(
follow_orientation=True,
),
)
# Stay 10 units behind the leader (relative to leader's heading)
self.follower.set_relative_position((-10, 0, 0))
def handle_timer(self, timer):
pass
def handle_packet(self, message):
pass
def handle_telemetry(self, telemetry):
pass
def finish(self):
pass
API Reference
gradysim.protocol.plugin.follow_mobility
This module declares two plugin for the protocol: a leader and a follower. The leader broadcasts its position and the follower follows it.
Beware that this plugin controls your protocol's mobility to implement its behaviour, so you should not use any other mobility plugin with it or implement any mobility behaviour in your protocol. The MobilityLeaderPlugin does not affect the node's movement and thus should be fine to use with other mobility plugin or mobility behaviour.
MobilityFollowerConfiguration
dataclass
Source code in gradysim/protocol/plugin/follow_mobility/follower.py
auto_follow: bool = True
class-attribute
instance-attribute
Automatically follows the first leader available if set to True. If set to False, the user must call follow_leader manually. If True the user can still call follow_leader to follow a specific leader, but if connection to that leader is lost the follower will automatically follow the first leader available.
follow_orientation: bool = True
class-attribute
instance-attribute
Whether the follower's relative position should shift with the leader's orientation. If True, relative (X, Y) is rotated by the leader's orientation. If False, relative position remains fixed in world coordinates.
leader_timeout: float = 2
class-attribute
instance-attribute
After this amount of simulation seconds without receiving a broadcast from the leader, we consider it disconnected
scanning_interval: float = 0.5
class-attribute
instance-attribute
Interval between leader scans, in simulation seconds. The follower will update the list of leaders and the current leader.
MobilityFollowerPlugin
Source code in gradysim/protocol/plugin/follow_mobility/follower.py
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | |
MobilityLeaderConfiguration
dataclass
Source code in gradysim/protocol/plugin/follow_mobility/leader.py
broadcast_interval: float = 0.02
class-attribute
instance-attribute
The interval at which the leader broadcasts its position
follower_timeout: float = 5
class-attribute
instance-attribute
If we don't receive a message from a follower for this amount of simulation seconds we consider it disconnected
initial_orientation: float = 0.0
class-attribute
instance-attribute
The initial orientation of the leader in degrees (0° along +X, 90° along +Y)
MobilityLeaderPlugin
Source code in gradysim/protocol/plugin/follow_mobility/leader.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | |