├── .gitignore
├── LICENSE.md
├── LICENSE_THIRD_PARTY.md
├── README.md
├── README_ja.md
├── bin
└── data
│ ├── camera
│ ├── example
│ │ ├── GV-USB2_iPad.xml
│ │ ├── GV-USB2_iPhone.xml
│ │ ├── HD.xml
│ │ └── VGA.xml
│ └── fpv.xml
│ ├── pilots
│ ├── pilots.xml
│ ├── sample pilot.png
│ └── フジヤマFPV.png
│ ├── results
│ └── .gitkeep
│ └── system
│ ├── GenShinGothic-Monospace-Bold.ttf
│ ├── GenShinGothic-P-Bold.ttf
│ ├── background.png
│ ├── beep.wav
│ ├── beep3.wav
│ ├── button_fullscreen.png
│ ├── button_quit.png
│ ├── button_settings.png
│ ├── button_window.png
│ ├── cancel.wav
│ ├── count.wav
│ ├── finish.wav
│ ├── logo_large.png
│ ├── logo_small.png
│ ├── marker.xml
│ ├── notify.wav
│ └── pilot_icon.png
├── docs
├── HowToBuild.md
├── HowToBuild_en.md
├── OSCAPI.md
├── OSCAPI_en.md
├── gate
│ ├── MainGate_TypeA.pdf
│ ├── MainGate_TypeA.svg
│ ├── MainGate_TypeA_A4.pdf
│ ├── MainGate_TypeA_A4.svg
│ ├── MainGate_TypeB.pdf
│ ├── MainGate_TypeB.svg
│ ├── MainGate_TypeC.pdf
│ ├── MainGate_TypeC.svg
│ ├── MainGate_TypeC_A3.pdf
│ ├── MainGate_TypeC_A3.svg
│ └── bakcup
│ │ ├── MainGate_TypeA.pdf
│ │ ├── MainGate_TypeA.svg
│ │ ├── MainGate_TypeD.pdf
│ │ ├── MainGate_TypeD.svg
│ │ └── Marker_Main_0.svg
└── img
│ ├── argate_multi.png
│ ├── argate_single.png
│ ├── button_fullscreen.png
│ ├── button_quit.png
│ ├── button_settings.png
│ ├── button_window.png
│ ├── install_mac.png
│ ├── marker_00_main_a.png
│ ├── marker_01_main_b.png
│ ├── marker_02_main_c.png
│ ├── marker_03_main_d.png
│ ├── overview.jpg
│ ├── qr_betaflight.png
│ └── qr_screen.png
├── of.entitlements
├── src
├── main.cpp
├── ofApp.cpp
└── ofApp.h
└── test
├── .gitignore
├── osc_debug.js
├── osc_debug_lap.js
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | #.gitignore is a file which makes git ignore files which should
2 | # not go into version control in the first place
3 | # Questions? See
4 | # http://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository#Ignoring-Files
5 | # http://git-scm.com/docs/gitignore
6 |
7 | ###########################
8 | # ignore generated binaries
9 | # but not the data folder
10 | ###########################
11 |
12 | /bin/*
13 | !/bin/data/
14 |
15 | #########
16 | # general
17 | #########
18 |
19 | [Bb]uild/
20 | [Oo]bj/
21 | *.o
22 | [Dd]ebug*/
23 | [Rr]elease*/
24 | *.mode*
25 | *.app/
26 | *.pyc
27 | .svn/
28 | *.log
29 |
30 | ########################
31 | # IDE files which should
32 | # be ignored
33 | ########################
34 |
35 | # XCode
36 | *.pbxuser
37 | *.perspective
38 | *.perspectivev3
39 | *.mode1v3
40 | *.mode2v3
41 | # XCode 4
42 | *.xccheckout
43 | xcuserdata/
44 |
45 | # Visual Studio
46 | *.sdf
47 | *.opensdf
48 | *.suo
49 | *.pdb
50 | *.ilk
51 | *.aps
52 | ipch/
53 |
54 | # Eclipse
55 | .metadata
56 | local.properties
57 | .externalToolBuilders
58 |
59 | # Android Studio
60 | .gradle
61 | /local.properties
62 | /.idea/workspace.xml
63 | /.idea/libraries
64 |
65 | ##################
66 | # operating system
67 | ##################
68 |
69 | # Linux
70 | *~
71 | # KDE
72 | .directory
73 | .AppleDouble
74 |
75 | # OSX
76 | .DS_Store
77 | *.swp
78 | *~.nib
79 | # Thumbnails
80 | ._*
81 |
82 | # Windows
83 | # Image file caches
84 | Thumbs.db
85 | # Folder config file
86 | Desktop.ini
87 |
88 | # Android
89 | .csettings
90 |
91 | ################
92 | # TVP additional
93 | ################
94 |
95 | Makefile
96 | Project.xcconfig
97 | addons.make
98 | config.make
99 | openFrameworks-Info.plist
100 | tinyviewplus.xcodeproj/
101 | bin/data/results/*
102 | !.gitkeep
103 | .vs/
104 | icon.rc
105 | *.db
106 | *.sln
107 | *vcxproj*
108 | addons/
109 | bin/data/settings.xml
110 | package-lock.json
111 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # License
2 |
3 | Tiny View Plus is distributed under the MIT License. This gives everyone the freedoms to use Tiny View Plus in any context: commercial or non-commercial, public or private, open or closed source.
4 |
5 | ---
6 |
7 | Copyright (c) 2018 t-asano
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining a copy
10 | of this software and associated documentation files (the "Software"), to deal
11 | in the Software without restriction, including without limitation the rights
12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | copies of the Software, and to permit persons to whom the Software is
14 | furnished to do so, subject to the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included in all
17 | copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | SOFTWARE.
26 |
--------------------------------------------------------------------------------
/LICENSE_THIRD_PARTY.md:
--------------------------------------------------------------------------------
1 | # Third Party Licenses
2 |
3 | ## openFrameworks
4 |
5 | [http://openframeworks.cc/about/license/](http://openframeworks.cc/about/license/)
6 |
7 | ## ofxTrueTypeFontUC
8 |
9 | [https://github.com/kr15h/ofxTrueTypeFontUC](https://github.com/kr15h/ofxTrueTypeFontUC)
10 |
11 | ## Gen Shin Gothic
12 |
13 | [http://jikasei.me/font/genshin](http://jikasei.me/font/genshin)
14 |
15 | ## ofxAruco
16 |
17 | [https://github.com/chparsons/ofxAruco](https://github.com/chparsons/ofxAruco)
18 |
19 | ## ofxCv
20 |
21 | [https://github.com/kylemcdonald/ofxCv](https://github.com/kylemcdonald/ofxCv)
22 |
23 | ## ofxZxing
24 |
25 | [https://github.com/Iwanaka/ofxZxing](https://github.com/Iwanaka/ofxZxing)
26 |
27 | ## ofxJoystick
28 |
29 | [https://github.com/Lacty/ofxJoystick](https://github.com/Lacty/ofxJoystick)
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Tiny View Plus
2 |
3 | 日本語版ドキュメントは[こちら](./README_ja.md)。
4 |
5 | Tiny View Plus is a FPV multi-view and lap timing system. It works on PC with UVC compatible FPV receivers. Up to 4 receivers(\*) can be connected.
6 |
7 | 
8 |
9 | **(\*)On Windows, please connect only one receiver to each USB port built in PC.**
10 |
11 | ## Environment
12 |
13 |
14 |
15 | OS macOS (15 Sequoia is recommended) Windows (11 is recommended)
16 |
17 |
18 | FPV Receiver Eachine ROTG02 Eachine ROTG01 Pro Eachine ROTG01
19 |
20 |
21 |
22 | ## Install
23 |
24 | Attention: We are not responsible for any problems caused by running the application.
25 |
26 | If you want to build from source code, please refer to [this document](docs/HowToBuild_en.md).
27 |
28 | ### macOS
29 |
30 | 1. Download a zip file from [Release page](https://github.com/t-asano/tinyviewplus/releases).
31 | 2. Remove extended file attribute from zip file.
32 | - Run following command on the "Terminal" app.
33 | - ```xattr -c ~/Downloads/tinyviewplus_*_macos64bit.zip```
34 | 3. Extract zip file.
35 | 4. Place app file in the "Application" folder.
36 | 
37 | - If you place it anywhere else, file write functions will not work.
38 |
39 | ### Windows
40 |
41 | 1. Download a zip file from [Release page](https://github.com/t-asano/tinyviewplus/releases).
42 | 2. Extract it and place its contents in the proper place.
43 | 3. Install [Microsoft Visual C++ Redistributable for Visual Studio(vc_redist.x64.exe)](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads).
44 |
45 | ## Usage
46 |
47 | ### Launch
48 |
49 | 1. Connect receivers(Up to 4) to computer.
50 | 2. Launch application.
51 |
52 | ### Detection of receivers
53 |
54 | If receivers are not successfully detected, please try following operation.
55 |
56 | 1. Remove all receivers.
57 | 2. If using a USB hub, reconnect it or remove it.
58 | 3. Connect receivers one by one at intervals of several seconds.
59 |
60 | On macOS, if you are using a USB hub and the picture drops, please reduce the number of receivers per USB hub.
61 |
62 | On Windows, if multiple receivers are connected to same USB hub, only one of them may operate.
63 |
64 | ### Keyboard operations
65 |
66 | #### System
67 |
68 | | key | Function | Default value |
69 | | --- | -------------------------------------- | --------------------- |
70 | | N | Set speech language (Japanese/English) | Same as system locale |
71 | | S | Set system statistics (On/Off) | Off |
72 | | H | Display "Settings/Commands" | - |
73 | | I | Initialize settings | - |
74 |
75 | #### Display
76 |
77 | | key | Function | Default value |
78 | | ------------- | ---------------------------------------------------- | -------------- |
79 | | F,Esc | Set fullscreen mode (On/Off) | Off |
80 | | B | Set background image (\*1) | Built-in image |
81 | | T | Set camera view trimming (On/Off) (\*2) | Off |
82 | | E | Set camera frame visibility (On/Off) | Off |
83 | | 1~4 | Set camera 1~4 enhanced view (On/Off) | Off |
84 | | command + 1~4 | Set camera 1~4 visibility (On/Off) [macOS] | On |
85 | | Alt + 1~4 | Set camera 1~4 visibility (On/Off) [Windows] | On |
86 | | L | Set lap history view mode (Off/Inside/Outside) (\*3) | Off |
87 | | Q | Start/Stop QR Code reader for camera label (\*4) | - |
88 |
89 | - (\*1) The background image will be scaled according to the screen. Upper left corner will be displayed in priority.
90 | - (\*2) Camera image will be cropped and displayed as large as possible, when 1 or 3 cameras are connected.
91 | - (\*3) "Outside" will be effective, when 3 cameras are connected.
92 | - (\*4) Sets the characters scanned from the QR Code to the camera label.
93 |
94 | #### Race
95 |
96 | | key | Function | Default value |
97 | | -------------------- | -------------------------------------------------------- | ---------------------- |
98 | | A | Set AR lap timer mode (Normal/Loose/Off) (\*1) | Normal |
99 | | Left/Right,Up/Down,D | Set race duration time (0\~36,000s) and laps (1\~10,000) | 0s (No limit), 10 laps |
100 | | W | Set wait for lap after time limit (On/Off) | Off |
101 | | PgUp/PgDown | Set minimum lap time (1~100s) | 3s |
102 | | G | Set staggered start (On/Off) (\*2) | Off |
103 | | Space | Start/Stop race | - |
104 | | 5~8,Z,/ | Add lap at camera 1~4,1,3 (manual measurement) | - |
105 | | command + 5~8,Z,/ | Delete previos lap at camera 1~4,1,3 [macOS] | - |
106 | | Alt + 5~8,Z,/ | Delete previos lap at camera 1~4,1,3 [Windows] | - |
107 | | R | Display race result (\*3) | - |
108 | | C | Clear race result | - |
109 |
110 | - (\*1) In loose mode, lap time will be measured even if the drone passes outside the gate.
111 | - (\*2) Time measurement starts after passing the first gate.
112 | - (\*3) Race results will be saved under predefined folder when race finish.
113 | - macOS binary: Tiny View Plus.app/Contents/ Resources/data/pilots
114 | - others: data/pilots
115 |
116 | #### Attention
117 |
118 | - When you exit the application, system/race settings will be saved.
119 | - When you exit the application, some display settings will be saved.
120 | - Camera audio is not supported.
121 |
122 | ### Mouse operations
123 |
124 | Some functions can be operated with mouse.
125 |
126 | | Operation | Function |
127 | | ---------------------------------------------------------- | --------------------------- |
128 | | Click camera 1~4 icon | Change icon (\*1) |
129 | | Click camera 1~4 label | Change label (\*2) |
130 | | Click  button | Display "Settings/Commands" |
131 | | Click  button | Set fullscreen mode to On |
132 | | Click  button | Set fullscreen mode to Off |
133 | | Click  button | Quit application |
134 |
135 | - (\*1) Camera label will be automatically changed according to changing camera icon.
136 | - The file name of the icon (excluding the extension) will be adopted.
137 | - (\*2) Camera icon will be automatically changed according to changing camera label.
138 | - If {label string}.jpg/png/bmp was found under predefined folder, it will be adopted as an icon image in this priority order.
139 | - macOS binary: Tiny View Plus.app/Contents/ Resources/data/pilots
140 | - others: data/pilots
141 | - If no image file is found, the default icon will be adopted.
142 | - The aspect ratio is forced to 1:1.
143 |
144 | ### Gamepad operations
145 |
146 | Some functions can also be operated with gamepad. Up to 4 gamepads can be used simultaneously.
147 |
148 | | Button | Function |
149 | | ------- | ------------------------------------------ |
150 | | 1~4 | Add lap at camera 1~4 (manual measurement) |
151 | | 5 + 1~4 | Delete previos lap at camera 1~4 |
152 |
153 | ### QR Code for label setting
154 |
155 | You can set the camera label by the QR Code.
156 |
157 | 
158 |
159 | You can use Google Charts API to create QR Code. An example of URL is as follows.
160 |
161 | [https://chart.apis.google.com/chart?cht=qr&chs=500x500&chl=TinyViewPlus](https://chart.apis.google.com/chart?cht=qr&chs=500x500&chl=TinyViewPlus)
162 |
163 | It is convenient to embed the QR Code in the OSD. An example of an image for the Betaflight is as follows.
164 |
165 | 
166 |
167 | \* "QR Code" is a registered trademark of DENSO WAVE INCORPORATED.
168 |
169 | ### AR lap timer
170 |
171 | You can measure the lap time by using AR marker.
172 |
173 | 
174 | 
175 |
176 | Please place 8 or more markers around the gate. Also make sure that the top of the marker faces the center of the gate. Following four types of markers are supported. It does not matter if only one type is placed as shown above.
177 |
178 | - [marker_00_main_a.png](docs/img/marker_00_main_a.png)
179 | - [marker_01_main_b.png](docs/img/marker_01_main_b.png)
180 | - [marker_02_main_c.png](docs/img/marker_02_main_c.png)
181 | - [marker_03_main_d.png](docs/img/marker_03_main_d.png)
182 |
183 | The size of the marker should be 120-150mm per side. Larger marker will be suitable for higher speed range. If marker recognition is not successful, please try increasing the size of the marker or placing them in a brighter place.
184 |
185 | Following are gate design prototypes.
186 |
187 | - Normal gate : [Whole (A0)](docs/gate/MainGate_TypeA.pdf) [Part (A4)](docs/gate/MainGate_TypeA_A4.pdf)
188 | - Gate for high speed : [Whore (A0)](docs/gate/MainGate_TypeC.pdf) [Part (A3)](docs/gate/MainGate_TypeC_A3.pdf)
189 | - [Others](docs/gate)
190 |
191 | Lap time will be measured only during the race. After detecting two or more correctly oriented markers simultaneously, when the marker disappears from the screen, lap time will be confirmed. However, if the direction of the last displayed marker is incorrect, the measurement will be canceled.
192 |
193 | Depending on the environment, recognition processing of markers might be heavy. In that case, please disable the function.
194 |
195 | ### Combination of automatic and manual measurement
196 |
197 | When automatic and manual measurement are used together, the one with earlier timing will be adopted and recorded. The one with later timing will be rejected and not be recorded.
198 |
199 | However, if the interval between the two is equal to or greater than the minimum lap time setting, it will be considered as individual laps, both will be adopted and will be recorded.
200 |
201 | ## OSC API
202 |
203 | Tiny View Plus can be controlled and monitored by OSC protocol. Detailed information is [here](docs/OSCAPI_en.md).
204 |
205 | ## License
206 |
207 | Tiny View Plus is distributed under the MIT License. This gives everyone the freedoms to use Tiny View Plus in any context: commercial or non-commercial, public or private, open or closed source. Please see [LICENSE.md](LICENSE.md) and [LICENSE\_THIRD\_PARTY.md](LICENSE_THIRD_PARTY.md) for details.
--------------------------------------------------------------------------------
/README_ja.md:
--------------------------------------------------------------------------------
1 | # Tiny View Plus
2 |
3 | The English version is [here](./README.md).
4 |
5 | Tiny View Plusはラップ計測に対応したFPVマルチビューアーです。UVC対応のFPV受信機をPCに接続して使用します。受信機は4台まで(※)接続できます。
6 |
7 | 
8 |
9 | **(※)Windowsの場合、USBハブに複数の受信機を接続すると正しく動作しないことがあります。USBポート1つにつき、受信機1台のみを接続してください。ただし、PC内部でハブが接続されている場合もあり、その場合には正しく動作しません。**
10 |
11 | ## 動作環境
12 |
13 |
14 |
15 | OS macOS (15 Sequoia推奨) Windows (11推奨)
16 |
17 |
18 | 受信機 Eachine ROTG02 Eachine ROTG01 Pro Eachine ROTG01
19 |
20 |
21 |
22 | 冒頭の写真の例では、USBハブ(C-A)とUSBケーブル(A-microB)を別途用意しています。この場合、ROTG付属のUSBケーブル(OTG用microB-microB)は使用しません。
23 |
24 | ## インストール
25 |
26 | バイナリの作成にあたっては細心の注意を払っていますが、アプリを実行することで起こる不具合については、一切責任を負いません。
27 |
28 | ソースコードからビルドする場合は、[こちらのドキュメント](docs/HowToBuild.md)を参照してください。
29 |
30 | ### macOSの場合
31 |
32 | 1. [リリースページ](https://github.com/t-asano/tinyviewplus/releases)よりzipファイルをダウンロード
33 | 2. zipファイルに付いている拡張属性を削除
34 | - 以下のコマンドをmacOSの「ターミナル」で実行
35 | - ```xattr -c ~/Downloads/tinyviewplus_*_macos64bit.zip```
36 | 3. zipファイルを展開
37 | 4. アプリ本体を「アプリケーション」フォルダの下に配置
38 | 
39 | - 別の場所に配置すると、設定保存機能などが正しく動作しません。
40 |
41 | ### Windowsの場合
42 |
43 | 1. [リリースページ](https://github.com/t-asano/tinyviewplus/releases)よりzipファイルをダウンロード
44 | 2. zipファイルを展開して適当な場所に配置
45 | 3. [Visual Studio 用 Microsoft Visual C++ 再頒布可能パッケージ(vc_redist.x64.exe)](https://support.microsoft.com/ja-jp/help/2977003/the-latest-supported-visual-c-downloads)をインストール
46 |
47 | ## 使い方
48 |
49 | ### 起動
50 |
51 | 1. コンピューターに受信機(4台まで)を接続
52 | 2. アプリ本体をダブルクリックして起動
53 |
54 | ### 受信機の検出
55 |
56 | 受信機がうまく検出されない場合は、以下をお試し下さい。
57 |
58 | 1. 受信機を全て外す
59 | 2. USBハブ使用の場合はそれを接続し直す、または撤去する
60 | 3. 受信機を一台ずつ数秒間隔で接続
61 |
62 | macOSの場合、USBハブを使用していて映像がコマ落ちするようなら、USBハブ1台あたりの受信機の数を2台以下を目安に減らしてください。
63 |
64 | Windowsの場合、USBハブに複数の受信機を接続した場合に、そのうち1台しか動作しないことがあります。この場合、USBハブを経由せずに接続すれば改善するかもしれません。
65 |
66 | ### キーボードによる操作
67 |
68 | #### システム
69 |
70 | | キー | 機能 | 初期値 |
71 | | --- | ------------------- | --------- |
72 | | N | 音声読み上げ言語の設定(日本語/英語) | システム設定に従う |
73 | | S | システム統計の設定(オン/オフ) | オフ |
74 | | H | ヘルプ(設定/コマンド)の表示 | - |
75 | | I | 設定の初期化 | - |
76 |
77 | #### 表示
78 |
79 | | キー | 機能 | 初期値 |
80 | | ------------- | -------------------------------- | -------- |
81 | | F,Esc | フルスクリーン表示の設定(オン/オフ) | オフ |
82 | | B | 背景画像の設定(※1) | アプリ内蔵の画像 |
83 | | T | カメラのトリミングの設定(オン/オフ)(※2) | オフ |
84 | | E | カメラ枠表示の設定(オン/オフ) | オフ |
85 | | 1~4 | カメラ1~4の拡大表示の設定(オン/オフ) | オフ |
86 | | command + 1~4 | カメラ1~4の表示の設定(オン/オフ) [macOS] | オン |
87 | | Alt + 1~4 | カメラ1~4の表示の設定(オン/オフ) [Windows] | オン |
88 | | L | レース中のラップ履歴表示モードの設定(オフ/内側/外側)(※3) | オフ |
89 | | Q | QRコードリーダーの開始/停止(※4) | - |
90 |
91 | - (※1)背景画像は、縦横比を維持したまま画面に合わせて拡大縮小され、左上隅が優先表示されます。
92 | - (※2)カメラが1台または3台の場合に、映像の一部をトリミングして大きく表示します。
93 | - (※3)カメラが3台の場合に「外側」が設定されていると、カメラ映像の外側にラップ履歴が表示されます。
94 | - (※4)QRコードから読み取った文字列を、カメラのラベルに設定します。
95 |
96 | #### レース
97 |
98 | | キー | 機能 | 初期値 |
99 | | -------------------- | -------------------------------------- | ------------ |
100 | | A | ARラップタイマーのモードの設定(ノーマル/ルーズ/オフ)(※1) | オン |
101 | | Left/Right,Up/Down,D | レースの制限時間(0\~36,000秒)、周回数(1\~10,000)の設定 | 0秒(制限なし)、10周 |
102 | | W | 制限時間経過後のラップ計測待ちの設定(オン/オフ) | オフ |
103 | | PgUp/PgDown | 最小ラップタイムの設定(1~100秒) | 3秒 |
104 | | G | 時差スタートの設定(オン/オフ)(※2) | オフ |
105 | | Space | レースの開始/終了 | - |
106 | | 5~8,Z,/ | カメラ1~4,1,3のラップの追加(手動計測) | - |
107 | | command + 5~8,Z,/ | カメラ1~4,1,3の直前ラップの削除 [macOS] | - |
108 | | Alt + 5~8,Z,/ | カメラ1~4,1,3の直前ラップの削除 [Windows] | - |
109 | | R | レースの結果の表示(※3) | - |
110 | | C | レースの結果の消去 | - |
111 |
112 | - (※1)ルーズモードでは、ゲートの外側を通過しても計測対象となります。
113 | - (※2)最初のゲートを通過した後にタイム計測を開始します。
114 | - (※3)レースの結果は、レース終了時に既定フォルダ内へも出力されます。
115 | - macOSバイナリ版: Tiny View Plus.app/Contents/Resources/data/results
116 | - それ以外: data/results
117 |
118 | #### ご注意
119 |
120 | - アプリを終了すると、システムとレースの設定および表示の一部が保存されます。
121 | - カメラの音声は出力されません。
122 |
123 | ### マウスによる操作
124 |
125 | 一部の機能は、マウスで操作できます。
126 |
127 | | 操作 | 機能 |
128 | | ------------------------------------------------------ | --------------- |
129 | | カメラ1~4のアイコンをクリック | アイコンの変更(※1) |
130 | | カメラ1~4のラベルをクリック | ラベルの変更(※2) |
131 | |  ボタンをクリック | ヘルプ(設定/コマンド)の表示 |
132 | |  ボタンをクリック | フルスクリーン表示のオン |
133 | |  ボタンをクリック | フルスクリーン表示のオフ |
134 | |  ボタンをクリック | アプリの終了 |
135 |
136 | - (※1)カメラのアイコンを変更すると、ラベルが自動的に変更されます。
137 | - アイコンのファイル名(拡張子を除く)が採用されます。
138 | - (※2)カメラのラベルを変更すると、アイコンが自動的に変更されます。
139 | - 既定フォルダ内に、ラベル文字列.jpg/png/bmp という画像ファイルが見つかると、この優先順でアイコン画像として採用されます。
140 | - macOSバイナリ版: Tiny View Plus.app/Contents/Resources/data/pilots
141 | - それ以外: data/pilots
142 | - 画像ファイルが見つからない場合は、デフォルトアイコンが採用されます。
143 | - 縦横比は強制的に1:1となります。
144 |
145 | ### ゲームパッドによる操作
146 |
147 | 一部の機能は、ゲームパッドでも操作もできます。ゲームパッドは、最大4台まで同時に利用できます。
148 |
149 | | ボタン | 機能 |
150 | | ------------- | ------------------- |
151 | | ボタン1~4 | カメラ1~4のラップの追加(手動計測) |
152 | | ボタン5 + ボタン1~4 | カメラ1~4の直前ラップの削除 |
153 |
154 | ### QRコードによるラベル設定
155 |
156 | QRコードを使用して、カメラのラベルを設定できます。
157 |
158 | 
159 |
160 | QRコードを作成するには、Google Charts APIが利用できます。以下は、QRコードを作成するためのURLの例です。
161 |
162 | [https://chart.apis.google.com/chart?cht=qr&chs=500x500&chl=TinyViewPlus](https://chart.apis.google.com/chart?cht=qr&chs=500x500&chl=TinyViewPlus)
163 |
164 | QRコードをOSDに組み込んでおくと便利です。以下は、Betaflight用のロゴ画像の例です。
165 |
166 | 
167 |
168 | ※QRコードは(株)デンソーウェーブの登録商標です。
169 |
170 | ### ARマーカーによるラップ計測
171 |
172 | ARマーカーを利用して、ラップタイムを計測できます。
173 |
174 | 
175 | 
176 |
177 | マーカーは8個以上を目安として、ゲートの周囲に配置してください。またその際に、マーカーの上側がゲートの中央を向くようにしてください。以下の4種類のマーカーに対応していますが、上の図のように1種類のみを配置する形でも構いません。
178 |
179 | - [marker_00_main_a.png](docs/img/marker_00_main_a.png)
180 | - [marker_01_main_b.png](docs/img/marker_01_main_b.png)
181 | - [marker_02_main_c.png](docs/img/marker_02_main_c.png)
182 | - [marker_03_main_d.png](docs/img/marker_03_main_d.png)
183 |
184 | マーカーのサイズは1辺120~150mmを目安として、通過スピードに応じて調整してください。ハイスピードレースにおいては、より大きなマーカーが適しています。マーカーの認識がうまくいかない場合は、マーカーを大きくしたり、より明るい場所に設置すると、改善するかもしれません。
185 |
186 | 以下は、試作中のゲートの印刷データです。ご活用ください。
187 |
188 | - 標準ゲート : [全体 (A0)](docs/gate/MainGate_TypeA.pdf) [分割 (A4)](docs/gate/MainGate_TypeA_A4.pdf)
189 | - 高速レース用ゲート : [全体 (A0)](docs/gate/MainGate_TypeC.pdf) [分割 (A3)](docs/gate/MainGate_TypeC_A3.pdf)
190 | - [その他](docs/gate)
191 |
192 | ラップタイムの計測は、レース中にのみ行われます。同時に2個以上の正しい向きのマーカーを検出した後、画面からマーカーが消えたタイミングでラップタイムが確定します。ただし、最後に映っていたマーカーの向きが正しくない(ゲートの外側を通った等の)場合は、計測の対象外となります。
193 |
194 | 環境によっては、マーカーの認識処理が重く、動作に支障があるかもしれません。その場合は、機能を無効化してください。
195 |
196 | ### 自動計測と手動計測の併用
197 |
198 | 自動計測と手動計測を併用した場合、タイミングが早い方が採用され、記録に残ります。タイミングが遅い方は却下され、記録に残りません。ただし、両者の間隔が最小ラップタイム設定値以上であれば、別々のラップとみなされ、両者ともに採用され、記録に残ります。
199 |
200 | ## OSCによる制御
201 |
202 | OSCプロトコルによって、外部からの制御と監視が可能です。詳しくは[こちら](docs/OSCAPI.md)をご覧ください。
203 |
204 | ## ライセンス
205 |
206 | Tiny View Plus is distributed under the MIT License. This gives everyone the freedoms to use Tiny View Plus in any context: commercial or non-commercial, public or private, open or closed source. Please see [LICENSE.md](LICENSE.md) and [LICENSE\_THIRD\_PARTY.md](LICENSE_THIRD_PARTY.md) for details.
--------------------------------------------------------------------------------
/bin/data/camera/example/GV-USB2_iPad.xml:
--------------------------------------------------------------------------------
1 |
2 | GV-USB2
3 | iPad(4:3 in squeezed 16:9)
4 |
5 | 704
6 | 480
7 |
8 |
9 | 82
10 | 0
11 | 540
12 | 480
13 |
14 |
15 | 4:3
16 |
17 |
--------------------------------------------------------------------------------
/bin/data/camera/example/GV-USB2_iPhone.xml:
--------------------------------------------------------------------------------
1 |
2 | GV-USB2
3 | iPhone(16:9 in squeezed 16:9)
4 |
5 | 704
6 | 480
7 |
8 |
9 | 0
10 | 0
11 | 704
12 | 480
13 |
14 |
15 | 16:9
16 |
17 |
--------------------------------------------------------------------------------
/bin/data/camera/example/HD.xml:
--------------------------------------------------------------------------------
1 |
2 | HD Device Name
3 | 16:9
4 |
5 | 1280
6 | 720
7 |
8 |
9 | 0
10 | 0
11 | 1280
12 | 720
13 |
14 |
15 | 16:9
16 |
17 |
--------------------------------------------------------------------------------
/bin/data/camera/example/VGA.xml:
--------------------------------------------------------------------------------
1 |
2 | VGA Device Name
3 | 4:3
4 |
5 | 640
6 | 480
7 |
8 |
9 | 0
10 | 0
11 | 640
12 | 480
13 |
14 |
15 | 4:3
16 |
17 |
--------------------------------------------------------------------------------
/bin/data/camera/fpv.xml:
--------------------------------------------------------------------------------
1 |
2 | GV-USB2
3 | squeezed 16:9
4 |
5 | 704
6 | 480
7 |
8 |
9 | 0
10 | 0
11 | 704
12 | 480
13 |
14 |
15 | 16:9
16 |
17 |
--------------------------------------------------------------------------------
/bin/data/pilots/pilots.xml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/pilots/pilots.xml
--------------------------------------------------------------------------------
/bin/data/pilots/sample pilot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/pilots/sample pilot.png
--------------------------------------------------------------------------------
/bin/data/pilots/フジヤマFPV.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/pilots/フジヤマFPV.png
--------------------------------------------------------------------------------
/bin/data/results/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/results/.gitkeep
--------------------------------------------------------------------------------
/bin/data/system/GenShinGothic-Monospace-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/GenShinGothic-Monospace-Bold.ttf
--------------------------------------------------------------------------------
/bin/data/system/GenShinGothic-P-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/GenShinGothic-P-Bold.ttf
--------------------------------------------------------------------------------
/bin/data/system/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/background.png
--------------------------------------------------------------------------------
/bin/data/system/beep.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/beep.wav
--------------------------------------------------------------------------------
/bin/data/system/beep3.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/beep3.wav
--------------------------------------------------------------------------------
/bin/data/system/button_fullscreen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/button_fullscreen.png
--------------------------------------------------------------------------------
/bin/data/system/button_quit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/button_quit.png
--------------------------------------------------------------------------------
/bin/data/system/button_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/button_settings.png
--------------------------------------------------------------------------------
/bin/data/system/button_window.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/button_window.png
--------------------------------------------------------------------------------
/bin/data/system/cancel.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/cancel.wav
--------------------------------------------------------------------------------
/bin/data/system/count.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/count.wav
--------------------------------------------------------------------------------
/bin/data/system/finish.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/finish.wav
--------------------------------------------------------------------------------
/bin/data/system/logo_large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/logo_large.png
--------------------------------------------------------------------------------
/bin/data/system/logo_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/logo_small.png
--------------------------------------------------------------------------------
/bin/data/system/marker.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4
4 | 4
5 | 4
6 | "1011010100110010"
7 | "0000111110011010"
8 | "0011001100101101"
9 | "1001100101000110"
10 |
11 |
--------------------------------------------------------------------------------
/bin/data/system/notify.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/notify.wav
--------------------------------------------------------------------------------
/bin/data/system/pilot_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/bin/data/system/pilot_icon.png
--------------------------------------------------------------------------------
/docs/HowToBuild.md:
--------------------------------------------------------------------------------
1 | # Tiny View Plusのビルド
2 |
3 | ## 開発環境のセットアップ
4 |
5 | ### macOSの場合
6 |
7 | 1. Xcode 16をインストールする
8 | 2. openFrameworks 0.12.0をインストールする
9 | - [openFrameworks for osx (zipファイル)](https://openframeworks.cc/download/)をダウンロードする
10 | - 拡張属性を取り除く
11 | - $ xattr -cr of\_\*\_osx_release.zip
12 | - 適当な場所に展開する
13 |
14 | ### Windowsの場合
15 |
16 | 1. Visual Studioをインストールする
17 | - [こちらのドキュメント](https://openframeworks.cc/setup/vs/)を参考とする
18 | - 「openFrameworks plugin for Visual Studio」は実施しない
19 | 2. openFrameworks 0.11.2をインストールする
20 | - [openFrameworks for visual studio (zipファイル)](https://openframeworks.cc/download/)をダウンロードする
21 | - 適当な場所に展開する
22 | 3. [Git for Windows](https://gitforwindows.org)をインストールする
23 | - これに含まれるGit Bashを使って、GitHubからのファイルの取得や、ローカルでのファイル操作を行うことになる
24 |
25 | ## プロジェクトの作成
26 |
27 | 1. 必要なアドオンをインストールしておく
28 |
29 | ```bash
30 | $ cd addons/
31 | $ git clone -b fix-of_v0.10 https://github.com/t-asano/ofxTrueTypeFontUC.git
32 | $ git clone https://github.com/t-asano/ofxAruco.git
33 | $ git clone https://github.com/kylemcdonald/ofxCv.git
34 | $ git clone https://github.com/t-asano/ofxZxing.git
35 | $ git clone https://github.com/t-asano/ofxJoystick.git
36 | ```
37 |
38 | 2. プロジェクトジェネレーターで、以下のアドオンを含むプロジェクトを作成する。プロジェクト名は「tinyviewplus」とする。
39 |
40 | - ofxOsc
41 | - ofxTrueTypeFontUC
42 | - ofxAruco
43 | - ofxCv
44 | - ofxOpenCv
45 | - ofxPoco
46 | - ofxZxing
47 | - ofxJoystick
48 | - ofxXmlSettings
49 |
50 | 3. 作成したプロジェクトに、Tiny View Plusのファイル一式をマージする
51 |
52 | ```bash
53 | $ cd apps/myApps
54 | $ mv tinyviewplus tvptemp
55 | $ git clone https://github.com/t-asano/tinyviewplus.git
56 | $ cp tvptemp/* tinyviewplus/
57 | $ cp -r tvptemp/*.xcodeproj tinyviewplus/ # macOSの場合のみ
58 | $ rm -r tvptemp
59 | ```
60 |
61 | ## ビルドの設定
62 |
63 | ### macOSの場合
64 |
65 | 1. プロジェクトファイル(tinyviewplus.xcodeproj)をXcodeで開く
66 |
67 | ### Windowsの場合
68 |
69 | 1. ソリューションファイル(tinyviewplus.sln)をVisualStudioで開く
70 |
71 | 2. ソースファイルの文字コードを固定する
72 |
73 | - tinyviewplusプロジェクトのプロパティを開く
74 | - [構成プロパティ] -> [C/C++] -> [コマンドライン] と進む
75 | - 「全ての構成」「すべてのプラットフォーム」に対して、「追加のオプション」として「/source-charset:utf-8」を追加する
76 |
77 | 3. アプリ起動時にコンソールが表示されるのを避ける
78 |
79 | - tinyviewplusプロジェクトのプロパティを開く
80 | - [構成プロパティ] -> [リンカ] -> [システム] と進む
81 | - 「全ての構成」「すべてのプラットフォーム」に対して、「サブシステム」として「Windows (/SUBSYSTEM:WINDOWS)」を指定する
82 | - [構成プロパティ] -> [リンカ] -> [詳細設定] と進む
83 | - 「全ての構成」「すべてのプラットフォーム」に対して、「エントリポイント」として「mainCRTStartup」を指定する
84 |
85 | 4. 文字化けを防ぐ
86 |
87 | - openFrameworks の ofSystemUtils.cpp を改造する
88 |
89 | ```cpp
90 | static void narrow(const std::wstring &src, std::string &dest) {
91 | setlocale(LC_CTYPE, "");
92 | char *mbs = new char[src.length() * MB_CUR_MAX + 1];
93 | wcstombs(mbs, src.c_str(), src.length() * MB_CUR_MAX + 1);
94 | dest = mbs;
95 | delete[] mbs;
96 | }
97 |
98 | std::string convertWideToNarrow( const wchar_t *s, char dfault = '?', const std::locale& loc = std::locale() )
99 | {
100 | #if 0
101 | std::ostringstream stm;
102 | while (*s != L'\0') {
103 | stm << std::use_facet< std::ctype >(loc).narrow(*s++, dfault);
104 | }
105 | return stm.str();
106 | #else
107 | std::wstring wstr(s);
108 | std::string ret;
109 | narrow(wstr, ret);
110 | return ret;
111 | #endif
112 | }
113 | ```
114 |
115 | ## ビルドと起動
116 |
117 | ### macOSの場合
118 |
119 | 1. ビルドターゲットを「tinyviewplus Release」に設定する
120 | 2. [Product] -> [Build] でビルドする
121 | 3. ビルドが成功したら [Product] -> [Run] で起動する
122 |
123 | ### Windowsの場合
124 |
125 | 1. ビルドターゲットを「Release」「x64」に設定する
126 | 2. [ビルド] -> [ソリューションのビルド] でビルドする
127 | 3. ビルドが成功したら [デバッグ] -> [デバッグの開始] で起動する
128 |
129 | ## アップデート
130 |
131 | 1. Tiny View Plusとアドオンを更新する
132 |
133 | ```bash
134 | $ cd apps/myApps/tinyviewplus
135 | $ git pull
136 | $ cd ../../../addons/ADDON_NAME
137 | $ git pull
138 | ```
139 |
140 | 2. アドオンを追加する(必要な場合のみ)
141 |
142 | - Gitコマンドで新規のアドオンを取得する
143 | - プロジェクトジェネレーターでアドオンを追加する
144 |
145 | 以上
--------------------------------------------------------------------------------
/docs/HowToBuild_en.md:
--------------------------------------------------------------------------------
1 | # How to build Tiny View Plus
2 |
3 | The English version is not available yet. The Japanese version is [here](HowToBuild.md).
--------------------------------------------------------------------------------
/docs/OSCAPI.md:
--------------------------------------------------------------------------------
1 | # OSCによるTiny View Plusの制御と監視
2 |
3 | Tiny View Plusは、OSCプロトコルによって、外部からの制御と監視が可能です。
4 |
5 | ## Tiny View Plusの制御(受信側)
6 |
7 | UDP4000番ポートでOSCパケットを受信します。
8 |
9 | ### カメラの拡大表示
10 |
11 | /v1/camera/{id}/solo {switch}
12 |
13 | - パラメーター
14 | - id ... カメラID(1~4)
15 | - switch ... "on" または "off"
16 | - 例: カメラ1を拡大表示する
17 | - /v1/camera/1/solo "on"
18 |
19 | ### カメラの表示/非表示
20 |
21 | /v1/camera/{id}/display {switch}
22 |
23 | - パラメーター
24 | - id ... カメラID(1~4)
25 | - switch ... "on" または "off"
26 | - 例: カメラ1を非表示とする
27 | - /v1/camera/1/display "off"
28 |
29 | ### カメラのラベルの変更
30 |
31 | /v1/camera/{id}/label {label}
32 |
33 | - パラメーター
34 | - id ... カメラID(1~4)
35 | - label ... 任意の文字列(パイロット名など)
36 | - 例: カメラ2のラベルを"Whooper2"とする
37 | - /v1/camera/2/label "Whooper 2"
38 |
39 | ラベルの変更と連動して、アイコンも自動的に変更されます。
40 |
41 | - macOSバイナリの場合は "Tiny View Plus.app/Contents/Resources/data/pilots" フォルダの下、それ以外の場合は "data/pilots" フォルダの下に、{label}.png または {label}.jpg という画像ファイルが見つかると、この優先順でアイコン画像として採用します
42 | - 画像ファイルが見つからない場合は、デフォルトアイコンが採用されます
43 | - 縦横比は強制的に1:1となります
44 |
45 | ### ラップタイムの設定
46 |
47 | /v1/camera/{id}/laptime {time}
48 |
49 | - パラメーター
50 | - id ... カメラID(1~4)
51 | - time ... ラップタイム(秒)
52 | - 例: カメラ3のラップタイムを128秒64とする
53 | - /v1/camera/3/laptime 128.64
54 |
55 | ### ラップの追加と削除
56 |
57 | /v1/camera/{id}/lap {command}
58 |
59 | - パラメーター
60 | - id ... カメラID(1~4)
61 | - command ... "add"(追加)または"del"(削除)
62 | - 例: カメラ3のラップを追加する
63 | - /v1/camera/3/lap "add"
64 |
65 | ### 音声読み上げ
66 |
67 | /v1/speech/{language}/say {text}
68 |
69 | - パラメーター
70 | - language ... "en"(英語)または"jp"(日本語)
71 | - text ... 読み上げ文
72 | - 例: 日本語で"ドローンで遊ぼう"と読み上げる
73 | - /v1/speeech/jp/say "ドローンで遊ぼう"
74 |
75 | ## Tiny View Plusの監視(送信側) ※実験的な機能
76 |
77 | "settings.xml"で指定されたホスト・ポートへOSCパケットを送信します。
78 |
79 | ```xml
80 |
81 | 1
82 | 127.0.0.1
83 | 4001
84 |
85 | ```
86 |
87 | "settings.xml"は初回起動時に自動生成されます。この機能を有効にするには、Tiny View Plusを終了させた状態で、"enabled"に1を設定してください。無効にするには、0を設定してください。
88 |
89 | ### システム情報の通知
90 |
91 | /v1/system/info {info}
92 |
93 | - パラメーター
94 | - info ... システム情報
95 | - 例: "hello"を通知する
96 | - /v1/system/info "hello"
97 |
98 | ### レースイベントの通知
99 |
100 | /v1/race/event {event}
101 |
102 | - パラメーター
103 | - event ... "started"または"finished"
104 | - 例: レースの開始を通知する
105 | - /v1/race/event "started"
106 |
107 | ### カメラのラベルの通知
108 |
109 | /v1/camera/{id}/label {label}
110 |
111 | - パラメーター
112 | - id ... カメラID(1~4)
113 | - label ... カメラのラベル(パイロット名など)
114 | - 例: カメラ2のラベルを通知する
115 | - /v1/camera/2/label "Whooper 2"
116 |
117 | レース開始時およびラベル変更時に通知します。
118 |
119 | ### ラップの通知
120 |
121 | /v1/camera/{id}/lap {lapnum} {laptime} {label}
122 |
123 | - パラメーター
124 | - id ... カメラID(1~4)
125 | - lapnum ... ラップ番号
126 | - laptime ... ラップタイム(秒)
127 | - label ... カメラのラベル(パイロット名など)
128 | - 例: カメラ3のラップを通知する(ラップ5、10.2秒)
129 | - /v1/camera/3/lap 5 10.2 "Whooper 3"
130 |
131 | ### ラップの削除の通知
132 |
133 | /v1/camera/{id}/lapdel {lapnum}
134 |
135 | - パラメーター
136 | - id ... カメラID(1~4)
137 | - lapnum ... ラップ番号
138 | - 例: カメラ3のラップの削除を通知する(ラップ5)
139 | - /v1/camera/3/lapdel 5
140 |
141 | ### レース結果の通知
142 |
143 | /v1/camera/{id}/result {label} {pos} {laps} {bestlap} {totaltime}
144 |
145 | - パラメーター
146 | - id ... カメラID(1~4)
147 | - label ... カメラのラベル(パイロット名など)
148 | - pos ... 順位
149 | - laps ... ラップ数
150 | - bestlap ... ベストラップ(秒)
151 | - totaltime ... 総合タイム(秒)
152 | - 例: カメラ1のレース結果を通知する(1位、10周、5.43秒、62.13秒)
153 | - /v1/camera/1/lap "Whooper 1" 1 10 5.43 62.13
154 |
155 | レース終了時に通知します。
156 |
--------------------------------------------------------------------------------
/docs/OSCAPI_en.md:
--------------------------------------------------------------------------------
1 | # OSC API for Tiny View Plus
2 |
3 | Tiny View Plus can be controlled and monitored by OSC protocol.
4 |
5 | ## Controlling(receiver)
6 |
7 | It receives OSC packet at UDP port 4000.
8 |
9 | ### Set camera enhanced view on / off
10 |
11 | /v1/camera/{id}/solo {switch}
12 |
13 | - Parameters
14 | - id ... Camera ID(1~4)
15 | - switch ... "on" or "off"
16 | - Example: Camera 1 enhanced view on
17 | - /v1/camera/1/solo "on"
18 |
19 | ### Set camera display on / off
20 |
21 | /v1/camera/{id}/display {switch}
22 |
23 | - Parameters
24 | - id ... Camera ID(1~4)
25 | - switch ... "on" or "off"
26 | - Example: Camera 1 off
27 | - /v1/camera/1/display "off"
28 |
29 | ### Set camera label
30 |
31 | /v1/camera/{id}/label {label}
32 |
33 | - Parameters
34 | - id ... Camera ID(1~4)
35 | - label ... Any string (such as pilot name)
36 | - Example: Set the label of camera 2 to "Whooper 2"
37 | - /v1/camera/2/label "Whooper 2"
38 |
39 | Camera icon is also automatically changed in conjunction with the camera label change.
40 |
41 | - If {label string}.png or {label string}.jpg was found under "Tiny View Plus.app / Contents / Presents / data / pilots" folder (on macOS binary), otherwise under the "data / pilots" folder, it is adopted as an icon image in this priority order.
42 | - If no image file is found, the default icon will be adopted.
43 | - The aspect ratio is forced to 1:1.
44 |
45 | ### Set laptime
46 |
47 | /v1/camera/{id}/laptime {time}
48 |
49 | - Parameters
50 | - id ... Camera ID(1~4)
51 | - time ... lap time(seconds)
52 | - Example: Set the lap time of camera 3 to 128.64 seconds
53 | - /v1/camera/3/laptime 128.64
54 |
55 | ### Add/Delete lap
56 |
57 | /v1/camera/{id}/lap {command}
58 |
59 | - Parameters
60 | - id ... Camera ID(1~4)
61 | - command ... "add" or "del"
62 | - Example: Add lap of camera 3
63 | - /v1/camera/3/lap "add"
64 |
65 | ### Speech synthesis
66 |
67 | /v1/speech/{language}/say {text}
68 |
69 | - Parameters
70 | - language ... "en"(English) or "jp"(Japanese)
71 | - text ... sentence to speak
72 | - Example: Say "We can fly!" in English
73 | - /v1/speeech/en/say "We can fly!"
74 |
75 | ## Monitoring(sender) ※experimental
76 |
77 | It sends OSC packet to the host/port specified in "settings.xml".
78 |
79 | ```xml
80 |
81 | 1
82 | 127.0.0.1
83 | 4001
84 |
85 | ```
86 |
87 | Set "enabled" to 1 to enable this feature. Set to 0 to disable.
88 |
89 | ### System information notification
90 |
91 | /v1/system/info {info}
92 |
93 | - Parameters
94 | - info ... System information
95 | - Example: "Hello"
96 | - /v1/system/info "hello"
97 |
98 | ### Race event notifiacation
99 |
100 | /v1/race/event {event}
101 |
102 | - Parameters
103 | - event ... "started" or "finished"
104 | - Example: Race has started
105 | - /v1/race/event "started"
106 |
107 | ### Camera label notification
108 |
109 | /v1/camera/{id}/label {label}
110 |
111 | - Parameters
112 | - id ... Camera ID(1~4)
113 | - label ... Camera label
114 | - Example: Notify the label of camera 2
115 | - /v1/camera/2/label "Whooper 2"
116 |
117 | This works at the start of the race and when changing labels.
118 |
119 | ### Lap notification
120 |
121 | /v1/camera/{id}/lap {lapnum} {laptime} {label}
122 |
123 | - Parameters
124 | - id ... Camera ID(1~4)
125 | - lapnum ... Lap number
126 | - laptime ... Lap time(seconds)
127 | - label ... Camera label
128 | - Example: Notify lap of camera 3(lap 5, 10.2 seconds)
129 | - /v1/camera/3/lap 5 10.2 "Whooper 3"
130 |
131 | ### Lap delete notification
132 |
133 | /v1/camera/{id}/lapdel {lapnum}
134 |
135 | - Parameters
136 | - id ... Camera ID(1~4)
137 | - lapnum ... Lap number
138 | - Example: Notify lap delete of camera 3(lap 5)
139 | - /v1/camera/3/lapdel 5
140 |
141 | ### Race result notification
142 |
143 | /v1/camera/{id}/result {label} {pos} {laps} {bestlap} {totaltime}
144 |
145 | - Parameters
146 | - id ... Camera ID(1~4)
147 | - label ... Camera label
148 | - pos ... Position
149 | - laps ... Laps
150 | - bestlap ... Best lap time(seconds)
151 | - totaltime ... Total time(minutes:seconds)
152 | - Example: Notify race result of camera 1(1st, 10 laps, 5.43 seconds, 62.13 seconds)
153 | - /v1/camera/1/lap "Whooper 1" 1 10 5.43 62.13
154 |
155 | This works at the end of the race.
--------------------------------------------------------------------------------
/docs/gate/MainGate_TypeA.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/gate/MainGate_TypeA.pdf
--------------------------------------------------------------------------------
/docs/gate/MainGate_TypeA.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
23 |
25 |
43 |
45 |
46 |
48 | image/svg+xml
49 |
51 |
52 |
53 |
54 |
55 |
61 |
69 |
75 |
87 |
99 |
111 |
123 |
135 |
147 | Tiny View Plus Main Gate Type A Rev.2 for Middle Speed Outer Circle : Φ700mm Inner Circle : Φ400mm Marker : 120x120mm
194 |
204 |
208 |
215 |
222 |
229 |
235 |
242 |
249 |
256 |
263 |
270 |
277 |
284 |
291 |
292 |
293 |
304 |
315 |
326 |
337 |
348 |
359 |
370 |
381 |
392 |
393 |
398 |
403 |
410 | A4
422 |
425 |
436 |
445 |
454 |
463 |
472 |
473 |
474 |
475 |
--------------------------------------------------------------------------------
/docs/gate/MainGate_TypeA_A4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/gate/MainGate_TypeA_A4.pdf
--------------------------------------------------------------------------------
/docs/gate/MainGate_TypeA_A4.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
22 |
24 |
43 |
45 |
46 |
48 | image/svg+xml
49 |
51 |
52 |
53 |
54 |
55 |
61 |
66 |
71 |
83 |
95 |
107 |
119 |
131 |
143 |
153 |
157 |
164 |
171 |
178 |
184 |
191 |
198 |
205 |
212 |
219 |
226 |
233 |
240 |
241 |
242 |
243 |
249 |
255 |
266 |
273 |
284 | Tiny View Plus - Main - Type A Rev.2
295 | A4 x 10 sheets
306 |
307 |
308 |
--------------------------------------------------------------------------------
/docs/gate/MainGate_TypeB.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/gate/MainGate_TypeB.pdf
--------------------------------------------------------------------------------
/docs/gate/MainGate_TypeB.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
23 |
25 |
43 |
45 |
46 |
48 | image/svg+xml
49 |
51 |
52 |
53 |
54 |
55 |
61 |
73 |
85 |
97 |
109 |
121 |
133 |
141 | Tiny View Plus Main Gate Type B for Low Speed Outer Circle : Φ700mm Inner Circle : Φ450mm Marker : 90x90mm
193 |
201 |
212 |
215 |
222 |
229 |
236 |
242 |
249 |
256 |
263 |
270 |
277 |
284 |
291 |
298 |
299 |
300 |
310 |
321 |
332 |
343 |
354 |
365 |
376 |
387 |
398 |
409 |
420 |
431 |
442 |
453 |
464 |
475 |
476 |
481 |
483 |
484 |
489 |
496 |
499 |
510 |
519 |
528 |
537 |
538 | A4
550 |
551 |
552 |
--------------------------------------------------------------------------------
/docs/gate/MainGate_TypeC.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/gate/MainGate_TypeC.pdf
--------------------------------------------------------------------------------
/docs/gate/MainGate_TypeC.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
20 |
22 |
40 |
42 |
43 |
45 | image/svg+xml
46 |
48 |
49 |
50 |
51 |
52 |
58 |
70 |
82 |
94 |
106 |
118 |
130 |
138 | Tiny View Plus Main Gate Type C for High Speed Outer Circle : Φ800mm Inner Circle : Φ400mm Marker : 160x160mm
190 |
198 |
209 |
212 |
219 |
226 |
233 |
239 |
246 |
253 |
260 |
267 |
274 |
281 |
288 |
295 |
296 |
297 |
307 |
318 |
329 |
340 |
351 |
362 |
373 |
384 |
385 |
390 |
392 |
393 |
398 |
405 |
408 |
419 |
428 |
437 |
446 |
447 | A3
459 |
460 |
461 |
--------------------------------------------------------------------------------
/docs/gate/MainGate_TypeC_A3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/gate/MainGate_TypeC_A3.pdf
--------------------------------------------------------------------------------
/docs/gate/MainGate_TypeC_A3.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
20 |
22 |
41 |
43 |
44 |
46 | image/svg+xml
47 |
49 |
50 |
51 |
52 |
53 |
58 |
70 |
82 |
94 |
106 |
118 |
130 |
135 |
140 |
151 |
154 |
161 |
168 |
175 |
181 |
188 |
195 |
202 |
209 |
216 |
223 |
230 |
237 |
238 |
239 |
249 |
250 |
256 |
258 |
259 |
265 |
270 |
275 |
280 |
285 |
290 |
295 |
300 |
305 |
310 |
315 |
320 |
325 |
330 |
331 | Tiny View Plus - Main Gate Type C - for High Speed OD: 800mm, ID: 400mm, Marker: 160x160mm
353 |
364 |
365 |
366 |
--------------------------------------------------------------------------------
/docs/gate/bakcup/MainGate_TypeA.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/gate/bakcup/MainGate_TypeA.pdf
--------------------------------------------------------------------------------
/docs/gate/bakcup/MainGate_TypeD.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/gate/bakcup/MainGate_TypeD.pdf
--------------------------------------------------------------------------------
/docs/gate/bakcup/MainGate_TypeD.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
23 |
25 |
43 |
45 |
46 |
48 | image/svg+xml
49 |
51 |
52 |
53 |
54 |
55 |
61 |
73 |
85 |
97 |
109 |
121 |
133 |
141 | Tiny View Plus Main Gate Type D for Low Speed Outer Circle : Φ820mm Inner Circle : Φ470mm Marker : 150x150mm
193 |
201 |
212 |
215 |
222 |
229 |
236 |
242 |
249 |
256 |
263 |
270 |
277 |
284 |
291 |
298 |
299 |
300 |
311 |
322 |
333 |
344 |
355 |
366 |
377 |
388 |
399 |
400 |
406 |
408 |
409 |
415 |
422 | A4
434 |
437 |
439 |
450 |
459 |
468 |
477 |
478 |
487 |
488 |
489 |
490 |
--------------------------------------------------------------------------------
/docs/gate/bakcup/Marker_Main_0.svg:
--------------------------------------------------------------------------------
1 |
2 |
18 |
20 |
21 |
23 | image/svg+xml
24 |
26 |
27 |
28 |
29 |
30 |
32 |
53 |
56 |
63 |
70 |
77 |
83 |
90 |
97 |
104 |
111 |
118 |
125 |
132 |
139 |
140 | vvv INSIDE vvv
151 |
152 |
--------------------------------------------------------------------------------
/docs/img/argate_multi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/img/argate_multi.png
--------------------------------------------------------------------------------
/docs/img/argate_single.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/img/argate_single.png
--------------------------------------------------------------------------------
/docs/img/button_fullscreen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/img/button_fullscreen.png
--------------------------------------------------------------------------------
/docs/img/button_quit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/img/button_quit.png
--------------------------------------------------------------------------------
/docs/img/button_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/img/button_settings.png
--------------------------------------------------------------------------------
/docs/img/button_window.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/img/button_window.png
--------------------------------------------------------------------------------
/docs/img/install_mac.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/img/install_mac.png
--------------------------------------------------------------------------------
/docs/img/marker_00_main_a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/img/marker_00_main_a.png
--------------------------------------------------------------------------------
/docs/img/marker_01_main_b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/img/marker_01_main_b.png
--------------------------------------------------------------------------------
/docs/img/marker_02_main_c.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/img/marker_02_main_c.png
--------------------------------------------------------------------------------
/docs/img/marker_03_main_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/img/marker_03_main_d.png
--------------------------------------------------------------------------------
/docs/img/overview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/img/overview.jpg
--------------------------------------------------------------------------------
/docs/img/qr_betaflight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/img/qr_betaflight.png
--------------------------------------------------------------------------------
/docs/img/qr_screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/t-asano/tinyviewplus/f319b57e612ff3a8b1c7bad7af325a4d1ebf9060/docs/img/qr_screen.png
--------------------------------------------------------------------------------
/of.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.device.audio-input
8 |
9 | com.apple.security.device.bluetooth
10 |
11 | com.apple.security.device.camera
12 |
13 | com.apple.security.device.usb
14 |
15 | com.apple.security.files.user-selected.read-write
16 |
17 | com.apple.security.network.client
18 |
19 | com.apple.security.network.server
20 |
21 | com.apple.security.print
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "ofMain.h"
2 | #include "ofApp.h"
3 |
4 | //========================================================================
5 | int main() {
6 | ofSetupOpenGL(1280, 720, OF_WINDOW);
7 | ofRunApp(new ofApp());
8 | }
9 |
--------------------------------------------------------------------------------
/src/ofApp.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include "ofMain.h"
5 | #include "ofxTrueTypeFontUC.h"
6 | #include "ofxOsc.h"
7 | #include "ofxAruco.h"
8 | #include "highlyreliablemarkers.h"
9 | #include "ofxZxing.h"
10 | #include "ofxJoystick.h"
11 | #include "ofxXmlSettings.h"
12 |
13 | /* ---------- definitions ---------- */
14 |
15 | // system
16 | #define APP_VER "v0.9.33 beta6"
17 | #define DEBUG_ENABLED false
18 | #define HELP_LINES 35 // must be <= OVLTXT_LINES
19 | #define SCENE_INIT 0
20 | #define SCENE_CAMS 1
21 | #define SCENE_MAIN 2
22 | #ifdef TARGET_OSX
23 | #define TVP_KEY_ALT OF_KEY_COMMAND
24 | #define TVP_STR_ALT "command"
25 | #else /* TARGET_OSX */
26 | #define TVP_KEY_ALT OF_KEY_ALT
27 | #define TVP_STR_ALT "Alt"
28 | #endif /* TARGET_WIN32 TARGET_LINUX */
29 | #define DFLT_SYS_STAT false
30 | #define TVP_VAL_PLUS 1
31 | #define TVP_VAL_MINUS -1
32 |
33 | // settings
34 | #define SETTINGS_FILE "settings.xml"
35 | #define SNM_SYS_SPCLANG "system:speechJpn"
36 | #define SNM_SYS_STAT "system:sysStat"
37 | #define SNM_OSCMON_ENA "oscMonitor:enabled"
38 | #define SNM_OSCMON_HOST "oscMonitor:host"
39 | #define SNM_OSCMON_PORT "oscMonitor:port"
40 | #define SNM_VIEW_FLLSCR "view:fullscreen"
41 | #define SNM_VIEW_BGIMG "view:bgImage"
42 | #define SNM_VIEW_CAMTRM "view:camTrim"
43 | #define SNM_VIEW_CAMFRM "view:camFrame"
44 | #define SNM_VIEW_LAPHST "view:lapHistMode"
45 | #define SNM_RACE_ARMODE "race:arMode"
46 | #define SNM_RACE_DRSECS "race:duraSecs"
47 | #define SNM_RACE_DRLAPS "race:duraLaps"
48 | #define SNM_RACE_MINLAP "race:minLapTime"
49 | #define SNM_RACE_STAGGR "race:staggStart"
50 | #define SNM_RACE_LAPTMO "race:lapAfterTmo"
51 | #define BTTN_FSCR_FILE "system/button_fullscreen.png"
52 | #define BTTN_QUIT_FILE "system/button_quit.png"
53 | #define BTTN_SETT_FILE "system/button_settings.png"
54 | #define BTTN_WNDW_FILE "system/button_window.png"
55 |
56 | // pilots
57 | #define PILOTS_FILE "pilots/pilots.xml"
58 | #define PLT_PILOT_LABEL "pilot:label_"
59 |
60 | // camera profile
61 | #define CAM_FPV_FILE "camera/fpv.xml"
62 | #define CFNM_NAME "camera:name"
63 | #define CFNM_GRAB_W "camera:grab:width"
64 | #define CFNM_GRAB_H "camera:grab:height"
65 | #define CFNM_CROP_X "camera:crop:x"
66 | #define CFNM_CROP_Y "camera:crop:y"
67 | #define CFNM_CROP_W "camera:crop:width"
68 | #define CFNM_CROP_H "camera:crop:height"
69 | #define CFNM_DRAW_ASPR "camera:draw:aspectRatio"
70 |
71 | // color
72 | #define COLOR_YELLOW 255,215,0
73 | #define COLOR_WHITE 255,255,255
74 | #define COLOR_LGRAY 127,127,127
75 | #define COLOR_DGRAY 15
76 | #define COLOR_BG_DARK 0,0,0,223
77 | #define COLOR_BG_MIDDLE 0,0,0,127
78 | #define COLOR_BG_LIGHT 0,0,0,31
79 | #define COLOR_ALERT 255,0,0
80 | // view
81 | #define FRAME_RATE 60
82 | #define MOVE_STEPS 10
83 | #define VERTICAL_SYNC true
84 | #define LOGO_LARGE_FILE "system/logo_large.png"
85 | #define LOGO_SMALL_FILE "system/logo_small.png"
86 | #define DFLT_WALL_FILE "system/background.png"
87 | #define DFLT_ICON_FILE "system/pilot_icon.png"
88 | #define CAMERA_MAXNUM 4
89 | #define CAMERA_WIDTH 640
90 | #define CAMERA_HEIGHT 480
91 | #define CAMERA_RATIO 1.3333
92 | #define FONT_P_FILE "system/GenShinGothic-P-Bold.ttf"
93 | #define FONT_M_FILE "system/GenShinGothic-Monospace-Bold.ttf"
94 | #define ICON_DIR "pilots/"
95 | #define ICON_WIDTH 50
96 | #define ICON_HEIGHT 50
97 | #define ICON_MARGIN_X 20
98 | #define ICON_MARGIN_Y 0
99 | #define NUMBER_HEIGHT 20
100 | #define NUMBER_MARGIN_X 1
101 | #define NUMBER_MARGIN_Y 35
102 | #define LABEL_HEIGHT 30
103 | #define LABEL_MARGIN_X 75
104 | #define LABEL_MARGIN_Y 40
105 | #define BASE_MARGIN_X 0
106 | #define BASE_MARGIN_Y 0
107 | #define BASE_WIDTH 20
108 | #define BASE_HEIGHT 50
109 | #define BASE_1_COLOR 201,58,64
110 | #define BASE_2_COLOR 160,194,56
111 | #define BASE_3_COLOR 0,116,191
112 | #define BASE_4_COLOR 248,128,23
113 | #define LAP_HEIGHT 20
114 | #define LAP_MARGIN_X 20
115 | #define LAP_MARGIN_Y 80
116 | #define LAPHIST_MD_OFF 0
117 | #define LAPHIST_MD_IN 1
118 | #define LAPHIST_MD_OUT 2
119 | #define LAPHIST_HEIGHT 15
120 | #define LAPHIST_MARGIN 8
121 | #define FRAME_LINEWIDTH 8
122 | #define DFLT_FSCR_ENBLD false
123 | #define DFLT_CAM_TRIM false
124 | #define DFLT_CAM_LAPHST LAPHIST_MD_OFF
125 | #define DFLT_CAM_FRAMED false
126 | #define ALIGN_LEFT 0
127 | #define ALIGN_CENTER 1
128 | #define ALIGN_RIGHT 2
129 | #define HIDECUR_TIME FRAME_RATE
130 | // overlay
131 | #define OVLMODE_NONE 0
132 | #define OVLMODE_HELP 1
133 | #define OVLMODE_MSG 2
134 | #define OVLMODE_RCRSLT 3
135 | #define OVLTXT_BLKS 13
136 | #define OVLTXT_LINES 35
137 | #define OVLTXT_LAPS 25
138 | #define OVLTXT_MARG 10
139 | #define OLVMSG_TIME FRAME_RATE
140 | #define INFO_HEIGHT 10
141 | #define WATCH_HEIGHT 40
142 | #define WATCH_OFFSET_Y 10
143 | // sound
144 | #define SND_BEEP_FILE "system/beep.wav"
145 | #define SND_BEEP3_FILE "system/beep3.wav"
146 | #define SND_COUNT_FILE "system/count.wav"
147 | #define SND_FINISH_FILE "system/finish.wav"
148 | #define SND_NOTIFY_FILE "system/notify.wav"
149 | #define SND_CANCEL_FILE "system/cancel.wav"
150 | // AR lap timer
151 | #define ARAP_MODE_NORM 0
152 | #define ARAP_MODE_LOOSE 1
153 | #define ARAP_MODE_OFF 2
154 | #define DFLT_ARAP_MODE ARAP_MODE_NORM
155 | #define DFLT_ARAP_RLAPS 10
156 | #define DFLT_ARAP_RSECS 0
157 | #define DFLT_ARAP_MNLAP 3
158 | #define DFLT_ARAP_SGATE false
159 | #define DFLT_ARAP_LAPTO false
160 | #define ARAP_MKR_FILE "system/marker.xml"
161 | #define ARAP_RESULT_DIR "results/"
162 | #define ARAP_MNUM_THR 2
163 | #define ARAP_MAX_RLAPS 10000
164 | #define ARAP_MAX_MNLAP 100
165 | #define ARAP_MAX_RSECS 36000
166 | #define ARAP_RSLT_SCRN 0
167 | #define ARAP_RSLT_FILE 1
168 | #define ARAP_RSLT_DELAY (FRAME_RATE * 3)
169 | #define ARAP_RECT_LINEW 5
170 | #define WATCH_COUNT_SEC 5
171 | // osc
172 | #define OSC_LISTEN_PORT 4000
173 | #define DFLT_OSCM_ENBLD true
174 | #define DFLT_OSCM_HOST "127.0.0.1"
175 | #define DFLT_OSCM_PORT 4001
176 | // speech
177 | #define DFLT_SPCH_ENBLD false
178 | #define SPCH_SLOT_NUM 8
179 | // QR code reader
180 | #define QR_CYCLE 6
181 | // gamepad
182 | #define GPAD_MAX_DEVS 4
183 | #define GPAD_ALT_BTN 4
184 |
185 | /* ---------- classes ---------- */
186 |
187 | class tvpCamView {
188 | public:
189 | // camera
190 | bool visible;
191 | int moveSteps;
192 | int width;
193 | int height;
194 | int heightWide;
195 | int widthTarget;
196 | int heightTarget;
197 | int heightWideTarget;
198 | int posX;
199 | int posY;
200 | int posYWide;
201 | int posXTarget;
202 | int posYTarget;
203 | int posYWideTarget;
204 | float imageScale;
205 | bool needCrop;
206 | bool needResize;
207 | bool isWide;
208 | ofPixels resizedPixels;
209 | ofImage resizedImage;
210 | // base
211 | ofColor baseColor;
212 | int basePosX;
213 | int basePosY;
214 | int basePosXTarget;
215 | int basePosYTarget;
216 | int baseWidth;
217 | int baseHeight;
218 | // number
219 | int numberPosX;
220 | int numberPosY;
221 | int numberPosXTarget;
222 | int numberPosYTarget;
223 | // icon
224 | ofImage iconImage;
225 | int iconPosX;
226 | int iconPosY;
227 | int iconPosXTarget;
228 | int iconPosYTarget;
229 | // label
230 | string labelString;
231 | int labelPosX;
232 | int labelPosY;
233 | int labelPosXTarget;
234 | int labelPosYTarget;
235 | // lap
236 | int lapPosX;
237 | int lapPosY;
238 | int lapPosXTarget;
239 | int lapPosYTarget;
240 | float lastLapTime;
241 | // AR lap timer
242 | ofxAruco aruco;
243 | int foundMarkerNum;
244 | int foundValidMarkerNum;
245 | bool enoughMarkers;
246 | float prevElapsedSec;
247 | int totalLaps;
248 | string lapHistName[ARAP_MAX_RLAPS + 1];
249 | float lapHistLapTime[ARAP_MAX_RLAPS + 1];
250 | float lapHistElpTime[ARAP_MAX_RLAPS + 1];
251 | int flickerCount;
252 | int flickerValidCount;
253 | int racePosition;
254 | // QR reader
255 | bool qrScanned;
256 | };
257 |
258 |
259 | class tvpCamProf {
260 | public:
261 | bool enabled;
262 | string name;
263 | int grabW;
264 | int grabH;
265 | int cropX;
266 | int cropY;
267 | int cropW;
268 | int cropH;
269 | string drawAspr;
270 | bool needCrop;
271 | bool needResize;
272 | bool isWide;
273 | };
274 |
275 | class ofApp : public ofBaseApp {
276 | public:
277 | void setup();
278 | void update();
279 | void draw();
280 | void keyPressed(int key);
281 | void keyReleased(int key);
282 | void mouseMoved(int x, int y);
283 | void mouseDragged(int x, int y, int button);
284 | void mousePressed(int x, int y, int button);
285 | void mouseReleased(int x, int y, int button);
286 | void mouseEntered(int x, int y);
287 | void mouseExited(int x, int y);
288 | void windowResized(int w, int h);
289 | void dragEvent(ofDragInfo dragInfo);
290 | void gotMessage(ofMessage msg);
291 | void exit();
292 | };
293 |
294 | /* ---------- functions ---------- */
295 |
296 | // -- splash --
297 | void setupInit();
298 | void loadWallImage(string);
299 | void loadSettingsFile();
300 | void saveSettingsFile();
301 | void savePilotsFile();
302 | void loadPilotsFile();
303 | void loadCameraProfileFile();
304 | void setupOsc();
305 | void updateInit();
306 | void drawInit();
307 | // -- camera setup --
308 | void setupCamCheck();
309 | void updateCamCheck();
310 | void drawCamCheck();
311 | void keyPressedCamCheck(int);
312 | void reloadCameras();
313 | // -- main --
314 | // common
315 | void initConfig();
316 | string getUserLocaleName();
317 | void toggleSysStat();
318 | // view
319 | void grabberUpdateResize(int);
320 | void toggleCameraSolo(int);
321 | void enableCameraSolo(int);
322 | void resetCameraSolo();
323 | void toggleCameraVisibility(int);
324 | int getCameraIdxNthVisibleAll(int);
325 | int getCameraIdxNthVisibleSub(int);
326 | void toggleFullscreen();
327 | void toggleCameraTrim();
328 | void toggleCameraFrame();
329 | void setupColors();
330 | void changeCameraLabel(int);
331 | void changeCameraIcon(int);
332 | void changeCameraIconPath(int, string, bool);
333 | void autoSelectCameraIcon(int, string);
334 | void changeWallImage();
335 | void setWallParams();
336 | void setViewParams();
337 | int calcViewParam(int, int, int);
338 | void updateViewParams();
339 | // osc
340 | void recvOsc();
341 | void recvOscCameraString(int, string, string);
342 | void recvOscCameraFloat(int, string, float);
343 | void recvOscSpeech(string, string);
344 | void sendOscSystemInfo(string);
345 | void sendOscRaceEvent(string);
346 | void sendOscCameraLap(int, int, float, string);
347 | void sendOscCameraLapDelete(int, int);
348 | void sendOscCameraLabel(int, string);
349 | void sendOscCameraLabelAll();
350 | void sendOscCameraResult(int, string, int, int, float, float);
351 | // speech
352 | void toggleSpeechLang();
353 | void autoSelectSpeechLang();
354 | void speakLap(int, float, int);
355 | void setNextNotifyRemainSecs(int);
356 | void speakRemainTime(int);
357 | void speakAny(string, string);
358 | // draw
359 | void drawCameraImage(int);
360 | void drawCameraFrame(int);
361 | void drawCameraARMarker(int, bool);
362 | void drawCameraPilot(int, bool);
363 | void drawCameraLapTime(int, bool);
364 | void drawCameraLapHistory(int, bool, bool);
365 | void drawCamera(int);
366 | string getWatchString(float);
367 | void drawWatch();
368 | void drawInfo();
369 | void drawStringWithShadow(ofxTrueTypeFontUC*, ofColor, ofColor, string, int, int);
370 | void drawSystemButtons();
371 | // input
372 | void keyPressedOverlayHelp(int);
373 | void keyPressedOverlayHelp(int);
374 | void keyPressedOverlayResult(int);
375 | void keyPressedOverlayNone(int);
376 | void mouseReleasedOverlayNone(int, int, int);
377 | // race
378 | void toggleRace();
379 | void initRaceVars();
380 | void startRace();
381 | void stopRace(bool);
382 | bool isVariousPilots(int);
383 | bool isVariousPilotsAll();
384 | bool isRecordedLaps();
385 | float getBestLap(int);
386 | int getMaxLaps();
387 | string getLapStr(float);
388 | void pushLapRecord(int, float);
389 | void popLapRecord(int);
390 | void updateRacePositions();
391 | void toggleARLap();
392 | void changeMinLap(int);
393 | void changeRaceTime(int);
394 | void changeRaceLaps(int);
395 | void changeRaceTimeAndLaps();
396 | void toggleUseStartGate();
397 | void toggleLapAfterTimeout();
398 | // overlay - common
399 | void setOverlayMode(int);
400 | void loadOverlayFont();
401 | void drawStringBlock(ofxTrueTypeFontUC*, string, int , int, int, int, int);
402 | void drawLineBlock(int, int, int, int, int);
403 | void drawULineBlock(int, int, int, int, int);
404 | // overlay - race result
405 | void generateDummyData();
406 | void fwriteRaceResult();
407 | int getRaceResultPages();
408 | void processRaceResultDisplay();
409 | void drawRaceResult(int);
410 | // overlay - help
411 | void drawHelp();
412 | void drawHelpBody(int);
413 | // overlay - message
414 | void initOverlayMessage();
415 | void setOverlayMessage(string);
416 | void drawOverlayMessageCore(ofxTrueTypeFontUC*, string);
417 | void drawOverlayMessage();
418 | // QR Code reader
419 | #ifdef TARGET_WIN32
420 | string utf8ToAnsi(string);
421 | string ansiToUtf8(string);
422 | #endif /* TARGET_WIN32 */
423 | void toggleQrReader();
424 | void processQrReader();
425 | // gamepad
426 | void checkGamePad(float);
427 | // others
428 | void toggleLapHistory();
429 | void activateCursor();
430 |
--------------------------------------------------------------------------------
/test/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/test/osc_debug.js:
--------------------------------------------------------------------------------
1 | // OSC debugger
2 |
3 | var osc = require('node-osc');
4 | var client = new osc.Client('127.0.0.1', 4000);
5 |
6 | function sendOsc(addr, arg1, wait) {
7 | var is_str = (typeof arg1 === 'string' || arg1 instanceof String);
8 | var ext = is_str ? '"' : '';
9 | setTimeout(function () {
10 | console.log(addr + ' ' + ext + arg1 + ext);
11 | client.send(addr, arg1, function () {});
12 | }, wait);
13 | }
14 |
15 | function exit() {
16 | client.kill();
17 | process.exit;
18 | }
19 |
20 | function test() {
21 | var wait = 0;
22 | var step = 800;
23 | var step_lap = 3000;
24 | var step_spc = 1200;
25 | console.log('Sending OSC message to udp://127.0.0.1:4000');
26 | // camera solo
27 | sendOsc("/v1/camera/1/solo", "on", wait += step);
28 | sendOsc("/v1/camera/1/solo", "off", wait += step);
29 | sendOsc("/v1/camera/2/solo", "on", wait += step);
30 | sendOsc("/v1/camera/2/solo", "off", wait += step);
31 | sendOsc("/v1/camera/3/solo", "on", wait += step);
32 | sendOsc("/v1/camera/3/solo", "off", wait += step);
33 | sendOsc("/v1/camera/4/solo", "on", wait += step);
34 | sendOsc("/v1/camera/4/solo", "off", wait += step);
35 | // camera display
36 | sendOsc("/v1/camera/1/display", "off", wait += step);
37 | sendOsc("/v1/camera/2/display", "off", wait += step);
38 | sendOsc("/v1/camera/3/display", "off", wait += step);
39 | sendOsc("/v1/camera/4/display", "off", wait += step);
40 | sendOsc("/v1/camera/1/display", "on", wait += step);
41 | sendOsc("/v1/camera/2/display", "on", wait += step);
42 | sendOsc("/v1/camera/3/display", "on", wait += step);
43 | sendOsc("/v1/camera/4/display", "on", wait += step);
44 | // camera label
45 | sendOsc("/v1/camera/1/label", "パイロット1", wait += step);
46 | sendOsc("/v1/camera/2/label", "パイロット2", wait += step);
47 | sendOsc("/v1/camera/3/label", "パイロット3", wait += step);
48 | sendOsc("/v1/camera/4/label", "パイロット4", wait += step);
49 | sendOsc("/v1/camera/1/label", "sample pilot", wait += step);
50 | sendOsc("/v1/camera/2/label", "sample pilot", wait += step);
51 | sendOsc("/v1/camera/3/label", "sample pilot", wait += step);
52 | sendOsc("/v1/camera/4/label", "sample pilot", wait += step);
53 | sendOsc("/v1/camera/1/label", "Pilot1", wait += step);
54 | sendOsc("/v1/camera/2/label", "Pilot2", wait += step);
55 | sendOsc("/v1/camera/3/label", "Pilot3", wait += step);
56 | sendOsc("/v1/camera/4/label", "Pilot4", wait += step);
57 | // camera lap
58 | sendOsc("/v1/camera/1/lap", "add", wait += step);
59 | sendOsc("/v1/camera/2/lap", "add", wait += step_lap);
60 | sendOsc("/v1/camera/3/lap", "add", wait += step_lap);
61 | sendOsc("/v1/camera/4/lap", "add", wait += step_lap);
62 | sendOsc("/v1/camera/1/lap", "del", wait += step_lap);
63 | sendOsc("/v1/camera/2/lap", "del", wait += step);
64 | sendOsc("/v1/camera/3/lap", "del", wait += step);
65 | sendOsc("/v1/camera/4/lap", "del", wait += step);
66 | // camera laptime
67 | sendOsc("/v1/camera/1/laptime", 62.09, wait += step);
68 | sendOsc("/v1/camera/2/laptime", 56.20, wait += step_lap);
69 | sendOsc("/v1/camera/3/laptime", 58.83, wait += step_lap);
70 | sendOsc("/v1/camera/4/laptime", 45.31, wait += step_lap);
71 | sendOsc("/v1/camera/1/laptime", 0, wait += step_lap);
72 | sendOsc("/v1/camera/2/laptime", 0, wait += step);
73 | sendOsc("/v1/camera/3/laptime", 0, wait += step);
74 | sendOsc("/v1/camera/4/laptime", 0, wait += step);
75 | // speech
76 | sendOsc("/v1/speech/jp/say", "ドローンで遊ぼう", wait += step);
77 | sendOsc("/v1/speech/en/say", "You can fly!", wait += step_spc);
78 | // exit
79 | setTimeout(exit, wait += step);
80 | }
81 |
82 | test();
83 |
--------------------------------------------------------------------------------
/test/osc_debug_lap.js:
--------------------------------------------------------------------------------
1 | // OSC debugger
2 |
3 | var osc = require('node-osc');
4 | var client = new osc.Client('127.0.0.1', 4000);
5 |
6 | function sendOsc(addr, arg1, wait) {
7 | var is_str = (typeof arg1 === 'string' || arg1 instanceof String);
8 | var ext = is_str ? '"' : '';
9 | setTimeout(function () {
10 | console.log(addr + ' ' + ext + arg1 + ext);
11 | client.send(addr, arg1, function () {});
12 | }, wait);
13 | }
14 |
15 | function exit() {
16 | client.kill();
17 | process.exit;
18 | }
19 |
20 | function test() {
21 | var wait = 0;
22 | var step = 800;
23 | var step_lap = 2000;
24 | var step_spc = 1000;
25 | console.log('Sending OSC message to udp://127.0.0.1:4000');
26 | // camera lap
27 | sendOsc("/v1/camera/1/lap", "add", wait += step);
28 | sendOsc("/v1/camera/2/lap", "add", wait += step_lap);
29 | sendOsc("/v1/camera/3/lap", "add", wait += step_lap);
30 | sendOsc("/v1/camera/4/lap", "add", wait += step_lap);
31 | sendOsc("/v1/camera/1/lap", "del", wait += step_lap);
32 | sendOsc("/v1/camera/2/lap", "del", wait += step);
33 | sendOsc("/v1/camera/3/lap", "del", wait += step);
34 | sendOsc("/v1/camera/4/lap", "del", wait += step);
35 | // exit
36 | setTimeout(exit, wait += step);
37 | }
38 |
39 | test();
40 |
--------------------------------------------------------------------------------
/test/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "osc_debug.js",
6 | "dependencies": {
7 | "node-osc": "^2.1.0"
8 | },
9 | "devDependencies": {},
10 | "scripts": {
11 | "test": "echo \"Error: no test specified\" && exit 1"
12 | },
13 | "author": "",
14 | "license": "ISC"
15 | }
16 |
--------------------------------------------------------------------------------