choose our fastproot.so in merge conflict
This commit is contained in:
commit
f027fb2034
11 changed files with 319 additions and 86 deletions
BIN
yaml parse test/ProotScreen1.png
Normal file
BIN
yaml parse test/ProotScreen1.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 1 KiB |
BIN
yaml parse test/ProotScreen2.png
Normal file
BIN
yaml parse test/ProotScreen2.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 1 KiB |
BIN
yaml parse test/ProotScreen3.png
Normal file
BIN
yaml parse test/ProotScreen3.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 1 KiB |
|
@ -2,4 +2,8 @@ Crosscompile instructions:
|
|||
* Build docker image with python armv7 installed:
|
||||
`docker build -t my-image .`
|
||||
* Use cross to crosscompile:
|
||||
`cross.exe build --target=armv7-unknown-linux-gnueabihf --release`
|
||||
`cross.exe build --target=armv7-unknown-linux-gnueabihf --release`
|
||||
* Move built library to the correct folder:
|
||||
`cp fastproot/target/armv7-unknown-linux-gnueabihf/release/libfastproot.so ./`
|
||||
* Move windows binary
|
||||
`cp fastproot/target/release/fastproot.dll ./fastproot.pyd`
|
BIN
yaml parse test/angryFace.png
Normal file
BIN
yaml parse test/angryFace.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 302 B |
Binary file not shown.
Before ![]() (image error) Size: 1,023 B After ![]() (image error) Size: 1,020 B ![]() ![]() |
|
@ -1,16 +1,35 @@
|
|||
use pyo3::prelude::*;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, FromPyObject)]
|
||||
#[derive(Copy, Clone, FromPyObject, Default, Debug)]
|
||||
pub struct Point {
|
||||
x: u8,
|
||||
y: u8,
|
||||
|
||||
color: (u8, u8, u8),
|
||||
color: [u8; 3],
|
||||
}
|
||||
|
||||
impl PartialEq for Point {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.x == other.x && self.y == other.y
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Point {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "({}, {})", self.x, self.y)
|
||||
}
|
||||
}
|
||||
|
||||
type TuplePoint = (u8,u8, (u8,u8,u8));
|
||||
|
||||
impl Point {
|
||||
pub fn new(x: u8, y: u8) -> Self {
|
||||
Self {
|
||||
x, y,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn distance(self, other: Point) -> f64 {
|
||||
let dx = self.x as f64 - other.x as f64;
|
||||
let dy = self.y as f64 - other.y as f64;
|
||||
|
@ -18,7 +37,20 @@ impl Point {
|
|||
}
|
||||
|
||||
fn into_tuple(&self) -> TuplePoint {
|
||||
(self.x, self.y, self.color)
|
||||
(self.x, self.y, (self.color[0], self.color[1], self.color[2]))
|
||||
}
|
||||
|
||||
fn interpolate(self, other: Point, percent: f32) -> Point{
|
||||
let x = self.x as f32 + ((other.x as f32 - self.x as f32) as f32 * percent);
|
||||
let y = self.y as f32 + ((other.y as f32 - self.y as f32) as f32 * percent);
|
||||
|
||||
let color = (0..3).map(|i| ((1.0 - percent) * self.color[i] as f32 + percent * other.color[i] as f32) as u8).collect::<Vec<_>>();
|
||||
let color = [
|
||||
color[0],
|
||||
color[1],
|
||||
color[2],
|
||||
];
|
||||
Point { x: x as u8, y: y as u8, color }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,17 +67,26 @@ pub fn solve(points1: Vec<Point>, points2: Vec<Point>) -> (Vec<usize>, Vec<usize
|
|||
lsap::solve(points1.len(), points2.len(), &cost_matrix, false).unwrap()
|
||||
}
|
||||
|
||||
pub fn flood_fill(point: Point, mut group: Vec<Point>, points: Vec<Point>) -> Vec<Point> {
|
||||
pub fn flood_fill(point: Point, mut group: Vec<Point>, points: &[Point]) -> Vec<Point> {
|
||||
if !group.contains(&point) {
|
||||
group.push(point);
|
||||
|
||||
let neighbors = [(point.x + 1, point.y), (point.x - 1, point.y), (point.x, point.y + 1), (point.x, point.y - 1)];
|
||||
let neighbors = [
|
||||
(point.x + 1, point.y),
|
||||
(point.x - 1, point.y),
|
||||
(point.x, point.y + 1),
|
||||
(point.x, point.y - 1),
|
||||
(point.x + 1, point.y + 1),
|
||||
(point.x + 1, point.y - 1),
|
||||
(point.x - 1, point.y + 1),
|
||||
(point.x - 1, point.y - 1),
|
||||
];
|
||||
for neighbor_coords in neighbors {
|
||||
let neighbor = points.iter().find(|p| p.x == neighbor_coords.0 && p.y == neighbor_coords.1);
|
||||
|
||||
if let Some(neighbor) = neighbor {
|
||||
if !group.contains(&neighbor) {
|
||||
group = flood_fill(*neighbor, group, points.clone())
|
||||
group = flood_fill(*neighbor, group, points)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,78 +95,181 @@ pub fn flood_fill(point: Point, mut group: Vec<Point>, points: Vec<Point>) -> Ve
|
|||
group
|
||||
}
|
||||
|
||||
// def divide_points_into_groups(points):
|
||||
// def flood_fill(point, group):
|
||||
// if point not in group:
|
||||
// group.append(point)
|
||||
// neighbors = [(point.x + 1, point.y), (point.x - 1, point.y), (point.x, point.y + 1), (point.x, point.y - 1)]
|
||||
// for neighbor_coords in neighbors:
|
||||
// neighbor = next((p for p in points if p.x == neighbor_coords[0] and p.y == neighbor_coords[1]), None)
|
||||
// if neighbor and neighbor not in group:
|
||||
// flood_fill(neighbor, group)
|
||||
//
|
||||
// groups = []
|
||||
// remaining_points = [point for point in points if point.x < 64] # Filter points with x < 64
|
||||
// while remaining_points:
|
||||
// group = []
|
||||
// flood_fill(remaining_points[0], group)
|
||||
// groups.append(group)
|
||||
// # Remove points in the group from the remaining points
|
||||
// remaining_points = [point for point in remaining_points if point not in group]
|
||||
// return groups
|
||||
|
||||
|
||||
#[pyfunction]
|
||||
pub fn divide_into_groups(points: Vec<Point>) -> Vec<Vec<TuplePoint>> {
|
||||
let mut groups = vec![];
|
||||
|
||||
let mut remaining = points.iter().filter(|p| p.x < 64).collect::<Vec<_>>();
|
||||
while let Some(&point) = remaining.get(0) {
|
||||
let group = flood_fill(*point, vec![], points.clone());
|
||||
groups.push(group.iter().map(|v| v.into_tuple()).collect());
|
||||
let mut remaining = points.clone().into_iter().filter(|p| p.x < 64).collect::<std::collections::VecDeque<_>>();
|
||||
while let Some(point) = remaining.pop_front() {
|
||||
let group = flood_fill(point, vec![], &points);
|
||||
groups.push(group.clone());
|
||||
|
||||
remaining = remaining.into_iter().filter(|p| !group.contains(p)).collect();
|
||||
}
|
||||
|
||||
groups
|
||||
groups.into_iter().map(|r| r.into_iter().map(|c| c.into_tuple()).collect()).collect()
|
||||
}
|
||||
|
||||
// #[pyfunction]
|
||||
// fn pair_groups(set_a: Vec<Vec<Point>>, set_b: Vec<Vec<Point>>) -> Vec<(TuplePoint, TuplePoint)> {
|
||||
// let mut pairs = vec![];
|
||||
|
||||
// // Create dictionaries to store bounding boxes for each group
|
||||
// let mut bounding_boxes_a: std::collections::HashMap::new(); // dict[int, tuple[float, float, float, float]] = {}
|
||||
// let mut bounding_boxes_a: std::collections::HashMap::new();
|
||||
pub fn distance(this: (u8, u8), other: (u8, u8)) -> f64 {
|
||||
let dx = this.0 as f64 - other.0 as f64;
|
||||
let dy = this.1 as f64 - other.1 as f64;
|
||||
(dx.powf(2.0) + dy.powf(2.0)).sqrt()
|
||||
}
|
||||
|
||||
// // Calculate bounding boxes for all groups in both sets
|
||||
// for (i, group) in set_a.iter().chain(set_b).iter().enumerate() {
|
||||
// let bounding_box = compute_bounding_box(group);
|
||||
// if i < set_a.len() {
|
||||
// bounding_boxes_a[i] = bounding_box;
|
||||
// } else {
|
||||
// bounding_boxes_b[i - set_a.len()] = bounding_box;
|
||||
// }
|
||||
// }
|
||||
pub fn centroid(points: &[Point]) -> (u8, u8) {
|
||||
let x = points.iter().fold(0usize, |acc, p| acc + p.x as usize) / points.len();
|
||||
let y = points.iter().fold(0usize, |acc, p| acc + p.y as usize) / points.len();
|
||||
(x as u8, y as u8)
|
||||
}
|
||||
|
||||
// // Check for overlaps and determine pairs
|
||||
// for (i, group_a) in set_a.iter().enumerate() {
|
||||
// let overlap_detected = false;
|
||||
// for (j, group_b) in set_b.iter().enenumerate() {
|
||||
// let bounding_box_a = bounding_boxes_a[i];
|
||||
// let bounding_box_b = bounding_boxes_b[j];
|
||||
// if (
|
||||
// bounding_box_a[0] <= bounding_box_b[1] &&
|
||||
// bounding_box_a[1] >= bounding_box_b[0] &&
|
||||
// bounding_box_a[2] <= bounding_box_b[3] &&
|
||||
// bounding_box_a[3] >= bounding_box_b[2]
|
||||
// ) {
|
||||
// pairs.push((group_a, group_b));
|
||||
// overlap_detected = true;
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
|
||||
// if !overlap_detected {
|
||||
// // Find the nearest neighbor in set B
|
||||
// let mut nearest_group = set_b[0];
|
||||
// let mut nearest_value = 0.0f64;
|
||||
// for val in set_b.iter() {
|
||||
// if calculate_distance(group_a, val) < nearest_value {
|
||||
// nearest_group = val;
|
||||
// }
|
||||
// }
|
||||
// pairs.append((group_a, nearest_group));
|
||||
// }
|
||||
// }
|
||||
#[pyfunction]
|
||||
pub fn pair_groups(smaller: Vec<Vec<Point>>, larger: Vec<Vec<Point>>) -> Vec<(Vec<TuplePoint>, Vec<TuplePoint>)> {
|
||||
let smaller_center = smaller.iter().map(|v| centroid(v)).collect::<Vec<_>>();
|
||||
let larger_center = larger.iter().map(|v| centroid(v)).collect::<Vec<_>>();
|
||||
|
||||
let mut map = std::collections::HashMap::<usize, Vec<usize>>::new();
|
||||
|
||||
// Map each item from centroids2 to an item in centroids1.
|
||||
for (idx2, coords2) in larger_center.iter().enumerate() {
|
||||
// Get nearest item in centroids1
|
||||
let mut nearest_idx = 0;
|
||||
let mut nearest_dist = f64::MAX;
|
||||
for (idx1, coords1) in smaller_center.iter().enumerate() {
|
||||
if distance(*coords1, *coords2) < nearest_dist {
|
||||
nearest_dist = distance(*coords1, *coords2);
|
||||
nearest_idx = idx1;
|
||||
}
|
||||
}
|
||||
// now, nearest_idx is the index in centroid1 of the nearest point.
|
||||
map.entry(nearest_idx).and_modify(|v| v.push(idx2)).or_insert_with(||vec![idx2]);
|
||||
}
|
||||
|
||||
let mut result = vec![];
|
||||
for (k, indexes) in map {
|
||||
let mut combined = vec![];
|
||||
for i in indexes {
|
||||
combined.extend(larger[i].iter())
|
||||
}
|
||||
|
||||
let key = smaller[k].iter().map(|v| v.into_tuple()).collect();
|
||||
let combined = combined.into_iter().map(|v: Point| v.into_tuple()).collect();
|
||||
result.push((key, combined))
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
pub fn interpolate_point_pairs(pairs: Vec<(Point, Point)>, percent: f32) -> Vec<TuplePoint> {
|
||||
let mut interpolated_points = vec![];
|
||||
for (point1, point2) in pairs {
|
||||
let interpolated_point = point1.interpolate(point2, percent);
|
||||
if !interpolated_points.contains(&interpolated_point){
|
||||
interpolated_points.push(interpolated_point);
|
||||
}
|
||||
}
|
||||
interpolated_points.into_iter().map(|v| v.into_tuple()).collect()
|
||||
}
|
||||
|
||||
// pairs
|
||||
// }
|
||||
|
||||
#[pymodule]
|
||||
fn fastproot(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
||||
m.add_function(wrap_pyfunction!(solve, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(divide_into_groups, m)?)?;
|
||||
// m.add_function(wrap_pyfunction!(pair_groups, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(pair_groups, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(interpolate_point_pairs, m)?)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use super::{Point, flood_fill, divide_into_groups, centroid, pair_groups, interpolate_point_pairs};
|
||||
#[test]
|
||||
fn should_do_flood_fill() {
|
||||
let groups = flood_fill(Point::new(1,1), vec![], &vec![
|
||||
Point::new(1,1),
|
||||
Point::new(1,2),
|
||||
Point::new(2,1),
|
||||
|
||||
Point::new(3,3),
|
||||
]);
|
||||
println!("{groups:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_divide_into_groups() {
|
||||
let groups = divide_into_groups(vec![
|
||||
Point::new(1,1),
|
||||
Point::new(1,2),
|
||||
Point::new(2,1),
|
||||
|
||||
Point::new(3,3),
|
||||
Point::new(3,4),
|
||||
Point::new(4,4)
|
||||
]);
|
||||
for (i, g) in groups.iter().enumerate() {
|
||||
println!("{i}: {g:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_create_centroid() {
|
||||
let centroid = centroid(&vec![
|
||||
Point::new(1,1),
|
||||
Point::new(1,2),
|
||||
Point::new(2,1),
|
||||
Point::new(20,10),
|
||||
]);
|
||||
|
||||
println!("{centroid:?}");
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn should_pair_groups() {
|
||||
|
||||
let a = vec![vec![(59, 2), (60, 2), (61, 2), (62, 2), (62, 3)], vec![(15, 8), (16, 8), (17, 8), (18, 8), (19, 8), (20, 8), (21, 8), (22, 8), (23, 8), (24, 8), (25, 8), (26, 8), (27, 8), (27, 9), (28, 9), (29, 9), (30, 9), (30, 10), (31, 10), (31, 11), (29, 10), (26, 9), (25, 9), (24, 9), (23, 9), (22, 9), (21, 9), (20, 9), (19, 9), (18, 9), (17, 9), (16, 9), (15, 9)], vec![(26, 22), (27, 22), (28, 22), (28, 23), (29, 23), (30, 23), (31, 23), (31, 24), (32, 24), (33, 24), (33, 25), (34, 25), (35, 25), (36, 25), (36, 26), (37, 26), (38, 26), (39, 26), (40, 26), (41, 26), (42, 26), (42, 27), (43, 27), (44, 27), (45, 27), (46, 27), (47, 27), (47, 26), (48, 26), (49, 26), (50, 26), (50, 25), (51, 25), (52, 25), (52, 26), (53, 26), (53, 27), (53, 28), (54, 28), (54, 29), (55, 29), (55, 30), (56, 30), (57, 30), (57, 29), (58, 29), (58, 28), (59, 28), (59, 27), (60, 27), (60, 26), (61, 26), (61, 25), (62, 25), (62, 24), (51, 24)]];
|
||||
let b = vec![vec![(21, 1), (22, 1), (23, 1), (24, 1), (25, 1), (26, 1), (27, 1), (28, 1), (28, 2), (29, 2), (30, 2), (31, 2), (31, 3), (32, 3), (32, 4), (33, 4), (33, 5), (34, 5), (34, 6), (34, 7), (35, 7), (35, 8), (35, 9), (35, 10), (35, 11), (34, 11), (34, 12), (33, 12), (33, 13), (32, 13), (32, 14), (31, 14), (30, 14), (29, 14), (29, 15), (28, 15), (27, 15), (26, 15), (25, 15), (24, 15), (23, 15), (22, 15), (21, 15), (20, 15), (19, 15), (19, 14), (18, 14), (17, 14), (16, 14), (16, 13), (15, 13), (15, 12), (14, 12), (13, 12), (13, 11), (12, 11), (12, 10), (12, 9), (12, 8), (21, 2), (20, 2), (19, 2), (18, 2), (18, 3), (17, 3), (17, 4), (17, 5), (17, 6), (16, 6), (16, 7), (16, 8), (16, 9), (17, 9), (17, 10), (18, 10), (18, 11), (19, 11), (19, 12), (20, 12), (21, 12), (21, 13), (22, 13), (23, 13), (24, 13), (25, 13), (26, 13), (27, 13), (27, 12), (28, 12), (29, 12), (29, 11), (30, 11), (30, 10), (31, 10), (31, 9), (31, 8), (31, 7), (30, 7), (30, 6), (30, 5), (29, 5), (28, 5), (28, 4), (27, 4), (26, 4), (25, 4), (24, 4), (23, 4), (22, 4), (22, 5), (21, 5), (21, 6), (20, 6), (20, 7), (20, 8), (20, 9), (21, 9), (21, 10), (22, 10), (23, 10), (24, 10), (25, 10), (26, 10), (27, 10), (27, 9), (27, 8), (28, 8), (27, 7), (26, 7), (25, 7), (24, 7)], vec![(59, 2), (60, 2), (61, 2), (62, 2), (62, 3)], vec![(26, 22), (27, 22), (28, 22), (28, 23), (29, 23), (30, 23), (31, 23), (31, 24), (32, 24), (33, 24), (33, 25), (34, 25), (35, 25), (36, 25), (36, 26), (37, 26), (38, 26), (39, 26), (40, 26), (41, 26), (42, 26), (42, 27), (43, 27), (44, 27), (45, 27), (46, 27), (47, 27), (47, 26), (48, 26), (49, 26), (50, 26), (50, 25), (51, 25), (52, 25), (52, 26), (53, 26), (53, 27), (53, 28), (54, 28), (54, 29), (55, 29), (55, 30), (56, 30), (57, 30), (57, 29), (58, 29), (58, 28), (59, 28), (59, 27), (60, 27), (60, 26), (61, 26), (61, 25), (62, 25), (62, 24), (51, 24)]];
|
||||
|
||||
let a = a.into_iter().map(|r| r.into_iter().map(|(x,y)| Point::new(x,y)).collect()).collect();
|
||||
let b = b.into_iter().map(|r| r.into_iter().map(|(x,y)| Point::new(x,y)).collect()).collect();
|
||||
|
||||
let res = pair_groups(a, b
|
||||
// vec![
|
||||
// vec![Point::new(1,1)],
|
||||
// vec![Point::new(3,3),Point::new(3,4)],
|
||||
// vec![Point::new(10,10), Point::new(11,11)]
|
||||
// ],
|
||||
// vec![
|
||||
// vec![Point::new(2,2)],
|
||||
// vec![Point::new(2,5)],
|
||||
// vec![Point::new(12,12)],
|
||||
// ]
|
||||
);
|
||||
for (i, s) in res {
|
||||
println!("====> {i:?} => {s:?}");
|
||||
}
|
||||
}
|
||||
}
|
BIN
yaml parse test/loveFace.png
Normal file
BIN
yaml parse test/loveFace.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 575 B |
|
@ -410,8 +410,8 @@ def main():
|
|||
decision_layer = DecisionLayer(animations, rendering_layer)
|
||||
|
||||
# Create and start random blinks interrupts
|
||||
screen_update_thread = threading.Thread(target=random_blinks)
|
||||
screen_update_thread.start()
|
||||
# screen_update_thread = threading.Thread(target=random_blinks)
|
||||
# screen_update_thread.start()
|
||||
|
||||
|
||||
decision_layer.handle_trigger("boot", "")
|
||||
|
|
|
@ -31,8 +31,85 @@ animations:
|
|||
# Additional comments or configuration options for Animation1 can go here.
|
||||
# For example, you can specify the duration, sound effects, or other details.
|
||||
|
||||
- name: blink
|
||||
- name: set closed
|
||||
description: Animation to close eyes
|
||||
loop_count: 1
|
||||
|
||||
trigger: Butn_0001_0001
|
||||
|
||||
overrideable: true
|
||||
|
||||
graphics:
|
||||
- type: transition
|
||||
to_file: eyesClosed_neutral.png
|
||||
duration: 10
|
||||
|
||||
- name: set confusion
|
||||
description: Animation to be confused
|
||||
loop_count: 1
|
||||
|
||||
trigger: Butn_0002_0001
|
||||
|
||||
overrideable: true
|
||||
|
||||
graphics:
|
||||
- type: transition
|
||||
to_file: dizzyFace.png
|
||||
duration: 10
|
||||
|
||||
- name: set angry
|
||||
description: Animation to be confused
|
||||
loop_count: 1
|
||||
|
||||
trigger: Butn_0003_0001
|
||||
|
||||
overrideable: true
|
||||
|
||||
graphics:
|
||||
- type: transition
|
||||
to_file: angryFace.png
|
||||
duration: 10
|
||||
|
||||
- name: set love
|
||||
description: Animation for love eyes
|
||||
loop_count: 1
|
||||
|
||||
trigger: Butn_0004_0001
|
||||
|
||||
overrideable: true
|
||||
|
||||
graphics:
|
||||
- type: transition
|
||||
to_file: loveFace.png
|
||||
duration: 10
|
||||
|
||||
- name: reset to continuous blink
|
||||
description: Animation for blinking
|
||||
loop_count: 0
|
||||
|
||||
trigger: Butn_0004_0001
|
||||
|
||||
overrideable: true
|
||||
|
||||
graphics:
|
||||
- type: transition # close the eye from whatever the current state
|
||||
to_file: eyesClosed_neutral.png
|
||||
duration: 6
|
||||
|
||||
- type: image # hold eye closed
|
||||
source_file: eyesClosed_neutral.png
|
||||
duration: 10
|
||||
|
||||
- type: transition # open the eye again from being closed
|
||||
to_file: neutral.png
|
||||
duration: 6
|
||||
|
||||
- type: image # hold eye closed
|
||||
source_file: neutral.png
|
||||
duration: 400
|
||||
|
||||
- name: blink
|
||||
description: Animation for a blink
|
||||
loop_count: 1
|
||||
|
||||
trigger: blinkTimer #Button 2 pressed
|
||||
|
@ -41,43 +118,38 @@ animations:
|
|||
|
||||
graphics:
|
||||
- type: transition # close the eye from whatever the current state
|
||||
to_file: dizzyFace.png
|
||||
duration: 5
|
||||
to_file: eyesClosed_neutral.png
|
||||
duration: 6
|
||||
|
||||
- type: image # hold eye closed
|
||||
source_file: dizzyFace.png
|
||||
source_file: eyesClosed_neutral.png
|
||||
duration: 10
|
||||
|
||||
- type: transition # open the eye again from being closed
|
||||
to_file: neutral.png
|
||||
duration: 5
|
||||
duration: 6
|
||||
|
||||
- name: openEye
|
||||
description: Animation for blinking
|
||||
loop_count: 1
|
||||
- name: boot
|
||||
description: boot with blinking
|
||||
loop_count: 0
|
||||
|
||||
trigger: boot
|
||||
|
||||
overrideable: true # blink can be interupted at any time
|
||||
|
||||
graphics:
|
||||
- type: transition # close the eye from whatever the current state
|
||||
to_file: eyesClosed_neutral.png
|
||||
duration: 6
|
||||
|
||||
- type: image # hold eye closed
|
||||
source_file: eyesClosed_neutral.png
|
||||
duration: 1
|
||||
duration: 10
|
||||
|
||||
- type: transition # open the eye again from being closed
|
||||
to_file: dizzyFace.png
|
||||
duration: 5
|
||||
to_file: neutral.png
|
||||
duration: 6
|
||||
|
||||
- name: make dizzy
|
||||
description: Animation for making dizzy
|
||||
loop_count: 1
|
||||
|
||||
trigger: Butn_0002_0001
|
||||
|
||||
overrideable: true # blink can be interupted at any time
|
||||
|
||||
graphics:
|
||||
- type: transition # open the eye again from being closed
|
||||
to_file: dizzyFace.png
|
||||
duration: 5
|
||||
- type: image # hold eye closed
|
||||
source_file: neutral.png
|
||||
duration: 400
|
||||
|
|
13
yaml parse test/util.py
Normal file
13
yaml parse test/util.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
from time import time
|
||||
|
||||
def timer(func):
|
||||
# This function shows the execution time of
|
||||
# the function object passed
|
||||
def wrap_func(*args, **kwargs):
|
||||
t1 = time()
|
||||
result = func(*args, **kwargs)
|
||||
t2 = time()
|
||||
print(f'Function {func.__name__!r} execution: {(t2-t1):.4f}s')
|
||||
return result
|
||||
return wrap_func
|
||||
|
Loading…
Add table
Reference in a new issue