mirror of
https://github.com/BotChain-Robots/ui.git
synced 2026-07-08 06:57:22 +02:00
Initial commit after symposium
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 129 B |
23
Assets/ProgrammedMovements/SavedTimelines/CarDrive.json
Normal file
23
Assets/ProgrammedMovements/SavedTimelines/CarDrive.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"Timeline": [
|
||||
{
|
||||
"Second": 0,
|
||||
"Movements": [
|
||||
{
|
||||
"ModuleId": "43",
|
||||
"ModuleType": "DC",
|
||||
"Degree": 360.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
},
|
||||
{
|
||||
"ModuleId": "199",
|
||||
"ModuleType": "DC",
|
||||
"Degree": 360.0,
|
||||
"Direction": -1,
|
||||
"Track": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a766e3e27a1e54f738044fb1a05673fa
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
80
Assets/ProgrammedMovements/SavedTimelines/crawler.json
Normal file
80
Assets/ProgrammedMovements/SavedTimelines/crawler.json
Normal file
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"Timeline": [
|
||||
{
|
||||
"Second": 0,
|
||||
"Movements": [
|
||||
{
|
||||
"ModuleId": "11",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 180.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
},
|
||||
{
|
||||
"ModuleId": "23",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 0.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Second": 1,
|
||||
"Movements": [
|
||||
{
|
||||
"ModuleId": "112",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 0.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
},
|
||||
{
|
||||
"ModuleId": "111",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 90.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Second": 2,
|
||||
"Movements": [
|
||||
{
|
||||
"ModuleId": "11",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 0.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
},
|
||||
{
|
||||
"ModuleId": "23",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 180.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Second": 3,
|
||||
"Movements": [
|
||||
{
|
||||
"ModuleId": "112",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 0.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
},
|
||||
{
|
||||
"ModuleId": "111",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 0.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea96d3b03a0cb4b238d7bca13d16289d
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"Timeline": [
|
||||
{
|
||||
"Second": 0,
|
||||
"Movements": [
|
||||
{
|
||||
"ModuleId": "82",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 180.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
},
|
||||
{
|
||||
"ModuleId": "23",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 0.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Second": 1,
|
||||
"Movements": [
|
||||
{
|
||||
"ModuleId": "81",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 90.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
},
|
||||
{
|
||||
"ModuleId": "111",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 90.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Second": 2,
|
||||
"Movements": [
|
||||
{
|
||||
"ModuleId": "82",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 0.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
},
|
||||
{
|
||||
"ModuleId": "23",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 180.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Second": 3,
|
||||
"Movements": [
|
||||
{
|
||||
"ModuleId": "81",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 0.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
},
|
||||
{
|
||||
"ModuleId": "111",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 0.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41298426868554bd3b2199019a5bcbd7
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,115 @@
|
||||
{
|
||||
"Timeline": [
|
||||
{
|
||||
"Second": 0,
|
||||
"Movements": [
|
||||
{
|
||||
"ModuleId": "82",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 140.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
},
|
||||
{
|
||||
"ModuleId": "",
|
||||
"ModuleType": "",
|
||||
"Degree": 30.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
},
|
||||
{
|
||||
"ModuleId": "23",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 30.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Second": 1,
|
||||
"Movements": [
|
||||
{
|
||||
"ModuleId": "81",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 90.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
},
|
||||
{
|
||||
"ModuleId": "111",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 90.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
},
|
||||
{
|
||||
"ModuleId": "81",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 90.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Second": 2,
|
||||
"Movements": [
|
||||
{
|
||||
"ModuleId": "82",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 30.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
},
|
||||
{
|
||||
"ModuleId": "",
|
||||
"ModuleType": "",
|
||||
"Degree": 180.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
},
|
||||
{
|
||||
"ModuleId": "23",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 140.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Second": 3,
|
||||
"Movements": [
|
||||
{
|
||||
"ModuleId": "",
|
||||
"ModuleType": "",
|
||||
"Degree": 0.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
},
|
||||
{
|
||||
"ModuleId": "111",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 0.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
},
|
||||
{
|
||||
"ModuleId": "81",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 0.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
},
|
||||
{
|
||||
"ModuleId": "81",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 90.0,
|
||||
"Direction": 1,
|
||||
"Track": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17c74710af0d34b66a5f8fb1539c02b4
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19272
Assets/_Recovery/0 (1).unity
Normal file
19272
Assets/_Recovery/0 (1).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (1).unity.meta
Normal file
7
Assets/_Recovery/0 (1).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e91ecc6e13be5434fa9e6d7308bda8f6
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19558
Assets/_Recovery/0 (10).unity
Normal file
19558
Assets/_Recovery/0 (10).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (10).unity.meta
Normal file
7
Assets/_Recovery/0 (10).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1cc5cb9ea91b3438eb6943554af479e0
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19558
Assets/_Recovery/0 (11).unity
Normal file
19558
Assets/_Recovery/0 (11).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (11).unity.meta
Normal file
7
Assets/_Recovery/0 (11).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d29b4b46d666b4fceac7e86b37d5233f
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19558
Assets/_Recovery/0 (12).unity
Normal file
19558
Assets/_Recovery/0 (12).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (12).unity.meta
Normal file
7
Assets/_Recovery/0 (12).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2fadc0626274442a88fbcbb67c3c02a9
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
17002
Assets/_Recovery/0 (13).unity
Normal file
17002
Assets/_Recovery/0 (13).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (13).unity.meta
Normal file
7
Assets/_Recovery/0 (13).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ad9c2f14bd034266b05a1fb57a618ae
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
17002
Assets/_Recovery/0 (14).unity
Normal file
17002
Assets/_Recovery/0 (14).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (14).unity.meta
Normal file
7
Assets/_Recovery/0 (14).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad622b060751c4293b65f8544bd83241
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
16866
Assets/_Recovery/0 (15).unity
Normal file
16866
Assets/_Recovery/0 (15).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (15).unity.meta
Normal file
7
Assets/_Recovery/0 (15).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b73b4580f2bd4c0d9afa5ba4094f801
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
16866
Assets/_Recovery/0 (16).unity
Normal file
16866
Assets/_Recovery/0 (16).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (16).unity.meta
Normal file
7
Assets/_Recovery/0 (16).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa1bde07d623f4dd48cb3b408bc02584
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19917
Assets/_Recovery/0 (17).unity
Normal file
19917
Assets/_Recovery/0 (17).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (17).unity.meta
Normal file
7
Assets/_Recovery/0 (17).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d28939c93ae7542df8a6e49462e2f97b
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
21712
Assets/_Recovery/0 (18).unity
Normal file
21712
Assets/_Recovery/0 (18).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (18).unity.meta
Normal file
7
Assets/_Recovery/0 (18).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2cb723a40aa774d08839534b4be366f5
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
21712
Assets/_Recovery/0 (19).unity
Normal file
21712
Assets/_Recovery/0 (19).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (19).unity.meta
Normal file
7
Assets/_Recovery/0 (19).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4968fafe5fbc44544a18e7554e7e2985
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19272
Assets/_Recovery/0 (2).unity
Normal file
19272
Assets/_Recovery/0 (2).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (2).unity.meta
Normal file
7
Assets/_Recovery/0 (2).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 87b725cfe4c7749808454eece700e82e
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19272
Assets/_Recovery/0 (3).unity
Normal file
19272
Assets/_Recovery/0 (3).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (3).unity.meta
Normal file
7
Assets/_Recovery/0 (3).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b90e41d76235463888a900427b8a221
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19272
Assets/_Recovery/0 (4).unity
Normal file
19272
Assets/_Recovery/0 (4).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (4).unity.meta
Normal file
7
Assets/_Recovery/0 (4).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c1f7722b5d28540819476c465fa25291
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19272
Assets/_Recovery/0 (5).unity
Normal file
19272
Assets/_Recovery/0 (5).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (5).unity.meta
Normal file
7
Assets/_Recovery/0 (5).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c295493cb5194188a0060750219535f
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19272
Assets/_Recovery/0 (6).unity
Normal file
19272
Assets/_Recovery/0 (6).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (6).unity.meta
Normal file
7
Assets/_Recovery/0 (6).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 609bfbc38a85c4d3b82d0f9d924c3af7
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19272
Assets/_Recovery/0 (7).unity
Normal file
19272
Assets/_Recovery/0 (7).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (7).unity.meta
Normal file
7
Assets/_Recovery/0 (7).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 016c1320d930c4e1296a882953304c00
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19558
Assets/_Recovery/0 (8).unity
Normal file
19558
Assets/_Recovery/0 (8).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (8).unity.meta
Normal file
7
Assets/_Recovery/0 (8).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69845c5d906244084bda8dfe2a5e005c
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19558
Assets/_Recovery/0 (9).unity
Normal file
19558
Assets/_Recovery/0 (9).unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0 (9).unity.meta
Normal file
7
Assets/_Recovery/0 (9).unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c6424f6866c449cebd5a552966630e7
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19302
Assets/_Recovery/0.unity
Normal file
19302
Assets/_Recovery/0.unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/_Recovery/0.unity.meta
Normal file
7
Assets/_Recovery/0.unity.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 622a9bec8b1234ad6a14540f3295d57a
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
16
ProjectSettings/URPProjectSettings.asset
Normal file
16
ProjectSettings/URPProjectSettings.asset
Normal file
@@ -0,0 +1,16 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &1
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 61
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 247994e1f5a72c2419c26a37e9334c01, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.UniversalProjectSettings
|
||||
m_LastMaterialVersion: 10
|
||||
m_ProjectSettingFolderPath: URPDefaultResources
|
||||
326
README.md
Normal file
326
README.md
Normal file
@@ -0,0 +1,326 @@
|
||||
# Capstone
|
||||
|
||||
A modular robot control and visualization UI for a modular robotic system. Capstone provides a unified interface to visualize, control, and program robots built from connectable modules (servos, hubs, DC motors, sensors, etc.) through three main modes: Live View, Inverse Kinematics, and Programmed Movements.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Requirements](#requirements)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Project Structure](#project-structure)
|
||||
- [Technical Architecture](#technical-architecture)
|
||||
- [Major Features](#major-features)
|
||||
- [Data Formats](#data-formats)
|
||||
- [Building](#building)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Capstone is designed for:
|
||||
|
||||
- **Visualizing** robots built from modular components (servos, hubs, DC motors, grippers, sensors, etc.)
|
||||
- **Controlling** modules in real time via a native C library (`libc_control`) or mock JSON configs
|
||||
- **Programming** movement sequences via a timeline-based editor
|
||||
|
||||
The application supports both hardware-connected operation (with a native control library) and a **mock mode** for development and testing without physical hardware.
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
|
||||
| Requirement | Version |
|
||||
| ------------ | --------------------- |
|
||||
| **Unity** | 6000.3.6f1 (Unity 6) |
|
||||
| **Platform** | Windows, macOS, Linux |
|
||||
|
||||
|
||||
### Supported Platforms
|
||||
|
||||
- Windows (x64)
|
||||
- macOS (x64)
|
||||
- Linux (x86_64)
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
### 1. Clone and Open
|
||||
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd ui
|
||||
```
|
||||
|
||||
Open the project in Unity Hub using Unity 6000.3.6f1.
|
||||
|
||||
### 2. Run Without Hardware (Mock Mode)
|
||||
|
||||
To run without the native control library:
|
||||
|
||||
1. Open `ProjectSettings` or locate the `TopologyBuilder` component in your scene.
|
||||
2. Enable **Use JSON File** and **Mock Control Library**.
|
||||
3. The app will load topology from JSON files in `Assets/Resources/` (e.g. `mockData.json`, `mockDataSimple.json`, `mockDataWithDC.json`).
|
||||
|
||||
### 3. Run With Hardware
|
||||
|
||||
1. Ensure `libc_control` is built and available in the appropriate platform directory (e.g. `Plugins/`).
|
||||
2. Disable mock mode in `TopologyBuilder`.
|
||||
3. Use the **Discovery** overlay to select a connected robot leader.
|
||||
|
||||
### 4. Main Scene
|
||||
|
||||
- **SampleScene** (`Assets/Scenes/SampleScene.unity`) – primary scene for robot control and visualization.
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
ui/
|
||||
├── Assets/
|
||||
│ ├── Scenes/ # Main scenes (SampleScene, Playground)
|
||||
│ ├── Resources/ # JSON configs for mock mode
|
||||
│ │ ├── mockData.json
|
||||
│ │ ├── mockDataSimple.json
|
||||
│ │ ├── mockDataWithDC.json
|
||||
│ │ └── ...
|
||||
│ ├── Module/ # Topology, Hub, Discovery
|
||||
│ ├── IK/ # Inverse kinematics
|
||||
│ ├── ProgrammedMovements/ # Timeline-based movement
|
||||
│ │ └── SavedTimelines/ # Saved timeline JSON files
|
||||
│ ├── ControlLibrary/ # P/Invoke bridge to libc_control
|
||||
│ ├── FlatBuffers/ # FlatBuffers runtime
|
||||
│ ├── Flatbuffers_generated/ # Generated types (RobotConfiguration, etc.)
|
||||
│ ├── StarterAssets/ # Third-person controller, input
|
||||
│ ├── StandaloneFileBrowser/ # Cross-platform file dialogs
|
||||
│ ├── SyntyStudios/ # Polygon assets (PolygonCity, etc.)
|
||||
│ └── Editor/ # Build scripts
|
||||
├── ProjectSettings/
|
||||
├── Packages/
|
||||
└── README.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Technical Architecture
|
||||
|
||||
### Unity Version & Packages
|
||||
|
||||
|
||||
| Package | Version |
|
||||
| ------------------------------- | ------- |
|
||||
| Cinemachine | 2.10.3 |
|
||||
| Input System | 1.14.0 |
|
||||
| Universal Render Pipeline (URP) | 14.0.12 |
|
||||
| TextMeshPro | 3.0.7 |
|
||||
| Timeline | 1.7.7 |
|
||||
| UGUI | 1.0.0 |
|
||||
| Visual Scripting | 1.9.4 |
|
||||
| Collab Proxy | 2.8.2 |
|
||||
| Development | 1.0.1 |
|
||||
|
||||
|
||||
### Native Integration
|
||||
|
||||
The `ControlLibrary` communicates with the native C library `libc_control` via P/Invoke:
|
||||
|
||||
|
||||
| Function | Purpose |
|
||||
| ---------------------------------------- | ------------------------------------- |
|
||||
| `init()` | Initialize the control library |
|
||||
| `cleanup()` | Cleanup resources |
|
||||
| `send_angle_control(module_id, angle)` | Send angle command to a servo module |
|
||||
| `send_string_control(module_id, s)` | Send string command to a module |
|
||||
| `get_distance_control(module_id)` | Get distance sensor reading |
|
||||
| `get_configuration(out size, leader_id)` | Get robot configuration (FlatBuffers) |
|
||||
| `get_leaders(out length)` | Get list of connected robot leaders |
|
||||
| `control_sentry_*` | Sentry error reporting integration |
|
||||
|
||||
|
||||
If `libc_control` is missing, native calls are disabled and the app falls back to mock/JSON mode.
|
||||
|
||||
### Data Flow
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│ ViewBannerUI (3 modes) │
|
||||
├─────────────────┬─────────────────────┬──────────────────────────┤
|
||||
│ Live View │ Inverse Kinematics │ Programmed Movements │
|
||||
│ LiveViewPanel │ IKController + │ ProgrammedMovementsCtrl │
|
||||
│ ModuleSelector │ PositionControlGizmo│ Timeline (4 tracks) │
|
||||
└────────┬────────┴──────────┬──────────┴──────────────┬───────────┘
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ModuleBase (Servo, DC, Hub, Sensor, etc.) │
|
||||
│ SendToControlLibrary() │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ControlLibrary (P/Invoke) ←→ libc_control (native C library) │
|
||||
│ getRobotConfiguration, send_angle_control, get_leaders, etc. │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Major Features
|
||||
|
||||
### 1. View Modes
|
||||
|
||||
The top banner (`ViewBannerUI`) provides three modes:
|
||||
|
||||
|
||||
| Mode | Description |
|
||||
| ------------------------ | ---------------------------------------------------------------- |
|
||||
| **Live** | Real-time control of individual modules (sliders, buttons) |
|
||||
| **Inverse Kinematics** | Drag a 3D gizmo to move the end-effector; IK solves joint angles |
|
||||
| **Programmed Movements** | Timeline-based sequences (up to 10 seconds, 4 tracks) |
|
||||
|
||||
|
||||
### 2. Module System
|
||||
|
||||
|
||||
| Module Type | Description |
|
||||
| ----------------- | ------------------------------------------------------------------------------------ |
|
||||
| **ModuleBase** | Base class for all modules; sends commands via `ControlLibrary` |
|
||||
| **Hub modules** | `HubModule_MMMM`, `TriangleHubModule_MMF`, `TriangleHubModule_MMM`, `HubModule_MMMF` |
|
||||
| **Servo modules** | `ServoBendModule`, `ServoStraightModule`, `GripperModule` |
|
||||
| **Actuators** | `DCMotorModule` |
|
||||
| **Sensors** | `DistanceSensorModule`, `IMUSensorModule` |
|
||||
| **Other** | `DisplayModule`, `SpeakerModule`, `PowerModule`, `Battery` |
|
||||
|
||||
|
||||
### 3. Topology Builder
|
||||
|
||||
- Builds the robot graph from JSON or from `ControlLibrary.getRobotConfiguration()`.
|
||||
- Uses `ModuleSpawner` to instantiate prefabs and connect them.
|
||||
- Options: `useJsonFile`, `skipControlLibraryCalls`, `mockControlLibrary`.
|
||||
|
||||
### 4. Discovery
|
||||
|
||||
- Lists robot leaders from `ControlLibrary.getRobotLeaders()`.
|
||||
- Mock mode uses JSON files in `Resources/`.
|
||||
- Selecting a leader loads its topology.
|
||||
|
||||
### 5. Live View
|
||||
|
||||
- Side panel for the selected module.
|
||||
- **Servo**: angle slider (0–180°).
|
||||
- **DC motor**: direction and rotation controls.
|
||||
- **Sensors**: readouts (e.g. distance).
|
||||
- Uses `ModuleSelector` for selection.
|
||||
|
||||
### 6. Inverse Kinematics
|
||||
|
||||
- CCD-based IK solver for kinematic chains.
|
||||
- Builds chain from selected module to root (`GeneratedTopology`).
|
||||
- `PositionControlGizmo`: 3D gizmo for dragging end-effector position.
|
||||
- Supports `ServoStraightModule` joints with configurable deadzone and smoothing.
|
||||
|
||||
### 7. Programmed Movements
|
||||
|
||||
- Timeline: 4 tracks, 0–10 seconds.
|
||||
- Movement blocks per second per track.
|
||||
- **Run**: plays timeline and sends commands to modules.
|
||||
- **Save/Load**: JSON files in `Assets/ProgrammedMovements/SavedTimelines/`.
|
||||
- Uses `StandaloneFileBrowser` for cross-platform file dialogs.
|
||||
|
||||
### 8. File Browser
|
||||
|
||||
- **StandaloneFileBrowser** – cross-platform open/save dialogs (Windows, Mac, Linux).
|
||||
|
||||
---
|
||||
|
||||
## Data Formats
|
||||
|
||||
### Topology JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"Modules": [
|
||||
{ "Id": "splitter1", "Type": "Splitter4", "Degree": null },
|
||||
{ "Id": "servo1", "Type": "Servo1", "Degree": 45 }
|
||||
],
|
||||
"Connections": [
|
||||
{
|
||||
"FromModuleId": "splitter1",
|
||||
"ToModuleId": "servo1",
|
||||
"FromSocket": "MaleSocket1",
|
||||
"ToSocket": "FemaleSocket",
|
||||
"Orientation": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Programmed Movement Timeline JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"Timeline": [
|
||||
{
|
||||
"Second": 0,
|
||||
"Movements": [
|
||||
{
|
||||
"ModuleId": "11",
|
||||
"ModuleType": "Servo",
|
||||
"Degree": 180.0,
|
||||
"Direction": 1,
|
||||
"Track": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Robot Configuration
|
||||
|
||||
- **FlatBuffers** format: `RobotConfiguration`, `RobotModule`, `MotorState`, `ModuleConnection`, etc.
|
||||
- Generated types in `Assets/Flatbuffers_generated/`.
|
||||
|
||||
---
|
||||
|
||||
## Building
|
||||
|
||||
Build targets are configured in `Assets/Editor/BuildScript.cs`:
|
||||
|
||||
|
||||
| Platform | Output |
|
||||
| -------- | ------------------------------ |
|
||||
| Windows | `Builds/Windows/botchain.exe` |
|
||||
| Linux | `Builds/Linux/botchain.x86_64` |
|
||||
| macOS | `Builds/macOS/botchain.app` |
|
||||
|
||||
|
||||
### Default Resolution
|
||||
|
||||
- 1920×1080 (configurable in Project Settings)
|
||||
|
||||
---
|
||||
|
||||
## Key Scripts Reference
|
||||
|
||||
|
||||
| Script | Purpose |
|
||||
| ---------------------------------- | ------------------------------------------------------ |
|
||||
| `ModuleBase.cs` | Base for all modules; sends commands to ControlLibrary |
|
||||
| `ModuleSpawner.cs` | Spawns module prefabs by type |
|
||||
| `TopologyBuilder.cs` | Builds topology from JSON or native config |
|
||||
| `TopologyGraphModel.cs` | Graph data structures |
|
||||
| `ModuleSelector.cs` | Tracks selected module |
|
||||
| `ControlLibrary.cs` | P/Invoke bridge to `libc_control` |
|
||||
| `ViewBannerUI.cs` | Top banner and view switching |
|
||||
| `LiveViewModulePanel.cs` | Live view side panel |
|
||||
| `InverseKinematicsController.cs` | CCD IK solver |
|
||||
| `PositionControlGizmo.cs` | 3D drag gizmo for IK |
|
||||
| `ProgrammedMovementsController.cs` | Timeline UI and playback |
|
||||
| `DiscoverOverlayController.cs` | Discovery overlay UI |
|
||||
|
||||
|
||||
127
convert_tmp_to_text.py
Normal file
127
convert_tmp_to_text.py
Normal file
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Bulk-convert TextMeshProUGUI components to Unity UI Text in a .unity scene file."""
|
||||
import re, sys
|
||||
|
||||
TMP_GUID = "f4688fdb7df04437aeb418b961361dc5"
|
||||
TEXT_GUID = "5f7201a12d95ffc409449d95f23cf332"
|
||||
ARIAL_FONT = "{fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}"
|
||||
|
||||
# Already converted IDs (skip these)
|
||||
ALREADY_DONE = {"960000007", "1501844973", "1385057283"}
|
||||
|
||||
def extract_prop(block, key):
|
||||
m = re.search(rf'^\s+{key}:\s*(.+)$', block, re.MULTILINE)
|
||||
return m.group(1).strip() if m else None
|
||||
|
||||
def alignment_from_tmp(h_align, v_align):
|
||||
h = int(h_align) if h_align else 1
|
||||
v = int(v_align) if v_align else 256
|
||||
col = {1: 0, 2: 1, 4: 2, 8: 0}.get(h, 0) # Left=0, Center=1, Right=2
|
||||
row = {256: 0, 512: 1, 1024: 2}.get(v, 0) # Upper=0, Middle=1, Lower=2
|
||||
return row * 3 + col
|
||||
|
||||
def convert_block(block, file_id, game_obj_id):
|
||||
text = extract_prop(block, "m_text") or ""
|
||||
font_size = extract_prop(block, "m_fontSize") or "22"
|
||||
font_style = extract_prop(block, "m_fontStyle") or "0"
|
||||
color_r = color_g = color_b = color_a = None
|
||||
color_match = re.search(r'm_Color:\s*\{r:\s*([\d.]+),\s*g:\s*([\d.]+),\s*b:\s*([\d.]+),\s*a:\s*([\d.]+)\}', block)
|
||||
if color_match:
|
||||
color_r, color_g, color_b, color_a = color_match.groups()
|
||||
raycast = extract_prop(block, "m_RaycastTarget") or "1"
|
||||
h_align = extract_prop(block, "m_HorizontalAlignment")
|
||||
v_align = extract_prop(block, "m_VerticalAlignment")
|
||||
alignment = alignment_from_tmp(h_align, v_align)
|
||||
|
||||
color_str = f"{{r: {color_r}, g: {color_g}, b: {color_b}, a: {color_a}}}" if color_r else "{r: 1, g: 1, b: 1, a: 1}"
|
||||
|
||||
font_size_int = int(float(font_size))
|
||||
|
||||
return f"""--- !u!114 &{file_id}
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {{fileID: 0}}
|
||||
m_PrefabInstance: {{fileID: 0}}
|
||||
m_PrefabAsset: {{fileID: 0}}
|
||||
m_GameObject: {{fileID: {game_obj_id}}}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {{fileID: 11500000, guid: {TEXT_GUID}, type: 3}}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {{fileID: 0}}
|
||||
m_Color: {color_str}
|
||||
m_RaycastTarget: {raycast}
|
||||
m_RaycastPadding: {{x: 0, y: 0, z: 0, w: 0}}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {ARIAL_FONT}
|
||||
m_FontSize: {font_size_int}
|
||||
m_FontStyle: {font_style}
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: {alignment}
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: {text}"""
|
||||
|
||||
def main():
|
||||
path = sys.argv[1] if len(sys.argv) > 1 else "Assets/Scenes/SampleScene.unity"
|
||||
with open(path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Split into YAML documents (each starting with --- !u!)
|
||||
parts = re.split(r'(--- !u!\d+ &\d+)', content)
|
||||
|
||||
converted = 0
|
||||
result = []
|
||||
i = 0
|
||||
while i < len(parts):
|
||||
if i + 1 < len(parts) and parts[i].startswith('--- !u!'):
|
||||
header = parts[i]
|
||||
body = parts[i + 1]
|
||||
|
||||
file_id_match = re.search(r'&(\d+)', header)
|
||||
file_id = file_id_match.group(1) if file_id_match else None
|
||||
|
||||
if file_id and file_id not in ALREADY_DONE and TMP_GUID in body:
|
||||
game_obj_match = re.search(r'm_GameObject:\s*\{fileID:\s*(\d+)', body)
|
||||
game_obj_id = game_obj_match.group(1) if game_obj_match else "0"
|
||||
|
||||
full_block = header + body
|
||||
new_block = convert_block(full_block, file_id, game_obj_id)
|
||||
|
||||
# Find where the next --- !u! starts in body, keep the rest
|
||||
next_header_pos = body.find('\n--- !u!')
|
||||
if next_header_pos >= 0:
|
||||
remainder = body[next_header_pos:]
|
||||
result.append(new_block + remainder)
|
||||
else:
|
||||
result.append(new_block + '\n')
|
||||
|
||||
converted += 1
|
||||
i += 2
|
||||
continue
|
||||
|
||||
result.append(header)
|
||||
result.append(body)
|
||||
i += 2
|
||||
else:
|
||||
result.append(parts[i])
|
||||
i += 1
|
||||
|
||||
output = ''.join(result)
|
||||
with open(path, 'w') as f:
|
||||
f.write(output)
|
||||
|
||||
print(f"Converted {converted} TMP components to Unity Text")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user