Improve odometry with rotation estimation, daemon stability, and RTSP fixes
- Add rotation estimation via log-polar phase correlation (EstimateRotation,
rotateGray) — de-rotate before translation to avoid aliasing
- Track cumulative field rotation in Tracker, reject low-confidence frames
- Extract RTSP grabber into internal/rtspgrab module
- Daemon: pause odometry during slew (motion blur), auto-resume after settle
delay, add /pause and /resume HTTP endpoints, switch shooting mode before
opening camera, use ReqOpenCamera with rtsp_encode_type=1
- WebSocket heartbeat (ping/pong every 10s) to prevent idle disconnects
- FFmpeg low-latency flags (-fflags nobuffer, -probesize, -analyzeduration)
- Add SendRaw API for custom payloads, increase daemon HTTP timeout to 60s
💘 Generated with Crush
Assisted-by: Crush:/models/Qwen3.6-27B-uncensored-heretic-v2-Native-MTP-Preserved-Q4_K_M.gguf
This commit is contained in:
53
dwarfctl/internal/odometry/rotate.go
Normal file
53
dwarfctl/internal/odometry/rotate.go
Normal file
@ -0,0 +1,53 @@
|
||||
package odometry
|
||||
|
||||
import "math"
|
||||
|
||||
// rotateGray rotates a grayscale matrix by angleDeg (positive = clockwise)
|
||||
// around its center, using bilinear interpolation. The output has the same
|
||||
// dimensions as the input.
|
||||
func rotateGray(g [][]float64, size int, angleDeg float64) [][]float64 {
|
||||
theta := angleDeg * math.Pi / 180.0
|
||||
cosT := math.Cos(theta)
|
||||
sinT := math.Sin(theta)
|
||||
cy := float64(size-1) / 2.0
|
||||
cx := float64(size-1) / 2.0
|
||||
|
||||
out := make([][]float64, size)
|
||||
for i := range out {
|
||||
out[i] = make([]float64, size)
|
||||
}
|
||||
|
||||
for oy := 0; oy < size; oy++ {
|
||||
for ox := 0; ox < size; ox++ {
|
||||
// Map output pixel to input coordinates via inverse rotation.
|
||||
dy := float64(oy) - cy
|
||||
dx := float64(ox) - cx
|
||||
sx := cx + dx*cosT + dy*sinT
|
||||
sy := cy - dx*sinT + dy*cosT
|
||||
|
||||
// Bilinear interpolation with clamp at borders.
|
||||
x0 := int(math.Floor(sx))
|
||||
y0 := int(math.Floor(sy))
|
||||
fx := sx - float64(x0)
|
||||
fy := sy - float64(y0)
|
||||
|
||||
x0 = clampInt(x0, 0, size-1)
|
||||
y0 = clampInt(y0, 0, size-1)
|
||||
x1 := clampInt(x0+1, 0, size-1)
|
||||
y1 := clampInt(y0+1, 0, size-1)
|
||||
|
||||
out[oy][ox] = (1-fy)*(1-fx)*g[y0][x0] +
|
||||
(1-fy)*fx*g[y0][x1] +
|
||||
fy*(1-fx)*g[y1][x0] +
|
||||
fy*fx*g[y1][x1]
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func absf(x float64) float64 {
|
||||
if x < 0 {
|
||||
return -x
|
||||
}
|
||||
return x
|
||||
}
|
||||
Reference in New Issue
Block a user