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.
- bluer_ugv/.abcli/swallow/dataset.sh +1 -1
- bluer_ugv/.abcli/swallow/video/play.sh +7 -0
- bluer_ugv/.abcli/swallow/video/playlist/cat.sh +14 -0
- bluer_ugv/.abcli/swallow/video/playlist/download.sh +18 -0
- bluer_ugv/.abcli/swallow/video/playlist/edit.sh +14 -0
- bluer_ugv/.abcli/swallow/video/playlist/upload.sh +9 -0
- bluer_ugv/.abcli/swallow/video/playlist.sh +15 -0
- bluer_ugv/.abcli/swallow/video.sh +15 -0
- bluer_ugv/.abcli/swallow.sh +1 -1
- bluer_ugv/.abcli/tests/help.sh +8 -0
- bluer_ugv/.abcli/tests/swallow_video_play.sh +11 -0
- bluer_ugv/.abcli/tests/swallow_video_playlist.sh +45 -0
- bluer_ugv/__init__.py +1 -1
- bluer_ugv/config.env +3 -1
- bluer_ugv/env.py +2 -0
- bluer_ugv/help/swallow/__init__.py +2 -0
- bluer_ugv/help/swallow/video/__init__.py +0 -0
- bluer_ugv/help/swallow/video/functions.py +41 -0
- bluer_ugv/help/swallow/video/playlist.py +89 -0
- bluer_ugv/swallow/session/classical/screen/__init__.py +0 -0
- bluer_ugv/swallow/session/classical/screen/classes.py +42 -0
- bluer_ugv/swallow/session/classical/screen/video/__init__.py +0 -0
- bluer_ugv/swallow/session/classical/screen/video/__main__.py +99 -0
- bluer_ugv/swallow/session/classical/screen/video/engine.py +125 -0
- bluer_ugv/swallow/session/classical/screen/video/player.py +117 -0
- bluer_ugv/swallow/session/classical/screen/video/playlist.py +116 -0
- bluer_ugv/swallow/session/classical/session.py +11 -7
- bluer_ugv/swallow/session/classical/ultrasonic_sensor/log.py +3 -0
- {bluer_ugv-7.359.1.dist-info → bluer_ugv-7.421.1.dist-info}/METADATA +2 -2
- {bluer_ugv-7.359.1.dist-info → bluer_ugv-7.421.1.dist-info}/RECORD +33 -15
- bluer_ugv/swallow/session/classical/screen.py +0 -11
- {bluer_ugv-7.359.1.dist-info → bluer_ugv-7.421.1.dist-info}/WHEEL +0 -0
- {bluer_ugv-7.359.1.dist-info → bluer_ugv-7.421.1.dist-info}/licenses/LICENSE +0 -0
- {bluer_ugv-7.359.1.dist-info → bluer_ugv-7.421.1.dist-info}/top_level.txt +0 -0
|
@@ -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,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
|
bluer_ugv/.abcli/swallow.sh
CHANGED
bluer_ugv/.abcli/tests/help.sh
CHANGED
|
@@ -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,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
bluer_ugv/config.env
CHANGED
bluer_ugv/env.py
CHANGED
|
@@ -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
|
+
)
|
|
File without changes
|
|
@@ -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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bluer_ugv
|
|
3
|
-
Version: 7.
|
|
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
|
[](https://github.com/kamangir/bluer-ugv/actions/workflows/pylint.yml) [](https://github.com/kamangir/bluer-ugv/actions/workflows/pytest.yml) [](https://github.com/kamangir/bluer-ugv/actions/workflows/bashtest.yml) [](https://pypi.org/project/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.
|
|
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=
|
|
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=
|
|
4
|
-
bluer_ugv/env.py,sha256=
|
|
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=
|
|
15
|
-
bluer_ugv/.abcli/swallow/dataset.sh,sha256=
|
|
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=
|
|
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=
|
|
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/
|
|
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=
|
|
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.
|
|
187
|
-
bluer_ugv-7.
|
|
188
|
-
bluer_ugv-7.
|
|
189
|
-
bluer_ugv-7.
|
|
190
|
-
bluer_ugv-7.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|