-
Notifications
You must be signed in to change notification settings - Fork 1
/
KuriBot.py
109 lines (93 loc) · 4.58 KB
/
KuriBot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
""" =================================================================
File: KuriBot.py
This file contains code for the KuriBot class that simulates a Kuri
robot by changing its facial expressions and heart light.
Authors: Anh Nguyen, Lily Irvin, Ryan Specht
Contributors: Emiliano Huerta, James Yang
==================================================================="""
import cv2
import os
import sys
import fcntl
# Stores the graphical variables for all 5 sentiments
# Format: [circle color, start left eye angle, end left eye angle,
# start right eye angle, end right eye angle, eye thickness]
SENTIMENT = {"very negative": [(112, 122, 255), 210, 390, 150, 330, -1],
"very positive": [(130, 214, 126), 0, 180, 0, 180, 25],
"neutral": [(200, 200, 200), 0, 360, 0, 360, -1],
"somewhat negative": [(205, 208, 255), 210, 390, 150, 330, -1],
"somewhat positive": [(194, 214, 193), 0, 180, 0, 180, 25]}
class KuriBot:
"""Represents a Kuri robot object"""
def __init__(self, sentiment):
"""Sets up and manages all the variables for a Kuri robot simulation"""
self.img = cv2.imread("./kuri_resized.jpg")
self.height, self.width = self.img.shape[0], self.img.shape[1]
self.sentiment = sentiment
# Variables for heart
self.color = SENTIMENT[self.sentiment][0]
self.size = 50
self.grow = True
# Variables for eyes
self.right_eye = ((433.57440185546875, 346.8737487792969), (78.96944427490234, 88.37602996826172),
178.60519409179688)
self.right_center = int(self.right_eye[0][0]), int(self.right_eye[0][1])
self.right_axes = int(self.right_eye[1][0]) // 2 + 2, int(self.right_eye[1][1]) // 2 + 2
self.left_eye = ((267.5984191894531, 346.9773254394531), (79.46482849121094, 88.4059066772461),
1.4226665496826172)
self.left_center = int(self.left_eye[0][0]), int(self.left_eye[0][1])
self.left_axes = int(self.left_eye[1][0]) // 2 + 2, int(self.left_eye[1][1]) // 2 + 2
self.theta = 178.60519409179688
def setSentiment(self, sentiment):
"""Sets the sentiment of the Kuri robot to the given sentiment"""
self.sentiment = sentiment
self.color = SENTIMENT[self.sentiment][0]
def drawEyes(self):
"""Draws the eyes of the Kuri robot"""
# Clears previous eyes
self.img = cv2.ellipse(self.img, self.left_center, (self.left_axes[0] + 15, self.left_axes[1] + 15),
self.theta, 0, 360, (245, 245, 245), thickness=-1)
self.img = cv2.ellipse(self.img, self.right_center, (self.right_axes[0] + 15, self.right_axes[1] + 15),
self.theta, 0, 360, (245, 245, 245), thickness=-1)
# Draws new eyes
self.img = cv2.ellipse(self.img, self.left_center, self.left_axes, self.theta, SENTIMENT[self.sentiment][1],
SENTIMENT[self.sentiment][2], (0, 0, 0), thickness=SENTIMENT[self.sentiment][5])
self.img = cv2.ellipse(self.img, self.right_center, self.right_axes, self.theta, SENTIMENT[self.sentiment][3],
SENTIMENT[self.sentiment][4], (0, 0, 0), thickness=SENTIMENT[self.sentiment][5])
def drawHeart(self):
"""Draws the circles that represent the Kuri robot's glowing heart light"""
cv2.circle(self.img, (self.width // 2, self.height - 100), self.size, self.color, -1)
cv2.imshow("KuriBot", self.img)
cv2.circle(self.img, (self.width // 2, self.height - 100), self.size, (248, 248, 248), -1)
# Continuously changes the radius of the heart light
if self.grow:
self.size += 1
else:
self.size -= 1
if self.size >= 70:
self.grow = False
if self.size <= 50:
self.grow = True
def runKuri(self):
"""Starts the Kuri robot simulation"""
self.drawEyes()
self.drawHeart()
cv2.waitKey(100)
# Implements a subprocess to run the Kuri robot simultaneously with the user input loop
if __name__ == "__main__":
kuri = KuriBot("neutral")
fd = sys.stdin.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
while True:
kuri.runKuri()
try:
sentiment = sys.stdin.readline()
sentiment = sentiment.strip()
if sentiment == 'q':
cv2.destroyAllWindows()
break
if sentiment in SENTIMENT:
kuri.setSentiment(sentiment)
except:
pass