Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@ BLUE=\033[0;34m
BLACK=\033[0;30m

help:
@echo "$(BLUE) make dist - build dist files"
@echo "$(BLUE) make test - run the fast test suite"
@echo " make testall - run the full test suite, including slow notebook/example tests"
@echo " make dist - build dist files"
@echo " make upload - upload to PyPI"
@echo " make clean - remove dist and docs build files"
@echo " make help - this message$(BLACK)"

test: .FORCE
pytest

testall: .FORCE
pytest --runall

dist: .FORCE
# $(MAKE) test
python -m build
Expand Down
25 changes: 13 additions & 12 deletions RVC3/examples/imu_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

import matplotlib.pyplot as plt

def tumble():
def IMU():
# accelerometer
g0 = unitvec( [0, 0, 9.8] ).T
gbias = 0.02 * np.r_[2, -2, 2].T # bias 2% of norm
Expand All @@ -30,7 +30,7 @@ def tumble():
mbias = 0.02 * np.r_[-1, -1, 2] # bias 2# of norm

# gyro
wbias = 0.05 * np.r_[-1, 2, -1] # bias 5% of max
wbias = 0.05 * np.r_[-1, 2, -1] # bias 10% of max

## simulation

Expand All @@ -56,7 +56,7 @@ def tumble():
w0, t)

# Solve for simulated sensor readings and true attitude
# 1 column per timestep
# 1 row per timestep
am = np.zeros(omega.shape)
mm = np.zeros(omega.shape)

Expand All @@ -71,8 +71,9 @@ def tumble():
# add bias to measured
wm = omega + wbias

data = namedtuple('tumble', 't omega_true attitude_true g B gyro accel magno')
return data(t, omega, truth, g0, m0, wm, am, mm)
imu = namedtuple('imu', 't dt gyro accel magno')
true = namedtuple('true', 't dt omega orientation g B')
return true(t, dt, omega, truth, g0, m0), imu(t, dt, wm, am, mm)

if __name__ == "__main__":

Expand All @@ -82,14 +83,14 @@ def plot(t, y, title):
plt.grid(True)
plt.title(title)

data = tumble()
true, imu = IMU()

print(data.attitude_true[100])
print(data.attitude_true[100].rpy())
print(true.orientation[100])
print(true.orientation[100].rpy())

plot(data.t, data.attitude_true.rpy(), 'attitude')
plot(data.t, data.gyro, 'gyro')
plot(data.t, data.accel, 'accel')
plot(data.t, data.magno, 'magno')
plot(true.t, true.orientation.rpy(), 'attitude')
plot(imu.t, imu.gyro, 'gyro')
plot(imu.t, imu.accel, 'accel')
plot(imu.t, imu.magno, 'magno')

plt.show(block=True)
44 changes: 24 additions & 20 deletions RVC3/examples/visodom.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@
#!/usr/bin/env python3

# from RVC3.tools import rvcprint
import sys
import numpy as np
import matplotlib.pyplot as plt
from machinevisiontoolbox import *
import spatialmath.base as smb

# optional CLI arg: max number of frames to process, eg. `%run -m visodom 50`
max_frames = int(sys.argv[1]) if len(sys.argv) > 1 else None

# load .enpeda dataset, 12bit pixel values
args = dict(mono=True, dtype="uint8", maxintval=4095, roi=[20, 750, 20, 480])
try:
Expand Down Expand Up @@ -54,16 +58,18 @@
n_no_overlap = 0
n_optimized = 0

for left, right in zip(lefts, rights):
for left_img, right_img in zip(lefts, rights):
if max_frames is not None and nframes >= max_frames:
break
nframes += 1
print("-----------------", left.id)
print("-----------------", left_img.id)
# plt.clf()
# plt.imshow(image.A, cmap='gray')
# smb.plot_text((20, 420), f"frame {image.id}", color='w', backgroundcolor='k', fontsize=12)

# find corner features
orbL = left.ORB(nfeatures=400, id="index")
orbR = right.ORB(nfeatures=400)
orbL = left_img.ORB(nfeatures=400, id="index")
orbR = right_img.ORB(nfeatures=400)

# robustly match left and right corner features
# - stereo match
Expand All @@ -74,7 +80,7 @@
# too few/degenerate stereo correspondences to triangulate this
# frame at all -- skip it entirely, keep the last good frame as
# the temporal reference for the next one
print(f" stereo F estimation failed for frame {left.id}: {e}")
print(f" stereo F estimation failed for frame {left_img.id}: {e}")
n_lr_fail += 1
continue
print(matchLR)
Expand All @@ -91,34 +97,36 @@
P, d = lines1.closest_to_line(lines2)
print(np.nanmedian(d))

if left.id > 0:
if left_img.id > 0:
# if we have a previous frame

# display two sequential stereo pairs
plt.clf()
view4 = Image.Tile([left, right, left_prev, right_prev], columns=2, sep=0)
view4 = Image.Tile(
[left_img, right_img, left_prev, right_prev], columns=2, sep=0
)
plt.imshow(view4.A, cmap="gray")

matchLR.plot_correspondence("y", offset=(left.width, 0), linewidth=0.5)
matchLR.plot_correspondence("y", offset=(left_img.width, 0), linewidth=0.5)

# temporal matching
matchFB = orbL.match(orbL_prev)
try:
F = matchFB.estimate(cam.points2F, method="ransac")
print(matchFB)
matchFB = matchFB.inliers # keep the inliers
matchFB.plot_correspondence("y", offset=(0, left.height), linewidth=0.5)
matchFB.plot_correspondence("y", offset=(0, left_img.height), linewidth=0.5)
plt.pause(0.1)
except ValueError as e:
# too few/degenerate temporal correspondences -- same downstream
# effect as zero overlapping landmarks below (no valid frame
# motion estimate), but caught earlier since points2F() itself
# can't even find a fundamental matrix here
print(f" temporal F estimation failed for frame {left.id}: {e}")
print(f" temporal F estimation failed for frame {left_img.id}: {e}")
n_fb_fail += 1
matchFB = None

# if left.id == 10:
# if left_img.id == 10:
# rvcprint.rvcprint(thicken=None)

# now create a bundle adjustment problem, if we have a usable
Expand All @@ -134,9 +142,7 @@
c_left = ba.add_view(
SE3(), fixed=True
) # first camera at origin (current frame)
c_leftprev = ba.add_view(
SE3()
) # initial guess, zero motion (prev frame)
c_leftprev = ba.add_view(SE3()) # initial guess, zero motion (prev frame)

for k, Pk in enumerate(P.T): # for every 3D point from stereo
if np.any(np.isnan(Pk)):
Expand All @@ -148,9 +154,7 @@
continue
landmark = ba.add_landmark(Pk)
ba.add_projection(c_left, landmark, m.p1) # current left camera
ba.add_projection(
c_leftprev, landmark, m.p2
) # previous left camera
ba.add_projection(c_leftprev, landmark, m.p2) # previous left camera
landmarks_added = True

if landmarks_added:
Expand All @@ -161,16 +165,16 @@
else:
print(
f" no overlapping stereo/temporal landmarks for frame "
f"{left.id} -- skipping bundle adjustment"
f"{left_img.id} -- skipping bundle adjustment"
)
n_no_overlap += 1
displacements.append(np.full(6, np.nan))
errors.append(np.nan)

# keep images and features for next cycle
orbL_prev = orbL
left_prev = left
right_prev = right
left_prev = left_img
right_prev = right_img

print()
print("===== summary =====")
Expand Down
2 changes: 1 addition & 1 deletion RVC3/models/IBVS-holonomic.bd
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@
false
],
[
"args",
"fargs",
[]
],
[
Expand Down
16 changes: 8 additions & 8 deletions RVC3/models/IBVS-nonholonomic.bd
Original file line number Diff line number Diff line change
Expand Up @@ -299,11 +299,11 @@
false
],
[
"args",
"fargs",
[]
],
[
"kwargs",
"fkwargs",
{}
],
[
Expand Down Expand Up @@ -491,11 +491,11 @@
false
],
[
"args",
"fargs",
[]
],
[
"kwargs",
"fkwargs",
{}
],
[
Expand Down Expand Up @@ -572,11 +572,11 @@
true
],
[
"args",
"fargs",
[]
],
[
"kwargs",
"fkwargs",
{}
],
[
Expand Down Expand Up @@ -996,7 +996,7 @@
false
],
[
"args",
"fargs",
[]
],
[
Expand Down Expand Up @@ -1162,7 +1162,7 @@
false
],
[
"args",
"fargs",
[]
],
[
Expand Down
4 changes: 2 additions & 2 deletions RVC3/models/IBVS-quadrotor.bd
Original file line number Diff line number Diff line change
Expand Up @@ -513,11 +513,11 @@
"=quadrotor"
],
[
"maxw",
"wmax",
1000
],
[
"minw",
"wmin",
5
],
[
Expand Down
2 changes: 1 addition & 1 deletion RVC3/models/braitenberg.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def sensorfunc(x, offset):
scale=[0, 100],
size=5,
shape="box",
trail=True,
path="b:",
name="sensor field",
init=background_graphics,
)
Expand Down
2 changes: 1 addition & 1 deletion RVC3/models/feedforward-main.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@

import matplotlib.pyplot as plt

plt.plot(out.t, out.x[:, 1], out.t, out.y0[:, 1])
plt.plot(out.t, out.x[:, 1], out.t, out.y[:, 1])
plt.show(block=True)
Loading