Compare commits
No commits in common. "webSockets" and "master" have entirely different histories.
webSockets
...
master
20
README.md
20
README.md
@ -1 +1,19 @@
|
||||
# 🐱Cat 🔫Cannon
|
||||
# 🐱Cat 🔫Cannon
|
||||
|
||||
The Cat Cannon is an automatically aiming water cannon designed to keep cats out of any location in which there presence is not desired. This solution is built on top of the Raspberry Pi driven by TypeScript and very little Python.
|
||||
|
||||
## Software Setup
|
||||
|
||||
Clone this repo and navigate to its saved directory
|
||||
|
||||
npm install
|
||||
|
||||
ts-node ./src/Robitics/main.ts
|
||||
|
||||
open a browser at http://localhost:5005
|
||||
|
||||
wait for cat to enter view of camera
|
||||
|
||||
what the machine protect your assets
|
||||
|
||||
|
||||
|
||||
4
dist/Vision/main.js
vendored
4
dist/Vision/main.js
vendored
File diff suppressed because one or more lines are too long
212
package-lock.json
generated
212
package-lock.json
generated
@ -96,6 +96,11 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/component-emitter": {
|
||||
"version": "1.2.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz",
|
||||
"integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg=="
|
||||
},
|
||||
"@types/connect": {
|
||||
"version": "3.4.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz",
|
||||
@ -105,6 +110,25 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg=="
|
||||
},
|
||||
"@types/cors": {
|
||||
"version": "2.8.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.9.tgz",
|
||||
"integrity": "sha512-zurD1ibz21BRlAOIKP8yhrxlqKx6L9VCwkB5kMiP6nZAhoF5MvC7qS1qPA7nRcr1GJolfkQC7/EAL4hdYejLtg=="
|
||||
},
|
||||
"@types/engine.io": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/engine.io/-/engine.io-3.1.5.tgz",
|
||||
"integrity": "sha512-DLVpLEGTEZGBXOYoYoagHSxXkDHONc0fZouF2ayw7Q18aRu1Afwci+1CFKvPpouCUOVWP+dmCaAWpQjswe7kpg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/eslint": {
|
||||
"version": "7.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz",
|
||||
@ -228,6 +252,32 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/socket.io": {
|
||||
"version": "2.1.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/socket.io/-/socket.io-2.1.12.tgz",
|
||||
"integrity": "sha512-oStc5VFkpb0AsjOxQUj9ztX5Iziatyla/rjZTYbFGoVrrKwd+JU2mtxk7iSl5RGYx9WunLo6UXW1fBzQok/ZyA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/engine.io": "*",
|
||||
"@types/node": "*",
|
||||
"@types/socket.io-parser": "*"
|
||||
}
|
||||
},
|
||||
"@types/socket.io-client": {
|
||||
"version": "1.4.35",
|
||||
"resolved": "https://registry.npmjs.org/@types/socket.io-client/-/socket.io-client-1.4.35.tgz",
|
||||
"integrity": "sha512-MI8YmxFS+jMkIziycT5ickBWK1sZwDwy16mgH/j99Mcom6zRG/NimNGQ3vJV0uX5G6g/hEw0FG3w3b3sT5OUGw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/socket.io-parser": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/socket.io-parser/-/socket.io-parser-2.2.1.tgz",
|
||||
"integrity": "sha512-+JNb+7N7tSINyXPxAJb62+NcpC1x/fPn7z818W4xeNCdPTp6VsO/X8fCsg6+ug4a56m1v9sEiTIIUKVupcHOFQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/webgl-ext": {
|
||||
"version": "0.0.30",
|
||||
"resolved": "https://registry.npmjs.org/@types/webgl-ext/-/webgl-ext-0.0.30.tgz",
|
||||
@ -719,6 +769,11 @@
|
||||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
|
||||
"dev": true
|
||||
},
|
||||
"backo2": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
|
||||
"integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
@ -780,6 +835,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"base64-arraybuffer": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
|
||||
"integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI="
|
||||
},
|
||||
"base64id": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
|
||||
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
|
||||
},
|
||||
"batch": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
|
||||
@ -1129,8 +1194,7 @@
|
||||
"component-emitter": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
|
||||
},
|
||||
"compressible": {
|
||||
"version": "2.0.18",
|
||||
@ -1219,6 +1283,15 @@
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"dev": true
|
||||
},
|
||||
"cors": {
|
||||
"version": "2.8.5",
|
||||
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||
"requires": {
|
||||
"object-assign": "^4",
|
||||
"vary": "^1"
|
||||
}
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
|
||||
@ -1244,7 +1317,6 @@
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
@ -1252,8 +1324,7 @@
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1440,6 +1511,64 @@
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"engine.io": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.0.tgz",
|
||||
"integrity": "sha512-vW7EAtn0HDQ4MtT5QbmCHF17TaYLONv2/JwdYsq9USPRZVM4zG7WB3k0Nc321z8EuSOlhGokrYlYx4176QhD0A==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "2.0.0",
|
||||
"cookie": "~0.4.1",
|
||||
"cors": "~2.8.5",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~4.0.0",
|
||||
"ws": "~7.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"cookie": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
|
||||
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.4.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz",
|
||||
"integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"engine.io-client": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-4.1.0.tgz",
|
||||
"integrity": "sha512-OUmn4m71/lW3ixICv4h3DuBRuh3ri0w3cDuepjsrINSbbqbni4Xw1shTFiKhl0v58lEtNpwJTpSKJJ3fondu5Q==",
|
||||
"requires": {
|
||||
"base64-arraybuffer": "0.1.4",
|
||||
"component-emitter": "~1.3.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~4.0.1",
|
||||
"has-cors": "1.1.0",
|
||||
"parseqs": "0.0.6",
|
||||
"parseuri": "0.0.6",
|
||||
"ws": "~7.4.2",
|
||||
"xmlhttprequest-ssl": "~1.5.4",
|
||||
"yeast": "0.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ws": {
|
||||
"version": "7.4.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz",
|
||||
"integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"engine.io-parser": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz",
|
||||
"integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==",
|
||||
"requires": {
|
||||
"base64-arraybuffer": "0.1.4"
|
||||
}
|
||||
},
|
||||
"enhanced-resolve": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz",
|
||||
@ -2040,6 +2169,11 @@
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"has-cors": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
|
||||
"integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
@ -2954,8 +3088,7 @@
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"dev": true
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"object-copy": {
|
||||
"version": "0.1.0",
|
||||
@ -3141,6 +3274,16 @@
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||
"dev": true
|
||||
},
|
||||
"parseqs": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz",
|
||||
"integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w=="
|
||||
},
|
||||
"parseuri": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz",
|
||||
"integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow=="
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
@ -3946,6 +4089,51 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"socket.io": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.0.tgz",
|
||||
"integrity": "sha512-Aqg2dlRh6xSJvRYK31ksG65q4kmBOqU4g+1ukhPcoT6wNGYoIwSYPlCPuRwOO9pgLUajojGFztl6+V2opmKcww==",
|
||||
"requires": {
|
||||
"@types/cookie": "^0.4.0",
|
||||
"@types/cors": "^2.8.8",
|
||||
"@types/node": "^14.14.10",
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "~2.0.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io": "~4.1.0",
|
||||
"socket.io-adapter": "~2.1.0",
|
||||
"socket.io-parser": "~4.0.3"
|
||||
}
|
||||
},
|
||||
"socket.io-adapter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz",
|
||||
"integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg=="
|
||||
},
|
||||
"socket.io-client": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-3.1.0.tgz",
|
||||
"integrity": "sha512-T4qPOL80KnoBwkdR70zMpiR6aH6zv3ZqLNriofHqsO9wvQllNTOez0mpV4GdVqo1Y55Z+h8YOlBo7c8pOxDlHw==",
|
||||
"requires": {
|
||||
"@types/component-emitter": "^1.2.10",
|
||||
"backo2": "~1.0.2",
|
||||
"component-emitter": "~1.3.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-client": "~4.1.0",
|
||||
"parseuri": "0.0.6",
|
||||
"socket.io-parser": "~4.0.4"
|
||||
}
|
||||
},
|
||||
"socket.io-parser": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
|
||||
"integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
|
||||
"requires": {
|
||||
"@types/component-emitter": "^1.2.10",
|
||||
"component-emitter": "~1.3.0",
|
||||
"debug": "~4.3.1"
|
||||
}
|
||||
},
|
||||
"sockjs": {
|
||||
"version": "0.3.21",
|
||||
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz",
|
||||
@ -5139,6 +5327,11 @@
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"xmlhttprequest-ssl": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
|
||||
"integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
|
||||
@ -5163,6 +5356,11 @@
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
|
||||
"integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA=="
|
||||
},
|
||||
"yeast": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
|
||||
"integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
|
||||
},
|
||||
"yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
|
||||
10
package.json
10
package.json
@ -4,7 +4,9 @@
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "webpack serve",
|
||||
"dev": "ts-node ./src/Robotics/main.ts",
|
||||
"vision": "webpack serve",
|
||||
"build": "webpack",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
@ -12,10 +14,14 @@
|
||||
"dependencies": {
|
||||
"@tensorflow-models/coco-ssd": "^2.2.1",
|
||||
"@tensorflow/tfjs": "^2.8.2",
|
||||
"express": "^4.17.1"
|
||||
"express": "^4.17.1",
|
||||
"socket.io": "^3.1.0",
|
||||
"socket.io-client": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.11",
|
||||
"@types/socket.io": "^2.1.12",
|
||||
"@types/socket.io-client": "^1.4.35",
|
||||
"ts-loader": "^8.0.13",
|
||||
"typescript": "^4.1.3",
|
||||
"webpack": "^5.11.1",
|
||||
|
||||
26
src/Robotics/Entities/EventManager.ts
Normal file
26
src/Robotics/Entities/EventManager.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { EventEmitter } from 'events'
|
||||
import IEventManager from '../Interfaces/IEventManager'
|
||||
|
||||
let instance: EventManager | null = null
|
||||
|
||||
class EventManager implements IEventManager {
|
||||
eventEmitter: EventEmitter
|
||||
|
||||
constructor () {
|
||||
if (!instance) instance = this
|
||||
|
||||
this.eventEmitter = new EventEmitter()
|
||||
|
||||
return instance
|
||||
}
|
||||
|
||||
listen = (eventName: string, callback: any) => {
|
||||
this.eventEmitter.addListener(eventName, callback)
|
||||
}
|
||||
|
||||
emit = (eventName: string, detail: any) => {
|
||||
this.eventEmitter.emit(eventName, detail)
|
||||
}
|
||||
}
|
||||
|
||||
export default EventManager
|
||||
17
src/Robotics/Entities/Motor.ts
Normal file
17
src/Robotics/Entities/Motor.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import IMotor from "../Interfaces/IMotor"
|
||||
|
||||
class Motor implements IMotor {
|
||||
public pinOne: number
|
||||
public pinTwo: number
|
||||
public pinThree: number
|
||||
public pinFour: number
|
||||
|
||||
constructor (props: IMotor) {
|
||||
this.pinOne = props.pinOne
|
||||
this.pinTwo = props.pinTwo
|
||||
this.pinThree = props.pinThree
|
||||
this.pinFour = props.pinFour
|
||||
}
|
||||
}
|
||||
|
||||
export default Motor
|
||||
70
src/Robotics/Entities/MotorMover.ts
Normal file
70
src/Robotics/Entities/MotorMover.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import IMotor from "../Interfaces/IMotor"
|
||||
import makeMotor from "../UseCases/Factories/makeMotor"
|
||||
import * as childProcesses from 'child_process'
|
||||
import IMotorMoverConstructor from "../Interfaces/IMotorMoverConstructor"
|
||||
import IMotorMover from "../Interfaces/IMotorMover"
|
||||
|
||||
class MotorMover implements IMotorMover {
|
||||
motor: IMotor
|
||||
moveProcess: childProcesses.ChildProcessWithoutNullStreams | null = null
|
||||
pauseIntervalTime: number
|
||||
movementState: 'CLOCKWISE' | 'COUNTERCLOCKWISE' | "IDLE" = 'IDLE'
|
||||
|
||||
constructor (props: IMotorMoverConstructor) {
|
||||
this.motor = makeMotor(props.motor)
|
||||
this.pauseIntervalTime = props.pauseIntervalTime
|
||||
}
|
||||
|
||||
public moveClockwise = () => {
|
||||
if (this.movementState === 'CLOCKWISE') return
|
||||
else {
|
||||
if (!this.moveProcess?.killed) this.moveProcess?.kill()
|
||||
}
|
||||
|
||||
const motorProcessArguments = [
|
||||
'src/Robotics/moveStepper.py',
|
||||
this.motor.pinOne.toString(),
|
||||
this.motor.pinTwo.toString(),
|
||||
this.motor.pinThree.toString(),
|
||||
this.motor.pinFour.toString(),
|
||||
'clockwise',
|
||||
this.pauseIntervalTime.toString()
|
||||
]
|
||||
|
||||
console.log('start clockwise')
|
||||
this.moveProcess = childProcesses.spawn('python', motorProcessArguments)
|
||||
this.movementState = 'CLOCKWISE'
|
||||
}
|
||||
|
||||
public moveCounterClockwise = () => {
|
||||
if (this.movementState === 'COUNTERCLOCKWISE') return
|
||||
else {
|
||||
if (!this.moveProcess?.killed) this.moveProcess?.kill()
|
||||
}
|
||||
|
||||
const motorProcessArguments = [
|
||||
'src/Robotics/moveStepper.py',
|
||||
this.motor.pinOne.toString(),
|
||||
this.motor.pinTwo.toString(),
|
||||
this.motor.pinThree.toString(),
|
||||
this.motor.pinFour.toString(),
|
||||
'counterClockwise',
|
||||
this.pauseIntervalTime.toString()
|
||||
]
|
||||
|
||||
console.log('start counterclockwise')
|
||||
this.moveProcess = childProcesses.spawn('python', motorProcessArguments)
|
||||
this.movementState = 'COUNTERCLOCKWISE'
|
||||
}
|
||||
|
||||
public stopMovement = () => {
|
||||
if (this.movementState === 'IDLE') return
|
||||
else {
|
||||
if (!this.moveProcess?.killed) this.moveProcess?.kill()
|
||||
console.log('start idle')
|
||||
this.movementState = 'IDLE'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default MotorMover
|
||||
69
src/Robotics/Entities/Server.ts
Normal file
69
src/Robotics/Entities/Server.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import express from 'express'
|
||||
import path from 'path'
|
||||
import bodyParser from 'body-parser'
|
||||
import http from 'http'
|
||||
import { Socket } from 'socket.io'
|
||||
import IEventManager from '../Interfaces/IEventManager'
|
||||
import EventManager from './EventManager'
|
||||
|
||||
class Server {
|
||||
public app = express()
|
||||
private eventManager: IEventManager
|
||||
|
||||
constructor (port: number) {
|
||||
this.createApp()
|
||||
this.setupAppOptions()
|
||||
this.setupAppRoutes()
|
||||
this.startServer(port)
|
||||
this.eventManager = new EventManager()
|
||||
}
|
||||
|
||||
createApp = () => {
|
||||
this.app.use(express.json())
|
||||
this.app.use(express.urlencoded({ extended: false }))
|
||||
this.app.use(express.static(path.join(process.cwd(), '/dist/Vision/')))
|
||||
this.app.use(bodyParser.json())
|
||||
}
|
||||
|
||||
setupAppRoutes = () => {
|
||||
this.app.use('/', (request, response, next) => {
|
||||
response.sendFile(path.join(process.cwd(), './dist/Vision/index.html'))
|
||||
})
|
||||
}
|
||||
|
||||
setupAppOptions = () => {
|
||||
this.app.use((request, response, next) => {
|
||||
response.header('Access-Control-Allow-Origin', request.headers.origin || '*')
|
||||
response.header('Access-Control-Allow-Methods', 'GET,POST,PUT,PATCH,HEAD,DELETE,OPTIONS')
|
||||
response.header('Access-Control-Allow-Headers', 'Content-Type,x-requested-with')
|
||||
next()
|
||||
})
|
||||
}
|
||||
|
||||
startServer = (port: number) => {
|
||||
const webService = new http.Server(this.app)
|
||||
const socketService = require("socket.io")(webService)
|
||||
this.openSockets(socketService)
|
||||
webService.listen(port, () => {
|
||||
console.log(`Server is listening on ${port}`)
|
||||
})
|
||||
}
|
||||
|
||||
openSockets = (socketService: any) => {
|
||||
socketService.on('connection', (socket: Socket) => {
|
||||
console.log('client connected')
|
||||
|
||||
socket.on('offsets', (offsets: any[]) => {
|
||||
this.onReceiveOffsets(offsets)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public onReceiveOffsets = (offsets: any[]) => {
|
||||
this.eventManager.emit('onReceiveOffsets', offsets)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Server
|
||||
13
src/Robotics/Entities/WaterPump.ts
Normal file
13
src/Robotics/Entities/WaterPump.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import IWaterPump from '../Interfaces/IWaterPump'
|
||||
|
||||
class WaterPump implements IWaterPump {
|
||||
public pinOne: number
|
||||
public pinTwo: number
|
||||
|
||||
constructor (props: IWaterPump) {
|
||||
this.pinOne = props.pinOne
|
||||
this.pinTwo = props.pinTwo
|
||||
}
|
||||
}
|
||||
|
||||
export default WaterPump
|
||||
46
src/Robotics/Entities/WaterPumper.ts
Normal file
46
src/Robotics/Entities/WaterPumper.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import IWaterPump from '../Interfaces/IWaterPump'
|
||||
import * as childProcesses from 'child_process'
|
||||
import IWaterPumperConstructor from '../Interfaces/IWaterPumperConstructor'
|
||||
import IWaterPumper from '../Interfaces/IWaterPumper'
|
||||
import makeWaterPump from '../UseCases/Factories/makeWaterPump'
|
||||
|
||||
class WaterPumper implements IWaterPumper {
|
||||
public waterPump: IWaterPump
|
||||
public isActive: boolean = false
|
||||
private pumpProcess: childProcesses.ChildProcessWithoutNullStreams | null = null
|
||||
private pumpActiveTimeInSeconds: number
|
||||
private pumpCoolDownTimeInSeconds: number
|
||||
|
||||
constructor (props: IWaterPumperConstructor) {
|
||||
this.waterPump = makeWaterPump({
|
||||
pinOne: props.pinOne,
|
||||
pinTwo: props.pinTwo
|
||||
})
|
||||
|
||||
this.pumpActiveTimeInSeconds =props.pumpActiveTimeInSeconds
|
||||
this.pumpCoolDownTimeInSeconds = props.pumpCoolDownTimeInSeconds
|
||||
}
|
||||
|
||||
private async coolDown () {
|
||||
return new Promise(resolve => setTimeout(resolve, this.pumpCoolDownTimeInSeconds * 1000))
|
||||
}
|
||||
|
||||
public async pump () {
|
||||
if (this.isActive) return
|
||||
|
||||
const pumpProcessArguments = [
|
||||
'src/Robotics/moveDcMotor.py',
|
||||
this.waterPump.pinOne.toString(),
|
||||
this.waterPump.pinTwo.toString(),
|
||||
this.pumpActiveTimeInSeconds.toString()
|
||||
]
|
||||
|
||||
this.pumpProcess = childProcesses.spawn('python', pumpProcessArguments)
|
||||
|
||||
this.isActive = true
|
||||
await this.coolDown()
|
||||
this.isActive = false
|
||||
}
|
||||
}
|
||||
|
||||
export default WaterPumper
|
||||
6
src/Robotics/Interfaces/IEventManager.ts
Normal file
6
src/Robotics/Interfaces/IEventManager.ts
Normal file
@ -0,0 +1,6 @@
|
||||
interface IEventManager {
|
||||
listen(eventName: string, callback: any): void,
|
||||
emit(eventName: string, detail: any): void
|
||||
}
|
||||
|
||||
export default IEventManager
|
||||
8
src/Robotics/Interfaces/IMotor.ts
Normal file
8
src/Robotics/Interfaces/IMotor.ts
Normal file
@ -0,0 +1,8 @@
|
||||
interface IMotor {
|
||||
pinOne: number,
|
||||
pinTwo: number,
|
||||
pinThree: number,
|
||||
pinFour: number
|
||||
}
|
||||
|
||||
export default IMotor
|
||||
8
src/Robotics/Interfaces/IMotorMover.ts
Normal file
8
src/Robotics/Interfaces/IMotorMover.ts
Normal file
@ -0,0 +1,8 @@
|
||||
interface IMotorMover {
|
||||
moveClockwise(): void,
|
||||
moveCounterClockwise(): void,
|
||||
stopMovement(): void,
|
||||
movementState: 'CLOCKWISE' | 'COUNTERCLOCKWISE' | "IDLE"
|
||||
}
|
||||
|
||||
export default IMotorMover
|
||||
8
src/Robotics/Interfaces/IMotorMoverConstructor.ts
Normal file
8
src/Robotics/Interfaces/IMotorMoverConstructor.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import IMotor from "./IMotor";
|
||||
|
||||
interface IMotorMoverConstructor {
|
||||
motor: IMotor,
|
||||
pauseIntervalTime: number
|
||||
}
|
||||
|
||||
export default IMotorMoverConstructor
|
||||
5
src/Robotics/Interfaces/IServer.ts
Normal file
5
src/Robotics/Interfaces/IServer.ts
Normal file
@ -0,0 +1,5 @@
|
||||
interface IServer {
|
||||
port: number
|
||||
}
|
||||
|
||||
export default IServer
|
||||
6
src/Robotics/Interfaces/IWaterPump.ts
Normal file
6
src/Robotics/Interfaces/IWaterPump.ts
Normal file
@ -0,0 +1,6 @@
|
||||
interface IWaterPump {
|
||||
pinOne: number,
|
||||
pinTwo: number
|
||||
}
|
||||
|
||||
export default IWaterPump
|
||||
9
src/Robotics/Interfaces/IWaterPumper.ts
Normal file
9
src/Robotics/Interfaces/IWaterPumper.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import IWaterPump from "./IWaterPump";
|
||||
|
||||
interface IWaterPumper {
|
||||
pump(): void
|
||||
isActive: boolean
|
||||
waterPump: IWaterPump
|
||||
}
|
||||
|
||||
export default IWaterPumper
|
||||
8
src/Robotics/Interfaces/IWaterPumperConstructor.ts
Normal file
8
src/Robotics/Interfaces/IWaterPumperConstructor.ts
Normal file
@ -0,0 +1,8 @@
|
||||
interface IWaterPumperConstructor {
|
||||
pinOne: number,
|
||||
pinTwo: number,
|
||||
pumpActiveTimeInSeconds: number,
|
||||
pumpCoolDownTimeInSeconds: number
|
||||
}
|
||||
|
||||
export default IWaterPumperConstructor
|
||||
7
src/Robotics/UseCases/Factories/makeEventManager.ts
Normal file
7
src/Robotics/UseCases/Factories/makeEventManager.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import EventManager from "../../Entities/EventManager"
|
||||
|
||||
function makeEventManager () {
|
||||
return new EventManager()
|
||||
}
|
||||
|
||||
export default makeEventManager
|
||||
8
src/Robotics/UseCases/Factories/makeMotor.ts
Normal file
8
src/Robotics/UseCases/Factories/makeMotor.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import Motor from "../../Entities/Motor"
|
||||
import IMotor from "../../Interfaces/IMotor"
|
||||
|
||||
function makeMotor (props: IMotor) {
|
||||
return new Motor(props)
|
||||
}
|
||||
|
||||
export default makeMotor
|
||||
8
src/Robotics/UseCases/Factories/makeMotorMover.ts
Normal file
8
src/Robotics/UseCases/Factories/makeMotorMover.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import MotorMover from "../../Entities/MotorMover"
|
||||
import IMotorMoverConstructor from "../../Interfaces/IMotorMoverConstructor"
|
||||
|
||||
function makeMotorMover (props: IMotorMoverConstructor) {
|
||||
return new MotorMover(props)
|
||||
}
|
||||
|
||||
export default makeMotorMover
|
||||
9
src/Robotics/UseCases/Factories/makeServer.ts
Normal file
9
src/Robotics/UseCases/Factories/makeServer.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import Server from "../../Entities/Server"
|
||||
|
||||
function makeServer (port: number) {
|
||||
const defaultPort = 5005
|
||||
|
||||
return new Server(port || defaultPort)
|
||||
}
|
||||
|
||||
export default makeServer
|
||||
8
src/Robotics/UseCases/Factories/makeWaterPump.ts
Normal file
8
src/Robotics/UseCases/Factories/makeWaterPump.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import WaterPump from "../../Entities/WaterPump"
|
||||
import IWaterPump from "../../Interfaces/IWaterPump"
|
||||
|
||||
function makeWaterPump (props: IWaterPump) {
|
||||
return new WaterPump(props)
|
||||
}
|
||||
|
||||
export default makeWaterPump
|
||||
8
src/Robotics/UseCases/Factories/makeWaterPumper.ts
Normal file
8
src/Robotics/UseCases/Factories/makeWaterPumper.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import WaterPumper from "../../Entities/WaterPumper"
|
||||
import IWaterPumperConstructor from "../../Interfaces/IWaterPumperConstructor"
|
||||
|
||||
function makeWaterPumper (props: IWaterPumperConstructor) {
|
||||
return new WaterPumper(props)
|
||||
}
|
||||
|
||||
export default makeWaterPumper
|
||||
60
src/Robotics/main.ts
Normal file
60
src/Robotics/main.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import IEventManager from './Interfaces/IEventManager'
|
||||
import IMotorMover from './Interfaces/IMotorMover'
|
||||
import IWaterPumper from './Interfaces/IWaterPumper'
|
||||
|
||||
import makeServer from './UseCases/Factories/makeServer'
|
||||
import makeEventManager from './UseCases/Factories/makeEventManager'
|
||||
import makeMotorMover from './UseCases/Factories/makeMotorMover'
|
||||
import makeWaterPumper from './UseCases/Factories/makeWaterPumper'
|
||||
|
||||
const main = () => {
|
||||
console.log('Starting Robotics')
|
||||
|
||||
const port = 5005
|
||||
makeServer(port)
|
||||
|
||||
const eventManager: IEventManager = makeEventManager()
|
||||
|
||||
const xAxisMotorMover: IMotorMover = makeMotorMover({
|
||||
motor: { pinOne: 3, pinTwo: 5, pinThree: 7, pinFour: 11 },
|
||||
pauseIntervalTime: 0.05
|
||||
})
|
||||
|
||||
const yAxisMotorMover: IMotorMover = makeMotorMover({
|
||||
motor: { pinOne: 13, pinTwo: 15, pinThree: 19, pinFour: 21 },
|
||||
pauseIntervalTime: 0.05
|
||||
})
|
||||
|
||||
const waterPumper: IWaterPumper = makeWaterPumper({
|
||||
pinOne: 37,
|
||||
pinTwo: 35,
|
||||
pumpActiveTimeInSeconds: 1,
|
||||
pumpCoolDownTimeInSeconds: 5
|
||||
})
|
||||
|
||||
eventManager.listen('onReceiveOffsets', (offsets: any[]) => {
|
||||
if (offsets[0]?.x > 50) {
|
||||
xAxisMotorMover.moveCounterClockwise()
|
||||
} else if (offsets[0]?.x < - 50) {
|
||||
xAxisMotorMover.moveClockwise()
|
||||
} else {
|
||||
xAxisMotorMover.stopMovement()
|
||||
}
|
||||
|
||||
if (offsets[0]?.y > 50) {
|
||||
yAxisMotorMover.moveClockwise()
|
||||
} else if (offsets[0]?.y < - 50) {
|
||||
yAxisMotorMover.moveCounterClockwise()
|
||||
} else {
|
||||
yAxisMotorMover.stopMovement()
|
||||
}
|
||||
|
||||
if (offsets[0]?.hypotenuse <= 80) {
|
||||
waterPumper.pump()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
main()
|
||||
|
||||
export { main }
|
||||
22
src/Robotics/moveDcMotor.py
Normal file
22
src/Robotics/moveDcMotor.py
Normal file
@ -0,0 +1,22 @@
|
||||
# command arguments to run process
|
||||
# 1: int pin_one
|
||||
# 2: int pin_two
|
||||
# 3: int motor_active_time
|
||||
|
||||
import RPi.GPIO as GPIO
|
||||
from time import sleep
|
||||
import sys
|
||||
|
||||
motor_channel = (int(sys.argv[1]), int(sys.argv[2])) # (37, 35)
|
||||
|
||||
motor_active_time = int(sys.argv[3])
|
||||
|
||||
GPIO.setwarnings(True)
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
GPIO.setup(motor_channel, GPIO.OUT)
|
||||
|
||||
GPIO.output(motor_channel, (GPIO.HIGH, GPIO.LOW))
|
||||
print('Should be on')
|
||||
|
||||
sleep(motor_active_time)
|
||||
GPIO.output(motor_channel, (GPIO.LOW, GPIO.LOW))
|
||||
@ -1,38 +0,0 @@
|
||||
import express from 'express'
|
||||
import path from 'path'
|
||||
import bodyParser from 'body-parser'
|
||||
|
||||
class Server {
|
||||
public app = express()
|
||||
|
||||
constructor () {
|
||||
this.createApp()
|
||||
this.setupAppOptions()
|
||||
this.setupAppRoutes()
|
||||
}
|
||||
|
||||
createApp = () => {
|
||||
this.app.use(express.json())
|
||||
this.app.use(express.urlencoded({ extended: false }))
|
||||
this.app.use(express.static(path.join(process.cwd(), '/build')))
|
||||
this.app.use(bodyParser.json())
|
||||
}
|
||||
|
||||
setupAppRoutes = () => {
|
||||
// this.app.use('/api', apiRouter)
|
||||
this.app.use('/', (request, response, next) => {
|
||||
response.sendFile(path.join(process.cwd(), './dist/Vision/index.html'))
|
||||
})
|
||||
}
|
||||
|
||||
setupAppOptions = () => {
|
||||
this.app.use((request, response, next) => {
|
||||
response.header('Access-Control-Allow-Origin', request.headers.origin || '*')
|
||||
response.header('Access-Control-Allow-Methods', 'GET,POST,PUT,PATCH,HEAD,DELETE,OPTIONS')
|
||||
response.header('Access-Control-Allow-Headers', 'Content-Type,x-requested-with')
|
||||
next()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default Server
|
||||
@ -1,29 +0,0 @@
|
||||
import http from 'http'
|
||||
import Server from './Server'
|
||||
|
||||
const main = () => {
|
||||
|
||||
const port = normalizePort(process.env.PORT || '5005')
|
||||
const webService = createServer()
|
||||
|
||||
webService.listen(port, () => {
|
||||
console.log(`Server is listening on ${port}`)
|
||||
})
|
||||
}
|
||||
|
||||
const createServer = () => {
|
||||
const server = new Server()
|
||||
return http.createServer(server.app)
|
||||
}
|
||||
|
||||
const normalizePort = (portString: string) => {
|
||||
const port = parseInt(portString, 10)
|
||||
|
||||
if (isNaN(port)) return portString
|
||||
else if (port >= 0 ) return port
|
||||
else return 0
|
||||
}
|
||||
|
||||
main()
|
||||
|
||||
export { main, createServer, normalizePort }
|
||||
7
src/Vision/Interfaces/IRoboticsCommunicator.ts
Normal file
7
src/Vision/Interfaces/IRoboticsCommunicator.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import IOffset from "./IOffset";
|
||||
|
||||
interface IRoboticsCommunicator {
|
||||
sendOffsets(offsets: IOffset[]): void
|
||||
}
|
||||
|
||||
export default IRoboticsCommunicator
|
||||
@ -3,7 +3,7 @@ import ObjectDetector from "../ObjectDetector"
|
||||
|
||||
const defaultPredictions = [
|
||||
(prediction: DetectedObject) => prediction.score > 0.6,
|
||||
(prediction: DetectedObject) => prediction.class === 'person',
|
||||
(prediction: DetectedObject) => prediction.class === 'cat',
|
||||
]
|
||||
|
||||
function makeObjectDetector (filterPredicates?: Function[]): ObjectDetector {
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
import RoboticsCommunicator from "../RoboticsCommunicator"
|
||||
|
||||
|
||||
function makeRoboticsCommunicator () {
|
||||
return new RoboticsCommunicator()
|
||||
}
|
||||
|
||||
export default makeRoboticsCommunicator
|
||||
16
src/Vision/UseCases/RoboticsCommunicator.ts
Normal file
16
src/Vision/UseCases/RoboticsCommunicator.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import * as io from 'socket.io-client'
|
||||
import IOffset from '../Interfaces/IOffset'
|
||||
|
||||
class RoboticsCommunicator {
|
||||
socket: SocketIOClient.Socket
|
||||
|
||||
constructor () {
|
||||
this.socket = io.connect()
|
||||
}
|
||||
|
||||
sendOffsets = (offsets: IOffset[]) => {
|
||||
this.socket.emit('offsets', offsets)
|
||||
}
|
||||
}
|
||||
|
||||
export default RoboticsCommunicator
|
||||
@ -1,6 +1,7 @@
|
||||
import IObjectDetector from './Interfaces/IObjectDetector'
|
||||
import IObjectLocator from './Interfaces/IObjectLocator'
|
||||
import IOffset from './Interfaces/IOffset'
|
||||
import IRoboticsCommunicator from './Interfaces/IRoboticsCommunicator'
|
||||
import IUiRenderer from './Interfaces/IUiRenderer'
|
||||
import IVideoCapturer from "./Interfaces/IVideoCapturer"
|
||||
|
||||
@ -8,17 +9,20 @@ import makeObjectDetector from './UseCases/Factories/makeObjectDetector'
|
||||
import makeObjectLocator from './UseCases/Factories/makeObjectLocator'
|
||||
import makeUiRenderer from './UseCases/Factories/makeUiRenderer'
|
||||
import makeVideoCapturer from './UseCases/Factories/makeVideoCatpurer'
|
||||
import makeRoboticsCommunicator from './UseCases/Factories/mkaeRoboticsCommunicator'
|
||||
|
||||
class App {
|
||||
private objectDetector: IObjectDetector
|
||||
private objectLocator: IObjectLocator
|
||||
private videoCapturer: IVideoCapturer
|
||||
private roboticsCommunicator: IRoboticsCommunicator
|
||||
private uiRenderer: IUiRenderer
|
||||
|
||||
constructor () {
|
||||
this.videoCapturer = makeVideoCapturer()
|
||||
this.objectDetector = makeObjectDetector()
|
||||
this.objectLocator = makeObjectLocator()
|
||||
this.roboticsCommunicator = makeRoboticsCommunicator()
|
||||
this.uiRenderer = makeUiRenderer()
|
||||
|
||||
const eventTarget = new EventTarget()
|
||||
@ -36,6 +40,7 @@ class App {
|
||||
|
||||
const predictedObjects = await this.objectDetector.getPredictionsFromImageData(imageData)
|
||||
const offsets: IOffset[] = predictedObjects.map(obj => this.objectLocator.getOffsetsFromPredictions(obj))
|
||||
this.roboticsCommunicator.sendOffsets(offsets)
|
||||
this.uiRenderer.render({ imageData, predictedObjects, offsets })
|
||||
|
||||
window.requestAnimationFrame(this.predictImage)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user