bluer-ugv 7.359.1__py3-none-any.whl → 7.421.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. bluer_ugv/.abcli/swallow/dataset.sh +1 -1
  2. bluer_ugv/.abcli/swallow/video/play.sh +7 -0
  3. bluer_ugv/.abcli/swallow/video/playlist/cat.sh +14 -0
  4. bluer_ugv/.abcli/swallow/video/playlist/download.sh +18 -0
  5. bluer_ugv/.abcli/swallow/video/playlist/edit.sh +14 -0
  6. bluer_ugv/.abcli/swallow/video/playlist/upload.sh +9 -0
  7. bluer_ugv/.abcli/swallow/video/playlist.sh +15 -0
  8. bluer_ugv/.abcli/swallow/video.sh +15 -0
  9. bluer_ugv/.abcli/swallow.sh +1 -1
  10. bluer_ugv/.abcli/tests/help.sh +8 -0
  11. bluer_ugv/.abcli/tests/swallow_video_play.sh +11 -0
  12. bluer_ugv/.abcli/tests/swallow_video_playlist.sh +45 -0
  13. bluer_ugv/__init__.py +1 -1
  14. bluer_ugv/config.env +3 -1
  15. bluer_ugv/env.py +2 -0
  16. bluer_ugv/help/swallow/__init__.py +2 -0
  17. bluer_ugv/help/swallow/video/__init__.py +0 -0
  18. bluer_ugv/help/swallow/video/functions.py +41 -0
  19. bluer_ugv/help/swallow/video/playlist.py +89 -0
  20. bluer_ugv/swallow/session/classical/screen/__init__.py +0 -0
  21. bluer_ugv/swallow/session/classical/screen/classes.py +42 -0
  22. bluer_ugv/swallow/session/classical/screen/video/__init__.py +0 -0
  23. bluer_ugv/swallow/session/classical/screen/video/__main__.py +99 -0
  24. bluer_ugv/swallow/session/classical/screen/video/engine.py +125 -0
  25. bluer_ugv/swallow/session/classical/screen/video/player.py +117 -0
  26. bluer_ugv/swallow/session/classical/screen/video/playlist.py +116 -0
  27. bluer_ugv/swallow/session/classical/session.py +11 -7
  28. bluer_ugv/swallow/session/classical/ultrasonic_sensor/log.py +3 -0
  29. {bluer_ugv-7.359.1.dist-info → bluer_ugv-7.421.1.dist-info}/METADATA +2 -2
  30. {bluer_ugv-7.359.1.dist-info → bluer_ugv-7.421.1.dist-info}/RECORD +33 -15
  31. bluer_ugv/swallow/session/classical/screen.py +0 -11
  32. {bluer_ugv-7.359.1.dist-info → bluer_ugv-7.421.1.dist-info}/WHEEL +0 -0
  33. {bluer_ugv-7.359.1.dist-info → bluer_ugv-7.421.1.dist-info}/licenses/LICENSE +0 -0
  34. {bluer_ugv-7.359.1.dist-info → bluer_ugv-7.421.1.dist-info}/top_level.txt +0 -0
@@ -9,7 +9,7 @@ function bluer_ugv_swallow_dataset() {
9
9
  return
10
10
  fi
11
11
 
12
- python3 - bluer_ugv.swallow.dataset "$@"
12
+ python3 -m bluer_ugv.swallow.dataset "$@"
13
13
  }
14
14
 
15
15
  bluer_ai_source_caller_suffix_path /dataset
@@ -0,0 +1,7 @@
1
+ #! /usr/bin/env bash
2
+
3
+ function bluer_ugv_swallow_video_play() {
4
+ python3 -m bluer_ugv.swallow.session.classical.screen.video \
5
+ play \
6
+ "$@"
7
+ }
@@ -0,0 +1,14 @@
1
+ #! /usr/bin/env bash
2
+
3
+ function bluer_ugv_swallow_video_playlist_cat() {
4
+ local options=$1
5
+ local do_download=$(bluer_ai_option_int "$options" download 0)
6
+
7
+ [[ "$do_download" == 1 ]] &&
8
+ bluer_ugv_swallow_video_playlist_download \
9
+ filename=void \
10
+ $RANGIN_VIDEO_LIST_OBJECT
11
+
12
+ bluer_ai_cat \
13
+ $ABCLI_OBJECT_ROOT/$RANGIN_VIDEO_LIST_OBJECT/metadata.yaml
14
+ }
@@ -0,0 +1,18 @@
1
+ #! /usr/bin/env bash
2
+
3
+ function bluer_ugv_swallow_video_playlist_download() {
4
+ local options=${1:-policy=doesnt_exist}
5
+
6
+ [[ "$abcli_is_rpi" == true ]] &&
7
+ sudo chown pi:pi \
8
+ $ABCLI_OBJECT_ROOT/$RANGIN_VIDEO_LIST_OBJECT
9
+
10
+ bluer_objects_download \
11
+ filename=metadata.yaml \
12
+ $RANGIN_VIDEO_LIST_OBJECT
13
+ [[ $? -ne 0 ]] && return 1
14
+
15
+ bluer_objects_download \
16
+ ,$options \
17
+ $RANGIN_VIDEO_LIST_OBJECT
18
+ }
@@ -0,0 +1,14 @@
1
+ #! /usr/bin/env bash
2
+
3
+ function bluer_ugv_swallow_video_playlist_edit() {
4
+ local options=$1
5
+ local do_download=$(bluer_ai_option_int "$options" download 0)
6
+
7
+ [[ "$do_download" == 1 ]] &&
8
+ bluer_ugv_swallow_video_playlist_download \
9
+ filename=void \
10
+ $RANGIN_VIDEO_LIST_OBJECT
11
+
12
+ bluer_ai_code \
13
+ $ABCLI_OBJECT_ROOT/$RANGIN_VIDEO_LIST_OBJECT/metadata.yaml
14
+ }
@@ -0,0 +1,9 @@
1
+ #! /usr/bin/env bash
2
+
3
+ function bluer_ugv_swallow_video_playlist_upload() {
4
+ local options=${1:-filename=metadata.yaml}
5
+
6
+ bluer_objects_upload \
7
+ ,$options \
8
+ $RANGIN_VIDEO_LIST_OBJECT
9
+ }
@@ -0,0 +1,15 @@
1
+ #! /usr/bin/env bash
2
+
3
+ function bluer_ugv_swallow_video_playlist() {
4
+ local task=$1
5
+
6
+ local function_name=bluer_ugv_swallow_video_playlist_$task
7
+ if [[ $(type -t $function_name) == "function" ]]; then
8
+ $function_name "${@:2}"
9
+ return
10
+ fi
11
+
12
+ python3 -m bluer_ugv.swallow.session.classical.screen.video "$@"
13
+ }
14
+
15
+ bluer_ai_source_caller_suffix_path /playlist
@@ -0,0 +1,15 @@
1
+ #! /usr/bin/env bash
2
+
3
+ function bluer_ugv_swallow_video() {
4
+ local task=$1
5
+
6
+ local function_name=bluer_ugv_swallow_video_$task
7
+ if [[ $(type -t $function_name) == "function" ]]; then
8
+ $function_name "${@:2}"
9
+ return
10
+ fi
11
+
12
+ python3 -m bluer_ugv.swallow.session.classical.screen.video "$@"
13
+ }
14
+
15
+ bluer_ai_source_caller_suffix_path /video
@@ -9,7 +9,7 @@ function bluer_ugv_swallow() {
9
9
  return
10
10
  fi
11
11
 
12
- python3 - bluer_ugv.swallow "$@"
12
+ python3 -m bluer_ugv.swallow "$@"
13
13
  }
