Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 12 additions & 0 deletions animations/curious.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{"servo:tilt:mv": 10},
{"sleep": 0.5},
{"servo:pan:mv": 15},
{"sleep": 0.5},
{"servo:pan:mv": -15},
{"sleep": 0.5},
{"servo:tilt:mv": -10},
{"sleep": 0.5},
{"servo:pan:mv": 0},
{"servo:tilt:mv": 0}
]
17 changes: 17 additions & 0 deletions animations/excitement.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[
{"servo:pan:mv": 30},
{"servo:tilt:mv": 20},
{"sleep": 0.3},
{"servo:pan:mv": -30},
{"servo:tilt:mv": -20},
{"sleep": 0.3},
{"servo:pan:mv": 40},
{"servo:tilt:mv": 30},
{"sleep": 0.3},
{"servo:pan:mv": -40},
{"servo:tilt:mv": -30},
{"sleep": 0.3},
{"servo:pan:mv": 0},
{"servo:tilt:mv": 0},
{"sleep": 1}
]
14 changes: 14 additions & 0 deletions animations/excitement2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{"servo:pan:mv": 30},
{"servo:tilt:mv": 20},
{"led/color": "blue"},
{"sleep": 0.3},
{"servo:pan:mv": -30},
{"servo:tilt:mv": -20},
{"led/color": "red"},
{"sleep": 0.3},
{"servo:pan:mv": 0},
{"servo:tilt:mv": 0},
{"led/color": "green"},
{"sleep": 1}
]
4 changes: 4 additions & 0 deletions animations/level_neck.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[
{"servo:tilt:mvabs": 50},
{"sleep": 1}
]
10 changes: 10 additions & 0 deletions animations/sadness.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{"servo:tilt:mv": -20},
{"sleep": 1},
{"servo:pan:mv": -10},
{"sleep": 1},
{"servo:pan:mv": 10},
{"sleep": 1},
{"servo:pan:mv": 0},
{"servo:tilt:mv": 0}
]
11 changes: 11 additions & 0 deletions animations/surprise.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
{"piservo/move": 40},
{"servo:tilt:mv": 30},
{"sleep": 0.2},
{"servo:pan:mv": 20},
{"sleep": 0.2},
{"servo:pan:mv": -20},
{"sleep": 0.2},
{"servo:tilt:mv": 0},
{"sleep": 0.5}
]
4 changes: 3 additions & 1 deletion arduino_sketch/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ int PosSleep[SERVO_COUNT] = {40, 60, 95, 140, 120, 85, PosMax[7], 90, 180, 0};
//0, 3 = HIP
int PosStart[SERVO_COUNT] = {60, 0, 165, 120, 180, 30, 90, 90, 180, 0};

int PosBackpack[SERVO_COUNT] = {30, 5, 90, 130, 120, 160, 90, 90, 180, 0}; // Position legs to support when mounted to backpack
int PosBackpack[SERVO_COUNT] = {30, 5, 130, 130, 120, 160, 90, 90, 180, 0}; // Position legs to support when mounted to backpack
int PosStraight[SERVO_COUNT] = {45, 90, 165, 135, 90, 20, 90, 90, 180, 0}; // straighten legs and point feet to fit in backpack upright

//int PosRest[SERVO_COUNT] = {S1_REST, S2_REST, S3_REST, S4_REST, S5_REST, S6_REST, S7_REST, S8_REST, S9_REST};
Expand All @@ -79,6 +79,8 @@ int PosStand[SERVO_COUNT] = {45, 70, 80, 135, 110, 100, NOVAL, NOVAL, 180, 0};
int PosLookLeft[SERVO_COUNT] = {NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, 180, 180, 0};
int PosLookRight[SERVO_COUNT] = {NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, 0, 180, 0};
int PosLookRandom[SERVO_COUNT] = {NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, -1, -1, 180, 0}; // Made random by calling the function moveRandom() if the value is -1
int PosLookRandomRight[SERVO_COUNT] = {NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, -1, 30, 180, 0};
int PosLookRandomLeft[SERVO_COUNT] = {NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, -1, 150, 180, 0};
int PosLookUp[SERVO_COUNT] = {NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, 60, 90, 180, 0};
int PosLookDown[SERVO_COUNT] = {NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, NOVAL, 120, 90, 180, 0};

