18 Commits

Author SHA1 Message Date
5c945e43b5 Add some notes 2021-12-14 01:35:30 -05:00
dc3bc85607 I forgot where these came from 2021-08-19 10:00:13 -04:00
0d06a71fca Merge branch 'develop' of https://kitsunehosting.net/gitea/Kenwood/lewis-crawler into develop 2021-07-16 12:29:26 -04:00
5f9ea8867c Update frame model 2021-07-16 12:29:18 -04:00
b42055bd4b increase otp time duration 2021-07-15 11:38:21 -04:00
7ea7f13e9b regen bits 2021-07-15 11:29:50 -04:00
9bb1cf2055 Conduct OTP tests 2021-07-15 11:29:44 -04:00
151853b1d3 Tested a85 encoding 2021-07-15 10:47:57 -04:00
6106c46bd8 Merge branch 'develop' of https://kitsunehosting.net/gitea/Kenwood/lewis-crawler into develop 2021-07-15 10:36:04 -04:00
5062ada35a Do some image compression tests~ 2021-07-15 10:35:33 -04:00
c2d9fb20d7 Detach servo resource when done 2021-07-14 20:49:47 -04:00
cadc2b0c6a Add updating notes 2021-07-14 20:11:46 -04:00
a234275422 Create makefile for moving and setting up service file 2021-07-14 20:11:02 -04:00
c67bcdc484 Complete arduino makefile 2021-07-14 20:04:20 -04:00
61d77870a0 Fix merge 2021-07-14 19:45:58 -04:00
598e84603f Update requirements and makefile to build crawler companion software 2021-07-14 12:20:35 -04:00
3c0ecdd98c Create makefile though still with bugs 2021-06-30 12:13:33 -04:00
041bde458c Merge in crawler software into develop, re-structruing some of the git layout. 2021-06-30 11:59:41 -04:00
45 changed files with 5171 additions and 390 deletions

Binary file not shown.

View File

