feat(puppet): v0.3.0 — idle-return locomotion + version bump

- apply_locomotion idle-return: after (now - last_move_time) >
  idle_return_delay, the most-displaced planted leg steps back to its
  current hip position (over idle_step_duration). Group-stagger via
  bumping last_move_time forward by idle_return_stagger.
- M.move_to tracks p.last_move_time when position actually changes.
- README v0.3.0 changelog entry.
This commit is contained in:
Axel Meyer
2026-05-18 18:34:42 +02:00
parent 9882388097
commit 96ccb410d3
3 changed files with 53 additions and 2 deletions

View File

@@ -438,6 +438,7 @@ function M.move_to(handle, x, y)
p.facing = math.atan(dy, dx)
p.last_move_x = x
p.last_move_y = y
p.last_move_time = engine.time.now()
end
p.x = x
p.y = y
@@ -731,6 +732,41 @@ local function apply_locomotion(p, dt)
::continue::
end
if (now - p.last_move_time) > loco.idle_return_delay then
local any_stepping = false
for i, _ in ipairs(loco.legs) do
if p.foot_state[i].state ~= "planted" then any_stepping = true; break end
end
if not any_stepping then
local best_i, best_dist = nil, 0
for i, leg_def in ipairs(loco.legs) do
local fs = p.foot_state[i]
if fs.state == "planted" then
local hip_wx = p.bone_state[leg_def.leg].world.x
local hip_wy = p.bone_state[leg_def.leg].world.y
local d = math.sqrt((hip_wx - fs.anchor_x)^2 + (hip_wy - fs.anchor_y)^2)
if d > best_dist then
best_dist = d
best_i = i
end
end
end
if best_i and best_dist > 1 then
local fs = p.foot_state[best_i]
local hip_wx = p.bone_state[loco.legs[best_i].leg].world.x
local hip_wy = p.bone_state[loco.legs[best_i].leg].world.y
fs.state = "stepping"
fs.step_from_x = fs.cur_x
fs.step_from_y = fs.cur_y
fs.step_to_x = hip_wx
fs.step_to_y = hip_wy
fs.step_timer = 0
fs.step_total = loco.idle_step_duration
p.last_move_time = now - loco.idle_return_delay + loco.idle_return_stagger
end
end
end
end
-- ====================================================================