Init commit

This commit is contained in:
assada 2022-08-18 22:20:07 +03:00
parent 7783eda507
commit b5203d93dd
36 changed files with 11330 additions and 0 deletions

32
README.md Normal file
View File

@ -0,0 +1,32 @@
# UDrone
Flightcondroller for PX4 from browser via mqtt-mavlink bridge
## Requiremens
* Docker (for MQTT server. Also can be run at host without docker)
* Python 3
* Nodejs
*(full migration to docker in progress)*
## Starting
### Prepare frontend
```bash
npm install
cd node_modules/mqtt
npm install
webpack mqtt.js --output-library mqtt
npm run build
```
### Prepare backend
```bash
docker-compose up
```
### Run
```bash
python3 server/bridge.py
python3 server/server.py
```

52
css/flightindicators.css Normal file
View File

@ -0,0 +1,52 @@
/*
* jQuery Flight Indicators plugin
* By Sébastien Matton (seb_matton@hotmail.com)
* Published under GPLv3 License.
*
* https://github.com/sebmatton/jQuery-Flight-Indicators
*/
/* Global block of an indicator*/
div.instrument {
width: 250px;
height: 250px;
position: relative;
display: inline-block;
overflow: hidden;
}
/* The box containing any element of an indicator */
div.instrument .box {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* Default transformations */
div.instrument.attitude div.roll {
transform: rotate(0deg);
}
div.instrument.attitude div.roll div.pitch {
top: 0%;
}
div.instrument.heading div.yaw {
transform: rotate(0deg);
}
div.instrument.vario div.vario {
transform: rotate(0deg);
}
div.instrument.speed div.airspeed {
transform: rotate(90deg);
}
div.instrument.altimeter div.pressure {
transform: rotate(40deg);
}
div.instrument.altimeter div.needle {
transform: rotate(90deg);
}
div.instrument.altimeter div.needleSmall {
transform: rotate(90deg);
}

8
css/flightindicators.min.css vendored Normal file
View File

@ -0,0 +1,8 @@
/*
* jQuery Flight Indicators plugin
* By Sébastien Matton (seb_matton@hotmail.com)
* Published under GPLv3 License.
*
* https://github.com/sebmatton/jQuery-Flight-Indicators
*/
div.instrument{width:250px;height:250px;position:relative;display:inline-block;overflow:hidden}div.instrument .box{position:absolute;top:0;left:0;width:100%;height:100%}div.instrument.attitude div.roll{transform:rotate(0deg)}div.instrument.attitude div.roll div.pitch{top:0}div.instrument.heading div.yaw,div.instrument.vario div.vario{transform:rotate(0deg)}div.instrument.speed div.airspeed{transform:rotate(90deg)}div.instrument.altimeter div.pressure{transform:rotate(40deg)}div.instrument.altimeter div.needle,div.instrument.altimeter div.needleSmall{transform:rotate(90deg)}

237
dashboard.html Normal file
View File

@ -0,0 +1,237 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Dashboard</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<style>
body {
min-height: 100vh;
min-height: -webkit-fill-available;
}
html {
height: -webkit-fill-available;
}
main {
display: flex;
flex-wrap: nowrap;
height: 100vh;
height: -webkit-fill-available;
max-height: 100vh;
overflow-x: auto;
overflow-y: hidden;
}
.b-example-divider {
flex-shrink: 0;
width: 1.5rem;
height: 100vh;
background-color: rgba(255, 255, 255, .1);
border: solid rgba(0, 0, 0, .15);
border-width: 1px 0;
box-shadow: inset 0 .5em 1.5em rgba(230, 230, 230, .1), inset 0 .125em .5em rgba(255, 255, 255, .15);
}
.bi {
vertical-align: -.125em;
pointer-events: none;
fill: currentColor;
}
.dropdown-toggle { outline: 0; }
.nav-flush .nav-link {
border-radius: 0;
}
.btn-toggle {
display: inline-flex;
align-items: center;
padding: .25rem .5rem;
font-weight: 600;
color: rgba(0, 0, 0, .65);
background-color: transparent;
border: 0;
}
.btn-toggle:hover,
.btn-toggle:focus {
color: rgba(0, 0, 0, .85);
background-color: #d2f4ea;
}
.btn-toggle::before {
width: 1.25em;
line-height: 0;
content: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%280,0,0,.5%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e");
transition: transform .35s ease;
transform-origin: .5em 50%;
}
.btn-toggle[aria-expanded="true"] {
color: rgba(0, 0, 0, .85);
}
.btn-toggle[aria-expanded="true"]::before {
transform: rotate(90deg);
}
.btn-toggle-nav a {
display: inline-flex;
padding: .1875rem .5rem;
margin-top: .125rem;
margin-left: 1.25rem;
text-decoration: none;
}
.btn-toggle-nav a:hover,
.btn-toggle-nav a:focus {
background-color: #d2f4ea;
}
.scrollarea {
overflow-y: auto;
}
.fw-semibold { font-weight: 600; }
.lh-tight { line-height: 1.25; }
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="bootstrap" viewBox="0 0 118 94">
<title>Bootstrap</title>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.509 0c-6.733 0-11.715 5.893-11.492 12.284.214 6.14-.064 14.092-2.066 20.577C8.943 39.365 5.547 43.485 0 44.014v5.972c5.547.529 8.943 4.649 10.951 11.153 2.002 6.485 2.28 14.437 2.066 20.577C12.794 88.106 17.776 94 24.51 94H93.5c6.733 0 11.714-5.893 11.491-12.284-.214-6.14.064-14.092 2.066-20.577 2.009-6.504 5.396-10.624 10.943-11.153v-5.972c-5.547-.529-8.934-4.649-10.943-11.153-2.002-6.484-2.28-14.437-2.066-20.577C105.214 5.894 100.233 0 93.5 0H24.508zM80 57.863C80 66.663 73.436 72 62.543 72H44a2 2 0 01-2-2V24a2 2 0 012-2h18.437c9.083 0 15.044 4.92 15.044 12.474 0 5.302-4.01 10.049-9.119 10.88v.277C75.317 46.394 80 51.21 80 57.863zM60.521 28.34H49.948v14.934h8.905c6.884 0 10.68-2.772 10.68-7.727 0-4.643-3.264-7.207-9.012-7.207zM49.948 49.2v16.458H60.91c7.167 0 10.964-2.876 10.964-8.281 0-5.406-3.903-8.178-11.425-8.178H49.948z"></path>
</symbol>
<symbol id="home" viewBox="0 0 16 16">
<path d="M8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4.5a.5.5 0 0 0 .5-.5v-4h2v4a.5.5 0 0 0 .5.5H14a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146zM2.5 14V7.707l5.5-5.5 5.5 5.5V14H10v-4a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v4H2.5z"></path>
</symbol>
<symbol id="speedometer2" viewBox="0 0 16 16">
<path d="M8 4a.5.5 0 0 1 .5.5V6a.5.5 0 0 1-1 0V4.5A.5.5 0 0 1 8 4zM3.732 5.732a.5.5 0 0 1 .707 0l.915.914a.5.5 0 1 1-.708.708l-.914-.915a.5.5 0 0 1 0-.707zM2 10a.5.5 0 0 1 .5-.5h1.586a.5.5 0 0 1 0 1H2.5A.5.5 0 0 1 2 10zm9.5 0a.5.5 0 0 1 .5-.5h1.5a.5.5 0 0 1 0 1H12a.5.5 0 0 1-.5-.5zm.754-4.246a.389.389 0 0 0-.527-.02L7.547 9.31a.91.91 0 1 0 1.302 1.258l3.434-4.297a.389.389 0 0 0-.029-.518z"></path>
<path fill-rule="evenodd" d="M0 10a8 8 0 1 1 15.547 2.661c-.442 1.253-1.845 1.602-2.932 1.25C11.309 13.488 9.475 13 8 13c-1.474 0-3.31.488-4.615.911-1.087.352-2.49.003-2.932-1.25A7.988 7.988 0 0 1 0 10zm8-7a7 7 0 0 0-6.603 9.329c.203.575.923.876 1.68.63C4.397 12.533 6.358 12 8 12s3.604.532 4.923.96c.757.245 1.477-.056 1.68-.631A7 7 0 0 0 8 3z"></path>
</symbol>
<symbol id="table" viewBox="0 0 16 16">
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm15 2h-4v3h4V4zm0 4h-4v3h4V8zm0 4h-4v3h3a1 1 0 0 0 1-1v-2zm-5 3v-3H6v3h4zm-5 0v-3H1v2a1 1 0 0 0 1 1h3zm-4-4h4V8H1v3zm0-4h4V4H1v3zm5-3v3h4V4H6zm4 4H6v3h4V8z"></path>
</symbol>
<symbol id="people-circle" viewBox="0 0 16 16">
<path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"></path>
<path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"></path>
</symbol>
<symbol id="grid" viewBox="0 0 16 16">
<path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5v-3zM2.5 2a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zM1 10.5A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3z"></path>
</symbol>
<symbol id="collection" viewBox="0 0 16 16">
<path d="M2.5 3.5a.5.5 0 0 1 0-1h11a.5.5 0 0 1 0 1h-11zm2-2a.5.5 0 0 1 0-1h7a.5.5 0 0 1 0 1h-7zM0 13a1.5 1.5 0 0 0 1.5 1.5h13A1.5 1.5 0 0 0 16 13V6a1.5 1.5 0 0 0-1.5-1.5h-13A1.5 1.5 0 0 0 0 6v7zm1.5.5A.5.5 0 0 1 1 13V6a.5.5 0 0 1 .5-.5h13a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-.5.5h-13z"></path>
</symbol>
<symbol id="calendar3" viewBox="0 0 16 16">
<path d="M14 0H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zM1 3.857C1 3.384 1.448 3 2 3h12c.552 0 1 .384 1 .857v10.286c0 .473-.448.857-1 .857H2c-.552 0-1-.384-1-.857V3.857z"></path>
<path d="M6.5 7a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm-9 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm-9 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"></path>
</symbol>
<symbol id="chat-quote-fill" viewBox="0 0 16 16">
<path d="M16 8c0 3.866-3.582 7-8 7a9.06 9.06 0 0 1-2.347-.306c-.584.296-1.925.864-4.181 1.234-.2.032-.352-.176-.273-.362.354-.836.674-1.95.77-2.966C.744 11.37 0 9.76 0 8c0-3.866 3.582-7 8-7s8 3.134 8 7zM7.194 6.766a1.688 1.688 0 0 0-.227-.272 1.467 1.467 0 0 0-.469-.324l-.008-.004A1.785 1.785 0 0 0 5.734 6C4.776 6 4 6.746 4 7.667c0 .92.776 1.666 1.734 1.666.343 0 .662-.095.931-.26-.137.389-.39.804-.81 1.22a.405.405 0 0 0 .011.59c.173.16.447.155.614-.01 1.334-1.329 1.37-2.758.941-3.706a2.461 2.461 0 0 0-.227-.4zM11 9.073c-.136.389-.39.804-.81 1.22a.405.405 0 0 0 .012.59c.172.16.446.155.613-.01 1.334-1.329 1.37-2.758.942-3.706a2.466 2.466 0 0 0-.228-.4 1.686 1.686 0 0 0-.227-.273 1.466 1.466 0 0 0-.469-.324l-.008-.004A1.785 1.785 0 0 0 10.07 6c-.957 0-1.734.746-1.734 1.667 0 .92.777 1.666 1.734 1.666.343 0 .662-.095.931-.26z"></path>
</symbol>
<symbol id="cpu-fill" viewBox="0 0 16 16">
<path d="M6.5 6a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3z"></path>
<path d="M5.5.5a.5.5 0 0 0-1 0V2A2.5 2.5 0 0 0 2 4.5H.5a.5.5 0 0 0 0 1H2v1H.5a.5.5 0 0 0 0 1H2v1H.5a.5.5 0 0 0 0 1H2v1H.5a.5.5 0 0 0 0 1H2A2.5 2.5 0 0 0 4.5 14v1.5a.5.5 0 0 0 1 0V14h1v1.5a.5.5 0 0 0 1 0V14h1v1.5a.5.5 0 0 0 1 0V14h1v1.5a.5.5 0 0 0 1 0V14a2.5 2.5 0 0 0 2.5-2.5h1.5a.5.5 0 0 0 0-1H14v-1h1.5a.5.5 0 0 0 0-1H14v-1h1.5a.5.5 0 0 0 0-1H14v-1h1.5a.5.5 0 0 0 0-1H14A2.5 2.5 0 0 0 11.5 2V.5a.5.5 0 0 0-1 0V2h-1V.5a.5.5 0 0 0-1 0V2h-1V.5a.5.5 0 0 0-1 0V2h-1V.5zm1 4.5h3A1.5 1.5 0 0 1 11 6.5v3A1.5 1.5 0 0 1 9.5 11h-3A1.5 1.5 0 0 1 5 9.5v-3A1.5 1.5 0 0 1 6.5 5z"></path>
</symbol>
<symbol id="gear-fill" viewBox="0 0 16 16">
<path d="M9.405 1.05c-.413-1.4-2.397-1.4-2.81 0l-.1.34a1.464 1.464 0 0 1-2.105.872l-.31-.17c-1.283-.698-2.686.705-1.987 1.987l.169.311c.446.82.023 1.841-.872 2.105l-.34.1c-1.4.413-1.4 2.397 0 2.81l.34.1a1.464 1.464 0 0 1 .872 2.105l-.17.31c-.698 1.283.705 2.686 1.987 1.987l.311-.169a1.464 1.464 0 0 1 2.105.872l.1.34c.413 1.4 2.397 1.4 2.81 0l.1-.34a1.464 1.464 0 0 1 2.105-.872l.31.17c1.283.698 2.686-.705 1.987-1.987l-.169-.311a1.464 1.464 0 0 1 .872-2.105l.34-.1c1.4-.413 1.4-2.397 0-2.81l-.34-.1a1.464 1.464 0 0 1-.872-2.105l.17-.31c.698-1.283-.705-2.686-1.987-1.987l-.311.169a1.464 1.464 0 0 1-2.105-.872l-.1-.34zM8 10.93a2.929 2.929 0 1 1 0-5.86 2.929 2.929 0 0 1 0 5.858z"></path>
</symbol>
<symbol id="speedometer" viewBox="0 0 16 16">
<path d="M8 2a.5.5 0 0 1 .5.5V4a.5.5 0 0 1-1 0V2.5A.5.5 0 0 1 8 2zM3.732 3.732a.5.5 0 0 1 .707 0l.915.914a.5.5 0 1 1-.708.708l-.914-.915a.5.5 0 0 1 0-.707zM2 8a.5.5 0 0 1 .5-.5h1.586a.5.5 0 0 1 0 1H2.5A.5.5 0 0 1 2 8zm9.5 0a.5.5 0 0 1 .5-.5h1.5a.5.5 0 0 1 0 1H12a.5.5 0 0 1-.5-.5zm.754-4.246a.389.389 0 0 0-.527-.02L7.547 7.31A.91.91 0 1 0 8.85 8.569l3.434-4.297a.389.389 0 0 0-.029-.518z"></path>
<path fill-rule="evenodd" d="M6.664 15.889A8 8 0 1 1 9.336.11a8 8 0 0 1-2.672 15.78zm-4.665-4.283A11.945 11.945 0 0 1 8 10c2.186 0 4.236.585 6.001 1.606a7 7 0 1 0-12.002 0z"></path>
</symbol>
<symbol id="toggles2" viewBox="0 0 16 16">
<path d="M9.465 10H12a2 2 0 1 1 0 4H9.465c.34-.588.535-1.271.535-2 0-.729-.195-1.412-.535-2z"></path>
<path d="M6 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 1a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm.535-10a3.975 3.975 0 0 1-.409-1H4a1 1 0 0 1 0-2h2.126c.091-.355.23-.69.41-1H4a2 2 0 1 0 0 4h2.535z"></path>
<path d="M14 4a4 4 0 1 1-8 0 4 4 0 0 1 8 0z"></path>
</symbol>
<symbol id="tools" viewBox="0 0 16 16">
<path d="M1 0L0 1l2.2 3.081a1 1 0 0 0 .815.419h.07a1 1 0 0 1 .708.293l2.675 2.675-2.617 2.654A3.003 3.003 0 0 0 0 13a3 3 0 1 0 5.878-.851l2.654-2.617.968.968-.305.914a1 1 0 0 0 .242 1.023l3.356 3.356a1 1 0 0 0 1.414 0l1.586-1.586a1 1 0 0 0 0-1.414l-3.356-3.356a1 1 0 0 0-1.023-.242L10.5 9.5l-.96-.96 2.68-2.643A3.005 3.005 0 0 0 16 3c0-.269-.035-.53-.102-.777l-2.14 2.141L12 4l-.364-1.757L13.777.102a3 3 0 0 0-3.675 3.68L7.462 6.46 4.793 3.793a1 1 0 0 1-.293-.707v-.071a1 1 0 0 0-.419-.814L1 0zm9.646 10.646a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708zM3 11l.471.242.529.026.287.445.445.287.026.529L5 13l-.242.471-.026.529-.445.287-.287.445-.529.026L3 15l-.471-.242L2 14.732l-.287-.445L1.268 14l-.026-.529L1 13l.242-.471.026-.529.445-.287.287-.445.529-.026L3 11z"></path>
</symbol>
<symbol id="chevron-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"></path>
</symbol>
<symbol id="geo-fill" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M4 4a4 4 0 1 1 4.5 3.969V13.5a.5.5 0 0 1-1 0V7.97A4 4 0 0 1 4 3.999zm2.493 8.574a.5.5 0 0 1-.411.575c-.712.118-1.28.295-1.655.493a1.319 1.319 0 0 0-.37.265.301.301 0 0 0-.057.09V14l.002.008a.147.147 0 0 0 .016.033.617.617 0 0 0 .145.15c.165.13.435.27.813.395.751.25 1.82.414 3.024.414s2.273-.163 3.024-.414c.378-.126.648-.265.813-.395a.619.619 0 0 0 .146-.15.148.148 0 0 0 .015-.033L12 14v-.004a.301.301 0 0 0-.057-.09 1.318 1.318 0 0 0-.37-.264c-.376-.198-.943-.375-1.655-.493a.5.5 0 1 1 .164-.986c.77.127 1.452.328 1.957.594C12.5 13 13 13.4 13 14c0 .426-.26.752-.544.977-.29.228-.68.413-1.116.558-.878.293-2.059.465-3.34.465-1.281 0-2.462-.172-3.34-.465-.436-.145-.826-.33-1.116-.558C3.26 14.752 3 14.426 3 14c0-.599.5-1 .961-1.243.505-.266 1.187-.467 1.957-.594a.5.5 0 0 1 .575.411z"></path>
</symbol>
</svg>
<main>
<div class="d-flex flex-column flex-shrink-0 p-3 text-white bg-dark" style="width: 280px;">
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32"><use xlink:href="#bootstrap"></use></svg>
<span class="fs-4">UDrone</span>
</a>
<hr>
<ul class="nav nav-pills flex-column mb-auto">
<li class="nav-item">
<a href="#" class="nav-link active" aria-current="page">
<svg class="bi me-2" width="16" height="16"><use xlink:href="#home"></use></svg>
Головна
</a>
</li>
<li>
<a href="#" class="nav-link text-white">
<svg class="bi me-2" width="16" height="16"><use xlink:href="#speedometer2"></use></svg>
Мої дрони
</a>
</li>
<li>
<a href="map.html" class="nav-link text-white">
<svg class="bi me-2" width="16" height="16"><use xlink:href="#table"></use></svg>
Мапа
</a>
</li>
<li>
<a href="#" class="nav-link text-white">
<svg class="bi me-2" width="16" height="16"><use xlink:href="#grid"></use></svg>
Інформація
</a>
</li>
<li>
<a href="#" class="nav-link text-white">
<svg class="bi me-2" width="16" height="16"><use xlink:href="#people-circle"></use></svg>
Допомога
</a>
</li>
</ul>
<hr>
<div class="dropdown">
<a href="#" class="d-flex align-items-center text-white text-decoration-none dropdown-toggle" id="dropdownUser1" data-bs-toggle="dropdown" aria-expanded="false">
<img src="https://github.com/mdo.png" alt="" width="32" height="32" class="rounded-circle me-2">
<strong>ilienko</strong>
</a>
<ul class="dropdown-menu dropdown-menu-dark text-small shadow" aria-labelledby="dropdownUser1">
<!-- <li><hr class="dropdown-divider"></li>-->
<li><a class="dropdown-item" href="index.html">Вихід</a></li>
</ul>
</div>
</div>
<div class="b-example-divider"></div>
<div class="row">
<div class="col-md-12">
<h1>
Головна
</h1>
</div>
</div>
</main>
<script src="/docs/5.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<script src="sidebars.js"></script>
<a style="display: none; " id="exifview-absolute-url-convert-proxy" href="dummy"></a>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>

0
dist/.gitkeep vendored Normal file
View File

2
dist/bundle.js vendored Normal file

File diff suppressed because one or more lines are too long

35
dist/bundle.js.LICENSE.txt vendored Normal file
View File

@ -0,0 +1,35 @@
/*!
* Sizzle CSS Selector Engine v2.3.6
* https://sizzlejs.com/
*
* Copyright JS Foundation and other contributors
* Released under the MIT license
* https://js.foundation/
*
* Date: 2021-02-16
*/
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*/
/*!
* jQuery JavaScript Library v3.6.0
* https://jquery.com/
*
* Includes Sizzle.js
* https://sizzlejs.com/
*
* Copyright OpenJS Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
* Date: 2021-03-02T17:08Z
*/
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */

10
docker-compose.yml Normal file
View File

@ -0,0 +1,10 @@
version: "3"
services:
mosquitto:
image: eclipse-mosquitto
volumes:
- ./:/mosquitto/:rw
ports:
- 1883:1883
- 9001:9001

View File

@ -0,0 +1,14 @@
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
allow_anonymous true
allow_duplicate_messages true
connection_messages true
listener 1883
protocol mqtt
listener 9001
protocol websockets

47
gui.html Normal file
View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/relaxed-json@1.0.3/relaxed-json.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mqtt/4.3.7/mqtt.js" integrity="sha512-yX4jaiU9Ai9dzaimFoTq+tQYOrAMNP+EWiiUVsru3ypsAi76c0zCPBfxKagLkKjC4ZeLMEQTa7aE7CtjTmlgDA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body>
</body>
<script>
//const mqtt = require('mqtt')
const options = {
// Clean session
clean: true,
connectTimeout: 4000,
// Auth
clientId: 'emqx_test'
}
const client = mqtt.connect('ws://localhost:9001', options)
client.on('connect', function () {
console.log('Connected!')
client.subscribe('a1/#', function (err) {
if (!err) {
console.log('Subscribed!');
}
})
})
client.on('message', function (topic, message) {
let relaxedString = message.toString();
try {
let jsonString = RJSON.transform(relaxedString);
let obj = JSON.parse(jsonString);
console.log(topic, obj);
} catch {
console.log(relaxedString)
}
//client.end()
})
</script>
</html>

463
img/altitude_pressure.svg Normal file
View File

@ -0,0 +1,463 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="400px" height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve">
<defs>
<style type="text/css">
@import url('http://fonts.googleapis.com/css?family=Noto+Sans+KR|Nanum+Gothic+Coding');
</style>
</defs>
<style>
.marks {
transform: translate(50%, 50%);
}
.marks line {
--base-angle: 270deg;
--base-stroke-width: 1;
transform: rotate(var(--base-angle));
stroke-width: var(--base-stroke-width);
fill: none;
stroke: white;
stroke-miterlimit: 10;
}
.marks .long-ticks .tick {
--base-stroke-width: 2;
}
.marks .long-ticks .tick:nth-child(2) {
--base-angle: 280deg;
}
.marks .long-ticks .tick:nth-child(3) {
--base-angle: 290deg;
}
.marks .long-ticks .tick:nth-child(4) {
--base-angle: 300deg;
}
.marks .long-ticks .tick:nth-child(5) {
--base-angle: 310deg;
}
.marks .long-ticks .tick:nth-child(6) {
--base-angle: 320deg;
}
.marks .long-ticks .tick:nth-child(7) {
--base-angle: 330deg;
}
.marks .long-ticks .tick:nth-child(8) {
--base-angle: 340deg;
}
.marks .long-ticks .tick:nth-child(9) {
--base-angle: 350deg;
}
.marks .long-ticks .tick:nth-child(10) {
--base-angle: 0deg;
}
.marks .long-ticks .tick:nth-child(11) {
--base-angle: 10deg;
}
.marks .long-ticks .tick:nth-child(12) {
--base-angle: 20deg;
}
.marks .short-ticks .tick:nth-child(1) {
--base-angle: 262deg;
}
.marks .short-ticks .tick:nth-child(2) {
--base-angle: 264deg;
}
.marks .short-ticks .tick:nth-child(3) {
--base-angle: 266deg;
}
.marks .short-ticks .tick:nth-child(4) {
--base-angle: 268deg;
}
.marks .short-ticks .tick:nth-child(5) {
--base-angle: 272deg;
}
.marks .short-ticks .tick:nth-child(6) {
--base-angle: 274deg;
}
.marks .short-ticks .tick:nth-child(7) {
--base-angle: 276deg;
}
.marks .short-ticks .tick:nth-child(8) {
--base-angle: 278deg;
}
.marks .short-ticks .tick:nth-child(9) {
--base-angle: 282deg;
}
.marks .short-ticks .tick:nth-child(10) {
--base-angle: 284deg;
}
.marks .short-ticks .tick:nth-child(11) {
--base-angle: 286deg;
}
.marks .short-ticks .tick:nth-child(12) {
--base-angle: 288deg;
}
.marks .short-ticks .tick:nth-child(13) {
--base-angle: 292deg;
}
.marks .short-ticks .tick:nth-child(14) {
--base-angle: 294deg;
}
.marks .short-ticks .tick:nth-child(15) {
--base-angle: 296deg;
}
.marks .short-ticks .tick:nth-child(16) {
--base-angle: 298deg;
}
.marks .short-ticks .tick:nth-child(17) {
--base-angle: 302deg;
}
.marks .short-ticks .tick:nth-child(18) {
--base-angle: 304deg;
}
.marks .short-ticks .tick:nth-child(19) {
--base-angle: 306deg;
}
.marks .short-ticks .tick:nth-child(20) {
--base-angle: 308deg;
}
.marks .short-ticks .tick:nth-child(21) {
--base-angle: 312deg;
}
.marks .short-ticks .tick:nth-child(22) {
--base-angle: 314deg;
}
.marks .short-ticks .tick:nth-child(23) {
--base-angle: 316deg;
}
.marks .short-ticks .tick:nth-child(24) {
--base-angle: 318deg;
}
.marks .short-ticks .tick:nth-child(25) {
--base-angle: 322deg;
}
.marks .short-ticks .tick:nth-child(26) {
--base-angle: 324deg;
}
.marks .short-ticks .tick:nth-child(27) {
--base-angle: 326deg;
}
.marks .short-ticks .tick:nth-child(28) {
--base-angle: 328deg;
}
.marks .short-ticks .tick:nth-child(29) {
--base-angle: 332deg;
}
.marks .short-ticks .tick:nth-child(30) {
--base-angle: 334deg;
}
.marks .short-ticks .tick:nth-child(31) {
--base-angle: 336deg;
}
.marks .short-ticks .tick:nth-child(32) {
--base-angle: 338deg;
}
.marks .short-ticks .tick:nth-child(33) {
--base-angle: 342deg;
}
.marks .short-ticks .tick:nth-child(34) {
--base-angle: 344deg;
}
.marks .short-ticks .tick:nth-child(35) {
--base-angle: 346deg;
}
.marks .short-ticks .tick:nth-child(36) {
--base-angle: 348deg;
}
.marks .short-ticks .tick:nth-child(37) {
--base-angle: 352deg;
}
.marks .short-ticks .tick:nth-child(38) {
--base-angle: 354deg;
}
.marks .short-ticks .tick:nth-child(39) {
--base-angle: 356deg;
}
.marks .short-ticks .tick:nth-child(40) {
--base-angle: 358deg;
}
.marks .short-ticks .tick:nth-child(41) {
--base-angle: 2deg;
}
.marks .short-ticks .tick:nth-child(42) {
--base-angle: 4deg;
}
.marks .short-ticks .tick:nth-child(43) {
--base-angle: 6deg;
}
.marks .short-ticks .tick:nth-child(44) {
--base-angle: 8deg;
}
.marks .short-ticks .tick:nth-child(45) {
--base-angle: 12deg;
}
.marks .short-ticks .tick:nth-child(46) {
--base-angle: 14deg;
}
.marks .short-ticks .tick:nth-child(47) {
--base-angle: 16deg;
}
.marks .short-ticks .tick:nth-child(48) {
--base-angle: 18deg;
}
.marks .short-ticks .tick:nth-child(49) {
--base-angle: 22deg;
}
.marks .short-ticks .tick:nth-child(50) {
--base-angle: 24deg;
}
.marks .short-ticks .tick:nth-child(51) {
--base-angle: 26deg;
}
.marks .short-ticks .tick:nth-child(52) {
--base-angle: 28deg;
}
.marks .short-ticks .tick:nth-child(53) {
--base-angle: 32deg;
}
.marks .short-ticks .tick:nth-child(54) {
--base-angle: 34deg;
}
.marks .short-ticks .tick:nth-child(55) {
--base-angle: 36deg;
}
.marks .short-ticks .tick:nth-child(56) {
--base-angle: 38deg;
}
.mark-labels {
--base-x: 50%;
--base-y: 50%;
transform: translate(var(--base-x), var(--base-y));
}
.mark-labels>text {
--base-angle: 270deg;
font-family: Noto Sans KR, sans-serif;
font-size: 10px;
font-weight: 400;
fill: white;
dominant-baseline: middle;
text-anchor: middle;
transform: rotate(var(--base-angle));
}
.mark-labels .numerical {}
.mark-labels .numerical:nth-child(1) {
--base-angle: 20deg;
}
.mark-labels .numerical:nth-child(2) {
--base-angle: 10deg;
}
.mark-labels .numerical:nth-child(3) {
--base-angle: 0deg;
}
.mark-labels .numerical:nth-child(4) {
--base-angle: 350deg;
}
.mark-labels .numerical:nth-child(5) {
--base-angle: 340deg;
}
.mark-labels .numerical:nth-child(6) {
--base-angle: 330deg;
}
.mark-labels .numerical:nth-child(7) {
--base-angle: 320deg;
}
.mark-labels .numerical:nth-child(8) {
--base-angle: 310deg;
}
.mark-labels .numerical:nth-child(9) {
--base-angle: 300deg;
}
.mark-labels .numerical:nth-child(10) {
--base-angle: 290deg;
}
.mark-labels .numerical:nth-child(11) {
--base-angle: 280deg;
}
.mark-labels .numerical:nth-child(12) {
--base-angle: 270deg;
}
</style>
<circle fill="#232323" cx="200" cy="200" r="35%" />
<g class="marks">
<g class="long-ticks">
<line class="tick" x1="113" y1="0" x2="124" y2="0" />
<line class="tick" x1="113" y1="0" x2="124" y2="0" />
<line class="tick" x1="113" y1="0" x2="124" y2="0" />
<line class="tick" x1="113" y1="0" x2="124" y2="0" />
<line class="tick" x1="113" y1="0" x2="124" y2="0" />
<line class="tick" x1="113" y1="0" x2="124" y2="0" />
<line class="tick" x1="113" y1="0" x2="124" y2="0" />
<line class="tick" x1="113" y1="0" x2="124" y2="0" />
<line class="tick" x1="113" y1="0" x2="124" y2="0" />
<line class="tick" x1="113" y1="0" x2="124" y2="0" />
<line class="tick" x1="113" y1="0" x2="124" y2="0" />
<line class="tick" x1="113" y1="0" x2="124" y2="0" />
</g>
<g class="short-ticks">
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
<line class="tick" x1="115" y1="0" x2="122" y2="0" />
</g>
</g>
<g class="mark-labels">
<text class="numerical" x="100" y="0">980</text>
<text class="numerical" x="100" y="0">985</text>
<text class="numerical" x="100" y="0">990</text>
<text class="numerical" x="100" y="0">995</text>
<text class="numerical" x="100" y="0">1000</text>
<text class="numerical" x="100" y="0">1005</text>
<text class="numerical" x="100" y="0">1010</text>
<text class="numerical" x="100" y="0">1015</text>
<text class="numerical" x="100" y="0">1020</text>
<text class="numerical" x="100" y="0">1025</text>
<text class="numerical" x="100" y="0">1030</text>
<text class="numerical" x="100" y="0">1035</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

447
img/altitude_ticks.svg Normal file
View File

@ -0,0 +1,447 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="400px" height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve">
<defs>
<style type="text/css">
@import url('http://fonts.googleapis.com/css?family=Noto+Sans+KR|Nanum+Gothic+Coding');
</style>
</defs>
<style>
.marks {
transform: translate(50%, 50%);
}
.marks line {
--base-angle: 270deg;
--base-stroke-width: 2;
transform: rotate(var(--base-angle));
stroke-width: var(--base-stroke-width);
fill: none;
stroke: white;
stroke-miterlimit: 10;
}
.marks .long-ticks .tick {
--base-stroke-width: 4;
}
.marks .short-ticks .tick {
--base-stroke-width: 2;
}
.marks .long-ticks .tick:nth-child(2) {
--base-angle: 306deg;
}
.marks .long-ticks .tick:nth-child(3) {
--base-angle: 342deg;
}
.marks .long-ticks .tick:nth-child(4) {
--base-angle: 18deg;
}
.marks .long-ticks .tick:nth-child(5) {
--base-angle: 54deg;
}
.marks .long-ticks .tick:nth-child(6) {
--base-angle: 90deg;
}
.marks .long-ticks .tick:nth-child(7) {
--base-angle: 126deg;
}
.marks .long-ticks .tick:nth-child(8) {
--base-angle: 162deg;
}
.marks .long-ticks .tick:nth-child(9) {
--base-angle: 198deg;
}
.marks .long-ticks .tick:nth-child(10) {
--base-angle: 234deg;
}
.marks .short-ticks .tick:nth-child(1) {
--base-angle: 277.2deg;
}
.marks .short-ticks .tick:nth-child(2) {
--base-angle: 284.4deg;
}
.marks .short-ticks .tick:nth-child(3) {
--base-angle: 291.6deg;
}
.marks .short-ticks .tick:nth-child(4) {
--base-angle: 298.8deg;
}
.marks .short-ticks .tick:nth-child(5) {
--base-angle: 313.2deg;
}
.marks .short-ticks .tick:nth-child(6) {
--base-angle: 320.4deg;
}
.marks .short-ticks .tick:nth-child(7) {
--base-angle: 327.6deg;
}
.marks .short-ticks .tick:nth-child(8) {
--base-angle: 334.8deg;
}
.marks .short-ticks .tick:nth-child(9) {
--base-angle: 349.2deg;
}
.marks .short-ticks .tick:nth-child(10) {
--base-angle: 356.4deg;
}
.marks .short-ticks .tick:nth-child(11) {
--base-angle: 3.6deg;
}
.marks .short-ticks .tick:nth-child(12) {
--base-angle: 10.8deg;
}
.marks .short-ticks .tick:nth-child(13) {
--base-angle: 25.2deg;
}
.marks .short-ticks .tick:nth-child(14) {
--base-angle: 32.4deg;
}
.marks .short-ticks .tick:nth-child(15) {
--base-angle: 39.6deg;
}
.marks .short-ticks .tick:nth-child(16) {
--base-angle: 46.8deg;
}
.marks .short-ticks .tick:nth-child(17) {
--base-angle: 61.2deg;
}
.marks .short-ticks .tick:nth-child(18) {
--base-angle: 68.4deg;
}
.marks .short-ticks .tick:nth-child(19) {
--base-angle: 75.6deg;
}
.marks .short-ticks .tick:nth-child(20) {
--base-angle: 82.8deg;
}
.marks .short-ticks .tick:nth-child(21) {
--base-angle: 97.2deg;
}
.marks .short-ticks .tick:nth-child(22) {
--base-angle: 104.4deg;
}
.marks .short-ticks .tick:nth-child(23) {
--base-angle: 111.6deg;
}
.marks .short-ticks .tick:nth-child(24) {
--base-angle: 118.8deg;
}
.marks .short-ticks .tick:nth-child(25) {
--base-angle: 133.2deg;
}
.marks .short-ticks .tick:nth-child(26) {
--base-angle: 140.4deg;
}
.marks .short-ticks .tick:nth-child(27) {
--base-angle: 147.6deg;
}
.marks .short-ticks .tick:nth-child(28) {
--base-angle: 154.8deg;
}
.marks .short-ticks .tick:nth-child(29) {
--base-angle: 169.2deg;
}
.marks .short-ticks .tick:nth-child(30) {
--base-angle: 176.4deg;
}
.marks .short-ticks .tick:nth-child(31) {
--base-angle: 183.6deg;
}
.marks .short-ticks .tick:nth-child(32) {
--base-angle: 190.8deg;
}
.marks .short-ticks .tick:nth-child(33) {
--base-angle: 205.2deg;
}
.marks .short-ticks .tick:nth-child(34) {
--base-angle: 212.4deg;
}
.marks .short-ticks .tick:nth-child(35) {
--base-angle: 219.6deg;
}
.marks .short-ticks .tick:nth-child(36) {
--base-angle: 226.8deg;
}
.marks .short-ticks .tick:nth-child(37) {
--base-angle: 241.2deg;
}
.marks .short-ticks .tick:nth-child(38) {
--base-angle: 248.4deg;
}
.marks .short-ticks .tick:nth-child(39) {
--base-angle: 255.6deg;
}
.marks .short-ticks .tick:nth-child(40) {
--base-angle: 262.8deg;
}
.mark-labels {
--base-x: 50%;
--base-y: 50%;
transform: translate(var(--base-x), var(--base-y));
}
.mark-labels>text {
font-family: sans-serif;
font-size: 25px;
font-weight: bold;
dominant-baseline: middle;
text-anchor: middle;
fill: white;
}
.mark-labels .numerical {
--base-x: 0%;
--base-y: 0%;
transform: translate(var(--base-x), var(--base-y));
}
.mark-labels .numerical:nth-child(1) {
--base-x: 0;
--base-y: -27%;
}
.mark-labels .numerical:nth-child(2) {
--base-x: 16%;
--base-y: -22%;
}
.mark-labels .numerical:nth-child(3) {
--base-x: 27%;
--base-y: -11%;
}
.mark-labels .numerical:nth-child(4) {
--base-x: 27%;
--base-y: 13%;
}
.mark-labels .numerical:nth-child(5) {
--base-x: 16%;
--base-y: 22%;
}
.mark-labels .numerical:nth-child(6) {
--base-x: 0%;
--base-y: 28%;
}
.mark-labels .numerical:nth-child(7) {
--base-x: -17%;
--base-y: 22%;
}
.mark-labels .numerical:nth-child(8) {
--base-x: -26%;
--base-y: 9%;
}
.mark-labels .numerical:nth-child(9) {
--base-x: -26%;
--base-y: -8%;
}
.mark-labels .numerical:nth-child(10) {
--base-x: -16%;
--base-y: -22%;
}
.labels>text {
font-family: Noto Sans KR, sans-serif;
font-size: 11px;
dominant-baseline: middle;
text-anchor: middle;
fill: white;
}
.labels .title {
font-size: 18px;
font-weight: 600;
}
.labels>text>tspan {
font-size: 12px;
font-weight: 500;
}
</style>
<filter filterUnits="objectBoundingBox" id="filter-shadow">
<feGaussianBlur stdDeviation="5" result="blur" in="SourceAlpha"></feGaussianBlur>
<feOffset dy="0" dx="0" result="offsetBlurredAlpha" in="blur"></feOffset>
<feMerge>
<feMergeNode in="offsetBlurredAlpha"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<path fill="#232323" filter="url(#filter-shadow)"
d="M 200 47 A 153 153 0 1 0 200 353 A 153 153 0 1 0 200 47 Z M 276 222 C 278.5 210 278.5 190 276 178 L 325 165 C 330 189 330 211 325 235 Z" />
<g class="marks">
<g class="long-ticks">
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
</g>
<g class="short-ticks">
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
</g>
</g>
<g class="mark-labels">
<text class="numerical" x="0" y="0">0</text>
<text class="numerical" x="0" y="0">1</text>
<text class="numerical" x="0" y="0">2</text>
<text class="numerical" x="0" y="0">3</text>
<text class="numerical" x="0" y="0">4</text>
<text class="numerical" x="0" y="0">5</text>
<text class="numerical" x="0" y="0">6</text>
<text class="numerical" x="0" y="0">7</text>
<text class="numerical" x="0" y="0">8</text>
<text class="numerical" x="0" y="0">9</text>
</g>
<g class="labels">
<text x="53.5%" y="19%">M</text>
<text x="46%" y="19%">100</text>
<text class="title" x="50%" y="40%">ALTITUDE</text>
<text x="50%" y="34%">1000 M</text>
<text>
<tspan x="35%" y="48%">CALIBRATED</tspan>
<tspan x="35%" y="52%">TO 15 KM</tspan>
</text>
</g>
<g class="others">
<path fill="#FFFFFF"
d="M 154.5 277 C 160.7 280.7 167.5 283.7 174.6 285.8 L 156.2 274.2 Z M 160.4 267 L 196.4 289.6 C 197.7 289.7 199 289.7 200.2 289.7 C 204.4 289.7 208.5 289.4 212.5 288.9 L 165 259.1 Z M 169.5 251.7 L 224.7 286.3 C 228.5 285.2 232.2 283.9 235.8 282.4 L 174.3 243.8 Z M 202.3 240.7 C 192.4 240.8 185.2 238.7 179.1 235 L 178.2 236.4 L 244.3 277.8 C 244.8 277.5 245.3 277.3 245.7 277 L 237 262.4 Z M 221.1 235.1 C 219.1 236.3 216.9 237.3 214.7 238.2 L 227.9 246.5 Z" />
</g>
<!-- <g>
<path fill="none"
d="M174.243,243.809l61.533,38.566c3.073-1.324,6.051-2.824,8.936-4.471l-66.101-41.43L174.243,243.809z" />
<path fill="none"
d="M165.159,259.06l47.482,29.761c4.114-0.565,8.138-1.413,12.055-2.517l-55.169-34.578L165.159,259.06z" />
<path fill="none"
d="M214.732,238.17c-3.751,1.431-7.764,2.328-11.956,2.578l34.692,21.744l-9.571-16.07L214.732,238.17z" />
<path fill="none"
d="M156.076,274.312l18.447,11.562c7.001,2.103,14.36,3.375,21.967,3.696l-36.045-22.592L156.076,274.312z" />
<path fill="#FFFFFF" d="M154.451,277.04c6.239,3.724,12.973,6.701,20.072,8.833l-18.447-11.562L154.451,277.04z" />
<path fill="#FFFFFF" d="M160.444,266.978l36.045,22.592c1.275,0.054,2.555,0.09,3.844,0.09c4.176,0,8.285-0.286,12.308-0.839
l-47.482-29.761L160.444,266.978z" />
<path fill="#FFFFFF"
d="M169.527,251.726l55.169,34.578c3.801-1.072,7.5-2.386,11.079-3.929l-61.533-38.566L169.527,251.726z" />
<path fill="#FFFFFF" d="M200,240.833c-7.636,0-14.773-2.12-20.868-5.794l-0.855,1.437l66.101,41.43
c0.482-0.275,0.967-0.544,1.443-0.828l-8.686-14.584l-34.692-21.744C201.967,240.797,201.155,240.833,200,240.833z" />
<path fill="#FFFFFF" d="M221.14,235.076c-2.025,1.216-4.173,2.242-6.408,3.095l13.165,8.252L221.14,235.076z" />
</g> -->
<!-- <tspan x="35%" y="48%" fill="#FFFFFF" font-family="sans-serif" font-size="14" dominant-baseline="middle" text-anchor="middle">15 KM로</tspan>
<tspan x="35%" y="52%" fill="#FFFFFF" font-family="sans-serif" font-size="14" dominant-baseline="middle" text-anchor="middle">보정</tspan> -->
</svg>

After

Width:  |  Height:  |  Size: 15 KiB

19
img/fi_box.svg Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="400px" height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve">
<filter filterUnits="objectBoundingBox" id="filter-mask">
<feGaussianBlur stdDeviation="5" result="blur" in="SourceAlpha"></feGaussianBlur>
<feOffset dy="0" dx="0" result="offsetBlurredAlpha" in="blur"></feOffset>
<feMerge>
<feMergeNode in="offsetBlurredAlpha"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<g filter="url(#filter-mask)">
<path fill="#110F0F"
d="M 387 375 C 387 382 382 387 375 387 H 25 C 18 387 13 382 13 375 V 25 C 13 18 18 13 25 13 H 375 C 382 13 387 18 387 25 V 375 Z" />
<path fill="none" stroke="#FFFFFF" stroke-width="0.5" stroke-miterlimit="10"
d="M 387 375 C 387 382 382 387 375 387 H 25 C 18 387 13 382 13 375 V 25 C 13 18 18 13 25 13 H 375 C 382 13 387 18 387 25 V 375 Z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

32
img/fi_circle.svg Normal file
View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="400px" height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve">
<style>
.ring .frame {
fill: #232323;
stroke-width: 3;
}
.ring .border {
fill: none;
stroke: #353535;
stroke-width: 1.3;
stroke-miterlimit: 10;
}
</style>
<filter filterUnits="objectBoundingBox" id="filter-shadow">
<feGaussianBlur stdDeviation="5" result="blur" in="SourceAlpha"></feGaussianBlur>
<feOffset dy="0" dx="0" result="offsetBlurredAlpha" in="blur"></feOffset>
<feMerge>
<feMergeNode in="offsetBlurredAlpha"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<g class="ring" filter="url(#filter-shadow)">
<path class="frame"
d=" M 50 200 A 150 150 0 1 1 350 200 A 150 150 0 1 1 50 200 Z M 34 200 A 166 166 0 1 0 366 200 A 166 166 0 1 0 34 200 Z" />
<path class="border"
d=" M 50 200 A 150 150 0 1 1 350 200 A 150 150 0 1 1 50 200 Z M 34 200 A 166 166 0 1 0 366 200 A 166 166 0 1 0 34 200 Z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

22
img/fi_needle.svg Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="400px" height="400px" viewBox="0 0 400 400"
enable-background="new 0 0 400 400" xml:space="preserve">
<filter filterUnits="objectBoundingBox" id="AI_Shadow_1">
<feGaussianBlur stdDeviation="5" result="blur" in="SourceAlpha"></feGaussianBlur>
<feOffset dy="0" dx="0" result="offsetBlurredAlpha" in="blur"></feOffset>
<feMerge>
<feMergeNode in="offsetBlurredAlpha"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<g filter="url(#AI_Shadow_1)">
<polygon fill="#FFFFFF" stroke="#B2B2B2" stroke-width="0.5" stroke-miterlimit="10" points="76.445,196.417 68.082,200
76.423,203.583 184.334,203.583 184.334,196.417 " />
<path fill="#232323" stroke="#353535" stroke-width="0.5" stroke-miterlimit="10" d="M239.042,196.417
c-3.563-3.563-8.918,0-13.063,0c-0.787,0-3.148,0-3.148,0h-11.969c-1.51-4.271-5.573-7.337-10.362-7.337s-8.852,3.065-10.362,7.337
h-5.804v7.167h5.745c1.464,4.355,5.572,7.496,10.42,7.496s8.956-3.141,10.42-7.496h12.036c0,0,2.314,0,3.085,0
c3.874,0,9.458,3.542,13,0C241.124,201.501,241.25,198.625,239.042,196.417z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

26
img/fi_needle_small.svg Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="400px" height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve">
<filter filterUnits="objectBoundingBox" id="AI_Shadow_1">
<feGaussianBlur stdDeviation="5" result="blur" in="SourceAlpha"></feGaussianBlur>
<feOffset dy="0" dx="0" result="offsetBlurredAlpha" in="blur"></feOffset>
<feMerge>
<feMergeNode in="offsetBlurredAlpha"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<g filter="url(#AI_Shadow_1)">
<polygon fill="#FFFFFF" points="211.838,160.802 200.343,132.368 200.338,132.386 200.333,132.368 188.838,160.802 200.333,207
200.338,206.977 200.343,207 " />
<polygon fill="none" stroke="#B2B2B2" stroke-width="0.5" stroke-miterlimit="10" points="211.838,160.802 200.343,132.368
200.338,132.386 200.333,132.368 188.838,160.802 200.333,207 200.338,206.977 200.343,207 " />
</g>
<g filter="url(#AI_Shadow_1)">
<path fill="#232323" d="M200.331,196.091c0,0-9.492,18.192-9.331,24.818c0.062,2.56,1.828,4.228,9.331,4.228
s9.114-1.709,9.146-4.228c0.083-6.507-8.809-24.493-8.809-24.493" />
<path fill="none" stroke="#353535" stroke-width="0.5" stroke-miterlimit="10" d="M200.331,196.091c0,0-9.492,18.192-9.331,24.818
c0.062,2.56,1.828,4.228,9.331,4.228s9.114-1.709,9.146-4.228c0.083-6.507-8.809-24.493-8.809-24.493" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

15
img/fi_tc_airplane.svg Normal file
View File

@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" width="540" height="540">
<style>
.airplane {
fill: white;
fill-opacity: 1;
stroke: none;
}
</style>
<g class="airplane">
<path
d="M 270 249 C 257.7 249 247.6 258.7 247 270.8 L 125.1 270.6 C 120.6 270.6 119.7 276.9 124.6 277.7 L 251 284.9 C 255.1 291 262.1 295.1 270 295.1 C 278 295.1 285 291.1 289.1 285 L 416 277.7 C 420.9 276.9 420 270.6 415.5 270.6 L 293.1 270.9 C 292.5 258.7 282.4 249 270 249 Z" />
<path
d="M 216.66 253.4 L 323.21 253.4 C 327.59 253.35 329.04 246.7 322.96 246.23 L 278.51 244.1 C 274.82 243.43 274.48 241.82 274.22 239.73 L 273.71 214.51 C 273.71 210.62 266.28 210.55 266.28 214.51 L 265.78 239.73 C 265.51 241.82 265.17 243.43 261.49 244.1 L 216.91 246.23 C 210.83 246.7 212.28 253.35 216.66 253.4 Z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 888 B

26
img/heading_mechanics.svg Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="400px" height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve">
<filter filterUnits="objectBoundingBox" id="filter-mask">
<feGaussianBlur stdDeviation="5" result="blur" in="SourceAlpha"></feGaussianBlur>
<feOffset dy="0" dx="0" result="offsetBlurredAlpha" in="blur"></feOffset>
<feMerge>
<feMergeNode in="offsetBlurredAlpha"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<g filter="url(#filter-mask)">
<path fill="none" stroke="#FF2A00" stroke-width="3" stroke-miterlimit="10" d="M 200 81.42 C 200 81.42 192.96 93.04 188.71 106.17 S 181.58 157.54 181.58 157.54 L 127.37 196.84 C 127.37 196.84 113.83 205.34 111.07 212.44 C 110.11 214.91 109.58 218.29 109.46 220.29 C 109.24 223.97 109.46 234.04 109.46 234.04 C 109.58 236.17 110.96 237.92 115.46 236.42 S 184.96 213.29 184.96 213.29 L 187.71 267.54 C 187.71 267.54 170.99 280.49 165.83 285.29 C 164.6 286.44 162.78 288.06 161.77 290.17 C 160.73 292.35 160.61 295.7 160.58 297.42 C 160.54 299.85 160.45 305.56 160.77 306.48 C 161.27 307.92 161.83 308.4 163.91 308.4 C 166.53 308.4 176.83 302.67 176.83 302.67 L 195.58 293.42 L 199.92 305.67 H 200 L 204.42 293.42 L 223.17 302.67 C 223.17 302.67 233.47 308.4 236.1 308.4 C 238.17 308.4 238.73 307.92 239.23 306.48 C 239.55 305.56 239.46 299.86 239.42 297.42 C 239.39 295.7 239.28 292.35 238.23 290.17 C 237.22 288.06 235.4 286.44 234.17 285.29 C 229.02 280.49 212.29 267.54 212.29 267.54 L 215.04 213.29 C 215.04 213.29 280.04 234.92 284.54 236.42 S 290.42 236.17 290.54 234.04 C 290.54 234.04 290.76 223.97 290.54 220.29 C 290.42 218.29 289.89 214.91 288.93 212.44 C 286.17 205.34 272.63 196.84 272.63 196.84 L 218.42 157.54 C 218.42 157.54 215.54 119.29 211.29 106.17 S 200 81.42 200 81.42 V 61 Z" />
</g>
<g filter="url(#filter-mask)">
<polygon fill="#FF2A00" points="200.381,332.311 194.542,344.439 206.542,344.439" />
<polygon fill="#FF2A00" points="68.291,200.382 56.291,194.604 56.291,206.477" />
<polygon fill="#FF2A00" points="332.311,200.285 344.44,206.125 344.441,194.125" />
<polygon fill="#FF2A00" points="200.619,68.022 206.458,55.893 194.458,55.892" />
<polygon fill="#FFFFFF" points="294.272,294.239 298.743,307.01 307.272,298.481" />
<polygon fill="#FFFFFF" points="105.938,294.771 94.146,298.898 102.02,306.771" />
<polygon fill="#FFFFFF" points="106.001,106.041 101.801,94.041 93.787,102.055" />
<polygon fill="#FFFFFF" points="294.731,105.894 306.519,101.767 298.646,93.894" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

482
img/heading_yaw.svg Normal file
View File

@ -0,0 +1,482 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="400px" height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve">
<style>
.marks {
transform: translate(50%, 50%);
}
.marks line {
--base-angle: 270deg;
--base-stroke-width: 2;
transform: rotate(var(--base-angle));
stroke-width: var(--base-stroke-width);
fill: none;
stroke: white;
stroke-miterlimit: 10;
}
.marks .long-ticks .tick:nth-child(1) {
--base-angle: -80deg;
}
.marks .long-ticks .tick:nth-child(2) {
--base-angle: -70deg;
}
.marks .long-ticks .tick:nth-child(3) {
--base-angle: -60deg;
}
.marks .long-ticks .tick:nth-child(4) {
--base-angle: -50deg;
}
.marks .long-ticks .tick:nth-child(5) {
--base-angle: -40deg;
}
.marks .long-ticks .tick:nth-child(6) {
--base-angle: -30deg;
}
.marks .long-ticks .tick:nth-child(7) {
--base-angle: -20deg;
}
.marks .long-ticks .tick:nth-child(8) {
--base-angle: -10deg;
}
.marks .long-ticks .tick:nth-child(9) {
--base-angle: 0deg;
}
.marks .long-ticks .tick:nth-child(10) {
--base-angle: 10deg;
}
.marks .long-ticks .tick:nth-child(11) {
--base-angle: 20deg;
}
.marks .long-ticks .tick:nth-child(12) {
--base-angle: 30deg;
}
.marks .long-ticks .tick:nth-child(13) {
--base-angle: 40deg;
}
.marks .long-ticks .tick:nth-child(14) {
--base-angle: 50deg;
}
.marks .long-ticks .tick:nth-child(15) {
--base-angle: 60deg;
}
.marks .long-ticks .tick:nth-child(16) {
--base-angle: 70deg;
}
.marks .long-ticks .tick:nth-child(17) {
--base-angle: 80deg;
}
.marks .long-ticks .tick:nth-child(18) {
--base-angle: 90deg;
}
.marks .long-ticks .tick:nth-child(19) {
--base-angle: 100deg;
}
.marks .long-ticks .tick:nth-child(20) {
--base-angle: 110deg;
}
.marks .long-ticks .tick:nth-child(21) {
--base-angle: 120deg;
}
.marks .long-ticks .tick:nth-child(22) {
--base-angle: 130deg;
}
.marks .long-ticks .tick:nth-child(23) {
--base-angle: 140deg;
}
.marks .long-ticks .tick:nth-child(24) {
--base-angle: 150deg;
}
.marks .long-ticks .tick:nth-child(25) {
--base-angle: 160deg;
}
.marks .long-ticks .tick:nth-child(26) {
--base-angle: 170deg;
}
.marks .long-ticks .tick:nth-child(27) {
--base-angle: 180deg;
}
.marks .long-ticks .tick:nth-child(28) {
--base-angle: 190deg;
}
.marks .long-ticks .tick:nth-child(29) {
--base-angle: 200deg;
}
.marks .long-ticks .tick:nth-child(30) {
--base-angle: 210deg;
}
.marks .long-ticks .tick:nth-child(31) {
--base-angle: 220deg;
}
.marks .long-ticks .tick:nth-child(32) {
--base-angle: 230deg;
}
.marks .long-ticks .tick:nth-child(33) {
--base-angle: 240deg;
}
.marks .long-ticks .tick:nth-child(34) {
--base-angle: 250deg;
}
.marks .long-ticks .tick:nth-child(35) {
--base-angle: 260deg;
}
.marks .long-ticks .tick:nth-child(36) {
--base-angle: 270deg;
}
.marks .short-ticks .tick:nth-child(1) {
--base-angle: 275deg;
}
.marks .short-ticks .tick:nth-child(2) {
--base-angle: 285deg;
}
.marks .short-ticks .tick:nth-child(3) {
--base-angle: 295deg;
}
.marks .short-ticks .tick:nth-child(4) {
--base-angle: 305deg;
}
.marks .short-ticks .tick:nth-child(5) {
--base-angle: 315deg;
}
.marks .short-ticks .tick:nth-child(6) {
--base-angle: 325deg;
}
.marks .short-ticks .tick:nth-child(7) {
--base-angle: 335deg;
}
.marks .short-ticks .tick:nth-child(8) {
--base-angle: 345deg;
}
.marks .short-ticks .tick:nth-child(9) {
--base-angle: 355deg;
}
.marks .short-ticks .tick:nth-child(10) {
--base-angle: 365deg;
}
.marks .short-ticks .tick:nth-child(11) {
--base-angle: 375deg;
}
.marks .short-ticks .tick:nth-child(12) {
--base-angle: 385deg;
}
.marks .short-ticks .tick:nth-child(13) {
--base-angle: 395deg;
}
.marks .short-ticks .tick:nth-child(14) {
--base-angle: 405deg;
}
.marks .short-ticks .tick:nth-child(15) {
--base-angle: 415deg;
}
.marks .short-ticks .tick:nth-child(16) {
--base-angle: 425deg;
}
.marks .short-ticks .tick:nth-child(17) {
--base-angle: 435deg;
}
.marks .short-ticks .tick:nth-child(18) {
--base-angle: 445deg;
}
.marks .short-ticks .tick:nth-child(19) {
--base-angle: 455deg;
}
.marks .short-ticks .tick:nth-child(20) {
--base-angle: 465deg;
}
.marks .short-ticks .tick:nth-child(21) {
--base-angle: 475deg;
}
.marks .short-ticks .tick:nth-child(22) {
--base-angle: 485deg;
}
.marks .short-ticks .tick:nth-child(23) {
--base-angle: 495deg;
}
.marks .short-ticks .tick:nth-child(24) {
--base-angle: 505deg;
}
.marks .short-ticks .tick:nth-child(25) {
--base-angle: 515deg;
}
.marks .short-ticks .tick:nth-child(26) {
--base-angle: 525deg;
}
.marks .short-ticks .tick:nth-child(27) {
--base-angle: 535deg;
}
.marks .short-ticks .tick:nth-child(28) {
--base-angle: 545deg;
}
.marks .short-ticks .tick:nth-child(29) {
--base-angle: 555deg;
}
.marks .short-ticks .tick:nth-child(30) {
--base-angle: 565deg;
}
.marks .short-ticks .tick:nth-child(31) {
--base-angle: 575deg;
}
.marks .short-ticks .tick:nth-child(32) {
--base-angle: 585deg;
}
.marks .short-ticks .tick:nth-child(33) {
--base-angle: 595deg;
}
.marks .short-ticks .tick:nth-child(34) {
--base-angle: 605deg;
}
.marks .short-ticks .tick:nth-child(35) {
--base-angle: 615deg;
}
.marks .short-ticks .tick:nth-child(36) {
--base-angle: 625deg;
}
.mark-labels {
--base-x: 50%;
--base-y: 50%;
transform: translate(var(--base-x), var(--base-y));
}
.mark-labels text {
--base-angle: 270deg;
font-family: Noto Sans KR, sans-serif;
font-size: 28px;
fill: white;
writing-mode: tb;
dominant-baseline: middle;
text-anchor: middle;
transform: rotate(var(--base-angle));
}
.mark-labels .label:nth-child(1) {
--base-angle: 270deg;
}
.mark-labels .label:nth-child(2) {
--base-angle: 360deg;
}
.mark-labels .label:nth-child(3) {
--base-angle: 450deg;
}
.mark-labels .label:nth-child(4) {
--base-angle: 540deg;
}
.mark-labels .numerals .label {
font-family: sans-serif;
}
.mark-labels .numerals .label:nth-child(1) {
--base-angle: -60deg;
}
.mark-labels .numerals .label:nth-child(2) {
--base-angle: -30deg;
}
.mark-labels .numerals .label:nth-child(3) {
--base-angle: 30deg;
}
.mark-labels .numerals .label:nth-child(4) {
--base-angle: 60deg;
}
.mark-labels .numerals .label:nth-child(5) {
--base-angle: 120deg;
}
.mark-labels .numerals .label:nth-child(6) {
--base-angle: 150deg;
}
.mark-labels .numerals .label:nth-child(7) {
--base-angle: 210deg;
}
.mark-labels .numerals .label:nth-child(8) {
--base-angle: 240deg;
}
</style>
<circle fill="#232323" cx="200.333" cy="200" r="161" />
<g class="marks">
<g class="long-ticks">
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
</g>
<g class="short-ticks">
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
</g>
</g>
<g class="mark-labels">
<text class="label" x="107" y="0" dy="2.5%">N</text>
<text class="label" x="107" y="0" dy="3%">E</text>
<text class="label" x="107" y="0" dy="3%">S</text>
<text class="label" x="107" y="0" dy="2%">W</text>
<g class="numerals">
<text class="label" x="107" y="0" dy="2%">3</text>
<text class="label" x="107" y="0" dy="2%">6</text>
<text class="label" x="107" y="0" dy="2%">12</text>
<text class="label" x="107" y="0" dy="2%">15</text>
<text class="label" x="107" y="0" dy="2%">21</text>
<text class="label" x="107" y="0" dy="2%">24</text>
<text class="label" x="107" y="0" dy="2%">30</text>
<text class="label" x="107" y="0" dy="2%">33</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 15 KiB

10
img/horizon_back.svg Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="400px" height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve">
<linearGradient id="lg-back-horizon" gradientUnits="userSpaceOnUse" x1="200" y1="350" x2="200" y2="50">
<stop offset="0.5" style="stop-color:#503723" />
<stop offset="0.5" style="stop-color:#558EBB" />
</linearGradient>
<circle id="back-horizon" fill="url(#lg-back-horizon)" cx="200" cy="200" r="150" />
</svg>

After

Width:  |  Height:  |  Size: 702 B

137
img/horizon_ball.svg Normal file
View File

@ -0,0 +1,137 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="400px" height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400"
xml:space="preserve">
<filter filterUnits="objectBoundingBox" id="AI_Shadow_1">
<feGaussianBlur stdDeviation="5" result="blur" in="SourceAlpha"></feGaussianBlur>
<feOffset dy="0" dx="0" result="offsetBlurredAlpha" in="blur"></feOffset>
<feMerge>
<feMergeNode in="offsetBlurredAlpha"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<g filter="url(#AI_Shadow_1)">
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="200.333" y1="276.3325" x2="200.333" y2="124.3325">
<stop offset="0" style="stop-color:#3D2618"/>
<stop offset="0.4999" style="stop-color:#503723"/>
<stop offset="0.5001" style="stop-color:#9CCBE5"/>
<stop offset="1" style="stop-color:#558EBB"/>
</linearGradient>
<path fill="url(#SVGID_1_)" d="M301.333,200.333c0,41.936-33.963,75.938-75.885,76c-0.038,0-50.076,0-50.114,0
c-41.974,0-76-34.026-76-76s34.026-76,76-76c0.027,0,50.056,0,50.083,0C267.352,124.377,301.333,158.387,301.333,200.333z"/>
</g>
<line fill="none" stroke="#FFFFFF" stroke-width="2" stroke-miterlimit="10" x1="99.667" y1="200.457" x2="301.667" y2="200.457"/>
<line fill="none" stroke="#FFFFFF" stroke-width="2" stroke-miterlimit="10" x1="187.979" y1="187.374" x2="212.979" y2="187.374"/>
<line fill="none" stroke="#FFFFFF" stroke-width="2" stroke-miterlimit="10" x1="188.167" y1="213.499" x2="213.167" y2="213.499"/>
<line fill="none" stroke="#FFFFFF" stroke-width="2" stroke-miterlimit="10" x1="188.026" y1="241.42" x2="213.026" y2="241.42"/>
<line fill="none" stroke="#FFFFFF" stroke-width="2" stroke-miterlimit="10" x1="188.167" y1="159.374" x2="213.167" y2="159.374"/>
<line fill="none" stroke="#FFFFFF" stroke-width="2" stroke-miterlimit="10" x1="180.042" y1="173.405" x2="220.042" y2="173.405"/>
<line fill="none" stroke="#FFFFFF" stroke-width="2" stroke-miterlimit="10" x1="180.042" y1="227.499" x2="220.042" y2="227.499"/>
<line fill="none" stroke="#FFFFFF" stroke-width="2" stroke-miterlimit="10" x1="170.042" y1="255.332" x2="230.042" y2="255.332"/>
<line fill="none" stroke="#FFFFFF" stroke-width="2" stroke-miterlimit="10" x1="170.042" y1="145.333" x2="230.042" y2="145.333"/>
<g>
<path fill="#FFFFFF" d="M166.644,169.224h2.25v7.901h-1.493v-6.488h-1.627L166.644,169.224z"/>
<path fill="#FFFFFF" d="M172.84,169.025c0.577,0,1.073,0.142,1.491,0.424c0.417,0.283,0.739,0.715,0.967,1.297
c0.227,0.582,0.341,1.392,0.341,2.43c0,1.049-0.115,1.866-0.347,2.449c-0.23,0.583-0.542,1.012-0.932,1.287
c-0.39,0.273-0.883,0.411-1.477,0.411s-1.094-0.138-1.499-0.414s-0.722-0.695-0.951-1.257s-0.344-1.362-0.344-2.401
c0-1.45,0.224-2.501,0.671-3.153C171.259,169.383,171.952,169.025,172.84,169.025z M172.875,170.454
c-0.253,0-0.479,0.082-0.675,0.244c-0.196,0.163-0.347,0.443-0.45,0.841s-0.155,0.979-0.155,1.746
c0,0.999,0.119,1.689,0.356,2.071c0.238,0.381,0.546,0.572,0.924,0.572c0.365,0,0.654-0.181,0.869-0.542
c0.261-0.437,0.391-1.167,0.391-2.191c0-1.039-0.117-1.754-0.351-2.148S173.247,170.454,172.875,170.454z"/>
</g>
<g>
<path fill="#FFFFFF" d="M155.584,143.883h-1.466c0.04-0.852,0.307-1.523,0.803-2.011c0.496-0.489,1.133-0.733,1.91-0.733
c0.48,0,0.903,0.101,1.27,0.304c0.367,0.202,0.661,0.494,0.881,0.875c0.221,0.382,0.331,0.769,0.331,1.163
c0,0.469-0.133,0.974-0.4,1.515s-0.755,1.18-1.464,1.917l-0.887,0.935h2.816v1.391h-5.473v-0.72l2.444-2.492
c0.591-0.598,0.984-1.079,1.179-1.442c0.195-0.363,0.292-0.692,0.292-0.985c0-0.304-0.101-0.556-0.303-0.755
c-0.203-0.198-0.463-0.298-0.782-0.298c-0.322,0-0.591,0.12-0.806,0.36S155.599,143.471,155.584,143.883z"/>
<path fill="#FFFFFF" d="M162.884,141.138c0.577,0,1.073,0.142,1.491,0.424c0.417,0.283,0.739,0.715,0.967,1.297
c0.227,0.582,0.341,1.392,0.341,2.43c0,1.049-0.115,1.866-0.347,2.449c-0.23,0.583-0.542,1.012-0.932,1.287
c-0.39,0.273-0.883,0.411-1.477,0.411s-1.094-0.138-1.499-0.414s-0.722-0.695-0.951-1.257s-0.344-1.362-0.344-2.401
c0-1.45,0.224-2.501,0.671-3.153C161.303,141.496,161.996,141.138,162.884,141.138z M162.918,142.567
c-0.253,0-0.479,0.082-0.675,0.244c-0.196,0.163-0.347,0.443-0.45,0.841s-0.155,0.979-0.155,1.746
c0,0.999,0.119,1.689,0.356,2.071c0.238,0.381,0.546,0.572,0.924,0.572c0.365,0,0.654-0.181,0.869-0.542
c0.261-0.437,0.391-1.167,0.391-2.191c0-1.039-0.117-1.754-0.351-2.148S163.291,142.567,162.918,142.567z"/>
</g>
<g>
<path fill="#FFFFFF" d="M234.958,143.784h-1.466c0.04-0.852,0.307-1.523,0.803-2.011c0.496-0.489,1.133-0.733,1.91-0.733
c0.48,0,0.903,0.101,1.27,0.304c0.367,0.202,0.661,0.494,0.881,0.875c0.221,0.382,0.331,0.769,0.331,1.163
c0,0.469-0.133,0.974-0.4,1.515s-0.755,1.18-1.464,1.917l-0.887,0.935h2.816v1.391h-5.473v-0.72l2.444-2.492
c0.591-0.598,0.984-1.079,1.179-1.442c0.195-0.363,0.292-0.692,0.292-0.985c0-0.304-0.101-0.556-0.303-0.755
c-0.203-0.198-0.463-0.298-0.782-0.298c-0.322,0-0.591,0.12-0.806,0.36S234.973,143.372,234.958,143.784z"/>
<path fill="#FFFFFF" d="M242.258,141.039c0.577,0,1.073,0.142,1.491,0.424c0.417,0.283,0.739,0.715,0.967,1.297
c0.227,0.582,0.341,1.392,0.341,2.43c0,1.049-0.115,1.866-0.347,2.449c-0.23,0.583-0.542,1.012-0.932,1.287
c-0.39,0.273-0.883,0.411-1.477,0.411s-1.094-0.138-1.499-0.414s-0.722-0.695-0.951-1.257s-0.344-1.362-0.344-2.401
c0-1.45,0.224-2.501,0.671-3.153C240.677,141.397,241.37,141.039,242.258,141.039z M242.292,142.468
c-0.253,0-0.479,0.082-0.675,0.244c-0.196,0.163-0.347,0.443-0.45,0.841s-0.155,0.979-0.155,1.746
c0,0.999,0.119,1.689,0.356,2.071c0.238,0.381,0.546,0.572,0.924,0.572c0.365,0,0.654-0.181,0.869-0.542
c0.261-0.437,0.391-1.167,0.391-2.191c0-1.039-0.117-1.754-0.351-2.148S242.665,142.468,242.292,142.468z"/>
</g>
<g>
<path fill="#FFFFFF" d="M224.341,169.224h2.25v7.901h-1.493v-6.488h-1.627L224.341,169.224z"/>
<path fill="#FFFFFF" d="M230.538,169.025c0.577,0,1.073,0.142,1.491,0.424c0.417,0.283,0.739,0.715,0.967,1.297
c0.227,0.582,0.341,1.392,0.341,2.43c0,1.049-0.115,1.866-0.347,2.449c-0.23,0.583-0.542,1.012-0.932,1.287
c-0.39,0.273-0.883,0.411-1.477,0.411s-1.094-0.138-1.499-0.414s-0.722-0.695-0.951-1.257s-0.344-1.362-0.344-2.401
c0-1.45,0.224-2.501,0.671-3.153C228.957,169.383,229.649,169.025,230.538,169.025z M230.572,170.454
c-0.253,0-0.479,0.082-0.675,0.244c-0.196,0.163-0.347,0.443-0.45,0.841s-0.155,0.979-0.155,1.746
c0,0.999,0.119,1.689,0.356,2.071c0.238,0.381,0.546,0.572,0.924,0.572c0.365,0,0.654-0.181,0.869-0.542
c0.261-0.437,0.391-1.167,0.391-2.191c0-1.039-0.117-1.754-0.351-2.148S230.944,170.454,230.572,170.454z"/>
</g>
<g>
<path fill="#FFFFFF" d="M166.644,223.224h2.25v7.901h-1.493v-6.488h-1.627L166.644,223.224z"/>
<path fill="#FFFFFF" d="M172.84,223.025c0.577,0,1.073,0.142,1.491,0.424c0.417,0.283,0.739,0.715,0.967,1.297
c0.227,0.582,0.341,1.392,0.341,2.43c0,1.049-0.115,1.866-0.347,2.449c-0.23,0.583-0.542,1.012-0.932,1.287
c-0.39,0.273-0.883,0.411-1.477,0.411s-1.094-0.138-1.499-0.414s-0.722-0.695-0.951-1.257s-0.344-1.362-0.344-2.401
c0-1.45,0.224-2.501,0.671-3.153C171.259,223.383,171.952,223.025,172.84,223.025z M172.875,224.454
c-0.253,0-0.479,0.082-0.675,0.244c-0.196,0.163-0.347,0.443-0.45,0.841s-0.155,0.979-0.155,1.746
c0,0.999,0.119,1.689,0.356,2.071c0.238,0.381,0.546,0.572,0.924,0.572c0.365,0,0.654-0.181,0.869-0.542
c0.261-0.437,0.391-1.167,0.391-2.191c0-1.039-0.117-1.754-0.351-2.148S173.247,224.454,172.875,224.454z"/>
</g>
<g>
<path fill="#FFFFFF" d="M224.341,223.224h2.25v7.901h-1.493v-6.488h-1.627L224.341,223.224z"/>
<path fill="#FFFFFF" d="M230.538,223.025c0.577,0,1.073,0.142,1.491,0.424c0.417,0.283,0.739,0.715,0.967,1.297
c0.227,0.582,0.341,1.392,0.341,2.43c0,1.049-0.115,1.866-0.347,2.449c-0.23,0.583-0.542,1.012-0.932,1.287
c-0.39,0.273-0.883,0.411-1.477,0.411s-1.094-0.138-1.499-0.414s-0.722-0.695-0.951-1.257s-0.344-1.362-0.344-2.401
c0-1.45,0.224-2.501,0.671-3.153C228.957,223.383,229.649,223.025,230.538,223.025z M230.572,224.454
c-0.253,0-0.479,0.082-0.675,0.244c-0.196,0.163-0.347,0.443-0.45,0.841s-0.155,0.979-0.155,1.746
c0,0.999,0.119,1.689,0.356,2.071c0.238,0.381,0.546,0.572,0.924,0.572c0.365,0,0.654-0.181,0.869-0.542
c0.261-0.437,0.391-1.167,0.391-2.191c0-1.039-0.117-1.754-0.351-2.148S230.944,224.454,230.572,224.454z"/>
</g>
<g>
<path fill="#FFFFFF" d="M155.584,253.883h-1.466c0.04-0.852,0.307-1.523,0.803-2.011c0.496-0.489,1.133-0.733,1.91-0.733
c0.48,0,0.903,0.101,1.27,0.304c0.367,0.202,0.661,0.494,0.881,0.875c0.221,0.382,0.331,0.769,0.331,1.163
c0,0.469-0.133,0.974-0.4,1.515s-0.755,1.18-1.464,1.917l-0.887,0.935h2.816v1.391h-5.473v-0.72l2.444-2.492
c0.591-0.598,0.984-1.079,1.179-1.442c0.195-0.363,0.292-0.692,0.292-0.985c0-0.304-0.101-0.556-0.303-0.755
c-0.203-0.198-0.463-0.298-0.782-0.298c-0.322,0-0.591,0.12-0.806,0.36S155.599,253.471,155.584,253.883z"/>
<path fill="#FFFFFF" d="M162.884,251.138c0.577,0,1.073,0.142,1.491,0.424c0.417,0.283,0.739,0.715,0.967,1.297
c0.227,0.582,0.341,1.392,0.341,2.43c0,1.049-0.115,1.866-0.347,2.449c-0.23,0.583-0.542,1.012-0.932,1.287
c-0.39,0.273-0.883,0.411-1.477,0.411s-1.094-0.138-1.499-0.414s-0.722-0.695-0.951-1.257s-0.344-1.362-0.344-2.401
c0-1.45,0.224-2.501,0.671-3.153C161.303,251.496,161.996,251.138,162.884,251.138z M162.918,252.567
c-0.253,0-0.479,0.082-0.675,0.244c-0.196,0.163-0.347,0.443-0.45,0.841s-0.155,0.979-0.155,1.746
c0,0.999,0.119,1.689,0.356,2.071c0.238,0.381,0.546,0.572,0.924,0.572c0.365,0,0.654-0.181,0.869-0.542
c0.261-0.437,0.391-1.167,0.391-2.191c0-1.039-0.117-1.754-0.351-2.148S163.291,252.567,162.918,252.567z"/>
</g>
<g>
<path fill="#FFFFFF" d="M234.958,253.784h-1.466c0.04-0.852,0.307-1.523,0.803-2.011c0.496-0.489,1.133-0.733,1.91-0.733
c0.48,0,0.903,0.101,1.27,0.304c0.367,0.202,0.661,0.494,0.881,0.875c0.221,0.382,0.331,0.769,0.331,1.163
c0,0.469-0.133,0.974-0.4,1.515s-0.755,1.18-1.464,1.917l-0.887,0.935h2.816v1.391h-5.473v-0.72l2.444-2.492
c0.591-0.598,0.984-1.079,1.179-1.442c0.195-0.363,0.292-0.692,0.292-0.985c0-0.304-0.101-0.556-0.303-0.755
c-0.203-0.198-0.463-0.298-0.782-0.298c-0.322,0-0.591,0.12-0.806,0.36S234.973,253.372,234.958,253.784z"/>
<path fill="#FFFFFF" d="M242.258,251.039c0.577,0,1.073,0.142,1.491,0.424c0.417,0.283,0.739,0.715,0.967,1.297
c0.227,0.582,0.341,1.392,0.341,2.43c0,1.049-0.115,1.866-0.347,2.449c-0.23,0.583-0.542,1.012-0.932,1.287
c-0.39,0.273-0.883,0.411-1.477,0.411s-1.094-0.138-1.499-0.414s-0.722-0.695-0.951-1.257s-0.344-1.362-0.344-2.401
c0-1.45,0.224-2.501,0.671-3.153C240.677,251.397,241.37,251.039,242.258,251.039z M242.292,252.468
c-0.253,0-0.479,0.082-0.675,0.244c-0.196,0.163-0.347,0.443-0.45,0.841s-0.155,0.979-0.155,1.746
c0,0.999,0.119,1.689,0.356,2.071c0.238,0.381,0.546,0.572,0.924,0.572c0.365,0,0.654-0.181,0.869-0.542
c0.261-0.437,0.391-1.167,0.391-2.191c0-1.039-0.117-1.754-0.351-2.148S242.665,252.468,242.292,252.468z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

127
img/horizon_circle.svg Normal file
View File

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="400px" height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve">
<style>
.marks {
transform: translate(50%, 50%);
}
.marks line {
fill: none;
stroke: white;
stroke-width: 4;
stroke-miterlimit: 10;
}
.marks polygon {
fill: white;
}
.marks line {
--base-angle: 270deg;
--base-stroke-width: 2;
transform: rotate(var(--base-angle));
stroke-width: var(--base-stroke-width);
fill: none;
stroke: white;
stroke-miterlimit: 10;
}
.marks .triangles polygon {
--base-angle: 0deg;
transform: rotate(var(--base-angle));
}
.marks .long-ticks .tick:nth-child(1) {
--base-angle: 210deg;
}
.marks .long-ticks .tick:nth-child(2) {
--base-angle: 240deg;
}
.marks .long-ticks .tick:nth-child(3) {
--base-angle: 300deg;
}
.marks .long-ticks .tick:nth-child(4) {
--base-angle: 330deg;
}
.marks .long-ticks .tick:nth-child(5) {
--base-angle: 0deg;
}
.marks .long-ticks .tick:nth-child(6) {
--base-angle: 180deg;
}
.marks .short-ticks .tick:nth-child(1) {
--base-angle: 260deg;
}
.marks .short-ticks .tick:nth-child(2) {
--base-angle: 250deg;
}
.marks .short-ticks .tick:nth-child(3) {
--base-angle: 280deg;
}
.marks .short-ticks .tick:nth-child(4) {
--base-angle: 290deg;
}
.marks .triangles polygon:nth-child(1) {
--base-angle: 180deg;
}
.marks .triangles polygon:nth-child(2) {
--base-angle: 225deg;
}
.marks .triangles polygon:nth-child(3) {
--base-angle: 135deg;
}
</style>
<filter filterUnits="objectBoundingBox" id="filter-shadow">
<feGaussianBlur stdDeviation="5" result="blur" in="SourceAlpha"></feGaussianBlur>
<feOffset dy="0" dx="0" result="offsetBlurredAlpha" in="blur"></feOffset>
<feMerge>
<feMergeNode in="offsetBlurredAlpha"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<linearGradient id="donut-gradient" gradientUnits="userSpaceOnUse" x1="50%" y1="350" x2="50%" y2="50">
<stop offset="0.5" style="stop-color:#503723" />
<stop offset="0.5" style="stop-color:#558EBB" />
</linearGradient>
<g id="donut">
<path fill="url(#donut-gradient)" filter="url(#filter-shadow)"
d="M 200 50 A 150 150 0 1 0 200 350 A 150 150 0 1 0 200 50 Z M 200 100 A 100 100 0 1 1 200 300 A 100 100 0 1 1 200 100 Z" />
</g>
<g class="marks">
<g class="triangles">
<polygon points="0,100 -15,140 15,140" />
<polygon points="0,100 -6,116 6,116" />
<polygon points="0,100 -6,116 6,116" />
</g>
<g class="long-ticks">
<line class="tick" x1="100" y1="0" x2="140" y2="0" />
<line class="tick" x1="100" y1="0" x2="140" y2="0" />
<line class="tick" x1="100" y1="0" x2="140" y2="0" />
<line class="tick" x1="100" y1="0" x2="140" y2="0" />
<line class="tick" x1="100" y1="0" x2="150" y2="0" />
<line class="tick" x1="100" y1="0" x2="150" y2="0" />
</g>
<g class="short-ticks">
<line class="tick" x1="100" y1="0" x2="120" y2="0" />
<line class="tick" x1="100" y1="0" x2="120" y2="0" />
<line class="tick" x1="100" y1="0" x2="120" y2="0" />
<line class="tick" x1="100" y1="0" x2="120" y2="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

65
img/horizon_mechanics.svg Normal file
View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="400px" height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve">
<style>
.aim-marks {
fill: #FF4A24;
stroke: #FF4A24;
}
.aim-marks circle,
.aim-marks line {
fill: none;
stroke-width: 5;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.static-marks {
fill: none;
stroke: white;
stroke-width: 4;
stroke-miterlimit: 10;
}
</style>
<filter filterUnits="objectBoundingBox" id="filter-shadow">
<feGaussianBlur stdDeviation="5" result="blur" in="SourceAlpha"></feGaussianBlur>
<feOffset dy="0" dx="0" result="offsetBlurredAlpha" in="blur"></feOffset>
<feMerge>
<feMergeNode in="offsetBlurredAlpha"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<clipPath id="circle-out-off">
<rect x="0" y="50%" width="100%" height="100%" />
</clipPath>
<clipPath id="triangle-left-cut-off">
<rect x="%50" y="60" width="49.5%" height="25" />
</clipPath>
<clipPath id="triangle-right-cut-off">
<rect x="50.5%" y="60" width="100%" height="25" />
</clipPath>
<g class="aim-marks">
<circle class="aim" cx="50%" cy="50%" r="25" clip-path="url(#circle-out-off)" />
<circle class="dot" cx="50%" cy="50%" r="1" />
<line x1="120" y1="50%" x2="175" y2="50%" />
<line x1="225" y1="50%" x2="280" y2="50%" />
<polygon points="185,60 215,60 200,98" clip-path="url(#triangle-left-cut-off)" />
<polygon points="185,60 215,60 200,98" clip-path="url(#triangle-right-cut-off)" />
</g>
<g filter="url(#filter-shadow)">
<path fill="#232323" d="M 80 298 A 155 155 0 0 0 320 298 Z" />
<path fill="none" stroke="#353535" stroke-width="1.3" stroke-miterlimit="10"
d="M 80 298 A 155 155 0 0 0 320 298 Z" />
</g>
<g class="static-marks" filter="url(#filter-shadow)">
<line x1="50%" y1="298" x2="50%" y2="330" />
<line x1="254" y1="298" x2="254" y2="308" />
<line x1="146" y1="298" x2="146" y2="308" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

313
img/speed_mechanics.svg Normal file
View File

@ -0,0 +1,313 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="400px" height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve">
<defs>
<style type="text/css">
@import url('http://fonts.googleapis.com/css?family=Noto+Sans+KR|Nanum+Gothic+Coding');
</style>
</defs>
<style>
.color-marks .level {
--level-color: green;
fill: none;
stroke: var(--level-color);
stroke-width: 10;
stroke-miterlimit: 10;
}
.color-marks .level.high {
--level-color: yellow;
}
.color-marks .level.critical {
--level-color: red;
}
.marks {
transform: translate(50%, 50%);
}
.marks line {
--base-angle: 270deg;
--base-stroke-width: 2;
transform: rotate(var(--base-angle));
stroke-width: var(--base-stroke-width);
fill: none;
stroke: white;
stroke-miterlimit: 10;
}
.marks .wide-ticks .tick {
--base-stroke-width: 4;
}
.marks .wide-ticks .tick:nth-child(2) {
--base-angle: 310deg;
}
.marks .wide-ticks .tick:nth-child(3) {
--base-angle: 350deg;
}
.marks .wide-ticks .tick:nth-child(4) {
--base-angle: 30deg;
}
.marks .wide-ticks .tick:nth-child(5) {
--base-angle: 70deg;
}
.marks .wide-ticks .tick:nth-child(6) {
--base-angle: 110deg;
}
.marks .wide-ticks .tick:nth-child(7) {
--base-angle: 150deg;
}
.marks .wide-ticks .tick:nth-child(8) {
--base-angle: 190deg;
}
.marks .wide-ticks .tick:nth-child(9) {
--base-angle: 230deg;
}
.marks .wide-ticks .tick:nth-child(10) {
--base-angle: 270deg;
}
.marks .short-ticks .tick:nth-child(1) {
--base-angle: 280deg;
}
.marks .short-ticks .tick:nth-child(2) {
--base-angle: 300deg;
}
.marks .short-ticks .tick:nth-child(3) {
--base-angle: 320deg;
}
.marks .short-ticks .tick:nth-child(4) {
--base-angle: 340deg;
}
.marks .short-ticks .tick:nth-child(5) {
--base-angle: 0deg;
}
.marks .short-ticks .tick:nth-child(6) {
--base-angle: 20deg;
}
.marks .short-ticks .tick:nth-child(7) {
--base-angle: 40deg;
}
.marks .short-ticks .tick:nth-child(8) {
--base-angle: 60deg;
}
.marks .short-ticks .tick:nth-child(9) {
--base-angle: 80deg;
}
.marks .short-ticks .tick:nth-child(10) {
--base-angle: 100deg;
}
.marks .short-ticks .tick:nth-child(11) {
--base-angle: 120deg;
}
.marks .short-ticks .tick:nth-child(12) {
--base-angle: 140deg;
}
.marks .short-ticks .tick:nth-child(13) {
--base-angle: 160deg;
}
.marks .short-ticks .tick:nth-child(14) {
--base-angle: 180deg;
}
.marks .short-ticks .tick:nth-child(15) {
--base-angle: 200deg;
}
.marks .short-ticks .tick:nth-child(16) {
--base-angle: 220deg;
}
.marks .long-ticks .tick:nth-child(1) {
--base-angle: 290deg;
}
.marks .long-ticks .tick:nth-child(2) {
--base-angle: 330deg;
}
.marks .long-ticks .tick:nth-child(3) {
--base-angle: 10deg;
}
.marks .long-ticks .tick:nth-child(4) {
--base-angle: 50deg;
}
.marks .long-ticks .tick:nth-child(5) {
--base-angle: 90deg;
}
.marks .long-ticks .tick:nth-child(6) {
--base-angle: 130deg;
}
.marks .long-ticks .tick:nth-child(7) {
--base-angle: 170deg;
}
.marks .long-ticks .tick:nth-child(8) {
--base-angle: 210deg;
}
.mark-labels {
transform: translate(50%, 50%);
}
.mark-labels>text {
fill: white;
font-family: Noto Sans KR, sans-serif;
font-size: 18px;
font-weight: bold;
dominant-baseline: middle;
text-anchor: middle;
}
.mark-labels .numerical {
--base-x: 0%;
--base-y: 0%;
transform: translate(var(--base-x), var(--base-y));
}
.mark-labels .numerical:nth-child(1) {
--base-x: 0;
--base-y: -28%;
}
.mark-labels .numerical:nth-child(2) {
--base-x: 16%;
--base-y: -22%;
}
.mark-labels .numerical:nth-child(3) {
--base-x: -15%;
--base-y: -22%;
}
.mark-labels .numerical:nth-child(4) {
--base-x: 27%;
--base-y: -5%;
}
.mark-labels .numerical:nth-child(5) {
--base-x: -26%;
--base-y: -5%;
}
.mark-labels .numerical:nth-child(6) {
--base-x: 24%;
--base-y: 14%;
}
.mark-labels .numerical:nth-child(7) {
--base-x: -23%;
--base-y: 14%;
}
.mark-labels .numerical:nth-child(8) {
--base-x: 10%;
--base-y: 27%;
}
.mark-labels .numerical:nth-child(9) {
--base-x: -11%;
--base-y: 27%;
}
</style>
<circle fill="#232323" cx="200" cy="200" r="160" />
<g class="color-marks">
<path class="level normal" d="M 326 128 A 145 145 -30 0 1 150 336" />
<path class="level high" d="M 150 336 A 145 145 110 0 1 57 175" />
<path class="level critical" d="M 57 175 A 145 145 190 0 1 107 89" />
</g>
<g class="marks">
<g class="wide-ticks">
<line class="tick" x1="130" y1="0" x2="150" y2="0" />
<line class="tick" x1="130" y1="0" x2="150" y2="0" />
<line class="tick" x1="130" y1="0" x2="150" y2="0" />
<line class="tick" x1="130" y1="0" x2="150" y2="0" />
<line class="tick" x1="130" y1="0" x2="150" y2="0" />
<line class="tick" x1="130" y1="0" x2="150" y2="0" />
<line class="tick" x1="130" y1="0" x2="150" y2="0" />
<line class="tick" x1="130" y1="0" x2="150" y2="0" />
<line class="tick" x1="130" y1="0" x2="150" y2="0" />
<line class="tick" x1="130" y1="0" x2="150" y2="0" />
</g>
<g class="short-ticks">
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
<line class="tick" x1="140" y1="0" x2="150" y2="0" />
</g>
<g class="long-ticks">
<line class="tick" x1="135" y1="0" x2="150" y2="0" />
<line class="tick" x1="135" y1="0" x2="150" y2="0" />
<line class="tick" x1="135" y1="0" x2="150" y2="0" />
<line class="tick" x1="135" y1="0" x2="150" y2="0" />
<line class="tick" x1="135" y1="0" x2="150" y2="0" />
<line class="tick" x1="135" y1="0" x2="150" y2="0" />
<line class="tick" x1="135" y1="0" x2="150" y2="0" />
<line class="tick" x1="135" y1="0" x2="150" y2="0" />
</g>
</g>
<g class="mark-labels">
<text class="numerical" x="0" y="0">0</text>
<text class="numerical" x="0" y="0">20</text>
<text class="numerical" x="0" y="0">160</text>
<text class="numerical" x="0" y="0">40</text>
<text class="numerical" x="0" y="0">140</text>
<text class="numerical" x="0" y="0">60</text>
<text class="numerical" x="0" y="0">120</text>
<text class="numerical" x="0" y="0">80</text>
<text class="numerical" x="0" y="0">100</text>
<text x="0" y="-10%">AIRSPEED</text>
<text x="0" y="10%">KM / H</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.1 KiB

211
img/turn_coordinator.svg Normal file
View File

@ -0,0 +1,211 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="540" height="540" id="svg6534"
preserveAspectRatio="X200Y200 meet">
<style type="text/css">
@import url('http://fonts.googleapis.com/css?family=Noto+Sans+KR|Nanum+Gothic+Coding');
.labels {
--base-x: 50%;
--base-y: 50%;
transform: translate(var(--base-x), var(--base-y));
}
.labels text {
font-family: Noto, sans-serif;
font-size: 16px;
dominant-baseline: middle;
text-anchor: middle;
fill: white;
filter: url(#inner-shadow)
}
.labels .placard .label {}
.labels .title {
font-size: 16px;
}
.labels .turn-time {
font-size: 20px;
}
.labels .trademarks .label {
font-size: 32px;
}
.labels .no-pitch .label {
font-size: 15px;
}
</style>
<defs id="defs6536">
<linearGradient id="linearGradient7398">
<stop style="stop-color:#a8a8a8;stop-opacity:1" offset="0" />
<stop style="stop-color:#515151;stop-opacity:1" offset="1" />
</linearGradient>
<linearGradient id="linearGradient7376">
<stop style="stop-color:#1d1d1d;stop-opacity:1" offset="0" />
<stop style="stop-color:#acacac;stop-opacity:1" offset="1" />
</linearGradient>
<linearGradient id="linearGradient7357">
<stop style="stop-color:#222222;stop-opacity:1" offset="0" />
<stop style="stop-color:#888888;stop-opacity:1" offset="1" />
</linearGradient>
<linearGradient id="linearGradient7280">
<stop style="stop-color:#989898;stop-opacity:1" offset="0" />
<stop style="stop-color:#161616;stop-opacity:1" offset="1" />
</linearGradient>
<filter x="0" y="0" width="1" height="1.5" color-interpolation-filters="sRGB"
id="filter7272">
<feGaussianBlur id="feGaussianBlur7274" stdDeviation="1.3586542" />
</filter>
<filter x="0" y="0" width="1" height="1.5" color-interpolation-filters="sRGB"
id="filter7276">
<feGaussianBlur id="feGaussianBlur7278" stdDeviation="1.3586542" />
</filter>
<filter x="-0.025320208" y="-0.4602949" width="1.0506403" height="1.9205898" color-interpolation-filters="sRGB"
id="filter7296">
<feGaussianBlur id="feGaussianBlur7298" stdDeviation="2.5395566" />
</filter>
<filter color-interpolation-filters="sRGB" id="filter7320">
<feGaussianBlur id="feGaussianBlur7322" stdDeviation="1.560427" />
</filter>
<filter x="-0.037216581" y="-1.1012783" width="1.0744332" height="3.2025566" color-interpolation-filters="sRGB"
id="filter7332">
<feGaussianBlur id="feGaussianBlur7334" stdDeviation="0.42103338" />
</filter>
<filter x="-0.03657512" y="-2.2894466" width="1.0731502" height="5.5788932" color-interpolation-filters="sRGB"
id="filter7336">
<feGaussianBlur id="feGaussianBlur7338" stdDeviation="0.37260582" />
</filter>
<filter color-interpolation-filters="sRGB" id="filter7340">
<feGaussianBlur id="feGaussianBlur7342" stdDeviation="12.323861" />
</filter>
<filter x="-1.5192107" y="-0.16643283" width="4.0384216" height="1.3328657" color-interpolation-filters="sRGB"
id="filter7344">
<feGaussianBlur id="feGaussianBlur7346" stdDeviation="2.4271454" />
</filter>
<filter x="-0.15478399" y="-0.095661767" width="1.309568" height="1.1913235" color-interpolation-filters="sRGB"
id="filter7390">
<feGaussianBlur id="feGaussianBlur7392" stdDeviation="2.6718665" />
</filter>
<radialGradient cx="436.2619" cy="383.55603" r="21.234371" fx="436.2619" fy="383.55603" id="radialGradient7450"
xlink:href="#linearGradient7280" gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.99962961,0.03151084,-0.03165606,1.3463234,12.30346,-151.54305)" />
<linearGradient x1="405.10495" y1="100.92" x2="429.60284" y2="491.39627" id="linearGradient7457"
xlink:href="#linearGradient7376" gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0317265,0,0,1.0317265,-10.411468,-40.920085)" />
<linearGradient x1="330.24167" y1="125.12653" x2="460.05554" y2="575.40216" id="linearGradient7460"
xlink:href="#linearGradient7357" gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,1,1.2957406,-32.018626)" />
<linearGradient x1="346.57809" y1="73.12307" x2="545.03467" y2="529.28961" id="linearGradient7498"
xlink:href="#linearGradient7398" gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,1,2.6,1.5)" />
<filter x="0" y="0" width="1" height="1.5" color-interpolation-filters="sRGB" id="filter3669">
<feGaussianBlur stdDeviation="3.5" />
</filter>
<filter id="inner-shadow">
<feOffset dx="0" dy="1" />
<feComposite operator="out" result="fc-out-result" in2="SourceGraphic" />
<feFlood flood-opacity=".6" flood-color="rgb(0,0,0)" />
<feComposite operator="in" in2="fc-out-result" result="fc-in-result" />
<feMerge>
<feMergeNode in="fc-in-result" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<g transform="translate(-78,33), scale(0.8)" id="layer3" style="display:inline">
<path
d="m 696.90144,298.23878 c 0,144.28485 -116.96598,261.25084 -261.25083,261.25084 -144.28485,0 -261.25084,-116.96599 -261.25084,-261.25084 0,-144.28486 116.96599,-261.250835 261.25084,-261.250835 144.28485,0 261.25083,116.965975 261.25083,261.250835 z m -10.10301,0 c 0,138.70511 -112.44272,251.14782 -251.14782,251.14782 -138.70511,0 -251.14782,-112.44271 -251.14782,-251.14782 0,-138.70511 112.44271,-251.147823 251.14782,-251.147823 138.7051,0 251.14782,112.442713 251.14782,251.147823 z"
id="path7394"
style="fill:url(#linearGradient7498);fill-opacity:1;fill-rule:evenodd;stroke:#262626;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
d="m 589.56061,345.52822 c 6.00401,3.72566 -12.18555,52.58809 -16.16244,60.14358 l -137.75312,32.10149 -131.52389,-28.06088 -15.27484,-62.04133 300.71429,-2.14286 z"
id="rect7294" style="fill:#c1c2a9;fill-opacity:1;fill-rule:evenodd;stroke:none" />
<path d="m 462.49999,391.78574 a 20.714285,33.516418 0 1 1 -41.42857,0 20.714285,33.516418 0 1 1 41.42857,0 z"
transform="matrix(1.0344828,0,0,0.89344242,-15.393402,42.833118)" id="path7384"
style="fill:#000000;fill-opacity:0.57213931;stroke:none;filter:url(#filter7390)" />
<path d="m 558.84631,370.52822 c -47.33809,11.3318 -95.59887,14.35943 -144.50945,11.53893" id="path7256"
style="opacity:0.7;fill:none;stroke:#fbf7d3;stroke-width:12;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter7296)" />
<path d="m 462.49999,391.78574 a 20.714285,33.516418 0 1 1 -41.42857,0 20.714285,33.516418 0 1 1 41.42857,0 z"
transform="matrix(1.0344828,0,0,0.89344242,-21.030537,41.561674)" id="path7231"
style="fill:url(#radialGradient7450);fill-opacity:1;stroke:none" />
<path
d="m 422.49578,368.30507 0.89439,0.70614 c 8.83169,0.30103 17.41075,0.26525 25.80997,-0.0103 l 0.44698,-0.38853"
id="path7324"
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.53266332;stroke-dasharray:none;filter:url(#filter7332)" />
<path
d="m 435.64988,123.75143 c -96.3635,0 -174.46875,78.1365 -174.46875,174.5 0,96.3635 78.10525,174.46875 174.46875,174.46875 96.3635,0 174.46875,-78.10525 174.46875,-174.46875 0,-96.3635 -78.10525,-174.5 -174.46875,-174.5 z m -127.75,230.28125 c 2.93053,-0.0399 6.74284,0.86595 10.84375,1.78125 38.73558,8.64556 91.06394,11.90625 116.90625,11.90625 25.84231,0 78.17067,-3.26069 116.90625,-11.90625 9.37351,-2.09211 17.16128,-4.12165 16.6875,5.0625 -0.8315,16.11858 1.45844,35.07601 -14.15625,40.40625 -36.57226,12.48432 -98.952,15.65625 -119.4375,15.65625 -20.4855,0 -82.86524,-3.17193 -119.4375,-15.65625 -15.61469,-5.33024 -13.32475,-24.28767 -14.15625,-40.40625 -0.2665,-5.16608 2.07592,-6.79242 5.84375,-6.84375 z"
id="path7226" style="fill:#363636;fill-opacity:1;stroke:none" />
<path d="m 678.82249,328.72943 a 246.47722,246.47722 0 1 1 -492.95443,0 246.47722,246.47722 0 1 1 492.95443,0 z"
transform="matrix(0.62780867,0,0,0.62780867,164.2205,91.859596)" id="path7132"
style="fill:none;stroke:#000000;stroke-width:9.55705166;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter7340)" />
<path
d="m 594.24456,298.23878 c 0,87.58902 -71.00493,158.59395 -158.59394,158.59395 -87.58902,0 -158.59395,-71.00493 -158.59395,-158.59395 0,-87.58902 71.00493,-158.59395 158.59395,-158.59395 87.58901,0 158.59394,71.00493 158.59394,158.59395 z m 70.71068,0 c 0,126.64145 -102.66318,229.30463 -229.30462,229.30463 -126.64145,0 -229.30463,-102.66318 -229.30463,-229.30463 0,-126.64145 102.66318,-229.304622 229.30463,-229.304622 126.64144,0 229.30462,102.663172 229.30462,229.304622 z"
id="path7313" style="fill:#424242;fill-opacity:1;fill-rule:evenodd;stroke:none" />
<rect width="29.78681" height="14.517226" rx="2.1428571" ry="2.1428571" x="248.20827" y="311.11826"
id="rect7208" style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
<rect width="29.78681" height="14.517226" rx="2.1428571" ry="2.1428571" x="118.46992" y="437.55161"
transform="matrix(0.93872509,-0.34466681,0.34466681,0.93872509,0,0)" id="rect7210"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
<path
d="m 458.52052,416.17411 c 1.89517,-16.28871 2.14229,-32.57742 0,-48.86613 m -45.73981,48.86613 c -1.89517,-16.28871 -2.14229,-32.57742 0,-48.86613"
id="path7223"
style="fill:none;stroke:#262626;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path d="M 565.45523,362.63603 C 481.61257,381.11769 397.76991,381.69222 313.92725,361.1208" id="path7235"
style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter7272)" />
<rect width="29.78681" height="14.517226" rx="2.1428571" ry="2.1428571" x="-622.44928" y="311.11826"
transform="scale(-1,1)" id="rect7249" style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
<rect width="29.78681" height="14.517226" rx="2.1428571" ry="2.1428571" x="-698.83789" y="137.46478"
transform="matrix(-0.93872509,-0.34466681,-0.34466681,0.93872509,0,0)" id="rect7251"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
<path d="m 324.17807,362.166 c -2.80164,11.19048 -4.52044,23.80952 -3.57142,35" id="path7258"
style="opacity:0.2;fill:none;stroke:#000000;stroke-width:5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter7344)" />
<path d="m 565.45523,367.43425 c -83.84266,18.48166 -167.68532,19.05619 -251.52798,-1.51523" id="path7233"
style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter7276)" />
<path d="m 423.88521,415.22423 c 8.42293,0.54697 16.54539,0.493 24.44979,0.003" id="path7330"
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.53266332;stroke-dasharray:none;filter:url(#filter7336)" />
<path d="m 678.82249,328.72943 a 246.47722,246.47722 0 1 1 -492.95443,0 246.47722,246.47722 0 1 1 492.95443,0 z"
transform="matrix(0.92001039,0,0,0.92001039,37.888468,-4.19571)" id="inner-ring-shadow"
style="fill:none;stroke:#000000;stroke-width:6.52166557;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter7340)" />
<path
d="m 683.27347,298.23877 c 0,136.75834 -110.86454,247.62287 -247.62287,247.62287 -136.75833,0 -247.62287,-110.86453 -247.62287,-247.62287 0,-136.75833 110.86454,-247.622866 247.62287,-247.622866 136.75833,0 247.62287,110.864536 247.62287,247.622866 z m -20.86126,1e-5 c 0,125.23697 -101.52462,226.76161 -226.7616,226.76161 -125.23697,0 -226.7616,-101.52464 -226.7616,-226.76161 0,-125.23697 101.52463,-226.761603 226.7616,-226.761603 125.23698,0 226.7616,101.524633 226.7616,226.761603 z"
id="inner-ring"
style="fill:url(#linearGradient7460);fill-opacity:1;fill-rule:evenodd;stroke:#363636;stroke-width:0.99999994;stroke-miterlimit:4;stroke-opacity:1" />
<!-- <path
d="m 689.94768,298.23878 c 0,140.4444 -113.85268,254.29708 -254.29707,254.29708 -140.44439,0 -254.29707,-113.85268 -254.29707,-254.29708 0,-140.4444 113.85268,-254.297077 254.29707,-254.297077 140.44439,0 254.29707,113.852677 254.29707,254.297077 z m -9.83409,0 c 0,135.01317 -109.44981,244.46298 -244.46298,244.46298 -135.01317,0 -244.46298,-109.44981 -244.46298,-244.46298 0,-135.01317 109.44981,-244.462978 244.46298,-244.462978 135.01317,0 244.46298,109.449808 244.46298,244.462978 z"
id="path7371" style="fill:url(#linearGradient7457);fill-opacity:1;fill-rule:evenodd;stroke:none" /> -->
</g>
<g>
<path d="M 474 270 A 204 204 0 1 0 66 270 A 204 204 0 1 0 474 270
M 466 270 A 196 196 0 1 0 74 270 A 196 196 0 1 0 466 270" id="in-border-ring"
style="fill:url(#linearGradient7457);fill-opacity:1;fill-rule:evenodd;stroke:none" />
</g>
<g class="labels">
<g class="placard">
<text class="label" x="0%" y="-29%">D.C.</text>
<text class="label" x="0%" y="-26%">ELEC.</text>
</g>
<text class="title" x="0%" y="7%">TURN COORDINATOR</text>
<text class="turn-time" x="0%" y="21%">2 MIN.</text>
<g class="trademarks">
<text class="label" x="-20%" y="20%">L</text>
<text class="label" x="20%" y="20%">R</text>
</g>
<g class="no-pitch">
<text class="label" x="0%" y="27%">NO PITCH</text>
<text class="label" x="0%" y="30%">INFORMATION</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 15 KiB

389
img/vertical_mechanics.svg Normal file
View File

@ -0,0 +1,389 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="400px" height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve">
<style>
.bg-base {
fill: #232323;
}
.shades>* {
--base-stroke-width: 2;
fill: none;
stroke: white;
stroke-miterlimit: 10;
stroke-width: var(--base-stroke-width);
}
.shades path {
}
.shades polygon {
fill: white;
}
.marks {
transform: translate(50%, 50%);
}
.marks line {
--base-angle: 270deg;
--base-stroke-width: 2;
transform: rotate(var(--base-angle));
stroke-width: var(--base-stroke-width);
fill: none;
stroke: white;
stroke-miterlimit: 10;
}
.marks .long-ticks .tick:nth-child(1) {
--base-angle: -90deg;
}
.marks .long-ticks .tick:nth-child(2) {
--base-angle: -45deg;
}
.marks .long-ticks .tick:nth-child(3) {
--base-angle: -9deg;
}
.marks .long-ticks .tick:nth-child(4) {
--base-angle: 9deg;
}
.marks .long-ticks .tick:nth-child(5) {
--base-angle: 45deg;
}
.marks .long-ticks .tick:nth-child(6) {
--base-angle: 90deg;
}
.marks .long-ticks .tick:nth-child(7) {
--base-angle: 135deg;
}
.marks .long-ticks .tick:nth-child(8) {
--base-angle: 180deg;
}
.marks .long-ticks .tick:nth-child(9) {
--base-angle: 225deg;
}
.marks .short-ticks .tick:nth-child(1) {
--base-angle: -81deg;
}
.marks .short-ticks .tick:nth-child(2) {
--base-angle: -72deg;
}
.marks .short-ticks .tick:nth-child(3) {
--base-angle: -63deg;
}
.marks .short-ticks .tick:nth-child(4) {
--base-angle: -54deg;
}
.marks .short-ticks .tick:nth-child(5) {
--base-angle: -36deg;
}
.marks .short-ticks .tick:nth-child(6) {
--base-angle: -27deg;
}
.marks .short-ticks .tick:nth-child(7) {
--base-angle: -18deg;
}
.marks .short-ticks .tick:nth-child(8) {
--base-angle: 18deg;
}
.marks .short-ticks .tick:nth-child(9) {
--base-angle: 27deg;
}
.marks .short-ticks .tick:nth-child(10) {
--base-angle: 36deg;
}
.marks .short-ticks .tick:nth-child(11) {
--base-angle: 54deg;
}
.marks .short-ticks .tick:nth-child(12) {
--base-angle: 63deg;
}
.marks .short-ticks .tick:nth-child(13) {
--base-angle: 72deg;
}
.marks .short-ticks .tick:nth-child(14) {
--base-angle: 81deg;
}
.marks .short-ticks .tick:nth-child(15) {
--base-angle: 99deg;
}
.marks .short-ticks .tick:nth-child(16) {
--base-angle: 108deg;
}
.marks .short-ticks .tick:nth-child(17) {
--base-angle: 117deg;
}
.marks .short-ticks .tick:nth-child(18) {
--base-angle: 126deg;
}
.marks .short-ticks .tick:nth-child(19) {
--base-angle: 139.5deg;
}
.marks .short-ticks .tick:nth-child(20) {
--base-angle: 144deg;
}
.marks .short-ticks .tick:nth-child(21) {
--base-angle: 148.5deg;
}
.marks .short-ticks .tick:nth-child(22) {
--base-angle: 153deg;
}
.marks .short-ticks .tick:nth-child(23) {
--base-angle: 157.5deg;
}
.marks .short-ticks .tick:nth-child(24) {
--base-angle: 162deg;
}
.marks .short-ticks .tick:nth-child(25) {
--base-angle: 166.5deg;
}
.marks .short-ticks .tick:nth-child(26) {
--base-angle: 171deg;
}
.marks .short-ticks .tick:nth-child(27) {
--base-angle: 175.5deg;
}
.marks .short-ticks .tick:nth-child(28) {
--base-angle: 184.5deg;
}
.marks .short-ticks .tick:nth-child(29) {
--base-angle: 189deg;
}
.marks .short-ticks .tick:nth-child(30) {
--base-angle: 193.5deg;
}
.marks .short-ticks .tick:nth-child(31) {
--base-angle: 198deg;
}
.marks .short-ticks .tick:nth-child(32) {
--base-angle: 202.5deg;
}
.marks .short-ticks .tick:nth-child(33) {
--base-angle: 207deg;
}
.marks .short-ticks .tick:nth-child(34) {
--base-angle: 211.5deg;
}
.marks .short-ticks .tick:nth-child(35) {
--base-angle: 216deg;
}
.marks .short-ticks .tick:nth-child(36) {
--base-angle: 220.5deg;
}
.marks .short-ticks .tick:nth-child(37) {
--base-angle: 234deg;
}
.marks .short-ticks .tick:nth-child(38) {
--base-angle: 243deg;
}
.marks .short-ticks .tick:nth-child(39) {
--base-angle: 252deg;
}
.marks .short-ticks .tick:nth-child(40) {
--base-angle: 261deg;
}
.mark-labels {
--base-x: 50%;
--base-y: 50%;
transform: translate(var(--base-x), var(--base-y));
}
.mark-labels>text {
font-family: sans-serif;
font-size: 25px;
font-weight: bold;
dominant-baseline: middle;
text-anchor: middle;
fill: white;
}
.mark-labels .numerical {
--base-x: 0%;
--base-y: 0%;
transform: translate(var(--base-x), var(--base-y));
letter-spacing: -3
}
.mark-labels .title {
font-family: Noto Sans KR, sans-serif;
font-size: 14px;
}
.mark-labels .numerical:nth-child(1) {
--base-y: -27%;
}
.mark-labels .numerical:nth-child(2) {
--base-x: 19%;
--base-y: -18%;
}
.mark-labels .numerical:nth-child(3) {
--base-x: 28%;
}
.mark-labels .numerical:nth-child(4) {
--base-x: 19%;
--base-y: 19%;
}
.mark-labels .numerical:nth-child(5) {
--base-y: 27%;
}
.mark-labels .numerical:nth-child(6) {
--base-x: -19.5%;
--base-y: 19%;
}
.mark-labels .numerical:nth-child(7) {
--base-x: -28%;
}
.mark-labels .numerical:nth-child(8) {
--base-x: -19.5%;
--base-y: -18.5%;
}
</style>
<circle class="bg-base" cx="200.333" cy="200" r="161" />
<g class="marks">
<g class="long-ticks">
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
<line class="tick" x1="127" y1="0" x2="150" y2="0" />
</g>
<g class="short-ticks">
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
<line class="tick" x1="134" y1="0" x2="150" y2="0" />
</g>
</g>
<g class="mark-labels">
<text class="numerical" x="0" y="0">1</text>
<text class="numerical" x="0" y="0">1.5</text>
<text class="numerical" x="0" y="0" dy="1">2</text>
<text class="numerical" x="0" y="0">1.5</text>
<text class="numerical" x="0" y="0">1</text>
<text class="numerical" x="0" y="0">.5</text>
<text class="numerical" x="0" y="0" dy="2">0</text>
<text class="numerical" x="0" y="0">.5</text>
<text class="title" x="0" y="-10%">VERTICAL SPEED</text>
<text class="title" x="0" y="10%">1 KM PER HOUR</text>
</g>
<g class="shades">
<path d="M 337 178 A 130 130 0 0 1 337 222" />
<path d="M 120 180 H 84 C 84 180 84 169 90 160" />
<polygon points="92,162 88,158 92,158" />
<path d="M 120 220 H 84 C 84 220 84 231 90 240" />
<polygon points="92,238 88,242 92,242" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

86
index.html Normal file
View File

@ -0,0 +1,86 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>UDrone</title>
<meta name="theme-color" content="#7952b3">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<style>
html,
body {
height: 100%;
}
body {
display: flex;
align-items: center;
padding-top: 40px;
padding-bottom: 40px;
background-color: #f5f5f5;
}
.form-signin {
width: 100%;
max-width: 330px;
padding: 15px;
margin: auto;
}
.form-signin .checkbox {
font-weight: 400;
}
.form-signin .form-floating:focus-within {
z-index: 2;
}
.form-signin input[type="email"] {
margin-bottom: -1px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
</style>
</head>
<body class="text-center">
<main class="form-signin">
<form>
<img class="mb-4" src="/docs/5.0/assets/brand/bootstrap-logo.svg" alt="" width="72" height="57">
<h1 class="h3 mb-3 fw-normal">Ввійдіть будьласка</h1>
<div class="form-floating">
<input type="text" class="form-control" id="floatingInput" placeholder="name@example.com">
<label for="floatingInput">Логін</label>
</div>
<div class="form-floating">
<input type="password" class="form-control" id="floatingPassword" placeholder="Password">
<label for="floatingPassword">Пароль</label>
</div>
<a href="dashboard.html" class="w-100 btn btn-lg btn-primary" type="submit">Вхід</a>
<p class="mt-5 mb-3 text-muted">&copy; 2022</p>
</form>
</main>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>

View File

@ -0,0 +1,173 @@
/*
* jQuery Flight Indicators plugin
* By Sébastien Matton (seb_matton@hotmail.com)
* Published under GPLv3 License.
*
* https://github.com/sebmatton/jQuery-Flight-Indicators
*/
(function($) {
function FlightIndicator( placeholder, type, options ) {
// Initial configuration
var attitude = this;
var settings = $.extend({
size : 200,
roll : 0,
pitch : 0,
turn : 0,
heading: 0,
vario: 0,
airspeed: 0,
altitude: 0,
pressure: 1000,
showBox : true,
img_directory : 'img/'
}, options );
var constants = {
pitch_bound:30,
vario_bound : 1.95,
airspeed_bound_l : 0,
airspeed_bound_h : 160
}
// Creation of the instrument
placeholder.each(function(){
switch(type){
case 'heading':
$(this).html('<div class="instrument heading"><img src="' + settings.img_directory + 'fi_box.svg" class="background box" alt="" /><div class="heading box"><img src="' + settings.img_directory + 'heading_yaw.svg" class="box" alt="" /></div><div class="mechanics box"><img src="' + settings.img_directory + 'heading_mechanics.svg" class="box" alt="" /><img src="' + settings.img_directory + 'fi_circle.svg" class="box" alt="" /></div></div>');
_setHeading(settings.heading);
break;
case 'variometer':
$(this).html('<div class="instrument vario"><img src="' + settings.img_directory + 'fi_box.svg" class="background box" alt="" /><img src="' + settings.img_directory + 'vertical_mechanics.svg" class="box" alt="" /><div class="vario box"><img src="' + settings.img_directory + 'fi_needle.svg" class="box" alt="" /></div><div class="mechanics box"><img src="' + settings.img_directory + 'fi_circle.svg" class="box" alt="" /></div></div>');
_setVario(settings.vario);
break;
case 'turn_coordinator':
$(this).html('<div class="instrument turn_coordinator"><img src="' + settings.img_directory + 'fi_box.svg" class="background box" alt="" /><img src="' + settings.img_directory + 'turn_coordinator.svg" class="box" alt="" /><div class="turn box"><img src="' + settings.img_directory + 'fi_tc_airplane.svg" class="box" alt="" /></div><div class="mechanics box"><img src="' + settings.img_directory + 'fi_circle.svg" class="box" alt="" /></div></div>');
_setTurn(settings.turn);
break;
case 'airspeed':
$(this).html('<div class="instrument airspeed"><img src="' + settings.img_directory + 'fi_box.svg" class="background box" alt="" /><img src="' + settings.img_directory + 'speed_mechanics.svg" class="box" alt="" /><div class="speed box"><img src="' + settings.img_directory + 'fi_needle.svg" class="box" alt="" /></div><div class="mechanics box"><img src="' + settings.img_directory + 'fi_circle.svg" class="box" alt="" /></div></div>');
_setAirSpeed(settings.airspeed);
break
case 'altimeter':
$(this).html('<div class="instrument altimeter"><img src="' + settings.img_directory + 'fi_box.svg" class="background box" alt="" /><div class="pressure box"><img src="' + settings.img_directory + 'altitude_pressure.svg" class="box" alt="" /></div><img src="' + settings.img_directory + 'altitude_ticks.svg" class="box" alt="" /><div class="needleSmall box"><img src="' + settings.img_directory + 'fi_needle_small.svg" class="box" alt="" /></div><div class="needle box"><img src="' + settings.img_directory + 'fi_needle.svg" class="box" alt="" /></div><div class="mechanics box"><img src="' + settings.img_directory + 'fi_circle.svg" class="box" alt="" /></div></div>');
_setAltitude(settings.altitude);
_setPressure(settings.pressure);
break;
default:
$(this).html('<div class="instrument attitude"><img src="' + settings.img_directory + 'fi_box.svg" class="background box" alt="" /><div class="roll box"><img src="' + settings.img_directory + 'horizon_back.svg" class="box" alt="" /><div class="pitch box"><img src="' + settings.img_directory + 'horizon_ball.svg" class="box" alt="" /></div><img src="' + settings.img_directory + 'horizon_circle.svg" class="box" alt="" /></div><div class="mechanics box"><img src="' + settings.img_directory + 'horizon_mechanics.svg" class="box" alt="" /><img src="' + settings.img_directory + 'fi_circle.svg" class="box" alt="" /></div></div>');
_setRoll(settings.roll);
_setPitch(settings.pitch);
}
$(this).find('div.instrument').css({height : settings.size, width : settings.size});
$(this).find('div.instrument img.box.background').toggle(settings.showBox);
});
// Private methods
function _setRoll(roll){
placeholder.each(function(){
$(this).find('div.instrument.attitude div.roll').css('transform', 'rotate('+roll+'deg)');
});
}
function _setPitch(pitch){
// alert(pitch);
if(pitch>constants.pitch_bound){pitch = constants.pitch_bound;}
else if(pitch<-constants.pitch_bound){pitch = -constants.pitch_bound;}
placeholder.each(function(){
$(this).find('div.instrument.attitude div.roll div.pitch').css('top', pitch*0.7 + '%');
});
}
function _setHeading(heading){
placeholder.each(function(){
$(this).find('div.instrument.heading div.heading').css('transform', 'rotate(' + -heading + 'deg)');
});
}
function _setTurn(turn){
placeholder.each(function(){
$(this).find('div.instrument.turn_coordinator div.turn').css('transform', 'rotate('+turn+'deg)');
});
}
function _setVario(vario){
if(vario > constants.vario_bound){vario = constants.vario_bound;}
else if(vario < -constants.vario_bound){vario = -constants.vario_bound;}
vario = vario*90;
placeholder.each(function(){
$(this).find('div.instrument.vario div.vario').css('transform', 'rotate(' + vario + 'deg)');
});
}
function _setAirSpeed(speed){
if(speed > constants.airspeed_bound_h){speed = constants.airspeed_bound_h;}
else if(speed < constants.airspeed_bound_l){speed = constants.airspeed_bound_l;}
speed = 90+speed*2;
placeholder.each(function(){
$(this).find('div.instrument.airspeed div.speed').css('transform', 'rotate(' + speed + 'deg)');
});
}
function _setAltitude(altitude){
var needle = 90 + altitude%1000 * 360 / 1000;
var needleSmall = altitude / 10000 * 360;
placeholder.each(function(){
$(this).find('div.instrument.altimeter div.needle').css('transform', 'rotate(' + needle + 'deg)');
$(this).find('div.instrument.altimeter div.needleSmall').css('transform', 'rotate(' + needleSmall + 'deg)');
});
}
function _setPressure(pressure){
pressure = 2*pressure - 1980;
placeholder.each(function(){
$(this).find('div.instrument.altimeter div.pressure').css('transform', 'rotate(' + pressure + 'deg)');
});
}
function _resize(size){
placeholder.each(function(){
$(this).find('div.instrument').css({height : size, width : size});
});
}
function _showBox(){
placeholder.each(function(){
$(this).find('img.box.background').show();
});
}
function _hideBox(){
placeholder.each(function(){
$(this).find('img.box.background').hide();
});
}
// Public methods
this.setRoll = function(roll){_setRoll(roll);}
this.setPitch = function(pitch){_setPitch(pitch);}
this.setHeading = function(heading){_setHeading(heading);}
this.setTurn = function(turn){_setTurn(turn);}
this.setVario = function(vario){_setVario(vario);}
this.setAirSpeed = function(speed){_setAirSpeed(speed);}
this.setAltitude = function(altitude){_setAltitude(altitude);}
this.setPressure = function(pressure){_setPressure(pressure);}
this.resize = function(size){_resize(size);}
this.showBox = function(){_showBox();}
this.hideBox = function(){_hideBox();}
return attitude;
};
// Extension to jQuery
$.flightIndicator = function(placeholder, type, options){
var flightIndicator = new FlightIndicator($(placeholder), type, options)
return flightIndicator;
}
$.fn.flightIndicator = function(data, type, options){
return this.each(function(){
$.flightIndicator(this, type, options);
});
}
}( jQuery ));

8
js/jquery.flightindicators.min.js vendored Normal file
View File

@ -0,0 +1,8 @@
/*
* jQuery Flight Indicators plugin
* By Sébastien Matton (seb_matton@hotmail.com)
* Published under GPLv3 License.
*
* https://github.com/sebmatton/jQuery-Flight-Indicators
*/
(function(b){function a(n,l,r){var f=this;var h=b.extend({size:200,roll:0,pitch:0,heading:0,vario:0,airspeed:0,altitude:0,pressure:1000,showBox:true,img_directory:"img/"},r);var q={pitch_bound:30,vario_bound:1.95,airspeed_bound_l:0,airspeed_bound_h:160};n.each(function(){switch(l){case"heading":b(this).html('<div class="instrument heading"><img src="'+h.img_directory+'fi_box.svg" class="background box" alt="" /><div class="heading box"><img src="'+h.img_directory+'heading_yaw.svg" class="box" alt="" /></div><div class="mechanics box"><img src="'+h.img_directory+'heading_mechanics.svg" class="box" alt="" /><img src="'+h.img_directory+'fi_circle.svg" class="box" alt="" /></div></div>');p(h.heading);break;case"variometer":b(this).html('<div class="instrument vario"><img src="'+h.img_directory+'fi_box.svg" class="background box" alt="" /><img src="'+h.img_directory+'vertical_mechanics.svg" class="box" alt="" /><div class="vario box"><img src="'+h.img_directory+'fi_needle.svg" class="box" alt="" /></div><div class="mechanics box"><img src="'+h.img_directory+'fi_circle.svg" class="box" alt="" /></div></div>');i(h.vario);break;case"airspeed":b(this).html('<div class="instrument airspeed"><img src="'+h.img_directory+'fi_box.svg" class="background box" alt="" /><img src="'+h.img_directory+'speed_mechanics.svg" class="box" alt="" /><div class="speed box"><img src="'+h.img_directory+'fi_needle.svg" class="box" alt="" /></div><div class="mechanics box"><img src="'+h.img_directory+'fi_circle.svg" class="box" alt="" /></div></div>');e(h.airspeed);break;case"altimeter":b(this).html('<div class="instrument altimeter"><img src="'+h.img_directory+'fi_box.svg" class="background box" alt="" /><div class="pressure box"><img src="'+h.img_directory+'altitude_pressure.svg" class="box" alt="" /></div><img src="'+h.img_directory+'altitude_ticks.svg" class="box" alt="" /><div class="needleSmall box"><img src="'+h.img_directory+'fi_needle_small.svg" class="box" alt="" /></div><div class="needle box"><img src="'+h.img_directory+'fi_needle.svg" class="box" alt="" /></div><div class="mechanics box"><img src="'+h.img_directory+'fi_circle.svg" class="box" alt="" /></div></div>');d(h.altitude);k(h.pressure);break;default:b(this).html('<div class="instrument attitude"><img src="'+h.img_directory+'fi_box.svg" class="background box" alt="" /><div class="roll box"><img src="'+h.img_directory+'horizon_back.svg" class="box" alt="" /><div class="pitch box"><img src="'+h.img_directory+'horizon_ball.svg" class="box" alt="" /></div><img src="'+h.img_directory+'horizon_circle.svg" class="box" alt="" /></div><div class="mechanics box"><img src="'+h.img_directory+'horizon_mechanics.svg" class="box" alt="" /><img src="'+h.img_directory+'fi_circle.svg" class="box" alt="" /></div></div>');o(h.roll);m(h.pitch)}b(this).find("div.instrument").css({height:h.size,width:h.size});b(this).find("div.instrument img.box.background").toggle(h.showBox)});function o(s){n.each(function(){b(this).find("div.instrument.attitude div.roll").css("transform","rotate("+s+"deg)")})}function m(s){if(s>q.pitch_bound){s=q.pitch_bound}else{if(s<-q.pitch_bound){s=-q.pitch_bound}}n.each(function(){b(this).find("div.instrument.attitude div.roll div.pitch").css("top",s*0.7+"%")})}function p(s){n.each(function(){b(this).find("div.instrument.heading div.heading").css("transform","rotate("+-s+"deg)")})}function i(s){if(s>q.vario_bound){s=q.vario_bound}else{if(s<-q.vario_bound){s=-q.vario_bound}}s=s*90;n.each(function(){b(this).find("div.instrument.vario div.vario").css("transform","rotate("+s+"deg)")})}function e(s){if(s>q.airspeed_bound_h){s=q.airspeed_bound_h}else{if(s<q.airspeed_bound_l){s=q.airspeed_bound_l}}s=90+s*2;n.each(function(){b(this).find("div.instrument.airspeed div.speed").css("transform","rotate("+s+"deg)")})}function d(s){var u=90+s%1000*360/1000;var t=s/10000*360;n.each(function(){b(this).find("div.instrument.altimeter div.needle").css("transform","rotate("+u+"deg)");b(this).find("div.instrument.altimeter div.needleSmall").css("transform","rotate("+t+"deg)")})}function k(s){s=2*s-1980;n.each(function(){b(this).find("div.instrument.altimeter div.pressure").css("transform","rotate("+s+"deg)")})}function j(s){n.each(function(){b(this).find("div.instrument").css({height:s,width:s})})}function g(){n.each(function(){b(this).find("img.box.background").show()})}function c(){n.each(function(){b(this).find("img.box.background").hide()})}this.setRoll=function(s){o(s)};this.setPitch=function(s){m(s)};this.setHeading=function(s){p(s)};this.setVario=function(s){i(s)};this.setAirSpeed=function(s){e(s)};this.setAltitude=function(s){d(s)};this.setPressure=function(s){k(s)};this.resize=function(s){j(s)};this.showBox=function(){g()};this.hideBox=function(){c()};return f}b.flightIndicator=function(e,d,c){var f=new a(b(e),d,c);return f};b.fn.flightIndicator=function(e,d,c){return this.each(function(){b.flightIndicator(this,d,c)})}}(jQuery));

115
map.html Normal file
View File

@ -0,0 +1,115 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>UDrone</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link rel="stylesheet" type="text/css" href="./node_modules/flight-indicators-js/css/flight-indicators.css" />
<link href="https://api.mapbox.com/mapbox-gl-js/v2.9.2/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.9.2/mapbox-gl.js"></script>
<style>
body { margin: 0; padding: 0; font-family: sans-serif;}
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
#ui {
z-index: 99999;
position: absolute;
bottom: 0;
}
div.instrument .box {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transition: transform .3s;
}
.context-menu {
position: absolute;
z-index: 10000;
}
.menu {
display: flex;
flex-direction: column;
background-color: #edece1;
padding: 10px 0;
margin: 0;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
border-top-right-radius: 5px;
}
.menu > li > a {
font: inherit;
border: 0;
padding: 10px 30px 10px 15px;
display: flex;
align-items: center;
position: relative;
text-decoration: unset;
color: #000;
font-weight: 500;
}
.menu > li > a:hover {
background:#f1f3f7;
color: #013b01;
}
.menu > li {
text-decoration: none;
list-style-type: none; /* Remove bullets */
padding: 0; /* Remove padding */
margin: 0; /* Remove margins */
}
.menu > li > a > i {
padding-right: 10px;
}
.menu > li.trash > a:hover {
color: red;
}
.mapboxgl-popup {
max-width: 400px;
font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
}
#data {
display: block;
position: fixed;
width: 200px;
top: 0;
left: 0;
padding: 10px;
margin: 10px;
background-color: #00000047;
color: #fff;
}
</style>
</head>
<body>
<!-- <iframe width="300" style="position: absolute; z-index: 99999; right: 0;" height="230" src="http://www.youtube.com/embed/yotbnhfRgMY?autoplay=1" frameborder="0" allowfullscreen></iframe> -->
<div id="ui" style="height: 200px;">
<span id="attitude"></span>
<span id="heading"></span>
<div id="data">
<strong>PI 777</strong> (<span id="status"></span>)<br><br>
<strong>MODE:</strong> <span id="mode">manual</span><br>
<strong>ARMED:</strong> <span id="armed">false</span><br>
<strong>BATT:</strong> <span id="batt">0</span>%
<strong>SAT:</strong> <span id="satellites_visible">0</span>
</div>
</div>
<div id="contextMenu" class="context-menu" style="display: none">
<ul class="menu">
<li class="action"><a href="#">Бомбити сюди</a></li>
<li class="action"><a href="#">Дивитись туди</a></li>
</ul>
</div>
<div id="drone" style="cursor:pointer">
<span style="color: #c9003c; font-weight: bold">PI</span> <span style="color: #ffc9d9; font-weight: bold">777</span><br>
<img src="https://i.imgur.com/1gB9w4E.png" width="32px" alt="">
</div>
<div id="map"></div>
<script src="./dist/bundle.js"></script>
</body>
</html>