@@ -1,7 +1,19 @@
# To install on robot # To install on robot
``` ```
git clone <url> git clone https://kitsunehosting.net/gitea/Kenwood/lewis-crawler /srv/crawler
cd lewis-crawler/crawler_software/raspberry_pi cd /srv/crawler/crawler_software/raspberry_pi
make install? make install
``` ```
# Updating
```
cd /srv/crawler
git pull
```
# Notes
[Uart Stuff](https://www.reddit.com/r/raspberry_pi/comments/833qux/binary_file_tranfer_via_uart/)

View File

@@ -0,0 +1,23 @@
from discord_webhook import DiscordWebhook
from picamera import PiCamera
from time import sleep
def get_uptime():
with open('/proc/uptime', 'r') as f:
uptime_seconds = float(f.readline().split()[0])
return uptime_seconds
webhookURL = "https://discord.com/api/webhooks/856609966404534272/TR9tnLq2sIGZoOeADNswmGRNlzBcqM5aKihfU6snVTP9WhSSoVVvi7nT6i-ZfZS7Hcqm"
webhook = DiscordWebhook(url=webhookURL, content="Uptime: " + str( round( ((get_uptime() / 60) / 60 ), 2 )) + " hours")
camera = PiCamera()
sleep(3) # let iso settle out
camera.capture('still.jpg')
with open("still.jpg", "rb") as f:
webhook.add_file(file=f.read(), filename='still.jpg')
response = webhook.execute() # Hit send

Binary file not shown.

View File

@@ -1,22 +0,0 @@
Setting up getty override
=========================
```console
systemctl edit getty@tty1.service
```
add
```
[Service]
ExecStart=
ExecStart=-/opt/lewis-crawler/companion_software/dashboard/entrypoint.sh
StandardInput=tty
StandardOutput=tty
```
then
```
systemctl daemon-reload; systemctl restart getty@tty1.service
```

View File

@@ -1,9 +0,0 @@
#!/bin/bash
cd /opt/lewis-crawler/companion_software
git pull
pipenv install -r requirements.txt
pipenv run python -m houston -v

View File

@@ -1,43 +0,0 @@
# Lewis Crawler
# 2021 - 2022
# Kitsune Scientific
import logging
import argparse
import verboselogs
import coloredlogs
from houston.houston import Houston
# Get debug args
parser = argparse.ArgumentParser()
parser.add_argument(
'-d', '--debug',
help="Print lots of debugging statements",
action="store_const", dest="loglevel", const='DEBUG',
default='WARNING',
)
parser.add_argument(
'-v', '--verbose',
help="Be verbose",
action="store_const", dest="loglevel", const='INFO',
)
args = parser.parse_args()
# Install verbose logs
verboselogs.install()
# Create a logger object.
logger = logging.getLogger('Houston_Log')
# Install colored logs
coloredlogs.install(level=args.loglevel,
logger=logger,
fmt='%(asctime)s,%(msecs)03d %(hostname)s %(levelname)s %(message)s') # noqa: E501
logger.info('Lewis Companion Software Started.')
if __name__ == '__main__':
app = Houston(logger)
app.run()

View File

@@ -1,30 +0,0 @@
# Lewis Crawler
# 2021 - 2022
# Kitsune Scientific
import time
from houston.robotstreamer.streamer import RobotStreamer
class Houston:
def __init__(self, logger):
# Setup logger
self.log = logger
# Setup robotstreamer
self.rs = RobotStreamer(self.log)
# We're ready to go!
self.log.success('Ready to robot!')
def run(self):
self.rs.run()
# Junk~
while True:
try:
self.log.debug('Nothing to do.')
time.sleep(1)
except KeyboardInterrupt:
break

View File

@@ -1,3 +0,0 @@
# Lewis Crawler
# 2021 - 2022
# Kitsune Scientific

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

View File

@@ -1 +0,0 @@
ffmpeg -f image2 -loop 1 -framerate 25 -video_size 1280x720 -r 25 -i Test-Pattern.jpg -vcodec libx264 -profile:v main -preset:v medium -r 30 -g 60 -keyint_min 60 -sc_threshold 0 -b:v 2500k -maxrate 2500k -bufsize 2500k -sws_flags lanczos+accurate_rnd -acodec aac -b:a 96k -ar 48000 -ac 2 -f flv -maxrate 55k "rtmp://rtmp.robotstreamer.com/live/4619?key=jEquBubjizYDMQNe8nKjLdu88iqFpNe3sVQmGRJ2tzbxd4QJrkSSEZBQhi9UTL3k"

View File

@@ -1,30 +0,0 @@
# Lewis Crawler
# 2021 - 2022
# Kitsune Scientific
import ffmpeg
class RobotStreamer:
def __init__(self, logger):
self.log = logger
def run(self):
self.log.debug('Running RobotStreamer')
stream = ffmpeg.input(
'houston/robotstreamer/resources/Test-Pattern.jpg',
f='image2',
loop='1',
framerate=25,
video_size='1280x720')
stream = ffmpeg.output(
stream,
'http://robotstreamer.com/<secret>/1280/720',
f='mpegts',
bf=0,
muxdelay=0.001,
codec='mpeg1video')
ffmpeg.run(stream)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -1,79 +0,0 @@
import time
from PIL import Image, ImageDraw, ImageFont
def testScreen(
x=1280, y=720,
image=None,
stripeList=["lightgrey",
"yellow",
"cyan",
"lightgreen",
"magenta",
"red",
"blue"]):
if image is None:
image = Image.new("RGB", (x, y))
draw = ImageDraw.Draw(image)
for i, stripe in enumerate(stripeList):
draw.rectangle((
(x/len(stripeList)) * i, 0,
(x/len(stripeList)) * (i + 1), x),
fill=stripe)
draw.rectangle((
0, y - (y/3),
x, y),
fill="black")
for i, stripe in enumerate(stripeList):
if i % 2 != 0:
_fill = "black"
else:
_fill = stripeList[len(stripeList) - i - 1]
draw.rectangle((
(x/len(stripeList)) * i, y - (y/3.1),
(x/len(stripeList)) * (i + 1), y - (y/4.9)),
fill=_fill)
draw.rectangle((
(x/(len(stripeList)/4)), y - (y/5.3),
(0), y),
fill="darkblue")
draw.rectangle((
(x/(len(stripeList)/2)), y - (y/5.3),
(x/(len(stripeList)/1)), y),
fill="white")
return image
def drawText(image):
# get a font
fnt = ImageFont.truetype("FreeMono.ttf", 50)
# get a drawing context
d = ImageDraw.Draw(image)
# draw multiline text
d.multiline_text((10, 10), str(time.time()), font=fnt, fill=(0, 0, 0))
return image
if __name__ == '__main__':
blank_screen = testScreen()
while True:
annotated_image = drawText(blank_screen.copy())
annotated_image.save('Test-Pattern.png')
time.sleep(2)
# testScreen().save('Test-Pattern.png')

View File

@@ -1 +0,0 @@
ffmpeg -re -f image2 -loop 1 -framerate 25 -video_size 1280x720 -r 25 -i Test-Pattern.png -c:v libx264 -b:v 1M -g 50 -bf 0 -muxdelay 0.001 -f flv "rtmp://rtmp.robotstreamer.com/live/4619?key=jEquBubjizYDMQNe8nKjLdu88iqFpNe3sVQmGRJ2tzbxd4QJrkSSEZBQhi9UTL3k"

View File

@@ -1,3 +0,0 @@
coloredlogs
verboselogs
ffmpeg-python

5031
crawler_cad/External/Bed_moto.obj vendored Normal file

File diff suppressed because it is too large Load Diff

BIN
crawler_cad/External/bed_Moto.FCStd vendored Normal file

Binary file not shown.

BIN
crawler_cad/Frame.FCStd Normal file

Binary file not shown.

View File

@@ -1,70 +1,38 @@
### DISCLAIMER # A makefile for building the robot's slave software
### This is an example Makefile and it MUST be configured to suit your needs. # Uses arduino-cli
### For detailed explanations about all the available options, #
### please refer to https://github.com/sudar/Arduino-Makefile/blob/master/arduino-mk-vars.md # Kitsune Scientific 2021
### PROJECT_DIR # What board to build for and its core
### This is the path to where you have created/cloned your project CORE ?= arduino:avr
PROJECT_DIR = $(shell dirname $(shell pwd)) FQBN ?= arduino:avr:nano:cpu=atmega328old
### ARDMK_DIR # What port to build on
### Path to the Arduino-Makefile directory. ifndef SERIAL_DEV
ARDMK_DIR = $(PROJECT_DIR)/Arduino-Makefile ifneq (,$(wildcard /dev/ttyUSB0))
SERIAL_DEV = /dev/ttyUSB0
else ifneq (,$(wildcard /dev/ttyACM0))
SERIAL_DEV = /dev/ttyACM0
else
SERIAL_DEV = unknown
endif
endif
### ARDUINO_DIR all: requirements build upload
### Path to the Arduino application and resources directory.
ARDUINO_DIR = /usr/share/arduino
### USER_LIB_PATH build: requirements crawler_slave.ino
### Path to where the your project's libraries are stored. arduino-cli core install $(CORE)
USER_LIB_PATH := $(realpath $(PROJECT_DIR)/lib)
### BOARD_TAG & BOARD_SUB arduino-cli compile -b $(FQBN) crawler_slave
### For Arduino IDE 1.0.x
### Only BOARD_TAG is needed. It must be set to the board you are currently using. (i.e uno, mega2560, etc.)
# BOARD_TAG = mega2560
### For Arduino IDE 1.6.x
### Both BOARD_TAG and BOARD_SUB are needed. They must be set to the board you are currently using. (i.e BOARD_TAG = uno, mega, etc. & BOARD_SUB = atmega2560, etc.)
### Note: for the Arduino Uno, only BOARD_TAG is mandatory and BOARD_SUB can be equal to anything
BOARD_TAG = mega
BOARD_SUB = atmega2560
### MONITOR_PORT upload: requirements crawler_slave.ino
### The port your board is connected to. Using an '*' tries all the ports and finds the right one. Choose one of the two. arduino-cli upload -b $(FQBN) crawler_slave -p $(SERIAL_DEV)
MONITOR_PORT = /dev/ttyUSB*
# MONITOR_PORT = /dev/ttyACM*
### MONITOR_BAUDRATE requirements:
### It must be set to Serial baudrate value you are using. @if [ -e requirements.txt ]; \
MONITOR_BAUDRATE = 115200 then while read -r i ; do echo ; \
echo "---> Installing " '"'$$i'"' ; \
### AVR_TOOLS_DIR arduino-cli lib install "$$i" ; \
### Path to the AVR tools directory such as avr-gcc, avr-g++, etc. done < requirements.txt ; \
AVR_TOOLS_DIR = /usr else echo "---> MISSING requirements.txt file"; \
fi
### AVRDUDE
### Path to avrdude directory.
AVRDUDE = /usr/bin/avrdude
### CFLAGS_STD
CFLAGS_STD = -std=gnu11
### CXXFLAGS_STD
### You can choose wich ever you like
# CXXFLAGS_STD = -std=gnu++11
CXXFLAGS_STD = -std=gnu++17
### CPPFLAGS
### Flags you might want to set for debugging purpose. Comment to stop.
CXXFLAGS += -pedantic -Wall -Wextra
LDFLAGS += -fdiagnostics-color
### OBJDIR
### Don't touch this!
### This is were you put the binaries you just compile using 'make'
CURRENT_DIR = $(shell basename $(CURDIR))
OBJDIR = $(PROJECT_DIR)/build/$(CURRENT_DIR)/$(BOARD_TAG)
### path to Arduino.mk, inside the ARDMK_DIR, don't touch.
include $(ARDMK_DIR)/Arduino.mk

View File

@@ -51,7 +51,9 @@ void receiveEvent(int n) {
switch(id) { switch(id) {
case 1: case 1:
windowWiperServo.write(val); windowWiperServo.write(val); // Set a val
delay(5); // pause for a moment
windowWiperServo.detach(); // Detach (stop moving) the servo
break; break;
} }
} }

