From b52372f0d49336b16d6604014b2f66401b1ce017 Mon Sep 17 00:00:00 2001 From: Jacob Haip Date: Sun, 23 Jul 2023 09:24:16 -0400 Subject: add support for layered drawing and use to mask tags --- virtual-programs/mask-tags.folk | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 virtual-programs/mask-tags.folk (limited to 'virtual-programs') diff --git a/virtual-programs/mask-tags.folk b/virtual-programs/mask-tags.folk new file mode 100644 index 00000000..4f0ae4b2 --- /dev/null +++ b/virtual-programs/mask-tags.folk @@ -0,0 +1,16 @@ +When tag /something/ has corners /corners/ { + set tagCorners [lmap p $corners {::cameraToProjector $p}] + + set vecBottom [sub [lindex $tagCorners 1] [lindex $tagCorners 0]] + set vecRight [sub [lindex $tagCorners 2] [lindex $tagCorners 1]] + + set offsets {{-0.5 -0.5} {0.5 -0.5} {0.5 0.5} {-0.5 0.5}} + set scales [matmul $offsets [list $vecBottom $vecRight]] + set corners [add $tagCorners $scales] + + set p0 [lindex $corners 0] + set p1 [lindex $corners 1] + set p2 [lindex $corners 2] + set p3 [lindex $corners 3] + Display::drawOnTop Display::fillQuad $p0 $p1 $p2 $p3 black +} \ No newline at end of file -- cgit v1.2.3 From ffa09456af9674a4dd2645b2067e9c2c3e379df3 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Thu, 10 Aug 2023 21:21:43 -0400 Subject: Move display to virtual program Mostly to make it easier to debug the error spam, but it's nice that it's more consistent too --- virtual-programs/display.folk | 83 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 virtual-programs/display.folk (limited to 'virtual-programs') diff --git a/virtual-programs/display.folk b/virtual-programs/display.folk new file mode 100644 index 00000000..ce7c0c2c --- /dev/null +++ b/virtual-programs/display.folk @@ -0,0 +1,83 @@ +if {$::isLaptop} return + +namespace eval Display { + variable WIDTH + variable HEIGHT + variable LAYER 0 + regexp {mode "(\d+)x(\d+)"} [exec fbset] -> WIDTH HEIGHT + + proc drawOnTop {func args} { + set Display::LAYER 1 + uplevel [list $func {*}$args] + set Display::LAYER 0 + } + + proc stroke {points width color} { + uplevel [list Wish display runs [list Display::stroke $points $width $color] on layer $Display::LAYER] + } + + proc circle {x y radius thickness color} { + uplevel [list Wish display runs [list Display::circle $x $y $radius $thickness $color] on layer $Display::LAYER] + } + + proc text args { + uplevel [list Wish display runs [list Display::text {*}$args] on layer $Display::LAYER] + } + + proc fillTriangle args { + uplevel [list Wish display runs [list Display::fillTriangle {*}$args] on layer $Display::LAYER] + } + + proc fillQuad args { + uplevel [list Wish display runs [list Display::fillQuad {*}$args] on layer $Display::LAYER] + } + + proc fillPolygon args { + uplevel [list Wish display runs [list Display::fillPolygon {*}$args] on layer $Display::LAYER] + } + + variable displayTime none +} + +On process { + source pi/Display.tcl + Display::init + puts "Display tid: [getTid]" + + # TODO: Clean this up. We retract these so that we don't bounce + # statements back to the main Folk process that it sends us. + Retract /anyone/ wishes $::thisProcess shares all wishes + Retract /anyone/ wishes $::thisProcess shares all claims + Wish $::thisProcess shares statements like \ + [list /someone/ wishes /process/ receives statements like /pattern/] + Wish $::thisProcess shares statements like \ + [list /someone/ claims $::thisProcess has pid /pid/] + Wish $::thisProcess receives statements like \ + [list /someone/ wishes display runs /command/ on layer /layer/] + Wish $::thisProcess receives statements like \ + [list /someone/ wishes display runs /command/] + + forever { + set displayList [list] + foreach match [Statements::findMatches {/someone/ wishes display runs /command/ on layer /layer/}] { + lappend displayList [list [dict get $match layer] [dict get $match command]] + } + foreach match [Statements::findMatches {/someone/ wishes display runs /command/}] { + lappend displayList [list 0 [dict get $match command]] + } + + proc lcomp {a b} { + set layerA [lindex $a 0] + set layerB [lindex $b 0] + if {$layerA == $layerB} { + expr {[lindex $a 1 0] == "Display::text"} + } else { + expr {$layerA - $layerB} + } + } + + set displayCommands [join [lmap sublist [lsort -command lcomp $displayList] {lindex $sublist 1}] "\n"] + append displayCommands "\ncommitThenClearStaging" + set displayTime [time $displayCommands] + } +} -- cgit v1.2.3 From 6635ab4466548a2f9e370424f17cf68c1799605d Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Thu, 10 Aug 2023 21:25:17 -0400 Subject: Report display time --- virtual-programs/display.folk | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'virtual-programs') diff --git a/virtual-programs/display.folk b/virtual-programs/display.folk index ce7c0c2c..a771b045 100644 --- a/virtual-programs/display.folk +++ b/virtual-programs/display.folk @@ -56,6 +56,8 @@ On process { [list /someone/ wishes display runs /command/ on layer /layer/] Wish $::thisProcess receives statements like \ [list /someone/ wishes display runs /command/] + Wish $::thisProcess shares statements like \ + [list /someone/ claims the display time is /displayTime/] forever { set displayList [list] @@ -79,5 +81,10 @@ On process { set displayCommands [join [lmap sublist [lsort -command lcomp $displayList] {lindex $sublist 1}] "\n"] append displayCommands "\ncommitThenClearStaging" set displayTime [time $displayCommands] + Commit { Claim the display time is $displayTime } } } +# TODO: remove this compatibility hack +When the display time is /displayTime/ { + set ::Display::displayTime $displayTime +} -- cgit v1.2.3 From 1b887d8b53637e9c6a85a901e4e4ea3294bdddf2 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Fri, 11 Aug 2023 16:50:38 -0400 Subject: Add timestamps to camera frames --- virtual-programs/apriltags.folk | 61 ++++++++++++++++++++++++++++++++--------- virtual-programs/camera.folk | 11 ++++++-- 2 files changed, 56 insertions(+), 16 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/apriltags.folk b/virtual-programs/apriltags.folk index 01377b78..3e95ee64 100644 --- a/virtual-programs/apriltags.folk +++ b/virtual-programs/apriltags.folk @@ -9,29 +9,64 @@ On process { Retract /anyone/ wishes $::thisProcess shares all wishes Retract /anyone/ wishes $::thisProcess shares all claims Wish $::thisProcess receives statements like \ - [list /someone/ claims the camera frame is /grayFrame/] + [list /someone/ claims the camera frame is /grayFrame/ at /timestamp/] Wish $::thisProcess shares statements like \ [list /someone/ wishes /process/ receives statements like /pattern/] Wish $::thisProcess shares statements like \ - [list /someone/ claims tag /tag/ has center /center/ size /size/] - Wish $::thisProcess shares statements like \ - [list /someone/ claims tag /tag/ has corners /corners/] - Wish $::thisProcess shares statements like \ - [list /someone/ claims the AprilTag time is /aprilTime/] + [list /someone/ claims /process/ detects tags /tags/ at /timestamp/ in time /aprilTime/] Wish $::thisProcess shares statements like \ [list /someone/ claims $::thisProcess has pid /pid/] - When the camera frame is /grayFrame/ { + When the camera frame is /grayFrame/ at /timestamp/ { set aprilTime [time { set tags [AprilTags::detect $grayFrame] }] Commit { - Claim the AprilTag time is $aprilTime - - foreach tag $tags { - Claim tag [dict get $tag id] has center [dict get $tag center] size [dict get $tag size] - Claim tag [dict get $tag id] has corners [dict get $tag corners] - } + Claim $::thisProcess detects tags $tags at $timestamp in time $aprilTime } } } + +When /someone/ detects tags /tags/ at /timestamp/ in time /aprilTime/ { + Claim the AprilTag time is $aprilTime + foreach tag $tags { + Claim tag [dict get $tag id] has center [dict get $tag center] size [dict get $tag size] + Claim tag [dict get $tag id] has corners [dict get $tag corners] + } +} + +# On process { +# source pi/AprilTags.tcl +# AprilTags::init + +# # TODO: Clean this up. We retract these so that we don't bounce +# # statements back to the main Folk process that it sends us. +# Retract /anyone/ wishes $::thisProcess shares all wishes +# Retract /anyone/ wishes $::thisProcess shares all claims +# Wish $::thisProcess receives statements like \ +# [list /someone/ claims the camera frame is /grayFrame/] +# Wish $::thisProcess shares statements like \ +# [list /someone/ wishes /process/ receives statements like /pattern/] +# Wish $::thisProcess shares statements like \ +# [list /someone/ claims tag /tag/ has center /center/ size /size/] +# Wish $::thisProcess shares statements like \ +# [list /someone/ claims tag /tag/ has corners /corners/] +# Wish $::thisProcess shares statements like \ +# [list /someone/ claims the AprilTag time is /aprilTime/] +# Wish $::thisProcess shares statements like \ +# [list /someone/ claims $::thisProcess has pid /pid/] + +# When the camera frame is /grayFrame/ { +# set aprilTime [time { +# set tags [AprilTags::detect $grayFrame] +# }] +# Commit { +# Claim the AprilTag time is $aprilTime + +# foreach tag $tags { +# Claim tag [dict get $tag id] has center [dict get $tag center] size [dict get $tag size] +# Claim tag [dict get $tag id] has corners [dict get $tag corners] +# } +# } +# } +# } diff --git a/virtual-programs/camera.folk b/virtual-programs/camera.folk index d9dab784..4f59a576 100644 --- a/virtual-programs/camera.folk +++ b/virtual-programs/camera.folk @@ -18,15 +18,20 @@ On process { source pi/Camera.tcl Camera::init $width $height - puts "Camera tid: [getTid]" - + puts "Camera tid: [getTid] booting at [clock milliseconds]" + forever { set cameraTime [time { set grayFrame [Camera::grayFrame] }] Commit { Claim the camera time is $cameraTime - Claim the camera frame is $grayFrame + Claim the camera frame is $grayFrame at [clock milliseconds] } } } + +# For backward compatibility. +When the camera frame is /grayFrame/ at /timestamp/ { + Claim the camera frame is $grayFrame +} -- cgit v1.2.3 From 55f9cd4cc30e4fe157419315945d083184ecb871 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Fri, 11 Aug 2023 19:47:04 -0400 Subject: Measure display fps --- virtual-programs/display.folk | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/display.folk b/virtual-programs/display.folk index a771b045..b1d16be7 100644 --- a/virtual-programs/display.folk +++ b/virtual-programs/display.folk @@ -59,6 +59,7 @@ On process { Wish $::thisProcess shares statements like \ [list /someone/ claims the display time is /displayTime/] + set ::frames [list] forever { set displayList [list] foreach match [Statements::findMatches {/someone/ wishes display runs /command/ on layer /layer/}] { @@ -78,10 +79,20 @@ On process { } } - set displayCommands [join [lmap sublist [lsort -command lcomp $displayList] {lindex $sublist 1}] "\n"] - append displayCommands "\ncommitThenClearStaging" - set displayTime [time $displayCommands] - Commit { Claim the display time is $displayTime } + set displayCommands [lmap sublist [lsort -command lcomp $displayList] {lindex $sublist 1}] + lappend displayCommands "commitThenClearStaging" + set displayTime [baretime [list foreach command $displayCommands { {*}$command }]] + + set inLastSecond 0 + set now [clock milliseconds] + lappend frames $now + foreach frame $frames { + if {$frame > $now - 1000} { + incr inLastSecond + } + } + set frames [lreplace $frames 0 end-$inLastSecond] + Commit { Claim the display time is "$displayTime us ($inLastSecond fps)" } } } # TODO: remove this compatibility hack -- cgit v1.2.3 From 13dac3dd6b3ddbd926bf240fdf9061ae7d2a4758 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Sun, 13 Aug 2023 08:34:21 -0400 Subject: Add clock time for animation --- virtual-programs/time.folk | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 virtual-programs/time.folk (limited to 'virtual-programs') diff --git a/virtual-programs/time.folk b/virtual-programs/time.folk new file mode 100644 index 00000000..8ce4c028 --- /dev/null +++ b/virtual-programs/time.folk @@ -0,0 +1,3 @@ +When $::thisProcess has step count /t/ { + Claim $::thisProcess has clock time [clock milliseconds] +} -- cgit v1.2.3 From bc1fc7ecb1718abb556408db88e53743df754bae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Cuervo?= Date: Sun, 13 Aug 2023 09:36:36 -0400 Subject: Update global node time to seconds --- virtual-programs/time.folk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'virtual-programs') diff --git a/virtual-programs/time.folk b/virtual-programs/time.folk index 8ce4c028..961b1863 100644 --- a/virtual-programs/time.folk +++ b/virtual-programs/time.folk @@ -1,3 +1,3 @@ When $::thisProcess has step count /t/ { - Claim $::thisProcess has clock time [clock milliseconds] + Claim the clock time is [/ [clock milliseconds] 1000.0] } -- cgit v1.2.3 From 1484ed78971e1c6bdc0fa7995ef659bab0df027c Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Sun, 13 Aug 2023 12:06:47 -0400 Subject: Region helper --- virtual-programs/regions.folk | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'virtual-programs') diff --git a/virtual-programs/regions.folk b/virtual-programs/regions.folk index 5de19b98..945fcd20 100644 --- a/virtual-programs/regions.folk +++ b/virtual-programs/regions.folk @@ -1,3 +1,8 @@ When when the distance between /p1/ and /p2/ is /distanceVar/ /body/ with environment /e/ & /p1/ has region /r1/ & /p2/ has region /r2/ { Claim the distance between $p1 and $p2 is [region distance $r1 $r2] } + +When /someone/ wishes region /r/ is /verbed/ /x/ { + Claim $r has region $r + Wish $r is $verbed $x +} -- cgit v1.2.3 From 7d462c3bd10b29da1063c338ae66ab253a1e71d8 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Sun, 13 Aug 2023 19:26:00 -0400 Subject: display: Show render/commit split --- virtual-programs/display.folk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/display.folk b/virtual-programs/display.folk index b1d16be7..d5623d10 100644 --- a/virtual-programs/display.folk +++ b/virtual-programs/display.folk @@ -80,8 +80,8 @@ On process { } set displayCommands [lmap sublist [lsort -command lcomp $displayList] {lindex $sublist 1}] - lappend displayCommands "commitThenClearStaging" - set displayTime [baretime [list foreach command $displayCommands { {*}$command }]] + set renderTime [baretime [list foreach command $displayCommands { {*}$command }]] + set commitTime [baretime commitThenClearStaging] set inLastSecond 0 set now [clock milliseconds] @@ -92,7 +92,7 @@ On process { } } set frames [lreplace $frames 0 end-$inLastSecond] - Commit { Claim the display time is "$displayTime us ($inLastSecond fps)" } + Commit { Claim the display time is "render $renderTime us + commit $commitTime us ($inLastSecond fps)" } } } # TODO: remove this compatibility hack -- cgit v1.2.3 From 3ddc9e924e7e747f3d75501eaa8cd731d67f5e7c Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Sun, 13 Aug 2023 23:07:57 -0400 Subject: More small monitoring improvements. Remote flamegraph tid --- virtual-programs/display.folk | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/display.folk b/virtual-programs/display.folk index d5623d10..5e16797f 100644 --- a/virtual-programs/display.folk +++ b/virtual-programs/display.folk @@ -80,19 +80,20 @@ On process { } set displayCommands [lmap sublist [lsort -command lcomp $displayList] {lindex $sublist 1}] + set renderTime [baretime [list foreach command $displayCommands { {*}$command }]] set commitTime [baretime commitThenClearStaging] - set inLastSecond 0 + set framesInLastSecond 0 set now [clock milliseconds] lappend frames $now foreach frame $frames { if {$frame > $now - 1000} { - incr inLastSecond + incr framesInLastSecond } } - set frames [lreplace $frames 0 end-$inLastSecond] - Commit { Claim the display time is "render $renderTime us + commit $commitTime us ($inLastSecond fps)" } + set frames [lreplace $frames 0 end-$framesInLastSecond] + Commit { Claim the display time is "render $renderTime us + commit $commitTime us ($framesInLastSecond fps)" } } } # TODO: remove this compatibility hack -- cgit v1.2.3 From 11cdb9051327c873b334284ad8409be64fc6b3e7 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Sun, 13 Aug 2023 23:08:28 -0400 Subject: WIP: Start on incremental detector. Fix stride in AprilTags --- virtual-programs/apriltags.folk | 107 ++++++++++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 32 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/apriltags.folk b/virtual-programs/apriltags.folk index 3e95ee64..f8b94da2 100644 --- a/virtual-programs/apriltags.folk +++ b/virtual-programs/apriltags.folk @@ -35,38 +35,81 @@ When /someone/ detects tags /tags/ at /timestamp/ in time /aprilTime/ { } } -# On process { -# source pi/AprilTags.tcl -# AprilTags::init +On process { + source pi/AprilTags.tcl + AprilTags::init + + # TODO: Clean this up. We retract these so that we don't bounce + # statements back to the main Folk process that it sends us. + Retract /anyone/ wishes $::thisProcess shares all wishes + Retract /anyone/ wishes $::thisProcess shares all claims + Wish $::thisProcess receives statements like \ + [list /someone/ claims the camera frame is /grayFrame/ at /timestamp/] + Wish $::thisProcess receives statements like \ + [list /someone/ claims /process/ detects tags /tags/ at /timestamp/ in time /aprilTime/] + Wish $::thisProcess shares statements like \ + [list /someone/ wishes /process/ receives statements like /pattern/] + Wish $::thisProcess shares statements like \ + [list /someone/ claims $::thisProcess has pid /pid/] + Wish $::thisProcess shares statements like \ + [list /someone/ claims $::thisProcess detects tags /tags/ at /timestamp/ in time /aprilTime/] + Wish $::thisProcess shares statements like \ + [list /someone/ wishes /something/ is labelled /text/] + Wish $::thisProcess shares statements like \ + [list /someone/ wishes /something/ displays camera slice /slice/] + + proc subimage {im x y subwidth subheight} { + dict with im { + set x [expr {int($x)}] + set y [expr {int($y)}] + set subdata [expr {$data + ($y*$width + $x) * $components}] + dict create \ + width [int $subwidth] \ + height [int $subheight] \ + components $components \ + bytesPerRow $bytesPerRow \ + data [format 0x%x $subdata] + } + } -# # TODO: Clean this up. We retract these so that we don't bounce -# # statements back to the main Folk process that it sends us. -# Retract /anyone/ wishes $::thisProcess shares all wishes -# Retract /anyone/ wishes $::thisProcess shares all claims -# Wish $::thisProcess receives statements like \ -# [list /someone/ claims the camera frame is /grayFrame/] -# Wish $::thisProcess shares statements like \ -# [list /someone/ wishes /process/ receives statements like /pattern/] -# Wish $::thisProcess shares statements like \ -# [list /someone/ claims tag /tag/ has center /center/ size /size/] -# Wish $::thisProcess shares statements like \ -# [list /someone/ claims tag /tag/ has corners /corners/] -# Wish $::thisProcess shares statements like \ -# [list /someone/ claims the AprilTag time is /aprilTime/] -# Wish $::thisProcess shares statements like \ -# [list /someone/ claims $::thisProcess has pid /pid/] + When the camera frame is /grayFrame/ at /timestamp/ & \ + /process/ detects tags /prevTags/ at /something/ in time /something/ { -# When the camera frame is /grayFrame/ { -# set aprilTime [time { -# set tags [AprilTags::detect $grayFrame] -# }] -# Commit { -# Claim the AprilTag time is $aprilTime + if {$process eq $::thisProcess} { return } -# foreach tag $tags { -# Claim tag [dict get $tag id] has center [dict get $tag center] size [dict get $tag size] -# Claim tag [dict get $tag id] has corners [dict get $tag corners] -# } -# } -# } -# } + set tags [list] + set frameWidth [dict get $grayFrame width] + set frameHeight [dict get $grayFrame height] + set aprilTime 0 + foreach prevTag $prevTags { + set size [dict get $prevTag size] + set corners [dict get $prevTag corners] + set x [min {*}[lmap corner $corners {lindex $corner 0}]] + set y [min {*}[lmap corner $corners {lindex $corner 1}]] + set x1 [max {*}[lmap corner $corners {lindex $corner 0}]] + set y1 [max {*}[lmap corner $corners {lindex $corner 1}]] + + set x [max [- $x $size] 0] + set y [max [- $y $size] 0] + set x1 [min [+ $x1 $size] $frameWidth] + set y1 [min [+ $y1 $size] $frameHeight] + + set subimage [subimage $grayFrame $x $y [- $x1 $x] [- $y1 $y]] + Wish 6 displays camera slice $subimage + set aprilTime [+ $aprilTime [baretime { + lappend tags {*}[AprilTags::detect $subimage] + }]] + } + + Wish 6 is labelled "[llength $prevTags] -> [llength $tags] ($aprilTime us)" + + # Commit { + # Claim the AprilTag time is $aprilTime + + # foreach tag $tags { + # Claim tag [dict get $tag id] has center [dict get $tag center] size [dict get $tag size] + # Claim tag [dict get $tag id] has corners [dict get $tag corners] + # } + # } + } +} -- cgit v1.2.3 From f5f8719a3d13e6dcd5efe6fac1c9d52f0d891135 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Mon, 14 Aug 2023 21:03:45 -0400 Subject: apriltags: WIP: First working incremental detector --- virtual-programs/apriltags.folk | 60 ++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 24 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/apriltags.folk b/virtual-programs/apriltags.folk index f8b94da2..d9557644 100644 --- a/virtual-programs/apriltags.folk +++ b/virtual-programs/apriltags.folk @@ -1,6 +1,7 @@ if {$::isLaptop} return -On process { +# Plain detector. Runs on entire camera frame. +set mainDetectorProcess [On process { source pi/AprilTags.tcl AprilTags::init @@ -21,20 +22,12 @@ On process { set aprilTime [time { set tags [AprilTags::detect $grayFrame] }] - Commit { - Claim $::thisProcess detects tags $tags at $timestamp in time $aprilTime - } + Claim $::thisProcess detects tags $tags at $timestamp in time $aprilTime } -} - -When /someone/ detects tags /tags/ at /timestamp/ in time /aprilTime/ { - Claim the AprilTag time is $aprilTime - foreach tag $tags { - Claim tag [dict get $tag id] has center [dict get $tag center] size [dict get $tag size] - Claim tag [dict get $tag id] has corners [dict get $tag corners] - } -} +}] +# Incremental detector. Looks at regions where there were tags in the +# old camera frame. On process { source pi/AprilTags.tcl AprilTags::init @@ -46,7 +39,7 @@ On process { Wish $::thisProcess receives statements like \ [list /someone/ claims the camera frame is /grayFrame/ at /timestamp/] Wish $::thisProcess receives statements like \ - [list /someone/ claims /process/ detects tags /tags/ at /timestamp/ in time /aprilTime/] + [list /someone/ claims $mainDetectorProcess detects tags /tags/ at /timestamp/ in time /aprilTime/] Wish $::thisProcess shares statements like \ [list /someone/ wishes /process/ receives statements like /pattern/] Wish $::thisProcess shares statements like \ @@ -95,21 +88,40 @@ On process { set y1 [min [+ $y1 $size] $frameHeight] set subimage [subimage $grayFrame $x $y [- $x1 $x] [- $y1 $y]] - Wish 6 displays camera slice $subimage set aprilTime [+ $aprilTime [baretime { - lappend tags {*}[AprilTags::detect $subimage] + foreach tag [AprilTags::detect $subimage] { + dict with tag { + set center [vec2 add $center [list $x $y]] + set corners [lmap corner $corners {vec2 add $corner [list $x $y]}] + } + lappend tags $tag + } }]] } - Wish 6 is labelled "[llength $prevTags] -> [llength $tags] ($aprilTime us)" + # Wish 6 is labelled "[llength $prevTags] -> [llength $tags] ($aprilTime us)" - # Commit { - # Claim the AprilTag time is $aprilTime + Claim $::thisProcess detects tags $tags at $timestamp in time $aprilTime + } +} + +When the collected matches for [list /someone/ detects tags /tags/ at /timestamp/ in time /aprilTime/] are /matches/ { + # Find all tag IDs, then find the latest for each ID. + # Sort by timestamp, earliest first. + proc mcomp {a b} {> [dict get $a timestamp] [dict get $b timestamp]} + set matches [lsort -command mcomp $matches] + + set tagsSeen [dict create] + foreach match $matches { + set tags [dict get $match tags] + foreach tag $tags { + dict set tagsSeen [dict get $tag id] $tag + } + } - # foreach tag $tags { - # Claim tag [dict get $tag id] has center [dict get $tag center] size [dict get $tag size] - # Claim tag [dict get $tag id] has corners [dict get $tag corners] - # } - # } + dict for {id tag} $tagsSeen { + Claim tag $id has center [dict get $tag center] size [dict get $tag size] + Claim tag $id has corners [dict get $tag corners] } + Claim the AprilTag time is [lmap m $matches {dict get $m aprilTime}] } -- cgit v1.2.3 From cf16ae229066352c3194e8b225bdf9b996a40738 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Mon, 14 Aug 2023 22:56:16 -0400 Subject: Try to fix collect incremental --- virtual-programs/tags-and-calibration.folk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'virtual-programs') diff --git a/virtual-programs/tags-and-calibration.folk b/virtual-programs/tags-and-calibration.folk index afb4aef4..b219b541 100644 --- a/virtual-programs/tags-and-calibration.folk +++ b/virtual-programs/tags-and-calibration.folk @@ -119,7 +119,8 @@ When (non-capturing) tag /tag/ has center /c/ size /size/ { } When (non-capturing) tag /tag/ is a tag { - puts "Added tag $tag" + puts "Added tag $tag" + On unmatch { puts "Removed tag $tag" } set tempPath "$::env(HOME)/folk-printed-programs/$tag.folk.temp" -- cgit v1.2.3 From 986aa91a7483efa686eae99d218edaf2afbded42 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Mon, 14 Aug 2023 23:49:28 -0400 Subject: Use old positions so tags move 'monotonically' --- virtual-programs/apriltags.folk | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/apriltags.folk b/virtual-programs/apriltags.folk index d9557644..1f38f29b 100644 --- a/virtual-programs/apriltags.folk +++ b/virtual-programs/apriltags.folk @@ -105,17 +105,29 @@ On process { } } -When the collected matches for [list /someone/ detects tags /tags/ at /timestamp/ in time /aprilTime/] are /matches/ { - # Find all tag IDs, then find the latest for each ID. - # Sort by timestamp, earliest first. - proc mcomp {a b} {> [dict get $a timestamp] [dict get $b timestamp]} - set matches [lsort -command mcomp $matches] +# This cache is used to remember the last seen position of each tag, +# so that if the incremental detector blinks out, we still use the +# tag's last-found position from it, instead of the older position +# from the full detector, so as you move a tag its position doesn't +# glitch backward. +set ::tagsCache [dict create] +# TODO: Garbage-collect this cache. +When the collected matches for [list /someone/ detects tags /tags/ at /timestamp/ in time /aprilTime/] are /matches/ { set tagsSeen [dict create] foreach match $matches { - set tags [dict get $match tags] - foreach tag $tags { - dict set tagsSeen [dict get $tag id] $tag + set timestamp [dict get $match timestamp] + foreach tag [dict get $match tags] { + set id [dict get $tag id] + dict set tag timestamp $timestamp + + if {[dict exists $::tagsCache $id] && + [dict get $::tagsCache $id timestamp] > $timestamp} { + set tag [dict get $::tagsCache $id] + } else { + dict set ::tagsCache $id $tag + } + dict set tagsSeen $id $tag } } -- cgit v1.2.3 From f42902b4cf694a4ec3f4f345699384ab53e32ece Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Tue, 15 Aug 2023 17:14:19 -0400 Subject: WIP: Rewrite peering to use shm instead of websockets Huge performance increases, but crashy. --- virtual-programs/apriltags.folk | 1 + virtual-programs/camera.folk | 3 ++- virtual-programs/display.folk | 6 ++++-- virtual-programs/time.folk | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/apriltags.folk b/virtual-programs/apriltags.folk index 1f38f29b..ac2c4f8b 100644 --- a/virtual-programs/apriltags.folk +++ b/virtual-programs/apriltags.folk @@ -102,6 +102,7 @@ On process { # Wish 6 is labelled "[llength $prevTags] -> [llength $tags] ($aprilTime us)" Claim $::thisProcess detects tags $tags at $timestamp in time $aprilTime + # Wish 6 is labelled "\n\nStep time $::stepTime\n[join [lmap s [dict values [Statements::all]] {statement short $s}] "\n"]" } } diff --git a/virtual-programs/camera.folk b/virtual-programs/camera.folk index 4f59a576..225a5880 100644 --- a/virtual-programs/camera.folk +++ b/virtual-programs/camera.folk @@ -20,7 +20,7 @@ On process { puts "Camera tid: [getTid] booting at [clock milliseconds]" - forever { + while true { set cameraTime [time { set grayFrame [Camera::grayFrame] }] @@ -28,6 +28,7 @@ On process { Claim the camera time is $cameraTime Claim the camera frame is $grayFrame at [clock milliseconds] } + Step } } diff --git a/virtual-programs/display.folk b/virtual-programs/display.folk index 5e16797f..b0b878ca 100644 --- a/virtual-programs/display.folk +++ b/virtual-programs/display.folk @@ -60,7 +60,7 @@ On process { [list /someone/ claims the display time is /displayTime/] set ::frames [list] - forever { + while true { set displayList [list] foreach match [Statements::findMatches {/someone/ wishes display runs /command/ on layer /layer/}] { lappend displayList [list [dict get $match layer] [dict get $match command]] @@ -93,7 +93,9 @@ On process { } } set frames [lreplace $frames 0 end-$framesInLastSecond] - Commit { Claim the display time is "render $renderTime us + commit $commitTime us ($framesInLastSecond fps)" } + + Commit { Claim the display time is "render $renderTime us + commit $commitTime us ($::stepTime) ($framesInLastSecond fps)" } + Step } } # TODO: remove this compatibility hack diff --git a/virtual-programs/time.folk b/virtual-programs/time.folk index 961b1863..1dff734d 100644 --- a/virtual-programs/time.folk +++ b/virtual-programs/time.folk @@ -1,3 +1,3 @@ When $::thisProcess has step count /t/ { - Claim the clock time is [/ [clock milliseconds] 1000.0] + Claim the clock time is [/ [clock milliseconds] 1000.0] } -- cgit v1.2.3 From 05a416ced03c9e77bf29d12f04f67d12338bfeb1 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Wed, 16 Aug 2023 13:55:23 -0400 Subject: Support wish to display images. Make Folk allocator actually multiprocess-safe, make drawImageTransparent support components=3, make saveAsJpeg support components=3, add loadJpeg. --- virtual-programs/images.folk | 102 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 89 insertions(+), 13 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/images.folk b/virtual-programs/images.folk index 6846975e..d98c58d0 100644 --- a/virtual-programs/images.folk +++ b/virtual-programs/images.folk @@ -32,6 +32,7 @@ namespace eval ::image { defineImageType $cc $cc include $cc include + $cc import ::Heap::cc folkHeapAlloc as folkHeapAlloc $cc code { #undef EXTERN @@ -40,18 +41,30 @@ namespace eval ::image { #include void - jpeg(FILE* dest, uint8_t* rgb, uint32_t width, uint32_t height, int quality) + jpeg(FILE* dest, uint8_t* data, uint32_t components, uint32_t width, uint32_t height, int quality) { - JSAMPARRAY image; - image = calloc(height, sizeof (JSAMPROW)); - for (size_t i = 0; i < height; i++) { - image[i] = calloc(width * 3, sizeof (JSAMPLE)); - for (size_t j = 0; j < width; j++) { - image[i][j * 3 + 0] = rgb[(i * width + j)]; - image[i][j * 3 + 1] = rgb[(i * width + j)]; - image[i][j * 3 + 2] = rgb[(i * width + j)]; + JSAMPARRAY image; + if (components == 1) { + image = calloc(height, sizeof (JSAMPROW)); + for (size_t i = 0; i < height; i++) { + image[i] = calloc(width * 3, sizeof (JSAMPLE)); + for (size_t j = 0; j < width; j++) { + image[i][j * 3 + 0] = data[(i * width + j)]; + image[i][j * 3 + 1] = data[(i * width + j)]; + image[i][j * 3 + 2] = data[(i * width + j)]; + } + } + } else if (components == 3) { + image = calloc(height, sizeof (JSAMPROW)); + for (size_t i = 0; i < height; i++) { + image[i] = calloc(width * 3, sizeof (JSAMPLE)); + for (size_t j = 0; j < width; j++) { + image[i][j * 3 + 0] = data[(i * width + j) * 3]; + image[i][j * 3 + 1] = data[(i * width + j) * 3 + 1]; + image[i][j * 3 + 2] = data[(i * width + j) * 3 + 2]; + } + } } - } struct jpeg_compress_struct compress; struct jpeg_error_mgr error; @@ -79,9 +92,48 @@ namespace eval ::image { } $cc proc saveAsJpeg {image_t im char* filename} void { FILE* out = fopen(filename, "w"); - jpeg(out, im.data, im.width, im.height, 100); + jpeg(out, im.data, im.components, im.width, im.height, 100); fclose(out); } + $cc proc loadJpeg {char* filename} image_t { + FILE* file = fopen(filename, "rb"); + if (!file) { + fprintf(stderr, "Error opening file: %s\n", filename); + exit(1); + } + + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo, file); + jpeg_read_header(&cinfo, TRUE); + jpeg_start_decompress(&cinfo); + + image_t ret; + ret.width = cinfo.output_width; + ret.height = cinfo.output_height; + ret.components = cinfo.output_components; + ret.bytesPerRow = ret.width * ret.components; + ret.data = folkHeapAlloc(ret.bytesPerRow * ret.height); + + JSAMPROW row_pointer[1]; + while (cinfo.output_scanline < cinfo.output_height) { + row_pointer[0] = (JSAMPLE*)ret.data + cinfo.output_scanline * ret.bytesPerRow; + jpeg_read_scanlines(&cinfo, row_pointer, 1); + } + + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(file); + + return ret; + } + $cc proc freeJpeg {image_t im} void { + // TODO: Free the JPEG. + // ckfree(im.data); + } $cc compile namespace export * @@ -116,9 +168,33 @@ When when /p/ has camera slice /slice/ /lambda/ with environment /e/ { # Display a camera slice When /someone/ wishes /p/ displays camera slice /slice/ & /p/ has region /r/ { - set origin [lindex $r 0 0] + set center [region centroid $r] # set scale [expr {$Display::WIDTH / $Camera::WIDTH}] # Use 1x scale instead of $scale so the projected tag doesn't redetect. # TODO: Mask the tag out? - Wish display runs [list Display::image {*}$origin $slice 1] + Wish display runs [list Display::image {*}$center $slice 0 1] +} + +When /someone/ wishes /p/ displays image /im/ { + # TODO: Download im if it starts with https?:// + # Load im if it ends in .jpg or .png or .jpeg + if {[string match "*.jpg" $im] || + [string match "*.jpeg" $im] || + [string match "*.png" $im]} { + # TODO: Support .png + set path [expr {[file pathtype $im] eq "relative" ? + "$::env(HOME)/folk-images/$im" : + $im}] + set im [image loadJpeg $path] + } + When $p has region /r/ { + # Compute a scale for im that will fit in the region width/height + # Draw im with scale and rotation + set center [region centroid $r] + Wish display runs [list Display::image {*}$center $im 0 1] + } + On unmatch { + # HACK: Leaves time for the display to finish trying to display this. + after 5000 [list image freeJpeg $im] + } } -- cgit v1.2.3 From 0a02f43f28cbedd7143e0855935e41f163fe9105 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Wed, 16 Aug 2023 14:26:15 -0400 Subject: Image display rotation. WIP: Breaks camera slice --- virtual-programs/images.folk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'virtual-programs') diff --git a/virtual-programs/images.folk b/virtual-programs/images.folk index d98c58d0..09359ac6 100644 --- a/virtual-programs/images.folk +++ b/virtual-programs/images.folk @@ -191,7 +191,7 @@ When /someone/ wishes /p/ displays image /im/ { # Compute a scale for im that will fit in the region width/height # Draw im with scale and rotation set center [region centroid $r] - Wish display runs [list Display::image {*}$center $im 0 1] + Wish display runs [list Display::image {*}$center $im [region angle $r] 1] } On unmatch { # HACK: Leaves time for the display to finish trying to display this. -- cgit v1.2.3 From b774f27f5d3b6b4b1376f586e92ee04f93b65cd4 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Wed, 16 Aug 2023 16:32:12 -0400 Subject: Fix rotation of camera slices (don't use stride) --- virtual-programs/images.folk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'virtual-programs') diff --git a/virtual-programs/images.folk b/virtual-programs/images.folk index 09359ac6..3d5147d1 100644 --- a/virtual-programs/images.folk +++ b/virtual-programs/images.folk @@ -172,7 +172,7 @@ When /someone/ wishes /p/ displays camera slice /slice/ & /p/ has region /r/ { # set scale [expr {$Display::WIDTH / $Camera::WIDTH}] # Use 1x scale instead of $scale so the projected tag doesn't redetect. # TODO: Mask the tag out? - Wish display runs [list Display::image {*}$center $slice 0 1] + Wish display runs [list Display::image {*}$center $slice 0 1] } When /someone/ wishes /p/ displays image /im/ { -- cgit v1.2.3 From 5c1e806009788e2fa168a63598fed549fc9550ce Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Wed, 16 Aug 2023 17:43:50 -0400 Subject: Support getting images from internet, caching them --- virtual-programs/images.folk | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/images.folk b/virtual-programs/images.folk index 3d5147d1..72f62143 100644 --- a/virtual-programs/images.folk +++ b/virtual-programs/images.folk @@ -175,26 +175,40 @@ When /someone/ wishes /p/ displays camera slice /slice/ & /p/ has region /r/ { Wish display runs [list Display::image {*}$center $slice 0 1] } +set ::imagesCache [dict create] When /someone/ wishes /p/ displays image /im/ { - # TODO: Download im if it starts with https?:// - # Load im if it ends in .jpg or .png or .jpeg - if {[string match "*.jpg" $im] || - [string match "*.jpeg" $im] || - [string match "*.png" $im]} { - # TODO: Support .png - set path [expr {[file pathtype $im] eq "relative" ? - "$::env(HOME)/folk-images/$im" : - $im}] - set im [image loadJpeg $path] + if {[dict exists $::imagesCache $im]} { + set im [dict get $::imagesCache $im] + } else { + set impath $im + if {[string match "http*://*" $impath]} { + set im /tmp/[regsub -all {\W+} $impath "_"] + exec -ignorestderr curl -o$im $impath + } + if {[string match "*jpg" $im] || + [string match "*jpeg" $im] || + [string match "*png" $im]} { + # TODO: Support .png + set path [expr {[file pathtype $im] eq "relative" ? + "$::env(HOME)/folk-images/$im" : + $im}] + set im [image loadJpeg $path] + dict set ::imagesCache $impath $im + } } When $p has region /r/ { # Compute a scale for im that will fit in the region width/height # Draw im with scale and rotation set center [region centroid $r] + # set width [region width $r] + # set height [region height $r] + # set scale [expr {min($width / [image width $im], + # $height / [image height $im])}] + # Wish $p is labelled $im Wish display runs [list Display::image {*}$center $im [region angle $r] 1] } - On unmatch { - # HACK: Leaves time for the display to finish trying to display this. - after 5000 [list image freeJpeg $im] - } + # On unmatch { + # # HACK: Leaves time for the display to finish trying to display this. + # after 5000 [list image freeJpeg $im] + # } } -- cgit v1.2.3 From 4a8ac7cad8176d3b508c9384408898b351c60f03 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Thu, 17 Aug 2023 11:52:46 -0400 Subject: Skip already-existing files --- virtual-programs/print.folk | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'virtual-programs') diff --git a/virtual-programs/print.folk b/virtual-programs/print.folk index badd191f..44a7d433 100644 --- a/virtual-programs/print.folk +++ b/virtual-programs/print.folk @@ -163,6 +163,10 @@ proc nextId {} { set id 0 } + while {[file exists "$::env(HOME)/folk-printed-programs/$id.folk"]} { + incr id + } + set fp [open "$::env(HOME)/folk-printed-programs/next-id.txt" w] puts $fp [expr {$id + 1}] close $fp -- cgit v1.2.3 From 4fd01f6e8eacc3b63651efe3cd8e251d275f2fc9 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Thu, 17 Aug 2023 12:38:07 -0400 Subject: Factor out image load --- virtual-programs/images.folk | 48 ++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 20 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/images.folk b/virtual-programs/images.folk index 72f62143..c8e53951 100644 --- a/virtual-programs/images.folk +++ b/virtual-programs/images.folk @@ -136,6 +136,33 @@ namespace eval ::image { } $cc compile + variable imagesCache [dict create] + # Loads a URL or file path if passed. If passed a valid image_t, + # just returns that image_t. + proc load {im} { + variable imagesCache + if {[dict exists $imagesCache $im]} { + set im [dict get $imagesCache $im] + } else { + set impath $im + if {[string match "http*://*" $impath]} { + set im /tmp/[regsub -all {\W+} $impath "_"] + exec -ignorestderr curl -o$im $impath + } + if {[string match "*jpg" $im] || + [string match "*jpeg" $im] || + [string match "*png" $im]} { + # TODO: Support .png + set path [expr {[file pathtype $im] eq "relative" ? + "$::env(HOME)/folk-images/$im" : + $im}] + set im [image loadJpeg $path] + dict set imagesCache $impath $im + } + } + set im + } + namespace export * namespace ensemble create } @@ -175,27 +202,8 @@ When /someone/ wishes /p/ displays camera slice /slice/ & /p/ has region /r/ { Wish display runs [list Display::image {*}$center $slice 0 1] } -set ::imagesCache [dict create] When /someone/ wishes /p/ displays image /im/ { - if {[dict exists $::imagesCache $im]} { - set im [dict get $::imagesCache $im] - } else { - set impath $im - if {[string match "http*://*" $impath]} { - set im /tmp/[regsub -all {\W+} $impath "_"] - exec -ignorestderr curl -o$im $impath - } - if {[string match "*jpg" $im] || - [string match "*jpeg" $im] || - [string match "*png" $im]} { - # TODO: Support .png - set path [expr {[file pathtype $im] eq "relative" ? - "$::env(HOME)/folk-images/$im" : - $im}] - set im [image loadJpeg $path] - dict set ::imagesCache $impath $im - } - } + set im [image load $im] When $p has region /r/ { # Compute a scale for im that will fit in the region width/height # Draw im with scale and rotation -- cgit v1.2.3 From 42b780fd3aeb8ad6541de05eacb4e7202ccfca5e Mon Sep 17 00:00:00 2001 From: Zach Potter Date: Sun, 20 Aug 2023 23:26:55 -0700 Subject: Rework keyboard and implement global terminal --- virtual-programs/terminal.folk | 170 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 virtual-programs/terminal.folk (limited to 'virtual-programs') diff --git a/virtual-programs/terminal.folk b/virtual-programs/terminal.folk new file mode 100644 index 00000000..df333d28 --- /dev/null +++ b/virtual-programs/terminal.folk @@ -0,0 +1,170 @@ +# Terminal +# +# Claim $this is a terminal +# + +set cc [c create] +$cc cflags -I./vendor/libtmt ./vendor/libtmt/tmt.c + +# TODO: find the right libutil.so for the system +c loadlib /lib/aarch64-linux-gnu/libutil.so +$cc cflags -lutil + +$cc include +$cc include +$cc include +$cc include +$cc include +$cc include +$cc include +$cc include ;# For gettimeofday() + +$cc code { + #include "tmt.h" + + #define SHELL "/bin/bash" + + #define ROWS 12 + #define COLS 43 + char screen[ROWS][COLS + 1]; + int curs_r = 0; + int curs_c = 0; + + + #define PTYBUF 4096 + char iobuf[PTYBUF]; + + TMT *vt; + int pty_fd; + + void callback(tmt_msg_t m, TMT *vt, const void *a, void *p) { + const TMTSCREEN *s = tmt_screen(vt); + + if (m == TMT_MSG_UPDATE) { + for (size_t r = 0; r < s->nline; r++){ + if (s->lines[r]->dirty){ + for (size_t c = 0; c < s->ncol; c++){ + screen[r][c] = s->lines[r]->chars[c].c; + } + } + } + tmt_clean(vt); + } + } + + void initScreen() { + for (int r = 0; r < ROWS - 1; r++) { + screen[r][COLS] = '\n'; + } + screen[ROWS - 1][COLS] = '\0'; + } + + void updateCursor() { + // Restore char under old cursor + const TMTSCREEN *s = tmt_screen(vt); + screen[curs_r][curs_c] = s->lines[curs_r]->chars[curs_c].c; + + // Update new cursor + const TMTPOINT *c = tmt_cursor(vt); + curs_r = c->r; + curs_c = c->c; + + // Replace char with cursor every other second + struct timeval tv; + gettimeofday(&tv, NULL); + if (tv.tv_sec % 2 == 0) { + screen[curs_r][curs_c] = 0xDB; // block char: █ + } + } +} + +$cc proc termInit {} bool { + if (vt != NULL) { + return false; + } + + initScreen(); + vt = tmt_open(ROWS, COLS, callback, NULL, NULL); + + struct winsize ws = {.ws_row = ROWS, .ws_col = COLS}; + pid_t pid = forkpty(&pty_fd, NULL, NULL, &ws); + if (pid < 0){ + return false; + } else if (pid == 0){ + setenv("TERM", "ansi", 1); + execl(SHELL, SHELL, NULL); + return true; + } + + fcntl(pty_fd, F_SETFL, O_NONBLOCK); + return true; +} + +$cc proc termRead {} char* { + ssize_t r = read(pty_fd, iobuf, PTYBUF); + if (r > 0) { + tmt_write(vt, iobuf, r); + } + + updateCursor(); + return (char*)screen; +} + +$cc proc termWrite {char* key} void { + write(pty_fd, key, strlen(key)); +} + +$cc compile + +# Folk stuff... + +# From `man console_codes` +set keymap [dict create \ + ENTER "\x0d" \ + TAB "\x09" \ + BACKSPACE "\x08" \ + DELETE "\x7f" \ + ESC "\x1b" \ + UP "\x1b\[A" \ + DOWN "\x1b\[B" \ + RIGHT "\x1b\[C" \ + LEFT "\x1b\[D" \ +] + +proc remap {key modifiers} { + upvar keymap keymap + if {[string length $key] == 1} { + # Convert ctrl-A through ctrl-Z and others to terminal control characters + if {"ctrl" in $modifiers} { + set charCode [scan [string toupper $key] %c] + if {$charCode >= 64 && $charCode <= 95} { + set charCode [expr {$charCode - 64}] + return [format %c $charCode] + } + } + # All other single char keys can be passed through + return $key + } + if {[dict exists $keymap $key]} { + return [dict get $keymap $key] + } + return "" +} + +When /anyone/ claims /thing/ is a terminal { + termInit + + When /anyone/ claims key /key/ is /direction/ with modifiers /modifiers/ { + if {$direction != "up"} { + set key [remap $key $modifiers] + if {[string length $key] > 0} { + termWrite $key + } + } + } + + When $thing has region /r/ & /node/ has step count /c/ { + set display [region move $r up 180px] + Wish region $display is labelled [termRead] + } +} -- cgit v1.2.3 From 18a9be88eea6ee48232ab89f1ef7b12c5e0f817b Mon Sep 17 00:00:00 2001 From: Zach Potter Date: Mon, 21 Aug 2023 21:10:40 -0700 Subject: Move virtual terminal to lib/terminal.tcl --- virtual-programs/terminal.folk | 162 +++-------------------------------------- 1 file changed, 9 insertions(+), 153 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/terminal.folk b/virtual-programs/terminal.folk index df333d28..0d4d9a7f 100644 --- a/virtual-programs/terminal.folk +++ b/virtual-programs/terminal.folk @@ -3,168 +3,24 @@ # Claim $this is a terminal # -set cc [c create] -$cc cflags -I./vendor/libtmt ./vendor/libtmt/tmt.c - -# TODO: find the right libutil.so for the system -c loadlib /lib/aarch64-linux-gnu/libutil.so -$cc cflags -lutil - -$cc include -$cc include -$cc include -$cc include -$cc include -$cc include -$cc include -$cc include ;# For gettimeofday() - -$cc code { - #include "tmt.h" - - #define SHELL "/bin/bash" - - #define ROWS 12 - #define COLS 43 - char screen[ROWS][COLS + 1]; - int curs_r = 0; - int curs_c = 0; - - - #define PTYBUF 4096 - char iobuf[PTYBUF]; - - TMT *vt; - int pty_fd; - - void callback(tmt_msg_t m, TMT *vt, const void *a, void *p) { - const TMTSCREEN *s = tmt_screen(vt); - - if (m == TMT_MSG_UPDATE) { - for (size_t r = 0; r < s->nline; r++){ - if (s->lines[r]->dirty){ - for (size_t c = 0; c < s->ncol; c++){ - screen[r][c] = s->lines[r]->chars[c].c; - } - } - } - tmt_clean(vt); - } - } - - void initScreen() { - for (int r = 0; r < ROWS - 1; r++) { - screen[r][COLS] = '\n'; - } - screen[ROWS - 1][COLS] = '\0'; - } - - void updateCursor() { - // Restore char under old cursor - const TMTSCREEN *s = tmt_screen(vt); - screen[curs_r][curs_c] = s->lines[curs_r]->chars[curs_c].c; - - // Update new cursor - const TMTPOINT *c = tmt_cursor(vt); - curs_r = c->r; - curs_c = c->c; - - // Replace char with cursor every other second - struct timeval tv; - gettimeofday(&tv, NULL); - if (tv.tv_sec % 2 == 0) { - screen[curs_r][curs_c] = 0xDB; // block char: █ - } - } -} - -$cc proc termInit {} bool { - if (vt != NULL) { - return false; - } - - initScreen(); - vt = tmt_open(ROWS, COLS, callback, NULL, NULL); - - struct winsize ws = {.ws_row = ROWS, .ws_col = COLS}; - pid_t pid = forkpty(&pty_fd, NULL, NULL, &ws); - if (pid < 0){ - return false; - } else if (pid == 0){ - setenv("TERM", "ansi", 1); - execl(SHELL, SHELL, NULL); - return true; - } - - fcntl(pty_fd, F_SETFL, O_NONBLOCK); - return true; -} - -$cc proc termRead {} char* { - ssize_t r = read(pty_fd, iobuf, PTYBUF); - if (r > 0) { - tmt_write(vt, iobuf, r); - } - - updateCursor(); - return (char*)screen; -} - -$cc proc termWrite {char* key} void { - write(pty_fd, key, strlen(key)); -} - -$cc compile - -# Folk stuff... - -# From `man console_codes` -set keymap [dict create \ - ENTER "\x0d" \ - TAB "\x09" \ - BACKSPACE "\x08" \ - DELETE "\x7f" \ - ESC "\x1b" \ - UP "\x1b\[A" \ - DOWN "\x1b\[B" \ - RIGHT "\x1b\[C" \ - LEFT "\x1b\[D" \ -] - -proc remap {key modifiers} { - upvar keymap keymap - if {[string length $key] == 1} { - # Convert ctrl-A through ctrl-Z and others to terminal control characters - if {"ctrl" in $modifiers} { - set charCode [scan [string toupper $key] %c] - if {$charCode >= 64 && $charCode <= 95} { - set charCode [expr {$charCode - 64}] - return [format %c $charCode] - } - } - # All other single char keys can be passed through - return $key - } - if {[dict exists $keymap $key]} { - return [dict get $keymap $key] - } - return "" -} +source lib/terminal.tcl When /anyone/ claims /thing/ is a terminal { - termInit + Terminal::create + + # When /nobody/ claims $thing has term /x/ { + # Assert $thing has term $term + # } When /anyone/ claims key /key/ is /direction/ with modifiers /modifiers/ { if {$direction != "up"} { - set key [remap $key $modifiers] - if {[string length $key] > 0} { - termWrite $key - } + set ctrlPressed [expr {"ctrl" in $modifiers}] + Terminal::write $key $ctrlPressed } } When $thing has region /r/ & /node/ has step count /c/ { set display [region move $r up 180px] - Wish region $display is labelled [termRead] + Wish region $display is labelled [Terminal::read] } } -- cgit v1.2.3 From 00fe52037991e4a3747791518bc4968247a2c079 Mon Sep 17 00:00:00 2001 From: Zach Potter Date: Mon, 21 Aug 2023 22:05:23 -0700 Subject: multiple terminal instances --- virtual-programs/terminal.folk | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/terminal.folk b/virtual-programs/terminal.folk index 0d4d9a7f..ae13a080 100644 --- a/virtual-programs/terminal.folk +++ b/virtual-programs/terminal.folk @@ -6,21 +6,23 @@ source lib/terminal.tcl When /anyone/ claims /thing/ is a terminal { - Terminal::create - - # When /nobody/ claims $thing has term /x/ { - # Assert $thing has term $term - # } + # First time init, so that we don't get a new instance each time the $thing is detected + When /nobody/ claims $thing has term /t/ { + Assert terminal claims $thing has term [Terminal::create] + } - When /anyone/ claims key /key/ is /direction/ with modifiers /modifiers/ { - if {$direction != "up"} { - set ctrlPressed [expr {"ctrl" in $modifiers}] - Terminal::write $key $ctrlPressed + When terminal claims $thing has term /term/ { + # TODO: all terminals share the same keyboard! + When /anyone/ claims key /key/ is /direction/ with modifiers /modifiers/ { + if {$direction != "up"} { + set ctrlPressed [expr {"ctrl" in $modifiers}] + Terminal::write $term $key $ctrlPressed + } } - } - When $thing has region /r/ & /node/ has step count /c/ { - set display [region move $r up 180px] - Wish region $display is labelled [Terminal::read] + When $thing has region /r/ & /node/ has step count /c/ { + set display [region move $r up 180px] + Wish region $display is labelled [Terminal::read $term] + } } } -- cgit v1.2.3 From b29dbf7b3a288890ceb114d48d4ed77cdc070929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Cuervo?= Date: Thu, 24 Aug 2023 13:15:54 -0400 Subject: Left whisker color, red -> gold --- virtual-programs/points-at.folk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'virtual-programs') diff --git a/virtual-programs/points-at.folk b/virtual-programs/points-at.folk index 1472b379..a037f98f 100644 --- a/virtual-programs/points-at.folk +++ b/virtual-programs/points-at.folk @@ -19,7 +19,7 @@ When /someone/ wishes /rect/ points /direction/ with length /l/ & /rect/ has reg set whiskerRegion [region scale $region height 0.01px width $scale] set whiskerRegion [region move $whiskerRegion left \ [vec2 distance [region right $whiskerRegion] [region left $region]]px] - set color red + set color gold } elseif {$direction eq "right"} { set whiskerRegion [region scale $region height 0.01px width $scale] set whiskerRegion [region move $whiskerRegion right \ -- cgit v1.2.3 From 7590f4424917e34c01caac722bd97ac28587bcbc Mon Sep 17 00:00:00 2001 From: Zach Potter Date: Thu, 24 Aug 2023 22:33:57 -0700 Subject: cleanup and todos --- virtual-programs/terminal.folk | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/terminal.folk b/virtual-programs/terminal.folk index ae13a080..4cbf6339 100644 --- a/virtual-programs/terminal.folk +++ b/virtual-programs/terminal.folk @@ -1,28 +1,29 @@ # Terminal # -# Claim $this is a terminal +# Wish $this is a terminal +# Claim $this has keyboard input # source lib/terminal.tcl -When /anyone/ claims /thing/ is a terminal { - # First time init, so that we don't get a new instance each time the $thing is detected - When /nobody/ claims $thing has term /t/ { - Assert terminal claims $thing has term [Terminal::create] +When /anyone/ wishes /thing/ is a terminal { + # Create a new terminal instance for this $thing only once + When /nobody/ claims $thing has terminal instance /term/ { + Assert terminal claims $thing has terminal instance [Terminal::create] } - When terminal claims $thing has term /term/ { - # TODO: all terminals share the same keyboard! - When /anyone/ claims key /key/ is /direction/ with modifiers /modifiers/ { + When terminal claims $thing has terminal instance /term/ { + When $thing has region /r/ & /node/ has step count /c/ { + set display [region move $r up 180px] + Wish region $display is labelled [Terminal::read $term] + } + + When /anyone/ claims $thing has keyboard input & \ + /anyone/ claims key /key/ is /direction/ with modifiers /modifiers/ { if {$direction != "up"} { set ctrlPressed [expr {"ctrl" in $modifiers}] Terminal::write $term $key $ctrlPressed } } - - When $thing has region /r/ & /node/ has step count /c/ { - set display [region move $r up 180px] - Wish region $display is labelled [Terminal::read $term] - } } } -- cgit v1.2.3 From e4af18885d38613c55b6b5928af851732e931fa7 Mon Sep 17 00:00:00 2001 From: Jacob Haip Date: Sat, 26 Aug 2023 00:06:19 -0400 Subject: add warp image function --- virtual-programs/images.folk | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'virtual-programs') diff --git a/virtual-programs/images.folk b/virtual-programs/images.folk index c8e53951..ee3988ea 100644 --- a/virtual-programs/images.folk +++ b/virtual-programs/images.folk @@ -95,6 +95,32 @@ namespace eval ::image { jpeg(out, im.data, im.components, im.width, im.height, 100); fclose(out); } + # Given the four corners of a region in an image, warp it to a new image of a given width and height + $cc proc warp {image_t im uint32_t tl_x uint32_t tl_y uint32_t tr_x uint32_t tr_y uint32_t br_x uint32_t br_y uint32_t bl_x uint32_t bl_y uint32_t output_width uint32_t output_height} image_t { + image_t ret; + ret.width = output_width; + ret.height = output_height; + ret.components = im.components; + ret.bytesPerRow = ret.width * ret.components; + ret.data = folkHeapAlloc(ret.bytesPerRow * ret.height); + + for (int y = 0; y < output_height; y++) { + for (int x = 0; x < output_width; x++) { + // calculate the position in the input image + float u = (float)x / (float)(output_width - 1); + float v = (float)y / (float)(output_height - 1); + int input_x = tl_x + u * (int)(tr_x - tl_x) + v * (int)(bl_x - tl_x); + int input_y = tl_y + u * (int)(tr_y - tl_y) + v * (int)(bl_y - tl_y); + + if (input_x >= 0 && input_x < im.width && input_y >= 0 && input_y < im.height) { + memcpy(&ret.data[y * ret.bytesPerRow + x * ret.components], + &im.data[input_y * im.bytesPerRow + input_x * im.components], + im.components); + } + } + } + return ret; + } $cc proc loadJpeg {char* filename} image_t { FILE* file = fopen(filename, "rb"); if (!file) { -- cgit v1.2.3 From 43382a5be93b606346d5a55ab604a5d4edd08992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Cuervo?= Date: Wed, 30 Aug 2023 21:31:06 -0400 Subject: Fix esc-restart program --- virtual-programs/esc-restart.folk | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/esc-restart.folk b/virtual-programs/esc-restart.folk index 01a6dd94..02d66f63 100644 --- a/virtual-programs/esc-restart.folk +++ b/virtual-programs/esc-restart.folk @@ -1,5 +1,3 @@ -When the keyboard character log is /k/ { - foreach press $k { - if {$press eq "esc"} {exec sudo systemctl restart folk} - } +When keyboard claims key /key/ is /t/ with modifiers /m/ { + if {[string tolower $key] == "esc"} {exec sudo systemctl restart folk} } \ No newline at end of file -- cgit v1.2.3 From d540c5f990b75ed80acfd0c323da052672b8bb4c Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Sun, 3 Sep 2023 17:28:07 -0400 Subject: Use ::Display instead of Display for safety --- virtual-programs/display.folk | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/display.folk b/virtual-programs/display.folk index b0b878ca..c73b354c 100644 --- a/virtual-programs/display.folk +++ b/virtual-programs/display.folk @@ -1,39 +1,39 @@ if {$::isLaptop} return -namespace eval Display { +namespace eval ::Display { variable WIDTH variable HEIGHT variable LAYER 0 regexp {mode "(\d+)x(\d+)"} [exec fbset] -> WIDTH HEIGHT proc drawOnTop {func args} { - set Display::LAYER 1 + set ::Display::LAYER 1 uplevel [list $func {*}$args] - set Display::LAYER 0 + set ::Display::LAYER 0 } proc stroke {points width color} { - uplevel [list Wish display runs [list Display::stroke $points $width $color] on layer $Display::LAYER] + uplevel [list Wish display runs [list Display::stroke $points $width $color] on layer $::Display::LAYER] } proc circle {x y radius thickness color} { - uplevel [list Wish display runs [list Display::circle $x $y $radius $thickness $color] on layer $Display::LAYER] + uplevel [list Wish display runs [list Display::circle $x $y $radius $thickness $color] on layer $::Display::LAYER] } proc text args { - uplevel [list Wish display runs [list Display::text {*}$args] on layer $Display::LAYER] + uplevel [list Wish display runs [list Display::text {*}$args] on layer $::Display::LAYER] } proc fillTriangle args { - uplevel [list Wish display runs [list Display::fillTriangle {*}$args] on layer $Display::LAYER] + uplevel [list Wish display runs [list Display::fillTriangle {*}$args] on layer $::Display::LAYER] } proc fillQuad args { - uplevel [list Wish display runs [list Display::fillQuad {*}$args] on layer $Display::LAYER] + uplevel [list Wish display runs [list Display::fillQuad {*}$args] on layer $::Display::LAYER] } proc fillPolygon args { - uplevel [list Wish display runs [list Display::fillPolygon {*}$args] on layer $Display::LAYER] + uplevel [list Wish display runs [list Display::fillPolygon {*}$args] on layer $::Display::LAYER] } variable displayTime none -- cgit v1.2.3 From b8b397be679c4c8329aa4a5465ad3c0e70743bb2 Mon Sep 17 00:00:00 2001 From: Zach Potter Date: Mon, 4 Sep 2023 13:51:31 -0700 Subject: Proper escaping of keyboard keys; change esc-restart modifiers 1. Escape words in `subst` by wrapping them in a list! I took this tip from the "Generating Scripts and Lists" section of https://wiki.tcl-lang.org/page/subst 2. Change the esc-restart key from plain ESC to alt-ESC, so you can use the escape key in vim terminals. --- virtual-programs/esc-restart.folk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/esc-restart.folk b/virtual-programs/esc-restart.folk index 02d66f63..ee8aa847 100644 --- a/virtual-programs/esc-restart.folk +++ b/virtual-programs/esc-restart.folk @@ -1,3 +1,3 @@ -When keyboard claims key /key/ is /t/ with modifiers /m/ { - if {[string tolower $key] == "esc"} {exec sudo systemctl restart folk} -} \ No newline at end of file +When keyboard claims key ESC is down with modifiers alt { + exec sudo systemctl restart folk +} -- cgit v1.2.3 From 2d3b518e8db13b6cc534836d8a4125e9d49b7a25 Mon Sep 17 00:00:00 2001 From: Zach Potter Date: Sat, 2 Sep 2023 22:00:30 -0700 Subject: A more reactive terminal The terminal can now - spawn with specific commands - kill their children and clean up resources - have dynamic rows/cols - draw text on any region And I added some docs, with a simple editor program! --- virtual-programs/terminal.folk | 89 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 16 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/terminal.folk b/virtual-programs/terminal.folk index 4cbf6339..16741e9c 100644 --- a/virtual-programs/terminal.folk +++ b/virtual-programs/terminal.folk @@ -1,29 +1,86 @@ # Terminal # -# Wish $this is a terminal -# Claim $this has keyboard input +# Spawn terminals with any command (default "bash"): +# Wish $this is a terminal +# Wish $this is a terminal spawning "any command" +# +# Send keyboard events to the terminal: +# Claim $thing has keyboard input +# +# Optionally, draw the terminal on an arbitrary region: +# Claim $thing has terminal region $region +# +# +# Example program: Tie it all together with a simple vim editor... +# +# When $this points up at /target/ & /target/ has program /anything/ { +# Wish $this is a terminal spawning "vim ~/folk-printed-programs/$target.folk" +# When $this has region /r/ { +# Claim $this has terminal region [region move $r right 350px] +# } +# Claim $this has keyboard input +# } +# +# +# Note: Terminals are killed after ::termExpireMs of being unmatched. # source lib/terminal.tcl -When /anyone/ wishes /thing/ is a terminal { - # Create a new terminal instance for this $thing only once - When /nobody/ claims $thing has terminal instance /term/ { - Assert terminal claims $thing has terminal instance [Terminal::create] +set ::termExpireMs [expr {10*60*1000}] ;# 10 minutes +set ::termInstances [dict create] +set ::termTimeouts [dict create] + +proc ::matchTerminal {id cmd} { + set termKey "$id $cmd" + if {$termKey ni $::termInstances} { + dict set ::termInstances $termKey [Terminal::create 12 43 $cmd] } + if {$termKey in $::termTimeouts} { + after cancel [dict get $::termTimeouts $termKey] + dict unset ::termTimeouts $termKey + } + dict get $::termInstances $termKey +} - When terminal claims $thing has terminal instance /term/ { - When $thing has region /r/ & /node/ has step count /c/ { - set display [region move $r up 180px] - Wish region $display is labelled [Terminal::read $term] +proc ::unmatchTerminal {id cmd} { + set termKey "$id $cmd" + dict set ::termTimeouts $termKey [ + after $::termExpireMs "::destroyTerminal [list $termKey]" + ] +} + +proc ::destroyTerminal {termKey} { + Terminal::destroy [dict get $::termInstances $termKey] + dict unset ::termInstances $termKey + dict unset ::termTimeouts $termKey +} + +When /anyone/ wishes /thing/ is a terminal { + Wish $thing is a terminal spawning bash +} + +When /thing/ has terminal region /r/ & /r/ has keyboard input { + Claim $thing has keyboard input +} + +When /anyone/ wishes /thing/ is a terminal spawning /cmd/ { + set term [::matchTerminal $thing $cmd] + On unmatch { ::unmatchTerminal $thing $cmd } + + When $::thisProcess has step count /c/ { + set lambda { + Wish region $region is labelled [Terminal::read $term] } + When $thing has terminal region /region/ $lambda + When /nobody/ claims $thing has terminal region /x/ & $thing has region /region/ $lambda + } - When /anyone/ claims $thing has keyboard input & \ - /anyone/ claims key /key/ is /direction/ with modifiers /modifiers/ { - if {$direction != "up"} { - set ctrlPressed [expr {"ctrl" in $modifiers}] - Terminal::write $term $key $ctrlPressed - } + When /anyone/ claims $thing has keyboard input \ + & /anyone/ claims key /key/ is /direction/ with modifiers /modifiers/ { + if {$direction != "up"} { + set ctrlPressed [expr {"ctrl" in $modifiers}] + Terminal::write $term $key $ctrlPressed } } } -- cgit v1.2.3 From 2afdf58664d2aa2fd583115aa3d5ebb046ca6c0d Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Wed, 6 Sep 2023 00:45:43 -0400 Subject: terminal: lambda -> body --- virtual-programs/terminal.folk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/terminal.folk b/virtual-programs/terminal.folk index 16741e9c..3fb335b5 100644 --- a/virtual-programs/terminal.folk +++ b/virtual-programs/terminal.folk @@ -69,11 +69,11 @@ When /anyone/ wishes /thing/ is a terminal spawning /cmd/ { On unmatch { ::unmatchTerminal $thing $cmd } When $::thisProcess has step count /c/ { - set lambda { + set body { Wish region $region is labelled [Terminal::read $term] } - When $thing has terminal region /region/ $lambda - When /nobody/ claims $thing has terminal region /x/ & $thing has region /region/ $lambda + When $thing has terminal region /region/ $body + When /nobody/ claims $thing has terminal region /x/ & $thing has region /region/ $body } When /anyone/ claims $thing has keyboard input \ -- cgit v1.2.3 From 6b426aa5853d8aa4d389a36f076a8cf416a3c91c Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Wed, 6 Sep 2023 02:11:46 -0400 Subject: Some peering cleanup (receive before Step); build in FPS counting --- virtual-programs/camera.folk | 9 +++------ virtual-programs/display.folk | 13 +------------ 2 files changed, 4 insertions(+), 18 deletions(-) (limited to 'virtual-programs') diff --git a/virtual-programs/camera.folk b/virtual-programs/camera.folk index 225a5880..0a95c8f0 100644 --- a/virtual-programs/camera.folk +++ b/virtual-programs/camera.folk @@ -20,15 +20,12 @@ On process { puts "Camera tid: [getTid] booting at [clock milliseconds]" - while true { - set cameraTime [time { - set grayFrame [Camera::grayFrame] - }] + When $::thisProcess has step count /c/ { + set grayFrame [Camera::grayFrame] Commit { - Claim the camera time is $cameraTime + Claim the camera time is $::stepTime Claim the camera frame is $grayFrame at [clock milliseconds] } - Step } } diff --git a/virtual-programs/display.folk b/virtual-programs/display.folk index c73b354c..d3f6b610 100644 --- a/virtual-programs/display.folk +++ b/virtual-programs/display.folk @@ -59,7 +59,6 @@ On process { Wish $::thisProcess shares statements like \ [list /someone/ claims the display time is /displayTime/] - set ::frames [list] while true { set displayList [list] foreach match [Statements::findMatches {/someone/ wishes display runs /command/ on layer /layer/}] { @@ -84,17 +83,7 @@ On process { set renderTime [baretime [list foreach command $displayCommands { {*}$command }]] set commitTime [baretime commitThenClearStaging] - set framesInLastSecond 0 - set now [clock milliseconds] - lappend frames $now - foreach frame $frames { - if {$frame > $now - 1000} { - incr framesInLastSecond - } - } - set frames [lreplace $frames 0 end-$framesInLastSecond] - - Commit { Claim the display time is "render $renderTime us + commit $commitTime us ($::stepTime) ($framesInLastSecond fps)" } + Commit { Claim the display time is "render $renderTime us + commit $commitTime us ($::stepTime)" } Step } } -- cgit v1.2.3