7315
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

35
package.json Normal file
View File

@ -0,0 +1,35 @@
{
"name": "static",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"babel": {
"presets": [
"@babel/preset-env"
]
},
"devDependencies": {
"@babel/core": "^7.18.10",
"@babel/preset-env": "^7.18.10",
"babel-loader": "^8.2.5",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0"
},
"dependencies": {
"@aesqe/mapboxgl-minimap": "^1.0.0",
"flight-indicators-js": "^1.0.5",
"jquery": "^3.6.0",
"mapbox-gl": "^2.9.2",
"mapbox-gl-controls": "^2.3.5",
"mapbox.minimap": "^0.3.0",
"mqtt": "^4.3.7",
"relaxed-json": "^1.0.3"
}
}

11
server.py Normal file
View File

@ -0,0 +1,11 @@
from flask import Flask
from flask import render_template
app = Flask(__name__, template_folder='./', static_url_path='',
static_folder='./',)
@app.route("/")
def hello():
return render_template("map.html")
if __name__ == "__main__":
app.run()

115
server/bridge.py Normal file
View File

@ -0,0 +1,115 @@
#!/usr/bin/env python
from __future__ import print_function
import fnmatch
import os
import time
import paho.mqtt.client as mqtt
from pymavlink.mavextra import *
from argparse import ArgumentParser
import uuid
parser = ArgumentParser(description=__doc__)
parser.add_argument("--no-timestamps", dest="notimestamps", action='store_true', help="Log doesn't have timestamps")
parser.add_argument("--planner", action='store_true', help="use planner file format")
parser.add_argument("--robust", action='store_true', help="Enable robust parsing (skip over bad data)")
parser.add_argument("-f", "--follow", action='store_true', help="keep waiting for more data at end of file")
parser.add_argument("--condition", default=None, help="select packets by condition")
parser.add_argument("-q", "--quiet", action='store_true', help="don't display packets")
parser.add_argument("-o", "--output", default=None, help="output matching packets to give file")
parser.add_argument("-p", "--parms", action='store_true', help="preserve parameters in output with -o")
parser.add_argument("--format", default=None, help="Change the output format between 'standard', 'json', 'csv' and 'mat'. For the CSV output, you must supply types that you want. For MAT output, specify output file with --mat_file")
parser.add_argument("--csv_sep", dest="csv_sep", default=",", help="Select the delimiter between columns for the output CSV file. Use 'tab' to specify tabs. Only applies when --format=csv")
parser.add_argument("--types", default=None, help="types of messages (comma separated with wildcard)")
parser.add_argument("--nottypes", default=None, help="types of messages not to include (comma separated with wildcard)")
parser.add_argument("--mat_file", dest="mat_file", help="Output file path for MATLAB file output. Only applies when --format=mat")
parser.add_argument("-c", "--compress", action='store_true', help="Compress .mat file data")
parser.add_argument("--dialect", default="ardupilotmega", help="MAVLink dialect")
parser.add_argument("--zero-time-base", action='store_true', help="use Z time base for DF logs")
parser.add_argument("--no-bad-data", action='store_true', help="Don't output corrupted messages")
parser.add_argument("--show-source", action='store_true', help="Show source system ID and component ID")
parser.add_argument("--show-seq", action='store_true', help="Show sequence numbers")
parser.add_argument("--show-types", action='store_true', help="Shows all message types available on opened log")
parser.add_argument("--source-system", type=int, default=None, help="filter by source system ID")
parser.add_argument("--source-component", type=int, default=None, help="filter by source component ID")
parser.add_argument("--link", type=int, default=None, help="filter by comms link ID")
parser.add_argument("--verbose", action='store_true', help="Dump messages in a much more verbose (but non-parseable) format")
parser.add_argument("--mav10", action='store_true', help="parse as MAVLink1")
parser.add_argument("--reduce", type=int, default=0, help="reduce streaming messages")
parser.add_argument("log", metavar="LOG")
parser.add_argument("--profile", action='store_true', help="run the Yappi python profiler")
parser.add_argument("--meta", action='store_true', help="output meta-data msgs even if not matching condition")
args = parser.parse_args()
if not args.mav10:
os.environ['MAVLINK20'] = '1'
from pymavlink import mavutil
mqttBroker ="localhost"
client = mqtt.Client("telemetrics")
client.connect(mqttBroker)
mlog = mavutil.mavlink_connection("udpin:localhost:14540", #config
planner_format=args.planner,
notimestamps=args.notimestamps,
robust_parsing=args.robust,
dialect=args.dialect,
zero_time_base=args.zero_time_base)
types = args.types
if types is not None:
types = types.split(',')
nottypes = args.nottypes
if nottypes is not None:
nottypes = nottypes.split(',')
def match_type(mtype, patterns):
'''return True if mtype matches pattern'''
for p in patterns:
if fnmatch.fnmatch(mtype, p):
return True
return False
# for DF logs pre-calculate types list
match_types=None
if types is not None and hasattr(mlog, 'name_to_id'):
for k in mlog.name_to_id.keys():
if match_type(k, types):
if nottypes is not None and match_type(k, nottypes):
continue
if match_types is None:
match_types = []
match_types.append(k)
while True:
m = mlog.recv_match(blocking=args.follow, type=match_types)
if not mavutil.evaluate_condition(args.condition, mlog.messages) and (
not (m.get_type() in ['FMT', 'FMTU', 'MULT','PARM','MODE'] and args.meta)):
continue
if args.source_system is not None and args.source_system != m.get_srcSystem():
continue
if args.source_component is not None and args.source_component != m.get_srcComponent():
continue
if args.link is not None and args.link != m._link:
continue
if types is not None and m.get_type() != 'BAD_DATA' and not match_type(m.get_type(), types):
continue
# Ignore BAD_DATA messages is the user requested or if they're because of a bad prefix. The
# latter case is normally because of a mismatched MAVLink version.
if m.get_type() == 'BAD_DATA' and (args.no_bad_data is True or m.reason == "Bad prefix"):
continue
timestamp = getattr(m, '_timestamp', 0.0)
#s = "%s.%02u: %s" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(timestamp)), int(timestamp*100.0)%100, m)
m = str(m).split(" ", 1)
s = "%s: %s" % (m[0], m[1])
client.publish("a1/%s" % (m[0]), m[1])
##print(s)