View File

@@ -0,0 +1 @@
Servo

View File

@@ -0,0 +1,18 @@
# A makefile for installing the robot's python
# software and setting it up.
#
# Requires sudo
#
# Kitsune Scientific 2021
all: install
upload: crawler.service
sudo cp crawler.service /etc/systemd/system/crawler.service
sudo systemctl daemon-reload
sudo systemctl enable crawler.service
sudo systemctl start crawler.service
sudo systemctl status crawler

View File

@@ -0,0 +1,16 @@
from PIL import Image
import base64
im = Image.open('still.jpg')
# using Image.ADAPTIVE to avoid dithering
for i in range(8, 0, -1):
out = im.convert('P', palette=Image.ADAPTIVE, colors=i)
out.save(f'out_{i}_bits.png')
with open(f'out_{i}_bits.png', 'rb') as image_file:
encoded_string = base64.a85encode(image_file.read())
with open(f'out_{i}_bits.txt', 'w') as f:
f.write(encoded_string.decode('UTF-8'))

View File

@@ -0,0 +1 @@
M,6r;%14!\!!!!.8Ou6I!!!)I!!!&X#Qk&,!4s2MScA`m!)Q?g7AGd(zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz!.5pZZiC(+%V8a6Akbu".KBGK#QOi)zdSl>0!!-\'6pXdsSF+-I!<<*"_P$QtD$r"izzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz!!!"D(e?.W!V_LqE<#t=!(fUS7'8jaJc

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,14 +0,0 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
picamera = "*"
PySSTV = "*"
pyotp = "*"
[dev-packages]
[requires]
python_version = "3.9"