Expand Down
4 changes: 2 additions & 2 deletions config/vision.yml β†’ config/vision_imx500.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
vision:
enabled: true
vision_imx500:
enabled: false
path: 'modules.vision.imx500.vision.Vision'
config:
preview: false
Expand Down
5 changes: 5 additions & 0 deletions config/vision_opencv.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
vision_opencv:
enabled: true
path: 'modules.vision.opencv.vision.Vision'
config:
preview: false
Empty file added docs/NeoPx.md
Empty file.
61 changes: 41 additions & 20 deletions modules/archived/opencv/vision.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,31 @@
import cv2
from imutils.video import FPS # for FSP only

try:
from modules.opencv.faces import Faces
except ModuleNotFoundError as e:
# Local execution
from faces import Faces
import os
from video_stream import VideoStream
from modules.vision.opencv.faces import Faces
from modules.vision.opencv.video_stream import VideoStream

from modules.base_module import BaseModule

from pubsub import pub

class Vision:
def list_available_cameras(max_index=10):
available = []
for idx in range(max_index):
cap = cv2.VideoCapture(idx)
if cap.isOpened():
available.append(idx)
cap.release()
return available


class Vision(BaseModule):
MODE_MOTION = 0
MODE_FACES = 1

def __init__(self, video, **kwargs):
def __init__(self, **kwargs):
self.mode = kwargs.get('mode', Vision.MODE_MOTION)
self.path = kwargs.get('path', '/')
self.path = kwargs.get('path', '.')
# Make sure to use the correct camera index for your Pi camera
# Usually, index 0 is correct for the standard Pi camera
self.index = kwargs.get('index', 0)
self.static_back = None
self.dimensions = kwargs.get('resolution', (640, 480))
Expand All @@ -28,46 +35,58 @@ def __init__(self, video, **kwargs):

self.flip = kwargs.get('flip', False)
self.rotate = kwargs.get('rotate', False)
self.video = video
self.video = VideoStream(
resolution=self.dimensions,
index=self.index
)
self.lines = []
self.current_match = False
self.last_match = datetime.now() # @todo improve
pub.subscribe(self.exit, "exit")

# start the FPS counter
self.fps = FPS().start()

if self.mode == Vision.MODE_FACES:
self.cascade_path = self.path + "/modules/opencv/haarcascade_frontalface_default.xml"
self.cascade_path = self.path + "/modules/vision/opencv/haarcascade_frontalface_default.xml"
print(f"[Vision] Loading cascade from {self.cascade_path}")
self.cascade = cv2.CascadeClassifier(self.cascade_path)
self.faces = Faces(detector=self.cascade, path=self.path)

print("[Vision] Scanning for available cameras...")
available_cams = list_available_cameras(10)
print(f"[Vision] Available camera indexes: {available_cams}")

self.video.start()
self.running = True

def setup_messaging(self):
"""Subscribe to necessary topics."""
self.subscribe('system/loop', self.detect)

def exit(self):
self.running = False
self.video.stop()
# Destroying all the windows
cv2.destroyAllWindows()
self.fps.stop()
pub.sendMessage("log", msg="[Vision] Approx. FPS: {:.2f}".format(self.fps.fps()))
self.log("[Vision] Approx. FPS: {:.2f}".format(self.fps.fps()), 'debug')

def reset(self):
self.static_back = None

def detect(self):
if not self.running:
return
# if not self.video.stream.isOpened():
# raise Exception('Unable to load camera')
if not self.video.stream.isOpened():
raise Exception('Unable to load camera')
# update the FPS counter
self.fps.update()

matches = []

frame = self.video.read()
if frame is None:
return
if frame is None or frame is False:
raise Exception("[Vision] No frame captured, stopping detection")

if self.flip is True:
frame = cv2.flip(frame, 0)
Expand All @@ -88,8 +107,8 @@ def detect(self):
if len(matches) < 1:
if self.current_match:
self.current_match = False
pub.sendMessage('vision:nomatch')
if self.preview is False:
print("[Vision] No faces detected")
return matches

names = []
Expand Down Expand Up @@ -142,6 +161,8 @@ def detect(self):
if len(matches) > 0:
self.current_match = True
self.last_match = datetime.now()

print(f"[Vision] Detected {len(matches)} matches")

return matches

Expand Down
Empty file.
2 changes: 2 additions & 0 deletions modules/personality.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ def loop(self):
self.random_animation()

def random_animation(self):
self.publish('animate', action='level_neck')
animations = [
'head_shake',
'head_nod',
'head_left',
'head_right',
# 'look_down',
Expand Down
2 changes: 0 additions & 2 deletions modules/vision/imx500/tracking.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ def handle(self, matches):
"""Handle new detections by processing in an asynchronous thread."""
if not self.active or self.moving:
return
# print("Handling matches")
# print(matches)
asyncio.run(self.process_matches(matches))

@staticmethod
Expand Down
Loading