227
src/index.js Normal file
View File

@ -0,0 +1,227 @@
import mapboxgl from 'mapbox-gl';
import $ from "jquery";
import FlightIndicators from 'flight-indicators-js'
import mqtt from 'mqtt/dist/mqtt';
import RJSON from 'relaxed-json';
import { RulerControl, StylesControl } from 'mapbox-gl-controls';
const minimapQ = require('@aesqe/mapboxgl-minimap/mapboxgl-control-minimap')
import MiniMap from "@aesqe/mapboxgl-minimap/mapboxgl-control-minimap.js"
mapboxgl.accessToken = 'pk.eyJ1IjoiYXNzYWRhIiwiYSI6ImNrbTkzd2RlOTBrMmwyb3BoZGZ5bXpyZXIifQ.qPyi1nxJHcc4Z1xL1EKuuA';
const map = new mapboxgl.Map({
container: 'map', // container ID
style: 'mapbox://styles/mapbox/satellite-streets-v9', // style URL
center: [8.545564, 47.397974], // starting position [lng, lat]
zoom: 13, // starting zoom
projection: 'globe' // display the map as a 3D globe
});
map.addControl(new mapboxgl.NavigationControl(), 'bottom-right');
map.on('style.load', () => {
map.setFog({}); // Set the default atmosphere style
document.onclick = hideMenu;
});
map.addControl(new RulerControl(), 'top-right');
let minimap = new MiniMap({
center: [8.545564, 47.397974],
zoom: 6,
zoomLevels: [],
togglePosition: 'topright'
});
map.addControl(minimap, 'top-right');
// with custom styles:
map.addControl(new StylesControl({
styles: [
{
label: 'ST',
styleName: 'Mapbox Streets',
styleUrl: 'mapbox://styles/mapbox/streets-v9',
}, {
label: 'SA',
styleName: 'Satellite',
styleUrl: 'mapbox://styles/mapbox/satellite-streets-v9',
},
],
onChange: (style) => console.log(style),
}), 'top-right');
function hideMenu() {
console.log('hideMenu');
document.getElementById("contextMenu")
.style.display = "none"
}
map.on('contextmenu', (e) => {
console.log(e);
if (document.getElementById("contextMenu").style.display == "block") {
hideMenu();
} else {
var menu = document.getElementById("contextMenu")
menu.style.display = 'block';
menu.style.left = e.point.x + "px";
menu.style.top = e.point.y + "px";
console.log(menu);
}
});
// create the popup
const popup = new mapboxgl.Popup({ offset: 25 }).setHTML(
'<b>Командир:</b> Роман Валильйев'
);
// create DOM element for the marker
const el = document.createElement('div');
el.id = 'marker';
const marker = new mapboxgl.Marker({
color: "#FFFFFF",
draggable: false,
rotation: 90,
element: document.getElementById("drone")
}).setLngLat([37.9202856, 48.6063243])
.setPopup(popup)
.addTo(map);
const attitudeElement = document.querySelector("#attitude");
const attitude = new FlightIndicators(
attitudeElement,
FlightIndicators.TYPE_ATTITUDE,
{ roll: 50, pitch: -20, size: 200, hideBox: true }
);
const headingElement = document.querySelector("#heading")
const heading = new FlightIndicators(
headingElement,
FlightIndicators.TYPE_HEADING,
{ heading: 0, hideBox: true }
);
const options = {
// Clean session
clean: true,
connectTimeout: 4000,
// Auth
clientId: 'emqx_test'
}
const client = mqtt.connect('ws://localhost:9001', options)
client.on('connect', function () {
console.log('Connected!')
client.subscribe('a1/#', function (err) {
if (!err) {
console.log('Subscribed!');
}
})
})
client.on('message', function (topic, message) {
let relaxedString = message.toString();
try {
let jsonString = RJSON.transform(relaxedString);
let obj = JSON.parse(jsonString);
//console.log(topic, obj);
if (topic == 'a1/ATTITUDE') {
//console.log('ATTITUDE')
attitude.setRoll(obj.roll * 100);
attitude.setPitch(obj.pitch * 100);
} else if (topic == 'a1/VFR_HUD') {
//console.log('VFR_HUD');
heading.setHeading(obj.heading);
//altimeter.setAltitude(obj.alt / 3.2808399);
//console.log(obj)
marker.setRotation(obj.heading);
//variometer.setVario(obj.groundspeed);
}
if (topic == 'a1/SCALED_PRESSURE') {
//console.log(obj.press_abs)
//altimeter.setPressure(obj.press_abs);
}
if (topic == 'a1/SYS_STATUS') {
document.getElementById('batt').innerHTML = obj.battery_remaining
//{onboard_control_sensors_present : 2418573356, onboard_control_sensors_enabled : 2418573324, onboard_control_sensors_health : 2418966575, load : 274, voltage_battery : 16199, current_battery : -100, battery_remaining : 100, drop_rate_comm : 0, errors_comm : 0, errors_count1 : 0, errors_count2 : 0, errors_count3 : 0, errors_count4 : 0, onboard_control_sensors_present_extended : 0, onboard_control_sensors_enabled_extended : 0, onboard_control_sensors_health_extended : 0}
}
if (topic == 'a1/GPS_RAW_INT') {
document.getElementById('satellites_visible').innerHTML = obj.satellites_visible;
//{time_usec : 3834800000, fix_type : 3, lat : 473968579, lon : 85437830, alt : 497973, eph : 0, epv : 0, vel : 2, cog : 13030, satellites_visible : 10, alt_ellipsoid : 497973, h_acc : 1000, v_acc : 1000, vel_acc : 250, hdg_acc : 0, yaw : 0}
}
if (topic == 'a1/GLOBAL_POSITION_INT') {
//console.log('GLOBAL_POSITION_INT')
marker.setLngLat([obj.lon / 10000000, obj.lat / 10000000]);
}
if (topic == 'a1/HEARTBEAT') {
//{type : 2, autopilot : 12, base_mode : 29, custom_mode : 50593792, system_status : 3, mavlink_version : 3}
let statDOM = document.getElementById('status');
let status = 'unknown';
switch (obj.system_status) {
case 0:
status = 'unknown';
break;
case 1:
status = 'boot';
break;
case 2:
status = 'calibrating';
break;
case 3:
status = 'standby';
break;
case 4:
status = 'active';
break;
case 5:
status = 'CRITICAL';
break;
case 6:
status = 'EMERGENCY';
break;
case 7:
status = 'poweroff';
break;
case 8:
status = 'terminating';
break;
}
statDOM.innerHTML = status;
if (obj.type == 2) { // https://mavlink.io/en/messages/common.html#MAV_TYPE
//https://mavlink.io/en/messages/common.html#MAV_MODE_FLAG
let MAV_MODE_FLAG_SAFETY_ARMED = obj.base_mode & 128;
let MAV_MODE_FLAG_MANUAL_INPUT_ENABLED = obj.base_mode & 64; //false
let MAV_MODE_FLAG_HIL_ENABLED = obj.base_mode & 32; //false
let MAV_MODE_FLAG_STABILIZE_ENABLED = obj.base_mode & 16;
let MAV_MODE_FLAG_GUIDED_ENABLED = obj.base_mode & 8;
let MAV_MODE_FLAG_AUTO_ENABLED = obj.base_mode & 4;
let MAV_MODE_FLAG_TEST_ENABLED = obj.base_mode & 2; //false
let MAV_MODE_FLAG_CUSTOM_MODE_ENABLED = obj.base_mode & 1;
if (MAV_MODE_FLAG_SAFETY_ARMED === 128) {
document.getElementById('armed').innerHTML = 'true';
} else {
document.getElementById('armed').innerHTML = 'false';
}
console.log(MAV_MODE_FLAG_SAFETY_ARMED, MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, MAV_MODE_FLAG_HIL_ENABLED, MAV_MODE_FLAG_STABILIZE_ENABLED, MAV_MODE_FLAG_GUIDED_ENABLED, MAV_MODE_FLAG_AUTO_ENABLED, MAV_MODE_FLAG_TEST_ENABLED, MAV_MODE_FLAG_CUSTOM_MODE_ENABLED);
}
}
} catch (e) {
console.error(e)
console.log(topic);
console.log(relaxedString)
}
//client.end()
})

24
webpack.config.js Normal file
View File

@ -0,0 +1,24 @@
const path = require('path');
module.exports = {
entry: path.resolve(__dirname, './src/index.js'),
module: {
rules: [
{
test: /\.(js)$/,
exclude: /node_modules/,
use: ['babel-loader']
}
]
},
resolve: {
extensions: ['*', '.js']
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.js',
},
devServer: {
static: path.resolve(__dirname, './dist'),
},
};