View File

@@ -1,88 +0,0 @@
{
"_meta": {
"hash": {
"sha256": "bd19925493e125dc5aa15b339778c61c21e0f1a5574097d1721abf99245fa605"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.9"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"picamera": {
"hashes": [
"sha256:890815aa01e4d855a6a95dd3ad0953b872a6b954982106407df0c5a31a163e50"
],
"index": "pypi",
"version": "==1.13"
},
"pillow": {
"hashes": [
"sha256:0b2efa07f69dc395d95bb9ef3299f4ca29bcb2157dc615bae0b42c3c20668ffc",
"sha256:114f816e4f73f9ec06997b2fde81a92cbf0777c9e8f462005550eed6bae57e63",
"sha256:147bd9e71fb9dcf08357b4d530b5167941e222a6fd21f869c7911bac40b9994d",
"sha256:15a2808e269a1cf2131930183dcc0419bc77bb73eb54285dde2706ac9939fa8e",
"sha256:196560dba4da7a72c5e7085fccc5938ab4075fd37fe8b5468869724109812edd",
"sha256:1c03e24be975e2afe70dfc5da6f187eea0b49a68bb2b69db0f30a61b7031cee4",
"sha256:1fd5066cd343b5db88c048d971994e56b296868766e461b82fa4e22498f34d77",
"sha256:29c9569049d04aaacd690573a0398dbd8e0bf0255684fee512b413c2142ab723",
"sha256:2b6dfa068a8b6137da34a4936f5a816aba0ecc967af2feeb32c4393ddd671cba",
"sha256:2cac53839bfc5cece8fdbe7f084d5e3ee61e1303cccc86511d351adcb9e2c792",
"sha256:2ee77c14a0299d0541d26f3d8500bb57e081233e3fa915fa35abd02c51fa7fae",
"sha256:37730f6e68bdc6a3f02d2079c34c532330d206429f3cee651aab6b66839a9f0e",
"sha256:3f08bd8d785204149b5b33e3b5f0ebbfe2190ea58d1a051c578e29e39bfd2367",
"sha256:479ab11cbd69612acefa8286481f65c5dece2002ffaa4f9db62682379ca3bb77",
"sha256:4bc3c7ef940eeb200ca65bd83005eb3aae8083d47e8fcbf5f0943baa50726856",
"sha256:660a87085925c61a0dcc80efb967512ac34dbb256ff7dd2b9b4ee8dbdab58cf4",
"sha256:67b3666b544b953a2777cb3f5a922e991be73ab32635666ee72e05876b8a92de",
"sha256:70af7d222df0ff81a2da601fab42decb009dc721545ed78549cb96e3a1c5f0c8",
"sha256:75e09042a3b39e0ea61ce37e941221313d51a9c26b8e54e12b3ececccb71718a",
"sha256:8960a8a9f4598974e4c2aeb1bff9bdd5db03ee65fd1fce8adf3223721aa2a636",
"sha256:9364c81b252d8348e9cc0cb63e856b8f7c1b340caba6ee7a7a65c968312f7dab",
"sha256:969cc558cca859cadf24f890fc009e1bce7d7d0386ba7c0478641a60199adf79",
"sha256:9a211b663cf2314edbdb4cf897beeb5c9ee3810d1d53f0e423f06d6ebbf9cd5d",
"sha256:a17ca41f45cf78c2216ebfab03add7cc350c305c38ff34ef4eef66b7d76c5229",
"sha256:a2f381932dca2cf775811a008aa3027671ace723b7a38838045b1aee8669fdcf",
"sha256:a4eef1ff2d62676deabf076f963eda4da34b51bc0517c70239fafed1d5b51500",
"sha256:c088a000dfdd88c184cc7271bfac8c5b82d9efa8637cd2b68183771e3cf56f04",
"sha256:c0e0550a404c69aab1e04ae89cca3e2a042b56ab043f7f729d984bf73ed2a093",
"sha256:c11003197f908878164f0e6da15fce22373ac3fc320cda8c9d16e6bba105b844",
"sha256:c2a5ff58751670292b406b9f06e07ed1446a4b13ffced6b6cab75b857485cbc8",
"sha256:c35d09db702f4185ba22bb33ef1751ad49c266534339a5cebeb5159d364f6f82",
"sha256:c379425c2707078dfb6bfad2430728831d399dc95a7deeb92015eb4c92345eaf",
"sha256:cc866706d56bd3a7dbf8bac8660c6f6462f2f2b8a49add2ba617bc0c54473d83",
"sha256:d0da39795049a9afcaadec532e7b669b5ebbb2a9134576ebcc15dd5bdae33cc0",
"sha256:f156d6ecfc747ee111c167f8faf5f4953761b5e66e91a4e6767e548d0f80129c",
"sha256:f4ebde71785f8bceb39dcd1e7f06bcc5d5c3cf48b9f69ab52636309387b097c8",
"sha256:fc214a6b75d2e0ea7745488da7da3c381f41790812988c7a92345978414fad37",
"sha256:fd7eef578f5b2200d066db1b50c4aa66410786201669fb76d5238b007918fb24",
"sha256:ff04c373477723430dce2e9d024c708a047d44cf17166bf16e604b379bf0ca14"
],
"markers": "python_version >= '3.6'",
"version": "==8.3.1"
},
"pyotp": {
"hashes": [
"sha256:9d144de0f8a601d6869abe1409f4a3f75f097c37b50a36a3bf165810a6e23f28",
"sha256:d28ddfd40e0c1b6a6b9da961c7d47a10261fb58f378cb00f05ce88b26df9c432"
],
"index": "pypi",
"version": "==2.6.0"
},
"pysstv": {
"hashes": [
"sha256:91f85096591606e774811de8940aef57f30e10cbf81387064f8a686cff0ac3fa"
],
"index": "pypi",
"version": "==0.5.2"
}
},
"develop": {}
}

View File

@@ -0,0 +1,25 @@
from random import randrange
import time, pyotp, datetime
hotp = pyotp.HOTP(pyotp.random_base32())
success = 0
num_tries = 20
for i in range(0,num_tries):
epoch = int(time.time())
code = hotp.at(epoch)
print('------------------------')
print(f'Made a code {code} at {epoch}, sending a simualted instruction')
waittime = randrange(5)
print(f'Instuction will take {waittime} seconds to receive or be recieved')
time.sleep(waittime)
if hotp.verify(code, epoch):
print(f'code:{code} verified')
success += 1
else:
print(f'code:{code} expired')
print(f'Succeded {success} out of {num_tries} tries')