Add camera streaming guide with all access methods

Comprehensive documentation for accessing the DWARF camera streams:
- RTSP URLs and channels (ch0=tele, ch1=wide)
- The critical prerequisite: camera must be opened via WebSocket first
- ffmpeg commands for frame capture, timelapse, and video recording
- mpv and VLC usage with TCP transport
- Python/OpenCV integration example
- Troubleshooting common issues (black image, connection refused, VLC delay)
- Comparison of RTSP vs MJPEG modes across device models

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
This commit is contained in:
Jacquin Antoine
2026-07-13 19:56:04 +02:00
parent 7dc41ec368
commit c2f9e54eb4
13 changed files with 1866 additions and 5 deletions

View File

@ -0,0 +1,85 @@
package odometry
import "math"
// fft is an in-place iterative radix-2 Cooley-Tukey FFT.
// len(a) must be a power of two. If inverse is true the result is normalized
// by 1/n (so ifft(fft(x)) == x).
func fft(a []complex128, inverse bool) {
n := len(a)
if n <= 1 {
return
}
// Bit-reversal permutation.
for i, j := 1, 0; i < n; i++ {
bit := n >> 1
for ; j&bit != 0; bit >>= 1 {
j ^= bit
}
j ^= bit
if i < j {
a[i], a[j] = a[j], a[i]
}
}
// Butterfly stages.
for length := 2; length <= n; length <<= 1 {
// Standard forward DFT uses exp(-i*2π/length); inverse negates.
angle := -2 * math.Pi / float64(length)
if inverse {
angle = -angle
}
wlen := complex(math.Cos(angle), math.Sin(angle))
half := length / 2
for i := 0; i < n; i += length {
var w complex128 = 1
for k := 0; k < half; k++ {
u := a[i+k]
v := a[i+k+half] * w
a[i+k] = u + v
a[i+k+half] = u - v
w *= wlen
}
}
}
if inverse {
invN := complex(1/float64(n), 0)
for i := range a {
a[i] *= invN
}
}
}
// fftRows applies a 1-D FFT to every row of m (in place).
func fftRows(m [][]complex128, inverse bool) {
for i := range m {
fft(m[i], inverse)
}
}
// fftCols applies a 1-D FFT to every column of m (in place).
func fftCols(m [][]complex128, inverse bool) {
rows := len(m)
if rows == 0 {
return
}
cols := len(m[0])
col := make([]complex128, rows)
for j := 0; j < cols; j++ {
for i := 0; i < rows; i++ {
col[i] = m[i][j]
}
fft(col, inverse)
for i := 0; i < rows; i++ {
m[i][j] = col[i]
}
}
}
// fft2 performs a forward 2-D FFT on the rows×cols complex matrix m.
func fft2(m [][]complex128, inverse bool) {
fftRows(m, inverse)
fftCols(m, inverse)
}