14
14
 
15
15
  bluer_ai_source_caller_suffix_path /swallow
@@ -29,6 +29,14 @@ function test_bluer_ugv_help() {
29
29
  "@swallow ultrasonic review" \
30
30
  "@swallow ultrasonic test" \
31
31
  \
32
+ "@swallow video" \
33
+ "@swallow video play" \
34
+ "@swallow video playlist" \
35
+ "@swallow video playlist cat" \
36
+ "@swallow video playlist download" \
37
+ "@swallow video playlist edit" \
38
+ "@swallow video playlist upload" \
39
+ \
32
40
  "@ugv" \
33
41
  \
34
42
  "@ugv git" \
@@ -0,0 +1,11 @@
1
+ #! /usr/bin/env bash
2
+
3
+ function test_swallow_video_play() {
4
+ local options=$1
5
+
6
+ bluer_ai_eval ,$options \
7
+ bluer_ugv \
8
+ swallow \
9
+ video \
10
+ play
11
+ }
@@ -0,0 +1,45 @@
1
+ #! /usr/bin/env bash
2
+
3
+ function test_swallow_video_playlist_cat() {
4
+ local options=$1
5
+
6
+ bluer_ai_eval ,$options \
7
+ bluer_ugv \
8
+ swallow \
9
+ video \
10
+ playlist \
11
+ cat
12
+ }
13
+
14
+ function test_swallow_video_playlist_download_upload() {
15
+ local options=$1
16
+
17
+ bluer_ai_eval ,$options \
18
+ bluer_ugv \
19
+ swallow \
20
+ video \
21
+ playlist \
22
+ download \
23
+ policy=doesnt_exist
24
+ [[ $? -ne 0 ]] && return 1
25
+
26
+ bluer_ai_eval ,$options \
27
+ bluer_ugv \
28
+ swallow \
29
+ video \
30
+ playlist \
31
+ upload \
32
+ filename=metadata.yaml
33
+ }
34
+
35
+ function test_swallow_video_playlist_edit() {
36
+ local options=$1
37
+
38
+ bluer_ai_eval ,$options \
39
+ bluer_ugv \
40
+ swallow \
41
+ video \
42
+ playlist \
43
+ edit \
44
+ download
45
+ }
bluer_ugv/__init__.py CHANGED
@@ -4,7 +4,7 @@ ICON = "🐬"
4
4
 
5
5
  DESCRIPTION = f"{ICON} AI x UGV."
6
6
 
7
- VERSION = "7.359.1"
7
+ VERSION = "7.421.1"
8
8
 
9
9
  REPO_NAME = "bluer-ugv"
10
10
 
bluer_ugv/config.env CHANGED
@@ -27,4 +27,6 @@ BLUER_UGV_ULTRASONIC_SENSOR_MAX_M=0.8
27
27
 
28
28
  BLUER_UGV_ULTRASONIC_SENSOR_KEEP_LOG=1
29
29
 
30
- BLUER_UGV_ULTRASONIC_SENSOR_LOG=0
30
+ BLUER_UGV_ULTRASONIC_SENSOR_LOG=0
31
+
32
+ RANGIN_VIDEO_LIST_OBJECT=rangin-video-list-1
bluer_ugv/env.py CHANGED
@@ -81,3 +81,5 @@ BLUER_UGV_ULTRASONIC_SENSOR_LOG = get_env(
81
81
  "BLUER_UGV_ULTRASONIC_SENSOR_LOG",
82
82
  1,
83
83
  )
84
+
85
+ RANGIN_VIDEO_LIST_OBJECT = get_env("RANGIN_VIDEO_LIST_OBJECT")
@@ -6,6 +6,7 @@ from bluer_ugv.help.swallow.select_target import help_select_target
6
6
  from bluer_ugv.help.swallow.ultrasonic_sensor import (
7
7
  help_functions as help_ultrasonic_sensor,
8
8
  )
9
+ from bluer_ugv.help.swallow.video.functions import help_functions as help_video
9
10
 
10
11
  help_functions = {
11
12
  "dataset": help_dataset,
@@ -14,4 +15,5 @@ help_functions = {
14
15
  "keyboard": help_keyboard,
15
16
  "select_target": help_select_target,
16
17
  "ultrasonic": help_ultrasonic_sensor,
18
+ "video": help_video,
17
19
  }
File without changes
@@ -0,0 +1,41 @@
1
+ from typing import List
2
+
3
+ from bluer_options.terminal import show_usage, xtra
4
+
5
+ from bluer_ugv import env
6
+ from bluer_ugv.help.swallow.video.playlist import help_functions as help_playlist
7
+ from bluer_ugv.swallow.session.classical.screen.video.engine import VideoEngine
8
+
9
+
10
+ def help_play(
11
+ tokens: List[str],
12
+ mono: bool,
13
+ ) -> str:
14
+ args = [
15
+ "[--dryrun 1]",
16
+ "[--download 0]",
17
+ "[--engine {}]".format(
18
+ " | ".join(sorted([engine.name.lower() for engine in VideoEngine]))
19
+ ),
20
+ "[--loop 0]",
21
+ f"[--object_name <{env.RANGIN_VIDEO_LIST_OBJECT}>]",
22
+ "[--timeout <-1 | 10>]",
23
+ "[--video <loading|1>]",
24
+ ]
25
+
26
+ return show_usage(
27
+ [
28
+ "@swallow",
29
+ "video",
30
+ "play",
31
+ ]
32
+ + args,
33
+ "play <object-name>/<video>.",
34
+ mono=mono,
35
+ )
36
+
37
+
38
+ help_functions = {
39
+ "play": help_play,
40
+ "playlist": help_playlist,
41
+ }
@@ -0,0 +1,89 @@
1
+ from typing import List
2
+
3
+ from bluer_options.terminal import show_usage, xtra
4
+ from bluer_objects.help.download import options as download_options
5
+ from bluer_objects.help.upload import options as upload_options
6
+
7
+
8
+ def help_cat(
9
+ tokens: List[str],
10
+ mono: bool,
11
+ ) -> str:
12
+ options = xtra("download", mono=mono)
13
+
14
+ return show_usage(
15
+ [
16
+ "@swallow",
17
+ "video",
18
+ "playlist",
19
+ "cat",
20
+ f"[{options}]",
21
+ ],
22
+ "cat swallow playlist.",
23
+ mono=mono,
24
+ )
25
+
26
+
27
+ def help_download(
28
+ tokens: List[str],
29
+ mono: bool,
30
+ ) -> str:
31
+ options = download_options(mono=mono)
32
+
33
+ return show_usage(
34
+ [
35
+ "@swallow",
36
+ "video",
37
+ "playlist",
38
+ "download",
39
+ f"[{options}]",
40
+ ],
41
+ "download swallow playlist.",
42
+ mono=mono,
43
+ )
44
+
45
+
46
+ def help_edit(
47
+ tokens: List[str],
48
+ mono: bool,
49
+ ) -> str:
50
+ options = xtra("download", mono=mono)
51
+
52
+ return show_usage(
53
+ [
54
+ "@swallow",
55
+ "video",
56
+ "playlist",
57
+ "edit",
58
+ f"[{options}]",
59
+ ],
60
+ "edit swallow playlist.",
61
+ mono=mono,
62
+ )
63
+
64
+
65
+ def help_upload(
66
+ tokens: List[str],
67
+ mono: bool,
68
+ ) -> str:
69
+ options = upload_options(mono=mono)
70
+
71
+ return show_usage(
72
+ [
73
+ "@swallow",
74
+ "video",
75
+ "playlist",
76
+ "upload",
77
+ f"[{options}]",
78
+ ],
79
+ "upload swallow playlist.",
80
+ mono=mono,
81
+ )
82
+
83
+
84
+ help_functions = {
85
+ "cat": help_cat,
86
+ "download": help_download,
87
+ "edit": help_edit,
88
+ "upload": help_upload,
89
+ }
File without changes
@@ -0,0 +1,42 @@
1
+ from bluer_options.host.functions import is_headless
2
+
3
+ from bluer_ugv import env
4
+ from bluer_ugv.swallow.session.classical.screen.video.player import VideoPlayer
5
+ from bluer_ugv.swallow.session.classical.screen.video.playlist import PlayList
6
+ from bluer_ugv.logger import logger
7
+
8
+
9
+ class ClassicalScreen:
10
+ def __init__(self):
11
+ self.video_player = None if is_headless() else VideoPlayer()
12
+
13
+ self.playlist = PlayList(env.RANGIN_VIDEO_LIST_OBJECT)
14
+
15
+ logger.info(f"{self.__class__.__name__} created.")
16
+
17
+ def cleanup(self):
18
+ logger.info(f"{self.__class__.__name__}.cleanup")
19
+ self.video_player.stop()
20
+
21
+ def initialize(self) -> bool:
22
+ if self.video_player is None:
23
+ return True
24
+
25
+ return self.video_player.play(
26
+ self.playlist.get("loading"),
27
+ loop=True,
28
+ )
29
+
30
+ def update(self) -> bool:
31
+ if self.video_player is None:
32
+ return True
33
+
34
+ if self.video_player.process:
35
+ return True
36
+
37
+ self.playlist.next()
38
+
39
+ return self.video_player.play(
40
+ self.playlist.get(self.playlist.index),
41
+ loop=False,
42
+ )
@@ -0,0 +1,99 @@
1
+ import argparse
2
+ import time
3
+
4
+ from blueness import module
5
+ from blueness.argparse.generic import sys_exit
6
+ from bluer_options.host import is_rpi, is_headless
7
+ from bluer_options import string
8
+
9
+ from bluer_ugv import NAME, env
10
+ from bluer_ugv.swallow.session.classical.screen.video.playlist import PlayList
11
+ from bluer_ugv.swallow.session.classical.screen.video.player import VideoPlayer
12
+ from bluer_ugv.swallow.session.classical.screen.video.engine import VideoEngine
13
+ from bluer_ugv.logger import logger
14
+
15
+ NAME = module.name(__file__, NAME)
16
+
17
+ parser = argparse.ArgumentParser(NAME)
18
+ parser.add_argument(
19
+ "task",
20
+ type=str,
21
+ help="play",
22
+ )
23
+ parser.add_argument(
24
+ "--download",
25
+ type=int,
26
+ default=1,
27
+ help="0|1",
28
+ )
29
+ parser.add_argument(
30
+ "--dryrun",
31
+ type=int,
32
+ default=int(not is_rpi() or is_headless()),
33
+ help="0|1",
34
+ )
35
+ parser.add_argument(
36
+ "--engine",
37
+ type=str,
38
+ default=VideoEngine.VLC.name.lower(),
39
+ help=" | ".join(sorted([engine.name.lower() for engine in VideoEngine])),
40
+ )
41
+ parser.add_argument(
42
+ "--loop",
43
+ type=int,
44
+ default=1,
45
+ help="0|1",
46
+ )
47
+ parser.add_argument(
48
+ "--object_name",
49
+ type=str,
50
+ default=env.RANGIN_VIDEO_LIST_OBJECT,
51
+ )
52
+ parser.add_argument(
53
+ "--timeout",
54
+ type=int,
55
+ default=-1,
56
+ help="in seconds, -1: never",
57
+ )
58
+ parser.add_argument(
59
+ "--video",
60
+ type=str,
61
+ default="loading",
62
+ )
63
+ args = parser.parse_args()
64
+
65
+
66
+ success = False
67
+ if args.task == "play":
68
+ playlist = PlayList(
69
+ args.object_name,
70
+ download=args.download == 1,
71
+ )
72
+
73
+ video_player = VideoPlayer(
74
+ args.dryrun == 1,
75
+ engine=VideoEngine[args.engine.upper()],
76
+ )
77
+
78
+ success = video_player.play(
79
+ filename=playlist.get(args.video),
80
+ loop=args.loop == 1,
81
+ )
82
+
83
+ if success and args.timeout > 0:
84
+ logger.info(
85
+ "waiting for {}".format(
86
+ string.pretty_duration(
87
+ args.timeout,
88
+ )
89
+ )
90
+ )
91
+ time.sleep(args.timeout)
92
+ success = video_player.stop()
93
+
94
+ logger.info('💡 type in "reset" if the prompt is invisible.')
95
+
96
+ else:
97
+ success = None
98
+
99
+ sys_exit(logger, NAME, args.task, success)
@@ -0,0 +1,125 @@
1
+ import shlex
2
+ from enum import Enum, auto
3
+ import subprocess
4
+ import time
5
+ import socket
6
+
7
+ from bluer_objects.graphics.screen import get_size
8
+ from bluer_ugv.logger import logger
9
+
10
+
11
+ class VideoEngine(Enum):
12
+ MPV = auto()
13
+ VLC = auto()
14
+
15
+ def pause(self, process: subprocess.Popen):
16
+ # MPV: use stdin
17
+ if self == VideoEngine.MPV:
18
+ try:
19
+ if not process.stdin:
20
+ logger.error("mpv pause failed: no stdin")
21
+ return False
22
+ process.stdin.write(b"p")
23
+ process.stdin.flush()
24
+ except Exception as e:
25
+ logger.error(f"mpv pause exception: {e}")
26
+ return False
27
+ return True
28
+
29
+ # VLC: use RC TCP
30
+ if self == VideoEngine.VLC:
31
+ try:
32
+ s = socket.create_connection(("127.0.0.1", 41940), 0.5)
33
+ s.sendall(b"pause\n")
34
+ s.close()
35
+ return True
36
+ except Exception as e:
37
+ logger.error(f"vlc pause failed: {e}")
38
+ return False
39
+
40
+ logger.error(f"{self}: unknown video engine.")
41
+ return False
42
+
43
+ def play_command(
44
+ self,
45
+ filename: str,
46
+ fullscreen: bool = True,
47
+ loop: bool = False,
48
+ audio: bool = False,
49
+ ) -> str:
50
+ screen_height, screen_width = get_size()
51
+ logger.info("screen size: {}x{}".format(screen_height, screen_width))
52
+
53
+ if self == VideoEngine.MPV:
54
+ logger.info('press "q" to quit mpv.')
55
+
56
+ return " ".join(
57
+ [
58
+ "mpv",
59
+ "--no-border",
60
+ "--background=black", # FIXED
61
+ "--keepaspect=yes",
62
+ "--no-keepaspect-window",
63
+ "--geometry=0:0",
64
+ (f"--autofit={screen_width}x{screen_height}" if fullscreen else ""),
65
+ "--loop" if loop else "",
66
+ "--no-audio" if not audio else "",
67
+ shlex.quote(filename),
68
+ ]
69
+ )
70
+
71
+ if self == VideoEngine.VLC:
72
+ logger.info('press "Enter" to quit vlc.')
73
+
74
+ return " ".join(
75
+ [
76
+ "sudo -u pi",
77
+ "cvlc",
78
+ "--fullscreen",
79
+ "--no-video-title-show",
80
+ "--video-on-top",
81
+ "--no-osd",
82
+ "--loop" if loop else "",
83
+ "--no-audio" if not audio else "",
84
+ "--extraintf",
85
+ "rc",
86
+ "--rc-host=127.0.0.1:41940",
87
+ shlex.quote(filename),
88
+ ]
89
+ )
90
+
91
+ return "this-should-not-happen"
92
+
93
+ def stop(
94
+ self,
95
+ process: subprocess.Popen,
96
+ ) -> bool:
97
+ if self == VideoEngine.MPV:
98
+ try:
99
+ if process.stdin:
100
+ process.stdin.write(b"q")
101
+ process.stdin.flush()
102
+ except Exception as e:
103
+ logger.error(f"mpv quit failed: {e}")
104
+ return False
105
+
106
+ if self == VideoEngine.VLC:
107
+ try:
108
+ s = socket.create_connection(("127.0.0.1", 41940), 0.5)
109
+ s.sendall(b"quit\n")
110
+ s.close()
111
+ logger.info("vlc: sent 'quit' via TCP RC.")
112
+ except Exception as e:
113
+ logger.error(f"vlc rc quit failed: {e}")
114
+ return False
115
+
116
+ time.sleep(0.3)
117
+
118
+ try:
119
+ if process.poll() is None:
120
+ process.kill()
121
+ except Exception as e:
122
+ logger.warning(f"process.kill failed: {e}")
123
+ return False
124
+
125
+ return True
@@ -0,0 +1,117 @@
1
+ from typing import List, Optional
2
+ import subprocess
3
+ import shlex
4
+ import time
5
+
6
+ from bluer_options.logger import crash_report
7
+ from bluer_options.logger.config import log_list
8
+ from bluer_objects import file
9
+
10
+ from bluer_ugv.swallow.session.classical.screen.video.engine import VideoEngine
11
+ from bluer_ugv.logger import logger
12
+
13
+
14
+ class VideoPlayer:
15
+ def __init__(
16
+ self,
17
+ dryrun: bool = False,
18
+ engine: VideoEngine = VideoEngine.VLC,
19
+ ):
20
+ self.process: Optional[subprocess.Popen] = None
21
+ self.current_file: Optional[str] = None
22
+
23
+ self.paused = False
24
+ self.dryrun = dryrun
25
+ assert isinstance(engine, VideoEngine)
26
+ self.engine: VideoEngine = engine
27
+
28
+ logger.info(
29
+ "{} created on {}{}.".format(
30
+ self.__class__.__name__,
31
+ self.engine.name.lower(),
32
+ " [dryrun]" if dryrun else "",
33
+ )
34
+ )
35
+
36
+ def pause(self) -> bool:
37
+ if not self.dryrun:
38
+ if self.process and self.process.poll() is None:
39
+ if not self.engine.pause(self.process):
40
+ return False
41
+
42
+ logger.info(
43
+ "{}.{}".format(
44
+ self.__class__.__name__,
45
+ "resume" if self.paused else "pause",
46
+ )
47
+ )
48
+ self.paused = not self.paused
49
+
50
+ return True
51
+
52
+ def play(
53
+ self,
54
+ filename: str,
55
+ loop: bool = False,
56
+ audio: bool = False,
57
+ fullscreen: bool = True,
58
+ verbose: bool = True,
59
+ ) -> bool:
60
+ if not file.exists(filename):
61
+ logger.error(f"file not found: {filename}")
62
+ return False
63
+
64
+ self.stop()
65
+
66
+ command = self.engine.play_command(
67
+ filename=filename,
68
+ fullscreen=fullscreen,
69
+ loop=loop,
70
+ audio=audio,
71
+ )
72
+ logger.info(f"running on {self.engine.name.lower()}: {command}")
73
+
74
+ if not self.dryrun:
75
+ try:
76
+ # pylint: disable=consider-using-with
77
+ self.process = subprocess.Popen(
78
+ shlex.split(command),
79
+ stdin=subprocess.PIPE if self.engine == VideoEngine.MPV else None,
80
+ stdout=None if verbose else subprocess.DEVNULL,
81
+ stderr=None if verbose else subprocess.DEVNULL,
82
+ )
83
+
84
+ logger.info(
85
+ f"pid={self.process.pid}, "
86
+ f"stdin={self.process.stdin}, returncode={self.process.returncode}"
87
+ )
88
+
89
+ except Exception as e:
90
+ crash_report(f"failed to run: {e}")
91
+ self.process = None
92
+ return False
93
+
94
+ if not self.process:
95
+ logger.error("process is None.")
96
+ return False
97
+
98
+ self.current_file = filename
99
+
100
+ logger.info(
101
+ "{}.play({}{})".format(
102
+ self.__class__.__name__,
103
+ "loop: " if loop else "",
104
+ filename,
105
+ )
106
+ )
107
+
108
+ return True
109
+
110
+ def stop(self) -> bool:
111
+ if not self.dryrun and self.process and self.process.poll() is None:
112
+ if not self.engine.stop(self.process):
113
+ return False
114
+
115
+ self.process = None
116
+ logger.info(f"{self.__class__.__name__}.stop")
117
+ return True
@@ -0,0 +1,116 @@
1
+ from typing import Dict, List
2
+
3
+ from bluer_options.logger.config import log_dict, log_list
4
+ from bluer_objects.metadata import get_from_object
5
+ from bluer_objects import storage, objects
6
+ from bluer_objects.storage.policies import DownloadPolicy
7
+
8
+ from bluer_ugv.logger import logger
9
+
10
+
11
+ class PlayList:
12
+ def __init__(
13
+ self,
14
+ object_name: str,
15
+ download: bool = True,
16
+ ):
17
+ self.index: int = -1
18
+
19
+ self.object_name = object_name
20
+ self.download = download
21
+
22
+ if self.download:
23
+ storage.download(
24
+ self.object_name,
25
+ filename="metadata.yaml",
26
+ )
27
+
28
+ self.messages: Dict[str, str] = get_from_object(
29
+ self.object_name,
30
+ "messages",
31
+ default={},
32
+ )
33
+ log_dict(
34
+ logger,
35
+ "loaded",
36
+ self.messages,
37
+ "message(s)",
38
+ max_count=-1,
39
+ max_length=-1,
40
+ )
41
+
42
+ self.playlist: List[Dict[str, str]] = get_from_object(
43
+ self.object_name,
44
+ "playlist",
45
+ default=[],
46
+ )
47
+ log_list(
48
+ logger,
49
+ "loaded",
50
+ self.playlist,
51
+ "playlist item(s)",
52
+ max_count=-1,
53
+ max_length=-1,
54
+ )
55
+
56
+ logger.info(
57
+ "{} created from {}.".format(
58
+ self.__class__.__name__,
59
+ self.object_name,
60
+ )
61
+ )
62
+
63
+ def get(
64
+ self,
65
+ keyword: int | str = "loading",
66
+ what: str = "filename",
67
+ ) -> str:
68
+ filename = f"{keyword.__class__.__name__}-not-supported"
69
+
70
+ if isinstance(keyword, int):
71
+ filename = "bad-index-{}-from-{}".format(
72
+ keyword,
73
+ len(self.playlist),
74
+ )
75
+
76
+ if 0 <= keyword < len(self.playlist):
77
+ filename = self.playlist[keyword].get(
78
+ what,
79
+ f"{what}-not-found",
80
+ )
81
+
82
+ if isinstance(keyword, str):
83
+ filename = f"{keyword}-not-found"
84
+
85
+ if keyword.isnumeric():
86
+ return self.get(int(keyword), what=what)
87
+
88
+ if keyword in self.messages:
89
+ filename = self.messages[keyword].get(
90
+ what,
91
+ f"{what}-not-found",
92
+ )
93
+
94
+ if self.download:
95
+ storage.download(
96
+ self.object_name,
97
+ filename=filename,
98
+ policy=DownloadPolicy.DOESNT_EXIST,
99
+ )
100
+
101
+ return objects.path_of(
102
+ filename=filename,
103
+ object_name=self.object_name,
104
+ )
105
+
106
+ def next(self):
107
+ self.index += 1
108
+ if self.index >= len(self.playlist):
109
+ self.index = 0
110
+
111
+ logger.info(
112
+ "{}: video #{}".format(
113
+ self.__class__.__name__,
114
+ self.index,
115
+ )
116
+ )
@@ -24,7 +24,7 @@ from bluer_ugv.swallow.session.classical.motor import (
24
24
  )
25
25
  from bluer_ugv.swallow.session.classical.setpoint.classes import ClassicalSetPoint
26
26
  from bluer_ugv.swallow.session.classical.position import ClassicalPosition
27
- from bluer_ugv.swallow.session.classical.screen import ClassicalScreen
27
+ from bluer_ugv.swallow.session.classical.screen.classes import ClassicalScreen
28
28
  from bluer_ugv.swallow.session.classical.ultrasonic_sensor.classes import (
29
29
  ClassicalUltrasonicSensor,
30
30
  )
@@ -114,6 +114,8 @@ class ClassicalSession:
114
114
  object_name=self.object_name,
115
115
  )
116
116
 
117
+ self.screen = ClassicalScreen()
118
+
117
119
  logger.info(
118
120
  "{}: created for {}".format(
119
121
  self.__class__.__name__,
@@ -127,12 +129,10 @@ class ClassicalSession:
127
129
  self.ultrasonic_sensor.stop()
128
130
  self.camera.stop()
129
131
 
130
- for thing in [
131
- self.motor1,
132
- self.motor2,
133
- self.camera,
134
- ]:
135
- thing.cleanup()
132
+ self.motor1.cleanup()
133
+ self.motor2.cleanup()
134
+
135
+ self.camera.cleanup()
136
136
 
137
137
  GPIO.cleanup()
138
138
 
@@ -156,12 +156,15 @@ class ClassicalSession:
156
156
  loop_frequency,
157
157
  )
158
158
 
159
+ self.screen.cleanup()
160
+
159
161
  logger.info(f"{self.__class__.__name__}.cleanup")
160
162
 
161
163
  def initialize(self) -> bool:
162
164
  return all(
163
165
  thing.initialize()
164
166
  for thing in [
167
+ self.screen,
165
168
  self.push_button,
166
169
  self.leds,
167
170
  self.motor1,
@@ -183,6 +186,7 @@ class ClassicalSession:
183
186
  self.motor1,
184
187
  self.motor2,
185
188
  self.leds,
189
+ self.screen,
186
190
  ]:
187
191
  self.timing.start(thing.__class__.__name__)
188
192
 
@@ -1,4 +1,7 @@
1
1
  from typing import List
2
+ import matplotlib
3
+
4
+ matplotlib.use("Agg")
2
5
  import matplotlib.pyplot as plt
3
6
  from tqdm import tqdm
4
7
  import numpy as np
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bluer_ugv
3
- Version: 7.359.1
3
+ Version: 7.421.1
4
4
  Summary: 🐬 AI x UGV.
5
5
  Home-page: https://github.com/kamangir/bluer-ugv
6
6
  Author: Arash Abadpour (Kamangir)
@@ -64,7 +64,7 @@ pip install bluer_ugv
64
64
 
65
65
  [![pylint](https://github.com/kamangir/bluer-ugv/actions/workflows/pylint.yml/badge.svg)](https://github.com/kamangir/bluer-ugv/actions/workflows/pylint.yml) [![pytest](https://github.com/kamangir/bluer-ugv/actions/workflows/pytest.yml/badge.svg)](https://github.com/kamangir/bluer-ugv/actions/workflows/pytest.yml) [![bashtest](https://github.com/kamangir/bluer-ugv/actions/workflows/bashtest.yml/badge.svg)](https://github.com/kamangir/bluer-ugv/actions/workflows/bashtest.yml) [![PyPI version](https://img.shields.io/pypi/v/bluer-ugv.svg)](https://pypi.org/project/bluer-ugv/) [![PyPI - Downloads](https://img.shields.io/pypi/dd/bluer-ugv)](https://pypistats.org/packages/bluer-ugv)
66
66
 
67
- built by 🌀 [`bluer README`](https://github.com/kamangir/bluer-objects/tree/main/bluer_objects/README), based on 🐬 [`bluer_ugv-7.359.1`](https://github.com/kamangir/bluer-ugv).
67
+ built by 🌀 [`bluer README`](https://github.com/kamangir/bluer-objects/tree/main/bluer_objects/README), based on 🐬 [`bluer_ugv-7.421.1`](https://github.com/kamangir/bluer-ugv).
68
68
 
69
69
 
70
70
  built by 🌀 [`blueness-3.118.1`](https://github.com/kamangir/blueness).
@@ -1,7 +1,7 @@
1
- bluer_ugv/__init__.py,sha256=F_pqhqD98ev09BusRGLjekDPEOidSapK8Zmms3eqy94,288
1
+ bluer_ugv/__init__.py,sha256=DIp2tWw0bFz4fuPJU_T0okkuaLLLBoXArIvt-F3_gSY,288
2
2
  bluer_ugv/__main__.py,sha256=77TquqyMca7qHk0XtCixGVyzfW3_9ywnl5oXEPERlls,374
3
- bluer_ugv/config.env,sha256=RjdP3rLG6pqIrilFsCbYpg8ieTDhzMfBrqvQkJYZ1Sk,949
4
- bluer_ugv/env.py,sha256=asv-2OByZzf1c4ta3CHMZQDEcY8cd2WDUOa-_OCNYvU,1757
3
+ bluer_ugv/config.env,sha256=DvOq_s3WEo2qC0PF9jcrx_6NM17zggxBapxgCEg5nZ0,995
4
+ bluer_ugv/env.py,sha256=wep0iD09RRfpIb-ZGlP9kt8UATVLAjM9WytMGB8IyMo,1821
5
5
  bluer_ugv/host.py,sha256=DpdJCvBpUfP9LkZgcH4BcdLGD-WZUvbTsjvMfPtS8uY,292
6
6
  bluer_ugv/logger.py,sha256=faY6GL6xfZAzlZ1aJ-MEHuPRJZNx8PYS4jMyY3xuxMw,98
7
7
  bluer_ugv/sample.env,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -11,14 +11,15 @@ bluer_ugv/.abcli/actions.sh,sha256=SqOmx12IOMopT2PgiHgAu5BwLgIi92I98LZ64dZSsXw,2
11
11
  bluer_ugv/.abcli/aka.sh,sha256=RHDU_JbEEL2B0vvvRJ3NVSsRSEjSu09jNY85n7DLe-k,21
12
12
  bluer_ugv/.abcli/alias.sh,sha256=WgSjjtC6rCqs7kChT-89dILSmp4f79R9iY3wYkRPSkY,77
13
13
  bluer_ugv/.abcli/bluer_UGV.sh,sha256=d1R6TQgIQugKeUK3RZbxgm-6d9QqkJwwoPCQKOC8Xb0,250
14
- bluer_ugv/.abcli/swallow.sh,sha256=hfgFLNtqePdH5kDuNJoIvOfyKpef26Qq3pXhgsSaLAs,318
15
- bluer_ugv/.abcli/swallow/dataset.sh,sha256=w-uuMLZEkfDbseLlCZu4xsg0veznj6ATU88Lzclh3xo,342
14
+ bluer_ugv/.abcli/swallow.sh,sha256=b3LpA-OSCa7ykRtLnWDQYrqmOvMfoP15al90krLmb2I,319
15
+ bluer_ugv/.abcli/swallow/dataset.sh,sha256=rHRTCShdP3Uls5ZmTKhRzQHX6a5bZvi8Cj1QDpO4tH4,343
16
16
  bluer_ugv/.abcli/swallow/debug.sh,sha256=JVjExhotePW3gZG2MUS6IzbXVQwMAefKYJiSP88wqlk,559
17
17
  bluer_ugv/.abcli/swallow/env.sh,sha256=5rKCdZhrQa_9Lr96j1h7XrWBcf0YEeV3w3o0vLWGd0M,360
18
18
  bluer_ugv/.abcli/swallow/keyboard.sh,sha256=RYR5vgV0C1SATqekQ_F6Lr6Ums0IAkH9THX2ZPcitoY,402
19
19
  bluer_ugv/.abcli/swallow/select_target.sh,sha256=fwHmKbVcn_OEW4q-cjNc8Eyi6hOi1pMAb6x5tW8_lb0,183
20
20
  bluer_ugv/.abcli/swallow/session.sh,sha256=sgshMG8KOeSePa9CELbf9eRD5lCXUXCU-oqASx0NAQ4,1558
21
21
  bluer_ugv/.abcli/swallow/ultrasonic.sh,sha256=GqnVn4u-FFC8SVsCYHiwABBDkgALe4mgRMloitlfeP8,380
22
+ bluer_ugv/.abcli/swallow/video.sh,sha256=gEFF3YfKWFkfg8gYkwynQW8U_89YP6z0giZfDEYjsPY,360
22
23
  bluer_ugv/.abcli/swallow/dataset/combine.sh,sha256=OYS-9ONRhXuP41Z0z1A5-ay6bqLLSsLmVOUZNvwRnrk,965
23
24
  bluer_ugv/.abcli/swallow/dataset/download.sh,sha256=4Br0hYqENIEYm15yTJGJeHFNfVNFozQf1qg6US8KYlY,587
24
25
  bluer_ugv/.abcli/swallow/dataset/edit.sh,sha256=ujhKhv3XIpkqcahnp01JkL4WXaOgRp9gNu7eZpZSYaA,595
@@ -30,14 +31,22 @@ bluer_ugv/.abcli/swallow/env/set.sh,sha256=hMl5qO_nsV_C3Yvn4KDpw2lY7QD8aESzPsIH0
30
31
  bluer_ugv/.abcli/swallow/keyboard/test.sh,sha256=B04AO-Er3_utzULPziyKD0aybuN2bry7h9wrQBEJ0tA,218
31
32
  bluer_ugv/.abcli/swallow/ultrasonic/review.sh,sha256=XoKwUliTcH-yTHrIo1cc9RSxL3tYQsBfWf1XOJ6YtOI,717
32
33
  bluer_ugv/.abcli/swallow/ultrasonic/test.sh,sha256=WRq4jnm2lv6q7fAw-_6Xg7DD8kgki48t8ilwXA-SsBM,582
34
+ bluer_ugv/.abcli/swallow/video/play.sh,sha256=Y4HN9hNbqPYKhm2jWUAXFl3tJg-B3nvftH9fkGr0TS8,160
35
+ bluer_ugv/.abcli/swallow/video/playlist.sh,sha256=ZL1qO1zKm7zO-PVdl2F67lIPpy_W4I_q_SFmAU_Egjc,381
36
+ bluer_ugv/.abcli/swallow/video/playlist/cat.sh,sha256=JiYq9R3lmw5pxVYvnA79LheiHuP1edQQu_AxlFdq7wk,401
37
+ bluer_ugv/.abcli/swallow/video/playlist/download.sh,sha256=_HsWoW3rtLWMZpAxd2iemgTsYYiy3GPHvC5LHSu-vdw,457
38
+ bluer_ugv/.abcli/swallow/video/playlist/edit.sh,sha256=_l-XpJOybxIkfcE797DBXwlcBcWSZqzTwIEGxk14-BY,403
39
+ bluer_ugv/.abcli/swallow/video/playlist/upload.sh,sha256=8yGQtenNTNPQvifffED0FCP4Rjz0jHHvaDdcTv-vn9M,206
33
40
  bluer_ugv/.abcli/tests/README.sh,sha256=w1xjPWgCfWbLtON_LEn2cvSmPLulzm7kTBPEC3LJixs,142
34
- bluer_ugv/.abcli/tests/help.sh,sha256=WOPID4QyuS57vpl5uEyYwytOF_pnMsbm4YgcZUcuvu8,1193
41
+ bluer_ugv/.abcli/tests/help.sh,sha256=A8xHFj01T1y1iQ8HvwKbuEacvaC4Xo9uIr_cX9qocfY,1467
35
42
  bluer_ugv/.abcli/tests/swallow_dataset_combine.sh,sha256=tXjZj5iOOmCz3ito9lBDYjaAvR2odNzs2LRXsrM6d6c,291
36
43
  bluer_ugv/.abcli/tests/swallow_dataset_combine_explicit.sh,sha256=Ff4V7fi-h1myRT9ajjaKXesNrpaxLZMGDidBT8G31Kw,360
37
44
  bluer_ugv/.abcli/tests/swallow_dataset_combine_sequence.sh,sha256=N3Iq-zJV2OfEoft44D1BBLOlrkAbUDN_Rp_sAmjCEVk,311
38
45
  bluer_ugv/.abcli/tests/swallow_dataset_download_upload.sh,sha256=IPWm1El6fyQl66AgwF2v-j2ALW9cfmAfsPRg5Xygk2U,354
39
46
  bluer_ugv/.abcli/tests/swallow_dataset_edit.sh,sha256=01wLHLd35pPTUmMxFT_ugkwLOAFAYF_3CJijq5RLxBY,221
40
47
  bluer_ugv/.abcli/tests/swallow_dataset_list.sh,sha256=DPjikrMLMl0oJTHBV4EyYmkMZnMjEmwosJRocLIJGz0,256
48
+ bluer_ugv/.abcli/tests/swallow_video_play.sh,sha256=38AHfA0zw4NYrAYFi2ypVk4eZ65k91DnlyQ4vWp1jOs,180
49
+ bluer_ugv/.abcli/tests/swallow_video_playlist.sh,sha256=SRJOtziqmh7Gnuaq1BQyyyqPoZDVq5-sy0tgWYnnfII,827
41
50
  bluer_ugv/.abcli/tests/ultrasonic_sensor_review.sh,sha256=4LxfOGRAUJsZ5dnxrkwXCjWmkgQWSeqck-UYyza3aw8,243
42
51
  bluer_ugv/.abcli/tests/version.sh,sha256=7nVT4lERxIe-GkuDn86nfur9E_WGbvWtet_AJtr2S48,147
43
52
  bluer_ugv/.abcli/ugv/git.sh,sha256=U5p_5qrNwLw8O7HfHu7QZgLblbDc6Z6lIumgKwu3mzY,299
@@ -128,13 +137,16 @@ bluer_ugv/help/__init__.py,sha256=ajz1GSNU9xYVrFEDSz6Xwg7amWQ_yvW75tQa1ZvRIWc,3
128
137
  bluer_ugv/help/__main__.py,sha256=ww3p0cIRZm-SDODZ_fYAzPV_-nucxtidjK1IP2idW8g,229
129
138
  bluer_ugv/help/functions.py,sha256=_JcncL82A-6m9P9J6MX6Z_FtZ09k6HWuirozKl48xXY,367
130
139
  bluer_ugv/help/git.py,sha256=4CcaA8lHoplrrFgF5lolwVT79SLr3gE2iqXpAIfzH64,319
131
- bluer_ugv/help/swallow/__init__.py,sha256=LZRT9EhacDqXqTKgygmJ-LraGwqciP3Ahp3P4p5o7R8,650
140
+ bluer_ugv/help/swallow/__init__.py,sha256=t65DuR-96-29wNylRysfId86OLNxsW4AM2YnN4V4DbM,755
132
141
  bluer_ugv/help/swallow/dataset.py,sha256=59D5XLQG1PRWfPwfM73Jz1-f0qh_cO0q18qLtsxXtj0,2495
133
142
  bluer_ugv/help/swallow/debug.py,sha256=70krqg-YtjxPjPwWnx4J1Fxlvw46hHyAYq7pA7yPt50,481
134
143
  bluer_ugv/help/swallow/env.py,sha256=AwNGF7ZcwQz7-Q8uKaLuajyIMXpi9yGMS27Xq0-QvUs,1325
135
144
  bluer_ugv/help/swallow/keyboard.py,sha256=YNkGWvE7tN3agCaL2R30FSIF2zw6oXa5ZJdnTJQA3Hk,518
136
145
  bluer_ugv/help/swallow/select_target.py,sha256=s1-v2IyT6thAncIzo4wKnU8hFJ-rDyi-IDzx2kMaJrs,390
137
146
  bluer_ugv/help/swallow/ultrasonic_sensor.py,sha256=rhxHQWDU7orCvqC_TeJWMCJFrm4qyJyHdiUIUIpZmhU,1223
147
+ bluer_ugv/help/swallow/video/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
148
+ bluer_ugv/help/swallow/video/functions.py,sha256=Ek0wrBUCNXSbBGIgMwD-8GUuULvSzL4zDv4lD8SGe6I,939
149
+ bluer_ugv/help/swallow/video/playlist.py,sha256=Wg09FONWjuKOFYxDD7Ni3OjrSf8cnadscth0xU1NjfI,1663
138
150
  bluer_ugv/swallow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
139
151
  bluer_ugv/swallow/__main__.py,sha256=eQPKYwnIG5Brr39-mhyuLSW5ghj91FAhqwrO4kLLKi0,1199
140
152
  bluer_ugv/swallow/debug.py,sha256=0M-XjKqTnm-sNGaHWeuaM6tlkSSEQNqaLpmozNHALw0,2497
@@ -151,8 +163,7 @@ bluer_ugv/swallow/session/classical/mode.py,sha256=6rFe1IIpfijuI7Xd-wcGKhYQ7EdQx
151
163
  bluer_ugv/swallow/session/classical/mousepad.py,sha256=LI7yvmtrZZaGUgPGpxNU7zcPkW8D5ykHlY_O-4H2STs,1871
152
164
  bluer_ugv/swallow/session/classical/position.py,sha256=gNeNzNpUG8zkDrcwibxaYStPNKUN1_DV5RjHu_pHMIg,913
153
165
  bluer_ugv/swallow/session/classical/push_button.py,sha256=s8sPart_dECjLK-gfsJi0UorRYcFYf3ofLqjmG8PoA8,2397
154
- bluer_ugv/swallow/session/classical/screen.py,sha256=XzExo4l_FpQg151NsaL_KfXx_V0slY9aRCF7kXJnf5g,244
155
- bluer_ugv/swallow/session/classical/session.py,sha256=lHchI7OB9S65K5QGvqPYfFu90q3SN8eNlXZiXSdcvVI,5444
166
+ bluer_ugv/swallow/session/classical/session.py,sha256=n3Q9G3Qdbw8Cb12yaEj5HLfuyJm70kZi_DVJqxItD8E,5532
156
167
  bluer_ugv/swallow/session/classical/camera/__init__.py,sha256=KOehn6qHKj3EMbV5uGXKIfN_v4D5-E2xH9aCWqbNlAI,375
157
168
  bluer_ugv/swallow/session/classical/camera/generic.py,sha256=xmztClNYkosYo2TcIS2Ax4Bessc8lx4hlt9LnMcobfU,1216
158
169
  bluer_ugv/swallow/session/classical/camera/navigation.py,sha256=HoeTlifGEfnedb6o8P-O0TcP1bNDRJ0M7vWupQh1pL4,6790
@@ -169,6 +180,13 @@ bluer_ugv/swallow/session/classical/motor/left.py,sha256=eKyEI8CqQiUTTmpNlJrXro9
169
180
  bluer_ugv/swallow/session/classical/motor/rear.py,sha256=mIBpUxBeiw1me5WY3jbtMyaG8SzyCA1_SzUu6ywdy50,539
170
181
  bluer_ugv/swallow/session/classical/motor/right.py,sha256=3BwCXA6VxxyRBG3rsnRXGviS5gIda14UCqaELGMOJNk,539
171
182
  bluer_ugv/swallow/session/classical/motor/steering.py,sha256=-_-6C9cGYFgt_WH3hwTSV8jL5I_qkxc2O45Ck8SlFCo,545
183
+ bluer_ugv/swallow/session/classical/screen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
184
+ bluer_ugv/swallow/session/classical/screen/classes.py,sha256=5lS7vtDk2YeEPEd6ywowgiPgE2iYz9WIWoyBsCcUbGM,1156
185
+ bluer_ugv/swallow/session/classical/screen/video/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
186
+ bluer_ugv/swallow/session/classical/screen/video/__main__.py,sha256=2uyKoxnZ9LwYWlEP_KDEyvIrwRL31SjK7I-xvM-eZpI,2190
187
+ bluer_ugv/swallow/session/classical/screen/video/engine.py,sha256=-P_VSdqBjP2KBooMzcc-izWP-GMfl4q07t4Fyc6CQH4,3752
188
+ bluer_ugv/swallow/session/classical/screen/video/player.py,sha256=XLXYVHqseZKKD-CmyW2NXzuGarf91BJGSNP7t1nMJzM,3353
189
+ bluer_ugv/swallow/session/classical/screen/video/playlist.py,sha256=OAqPz_eOlBdWKlYDmqtD3FaO9duAbA94kr02jSbSFIo,2934
172
190
  bluer_ugv/swallow/session/classical/setpoint/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
173
191
  bluer_ugv/swallow/session/classical/setpoint/classes.py,sha256=a2ACbE4oEdguuOjtrP2bIyuEpl97TK_JCTGir05KZkg,5054
174
192
  bluer_ugv/swallow/session/classical/setpoint/steering.py,sha256=yuhW3u9YgZ756h4wyMWJYW9914d8oYRKLga67rTW-Tw,288
@@ -178,13 +196,13 @@ bluer_ugv/swallow/session/classical/ultrasonic_sensor/classes.py,sha256=glWK3p5l
178
196
  bluer_ugv/swallow/session/classical/ultrasonic_sensor/consts.py,sha256=eP5Kb6aGqOAcOBBlhGvSWbUL_hKJZ8w5ggwkndzKBqo,227
179
197
  bluer_ugv/swallow/session/classical/ultrasonic_sensor/detection.py,sha256=v_yCBzg4uvnra4Yy_M3Ngaab80PBEbkp2SHfaWfXgb8,3720
180
198
  bluer_ugv/swallow/session/classical/ultrasonic_sensor/detection_list.py,sha256=V4ChFybBrWdrjEGZyQ8z4dXEpzpYzJXdOGf-omvES8I,1268
181
- bluer_ugv/swallow/session/classical/ultrasonic_sensor/log.py,sha256=pitEgK3Fh7EYpotoq_Ek35w_xuBnunhozUSUSahmONU,10276
199
+ bluer_ugv/swallow/session/classical/ultrasonic_sensor/log.py,sha256=jqDVuYjWzyK-5n71fNmMCxURst0CyrhzjnLhEsWtnps,10317
182
200
  bluer_ugv/swallow/session/classical/ultrasonic_sensor/pack.py,sha256=bVcG8V0P6SlJz18za6OvVEPrkdsiR_78CGiAxrpcPQ4,1575
183
201
  bluer_ugv/swallow/session/classical/ultrasonic_sensor/review.py,sha256=_iQmec2VSq-ORkTVpXSNJg08hrSz2M1O8LzNZEtoT9U,959
184
202
  bluer_ugv/swallow/session/classical/ultrasonic_sensor/sensor.py,sha256=En-J8BRTiR8k9p2CBbW0cOUuw8nctD5DOXDm5uhCNO4,3987
185
203
  bluer_ugv/swallow/session/classical/ultrasonic_sensor/testing.py,sha256=yj2MY_Jo1FzeXnR_JoFAXsb9eHEVhicDiHEsUa8z03U,1525
186
- bluer_ugv-7.359.1.dist-info/licenses/LICENSE,sha256=ogEPNDSH0_dhiv_lT3ifVIdgIzHAqNA_SemnxUfPBJk,7048
187
- bluer_ugv-7.359.1.dist-info/METADATA,sha256=inKzOSENCNzh94pLL44tfprSakkIWG5DGP6Fk2T29ho,5573
188
- bluer_ugv-7.359.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
189
- bluer_ugv-7.359.1.dist-info/top_level.txt,sha256=_MlDhFvIPpher9Zs7xyJTHgO2xJJTbfR1dzncz3LQnk,10
190
- bluer_ugv-7.359.1.dist-info/RECORD,,
204
+ bluer_ugv-7.421.1.dist-info/licenses/LICENSE,sha256=ogEPNDSH0_dhiv_lT3ifVIdgIzHAqNA_SemnxUfPBJk,7048
205
+ bluer_ugv-7.421.1.dist-info/METADATA,sha256=b7ArtoEVxiPg1HUjUiM_x6lYaWtqzQOa8ZCmI7Bw4ac,5573
206
+ bluer_ugv-7.421.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
207
+ bluer_ugv-7.421.1.dist-info/top_level.txt,sha256=_MlDhFvIPpher9Zs7xyJTHgO2xJJTbfR1dzncz3LQnk,10
208
+ bluer_ugv-7.421.1.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- from bluer_options.host.functions import is_headless
2
-
3
- from bluer_ugv.logger import logger
4
-
5
-
6
- class ClassicalScreen:
7
- def __init__(self):
8
- if is_headless():
9
- return
10
-
11
- logger.info(f"{self.__class__.__name__} created.")