Compare commits
40 Commits
608af373e6
...
kw1fox-2/s
| Author | SHA1 | Date | |
|---|---|---|---|
| fdcb3aaf41 | |||
| f94499e753 | |||
| b466adaa80 | |||
| 9c73d1535a | |||
| 12d87af633 | |||
| 213e9e1b0f | |||
| 9e4369a3b3 | |||
| d8d7343f86 | |||
| cbcabda363 | |||
| ff6d5805bf | |||
| b32ec1880d | |||
| e4a7e565d1 | |||
| 395c4e6fbb | |||
| 9e08e1b2a6 | |||
|
|
15473e8d2a | ||
| 72294ead28 | |||
| b910ce08a8 | |||
| 529663f35b | |||
| c5cea53c50 | |||
| fe79ee08ec | |||
| ea5baa63b2 | |||
| 73ad31d641 | |||
| 95efff98ce | |||
| 5e749906a3 | |||
| d4cf5ebdd5 | |||
| 93f0ed2789 | |||
| 434f43556e | |||
| 02b38e96f5 | |||
| 9b02ac2aa3 | |||
| 0734206570 | |||
| 2693da2cc1 | |||
| f0bab10e25 | |||
| 40162a4c19 | |||
| 69990a4fbf | |||
| bb8ffcc983 | |||
| aa47771265 | |||
| 2569782b38 | |||
| 8ebbd31d14 | |||
| 5f9a30013d | |||
| 81c1148b49 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -10,3 +10,6 @@ __pycache__
|
||||
*.jpg
|
||||
*.wav
|
||||
*.pdf
|
||||
|
||||
# Dev
|
||||
.vscode
|
||||
|
||||
BIN
CAD/kw1fox-2/Assembly.FCStd
Normal file
BIN
CAD/kw1fox-2/Assembly.FCStd
Normal file
Binary file not shown.
178418
CAD/kw1fox-2/parts/APRN-pi-3D.step
Normal file
178418
CAD/kw1fox-2/parts/APRN-pi-3D.step
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
BIN
CAD/lewis_crawler/frame/Frame.FCStd
Normal file
BIN
CAD/lewis_crawler/frame/Frame.FCStd
Normal file
Binary file not shown.
BIN
CAD/lewis_crawler/lewis-crawler.FCStd
Normal file
BIN
CAD/lewis_crawler/lewis-crawler.FCStd
Normal file
Binary file not shown.
4824
CAD/resources/Kitsune Robotics Template.svg
Normal file
4824
CAD/resources/Kitsune Robotics Template.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 313 KiB |
BIN
CAD/resources/Kitsune Scientific.kra
Normal file
BIN
CAD/resources/Kitsune Scientific.kra
Normal file
Binary file not shown.
BIN
CAD/resources/RelayBox.FCStd
Normal file
BIN
CAD/resources/RelayBox.FCStd
Normal file
Binary file not shown.
356317
CAD/resources/raspberry_pi_3_b_plus.stp
Normal file
356317
CAD/resources/raspberry_pi_3_b_plus.stp
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Resources/KW1FOX-1_320x240.png
Normal file
BIN
Resources/KW1FOX-1_320x240.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
BIN
Resources/KW1FOX-1_450x240.png
Normal file
BIN
Resources/KW1FOX-1_450x240.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
BIN
Resources/KitSuneAero.png
Normal file
BIN
Resources/KitSuneAero.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 194 KiB |
BIN
Resources/RadioFont.ttf
Normal file
BIN
Resources/RadioFont.ttf
Normal file
Binary file not shown.
11
Simulation/Lewis_Crawler/model.config
Normal file
11
Simulation/Lewis_Crawler/model.config
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
<model>
|
||||
<name>Lewis_Crawler</name>
|
||||
<version>1.0</version>
|
||||
<sdf version="1.7">model.sdf</sdf>
|
||||
<author>
|
||||
<name>Joe Sedutto</name>
|
||||
<email>kenwood364@gmail.com</email>
|
||||
</author>
|
||||
<description></description>
|
||||
</model>
|
||||
109
Simulation/Lewis_Crawler/model.sdf
Normal file
109
Simulation/Lewis_Crawler/model.sdf
Normal file
@@ -0,0 +1,109 @@
|
||||
<?xml version='1.0'?>
|
||||
<sdf version='1.7'>
|
||||
<model name='Lewis_Crawler'>
|
||||
|
||||
<link name='chassis'>
|
||||
|
||||
<pose>-0.1524 -0.1 0.0508 0 0 0</pose>
|
||||
|
||||
<visual name='visual'>
|
||||
<pose>0 0 0 0 0 0</pose>
|
||||
|
||||
<geometry>
|
||||
<mesh>
|
||||
<uri>/home/joe/git/lewis-crawler/Simulation/Meshes/LCFrame.dae</uri>
|
||||
<scale>1 1 1</scale>
|
||||
</mesh>
|
||||
</geometry>
|
||||
|
||||
<material>
|
||||
<lighting>1</lighting>
|
||||
<script>
|
||||
<uri>file://media/materials/scripts/gazebo.material</uri>
|
||||
<name>Gazebo/Grey</name>
|
||||
</script>
|
||||
<shader type='pixel' />
|
||||
</material>
|
||||
|
||||
<transparency>0</transparency>
|
||||
<cast_shadows>1</cast_shadows>
|
||||
</visual>
|
||||
|
||||
<collision name='collision'>
|
||||
<laser_retro>0</laser_retro>
|
||||
<max_contacts>10</max_contacts>
|
||||
<pose>0 0 0 0 -0 0</pose>
|
||||
|
||||
<geometry>
|
||||
<mesh>
|
||||
<uri>/home/joe/git/lewis-crawler/Simulation/Meshes/LCFrame.dae</uri>
|
||||
<scale>1 1 1</scale>
|
||||
</mesh>
|
||||
</geometry>
|
||||
|
||||
</collision>
|
||||
|
||||
</link>
|
||||
|
||||
<link name="port_wheel">
|
||||
<pose>0.1524 0 0.1016 0 1.5707 0</pose>
|
||||
<collision name="collision">
|
||||
<geometry>
|
||||
<cylinder>
|
||||
<radius>.1</radius>
|
||||
<length>.05</length>
|
||||
</cylinder>
|
||||
</geometry>
|
||||
</collision>
|
||||
<visual name="visual">
|
||||
<geometry>
|
||||
<cylinder>
|
||||
<radius>.1</radius>
|
||||
<length>.05</length>
|
||||
</cylinder>
|
||||
</geometry>
|
||||
</visual>
|
||||
</link>
|
||||
|
||||
<link name="starboard_wheel">
|
||||
<pose>-0.1524 0 0.1016 0 1.5707 0</pose>
|
||||
<collision name="collision">
|
||||
<geometry>
|
||||
<cylinder>
|
||||
<radius>.1</radius>
|
||||
<length>.05</length>
|
||||
</cylinder>
|
||||
</geometry>
|
||||
</collision>
|
||||
<visual name="visual">
|
||||
<geometry>
|
||||
<cylinder>
|
||||
<radius>.1</radius>
|
||||
<length>.05</length>
|
||||
</cylinder>
|
||||
</geometry>
|
||||
</visual>
|
||||
</link>
|
||||
|
||||
<joint type="port_wheel" name="port_wheel_axle">
|
||||
<pose>0 0 -0.03 0 0 0</pose>
|
||||
<child>left_wheel</child>
|
||||
<parent>chassis</parent>
|
||||
<axis>
|
||||
<xyz>0 1 0</xyz>
|
||||
</axis>
|
||||
</joint>
|
||||
|
||||
<joint type="starboard_wheel" name="starboard_wheel_axle">
|
||||
<pose>0 0 0.03 0 0 0</pose>
|
||||
<child>right_wheel</child>
|
||||
<parent>chassis</parent>
|
||||
<axis>
|
||||
<xyz>0 1 0</xyz>
|
||||
</axis>
|
||||
</joint>
|
||||
|
||||
<static>0</static>
|
||||
<allow_auto_disable>1</allow_auto_disable>
|
||||
</model>
|
||||
</sdf>
|
||||
106
Simulation/Meshes/LCFrame.dae
Normal file
106
Simulation/Meshes/LCFrame.dae
Normal file
@@ -0,0 +1,106 @@
|
||||
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
|
||||
<asset>
|
||||
<contributor/>
|
||||
<created>2022-03-11T12:26:21.628371</created>
|
||||
<modified>2022-03-11T12:26:21.628375</modified>
|
||||
<unit name="meter" meter="1.0"/>
|
||||
<up_axis>Z_UP</up_axis>
|
||||
</asset>
|
||||
<library_effects>
|
||||
<effect id="effect_Body" name="effect_Body">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color>0.0 0.0 0.0 1.0</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color>0.0 0.0 0.0 1.0</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color>0.800000011920929 0.800000011920929 0.800000011920929 1.0</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color>1 1 1 1.0</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float>0.0</float>
|
||||
</shininess>
|
||||
<reflective>
|
||||
<color>0.0 0.0 0.0 1.0</color>
|
||||
</reflective>
|
||||
<reflectivity>
|
||||
<float>0.0</float>
|
||||
</reflectivity>
|
||||
<transparent>
|
||||
<color>0.0 0.0 0.0 1.0</color>
|
||||
</transparent>
|
||||
<transparency>
|
||||
<float>1.0</float>
|
||||
</transparency>
|
||||
</phong>
|
||||
</technique>
|
||||
<extra>
|
||||
<technique profile="GOOGLEEARTH">
|
||||
<double_sided>0</double_sided>
|
||||
</technique>
|
||||
</extra>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
</library_effects>
|
||||
<library_geometries>
|
||||
<geometry id="geometry0" name="Body">
|
||||
<mesh>
|
||||
<source id="cubeverts-array0">
|
||||
<float_array count="273" id="cubeverts-array0-array">0 0 0 0 0.0254 -4.3e-17 0.0254 0.0254 -3.7e-17 0.3048 0 0 0.2794 0.0254 -3.7e-17 0.3048 0.0254 -4.3e-17 0 1.28e-16 0.1651 0 0.0254 0.1651 -1.5e-17 0.0254 0.1397 -3e-18 0.0254 0.0254 0.3048 0.0254 0.0254 0.3048 0.0254 0.1397 0.3048 1.28e-16 0.1651 0.3048 0.0254 0.1651 0.0254 1.09e-16 0.1397 0.0254 2e-17 0.0254 0.2794 1.09e-16 0.1397 0.2794 2e-17 0.0254 0 0.5842 -1.258e-15 0.0254 0.5842 -9.98e-16 0.0254 0.0254 0.0254 0.2794 0.0254 0.0254 0.3048 0.5842 -1.258e-15 0.2794 0.5842 -9.98e-16 0.2794 0.0254 0.1651 0.1778 0.0254 0.1651 0.0254 0.0254 0.1651 0 0.5842 0.1397 -3.1e-17 0.1778 0.1397 0 0.5842 0.1651 -6e-18 0.1778 0.0254 0 0.5842 0.0254 0.3048 0.5842 0.0254 0.3048 0.1778 0.0254 0.3048 0.1778 0.1397 0.3048 0.5842 0.1397 0.3048 0.5842 0.1651 0.2794 0.0254 0.1397 0.0254 0.0254 0.1397 0.0254 0.5842 0.0254 0 0.6096 -1.176e-15 0.3048 0.6096 -1.176e-15 0.2794 0.5842 0.0254 0.2794 0.127 0.1651 0.2794 0.5842 0.1651 0.1778 0.127 0.1651 0.1778 0.0254 0.15875 0.2794 0.0254 0.15875 0.0254 0.5842 0.1651 0.0254 0.5842 0.1397 0.00635 0.1778 0.1397 0.00635 0.0254 0.1397 0 0.6096 0.1651 0 0.6096 0.1397 0.00635 0.1778 0.0254 0.00635 0.0254 0.0254 0.29845 0.1778 0.0254 0.29845 0.0254 0.0254 0.3048 0.6096 0.1397 0.3048 0.6096 0.1651 0.29845 0.1778 0.1397 0.2794 0.5842 0.1397 0.29845 0.0254 0.1397 0.0254 0.6096 0.0254 0.0254 0.6096 0.1397 0.2794 0.6096 0.0254 0.2794 0.6096 0.1397 0.2794 0.127 0.15875 0.2751267 0.6096 0.1651 0.02967325 0.6096 0.1651 0.1778 0.127 0.15875 0.1778 0.127 0.15875 0.2794 0.127 0.15875 0.1030465 0.7802151 0.1397 0.1524 0.8619303 0.1651 0.1524 0.8619303 0.1397 0.2017535 0.7802151 0.1397 0.02967325 0.6096 0.1397 0.1327197 0.7802151 0.1397 0.2751267 0.6096 0.1397 0.1720803 0.7802151 0.1397 0.1524 0.8128 0.1651 0.1016 0.7802151 0.1397 0.2032 0.7802151 0.1397 0.2032 0.8945151 0.1397 0.1016 0.8945151 0.1397 0.1524 0.8128 0.1397 0.1016 0.7802151 0.13335 0.2032 0.7802151 0.13335 0.1016 0.8945151 0.13335 0.2032 0.8945151 0.13335</float_array>
|
||||
<technique_common>
|
||||
<accessor count="91" source="#cubeverts-array0-array" stride="3">
|
||||
<param type="float" name="X"/>
|
||||
<param type="float" name="Y"/>
|
||||
<param type="float" name="Z"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<source id="cubenormals-array0">
|
||||
<float_array count="594" id="cubenormals-array0-array">2.362205e-16 -1.692914e-15 -1 -2.362205e-16 -1.692913e-15 -1 -0 -1.456693e-15 -1 0 -1.456693e-15 -1 -1 0 5.90551e-16 -1 -1.312335e-17 -1.049869e-16 -1 -1.999504e-31 -1.181102e-16 -1 -5.905512e-16 4.578471e-31 1 -0 0 1 0 0 1 -0 0 1 0 0 2.725684e-17 -1 7.752877e-16 8.748921e-18 -1 7.786527e-16 0 -1 7.480312e-16 0 -1 7.480312e-16 0 -1 7.874015e-16 -8.748847e-18 -1 7.786527e-16 -2.725685e-17 -1 7.752877e-16 0 -1 7.874016e-16 2.362205e-16 -2.174302e-15 -1 1.023622e-14 -1.719757e-15 -1 0 1 0 0 1 0 -2.362206e-16 -2.174302e-15 -1 -1.023622e-14 -1.719757e-15 -1 0 -0 1 -0 0 1 0 0 1 0 0 1 0 0 1 -1 7.627952e-17 0 -1 -1.049869e-16 5.905509e-16 -1 0 1.220472e-15 -1 -1.968504e-17 -2.187227e-16 -1 -1.049869e-16 -1.049869e-16 -1 1.476378e-17 0 -1 -1.968504e-17 -1.181102e-16 -1 -5.136147e-31 -2.362205e-16 1 0 0 1 -0 0 1 -0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -0 0 -1 0 0 -1 -1 0 0 -1 0 0 0 0 1 0 0 1 1 0 0 1 -0 0 1 -0 0 1 -0 0 1.023622e-14 3.228349e-15 -1 0 -7.007887e-15 -1 -0 -7.007887e-15 -1 -1.023622e-14 3.228349e-15 -1 -1 0 0 -1 0 0 0 0 1 0 0 1 0 -0 1 -0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 -0 0 1 -0 0 -1 0 0 -1 0 0 -1 0 -0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 -0 0 -0 1 0 0 1 0 0 1 0 -0 1 -0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 -0 0 1 -0 0 -0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 0 1 0 -0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 -0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 -0 1 -0 0 1 0 -0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -0 1 0 0 1 0 0 0 -1 0 0 -1 1 -0 0 1 0 0 1 0 0 1 -0 0 0 -1 0 0 -1 0 -0.85599 0.5169924 0 -0.85599 0.5169924 0 -0.85599 0.5169924 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0.8559899 0.5169926 0 0.85599 0.5169923 0 0.85599 0.5169924 5.217055e-07 0 0 1 -0 0 1 0 0 -1 0 0 -1 0 0 -1 1 -0 0 1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 -0 -1 0 0 -1 0 -0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 0 1 0 0 1 -0 0 1 -0 0 1 0 0 1 -0 -0 -1 0 0 -1 -0 0 -1 0 0 -1 0.85599 -0.5169924 0 0.8559901 -0.5169923 0 0.85599 -0.5169924 1.214709e-07 -0 -1 0 -0 -1 0 0 -1 0 0 -1 0 -0 -1 -0 -0 -1 -0 -0.8559899 -0.5169927 0 -0.85599 -0.5169923 -0 -0.85599 -0.5169924 -3.239225e-07 -1 0 0 -1 0 0 0 1 0 -0 1 0 1 0 0 1 0 0 0 0 1 0 0 -1 0 0 -1</float_array>
|
||||
<technique_common>
|
||||
<accessor count="198" source="#cubenormals-array0-array" stride="3">
|
||||
<param type="float" name="X"/>
|
||||
<param type="float" name="Y"/>
|
||||
<param type="float" name="Z"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<vertices id="cubeverts-array0-vertices">
|
||||
<input semantic="POSITION" source="#cubeverts-array0"/>
|
||||
</vertices>
|
||||
<triangles count="198" material="ref_Body">
|
||||
<input offset="0" semantic="VERTEX" source="#cubeverts-array0-vertices"/>
|
||||
<input offset="1" semantic="NORMAL" source="#cubenormals-array0"/>
|
||||
<p>0 0 1 0 2 0 3 1 4 1 5 1 3 2 0 2 2 2 3 3 2 3 4 3 6 4 7 4 8 4 0 5 8 5 9 5 0 6 9 6 1 6 0 7 6 7 8 7 3 8 5 8 10 8 11 9 3 9 10 9 12 10 11 10 13 10 12 11 3 11 11 11 0 12 14 12 6 12 15 13 14 13 0 13 16 14 12 14 6 14 16 15 6 15 14 15 17 16 15 16 0 16 3 17 16 17 17 17 3 18 12 18 16 18 3 19 17 19 0 19 2 20 1 20 18 20 2 21 18 21 19 21 20 22 4 22 2 22 21 23 4 23 20 23 5 24 4 24 22 24 22 25 4 25 23 25 12 26 13 26 24 26 25 27 12 27 24 27 6 28 25 28 26 28 6 29 26 29 7 29 6 30 12 30 25 30 27 31 28 31 29 31 8 32 7 32 28 32 7 33 29 33 28 33 30 34 9 34 28 34 9 35 8 35 28 35 30 36 31 36 18 36 1 37 9 37 30 37 18 38 1 38 30 38 32 39 33 39 22 39 10 40 5 40 33 40 5 41 22 41 33 41 34 42 10 42 33 42 34 43 11 43 10 43 34 44 35 44 36 44 13 45 11 45 34 45 36 46 13 46 34 46 37 47 14 47 38 47 16 48 14 48 37 48 17 49 16 49 37 49 17 50 37 50 21 50 15 51 17 51 21 51 15 52 21 52 20 52 14 53 15 53 20 53 14 54 20 54 38 54 2 55 19 55 39 55 20 56 2 56 39 56 19 57 18 57 40 57 23 58 40 58 41 58 23 59 19 59 40 59 22 60 23 60 41 60 23 61 4 61 42 61 4 62 21 62 42 62 43 63 36 63 44 63 24 64 13 64 43 64 13 65 36 65 43 65 45 66 25 66 43 66 43 67 25 67 24 67 25 68 46 68 26 68 26 69 46 69 38 69 47 70 37 70 46 70 37 71 38 71 46 71 7 72 26 72 29 72 29 73 26 73 48 73 49 74 50 74 27 74 50 75 28 75 27 75 38 76 51 76 50 76 49 77 38 77 50 77 27 78 29 78 52 78 27 79 52 79 53 79 31 80 53 80 40 80 31 81 27 81 53 81 18 82 31 82 40 82 30 83 50 83 54 83 30 84 28 84 50 84 54 85 39 85 31 85 30 86 54 86 31 86 55 87 20 87 54 87 20 88 39 88 54 88 42 89 56 89 32 89 56 90 33 90 32 90 21 91 57 91 56 91 42 92 21 92 56 92 32 93 22 93 41 93 58 94 32 94 41 94 35 95 58 95 59 95 35 96 32 96 58 96 36 97 35 97 59 97 60 98 34 98 56 98 56 99 34 99 33 99 60 100 61 100 35 100 34 101 60 101 35 101 62 102 37 102 60 102 37 103 61 103 60 103 62 104 57 104 37 104 37 105 57 105 21 105 38 106 20 106 51 106 51 107 20 107 55 107 42 108 39 108 19 108 23 109 42 109 19 109 53 110 63 110 40 110 64 111 63 111 53 111 58 112 65 112 66 112 63 113 65 113 40 113 58 114 41 114 65 114 65 115 41 115 40 115 67 116 43 116 44 116 67 117 44 117 61 117 37 118 47 118 67 118 61 119 37 119 67 119 44 120 36 120 59 120 44 121 59 121 68 121 69 122 44 122 68 122 48 123 69 123 52 123 48 124 44 124 69 124 29 125 48 125 52 125 25 126 70 126 46 126 25 127 45 127 70 127 45 128 43 128 70 128 70 129 43 129 67 129 47 130 71 130 72 130 46 131 71 131 47 131 26 132 38 132 48 132 48 133 38 133 49 133 51 134 55 134 54 134 51 135 54 135 50 135 31 136 49 136 27 136 39 137 49 137 31 137 52 138 73 138 53 138 73 139 74 139 75 139 52 140 74 140 73 140 62 141 60 141 57 141 57 142 60 142 56 142 42 143 35 143 61 143 32 144 35 144 42 144 74 145 76 145 75 145 76 146 59 146 58 146 74 147 59 147 76 147 39 148 42 148 63 148 63 149 42 149 65 149 77 150 73 150 78 150 64 151 73 151 77 151 53 152 73 152 64 152 49 153 39 153 64 153 64 154 39 154 63 154 42 155 66 155 65 155 42 156 61 156 66 156 66 157 76 157 58 157 79 158 80 158 76 158 79 159 76 159 66 159 44 160 48 160 49 160 61 161 44 161 49 161 81 162 59 162 74 162 81 163 68 163 59 163 81 164 52 164 69 164 74 165 52 165 81 165 68 166 79 166 69 166 69 167 79 167 77 167 75 168 82 168 73 168 75 169 76 169 83 169 75 170 83 170 84 170 85 171 75 171 84 171 85 172 82 172 75 172 66 173 61 173 79 173 61 174 77 174 79 174 77 175 49 175 64 175 61 176 49 176 77 176 78 177 69 177 77 177 81 178 78 178 86 178 81 179 69 179 78 179 73 180 82 180 87 180 78 181 73 181 87 181 88 182 80 182 78 182 88 183 78 183 87 183 76 184 80 184 88 184 83 185 76 185 88 185 80 186 81 186 86 186 68 187 80 187 79 187 68 188 81 188 80 188 87 189 85 189 89 189 82 190 85 190 87 190 89 191 84 191 90 191 85 192 84 192 89 192 84 193 83 193 88 193 84 194 88 194 90 194 86 195 78 195 80 195 87 196 89 196 88 196 88 197 89 197 90 197</p>
|
||||
</triangles>
|
||||
</mesh>
|
||||
</geometry>
|
||||
</library_geometries>
|
||||
<library_materials>
|
||||
<material id="mat_Body" name="Body">
|
||||
<instance_effect url="#effect_Body"/>
|
||||
</material>
|
||||
</library_materials>
|
||||
<library_visual_scenes>
|
||||
<visual_scene id="myscene">
|
||||
<node id="node0" name="node0">
|
||||
<instance_geometry url="#geometry0">
|
||||
<bind_material>
|
||||
<technique_common>
|
||||
<instance_material symbol="ref_Body" target="#mat_Body"/>
|
||||
</technique_common>
|
||||
</bind_material>
|
||||
</instance_geometry>
|
||||
</node>
|
||||
</visual_scene>
|
||||
</library_visual_scenes>
|
||||
<scene>
|
||||
<instance_visual_scene url="#myscene"/>
|
||||
</scene>
|
||||
</COLLADA>
|
||||
8
Software/houston/Makefile
Normal file
8
Software/houston/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
# Joe wrote this
|
||||
|
||||
install:
|
||||
sudo cp qsstv.service /etc/systemd/system/qsstv.service
|
||||
sudo cp robotstreamer.service /etc/systemd/system/robotstreamer.service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable qsstv.service
|
||||
sudo systemctl enable robotstreamer.service
|
||||
12
Software/houston/Pipfile
Normal file
12
Software/houston/Pipfile
Normal file
@@ -0,0 +1,12 @@
|
||||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
xlib = "*"
|
||||
pillow = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
78
Software/houston/Pipfile.lock
generated
Normal file
78
Software/houston/Pipfile.lock
generated
Normal file
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "d38f5cc73695023ab5e5dc66a552a8d0bb9d3842a276ca547364ce1d6baaf5b9"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"pillow": {
|
||||
"hashes": [
|
||||
"sha256:01ce45deec9df310cbbee11104bae1a2a43308dd9c317f99235b6d3080ddd66e",
|
||||
"sha256:0c51cb9edac8a5abd069fd0758ac0a8bfe52c261ee0e330f363548aca6893595",
|
||||
"sha256:17869489de2fce6c36690a0c721bd3db176194af5f39249c1ac56d0bb0fcc512",
|
||||
"sha256:21dee8466b42912335151d24c1665fcf44dc2ee47e021d233a40c3ca5adae59c",
|
||||
"sha256:25023a6209a4d7c42154073144608c9a71d3512b648a2f5d4465182cb93d3477",
|
||||
"sha256:255c9d69754a4c90b0ee484967fc8818c7ff8311c6dddcc43a4340e10cd1636a",
|
||||
"sha256:35be4a9f65441d9982240e6966c1eaa1c654c4e5e931eaf580130409e31804d4",
|
||||
"sha256:3f42364485bfdab19c1373b5cd62f7c5ab7cc052e19644862ec8f15bb8af289e",
|
||||
"sha256:3fddcdb619ba04491e8f771636583a7cc5a5051cd193ff1aa1ee8616d2a692c5",
|
||||
"sha256:463acf531f5d0925ca55904fa668bb3461c3ef6bc779e1d6d8a488092bdee378",
|
||||
"sha256:4fe29a070de394e449fd88ebe1624d1e2d7ddeed4c12e0b31624561b58948d9a",
|
||||
"sha256:55dd1cf09a1fd7c7b78425967aacae9b0d70125f7d3ab973fadc7b5abc3de652",
|
||||
"sha256:5a3ecc026ea0e14d0ad7cd990ea7f48bfcb3eb4271034657dc9d06933c6629a7",
|
||||
"sha256:5cfca31ab4c13552a0f354c87fbd7f162a4fafd25e6b521bba93a57fe6a3700a",
|
||||
"sha256:66822d01e82506a19407d1afc104c3fcea3b81d5eb11485e593ad6b8492f995a",
|
||||
"sha256:69e5ddc609230d4408277af135c5b5c8fe7a54b2bdb8ad7c5100b86b3aab04c6",
|
||||
"sha256:6b6d4050b208c8ff886fd3db6690bf04f9a48749d78b41b7a5bf24c236ab0165",
|
||||
"sha256:7a053bd4d65a3294b153bdd7724dce864a1d548416a5ef61f6d03bf149205160",
|
||||
"sha256:82283af99c1c3a5ba1da44c67296d5aad19f11c535b551a5ae55328a317ce331",
|
||||
"sha256:8782189c796eff29dbb37dd87afa4ad4d40fc90b2742704f94812851b725964b",
|
||||
"sha256:8d79c6f468215d1a8415aa53d9868a6b40c4682165b8cb62a221b1baa47db458",
|
||||
"sha256:97bda660702a856c2c9e12ec26fc6d187631ddfd896ff685814ab21ef0597033",
|
||||
"sha256:a325ac71914c5c043fa50441b36606e64a10cd262de12f7a179620f579752ff8",
|
||||
"sha256:a336a4f74baf67e26f3acc4d61c913e378e931817cd1e2ef4dfb79d3e051b481",
|
||||
"sha256:a598d8830f6ef5501002ae85c7dbfcd9c27cc4efc02a1989369303ba85573e58",
|
||||
"sha256:a5eaf3b42df2bcda61c53a742ee2c6e63f777d0e085bbc6b2ab7ed57deb13db7",
|
||||
"sha256:aea7ce61328e15943d7b9eaca87e81f7c62ff90f669116f857262e9da4057ba3",
|
||||
"sha256:af79d3fde1fc2e33561166d62e3b63f0cc3e47b5a3a2e5fea40d4917754734ea",
|
||||
"sha256:c24f718f9dd73bb2b31a6201e6db5ea4a61fdd1d1c200f43ee585fc6dcd21b34",
|
||||
"sha256:c5b0ff59785d93b3437c3703e3c64c178aabada51dea2a7f2c5eccf1bcf565a3",
|
||||
"sha256:c7110ec1701b0bf8df569a7592a196c9d07c764a0a74f65471ea56816f10e2c8",
|
||||
"sha256:c870193cce4b76713a2b29be5d8327c8ccbe0d4a49bc22968aa1e680930f5581",
|
||||
"sha256:c9efef876c21788366ea1f50ecb39d5d6f65febe25ad1d4c0b8dff98843ac244",
|
||||
"sha256:de344bcf6e2463bb25179d74d6e7989e375f906bcec8cb86edb8b12acbc7dfef",
|
||||
"sha256:eb1b89b11256b5b6cad5e7593f9061ac4624f7651f7a8eb4dfa37caa1dfaa4d0",
|
||||
"sha256:ed742214068efa95e9844c2d9129e209ed63f61baa4d54dbf4cf8b5e2d30ccf2",
|
||||
"sha256:f401ed2bbb155e1ade150ccc63db1a4f6c1909d3d378f7d1235a44e90d75fb97",
|
||||
"sha256:fb89397013cf302f282f0fc998bb7abf11d49dcff72c8ecb320f76ea6e2c5717"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==9.1.0"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
|
||||
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
|
||||
],
|
||||
"version": "==1.16.0"
|
||||
},
|
||||
"xlib": {
|
||||
"hashes": [
|
||||
"sha256:60b7cd5d90f5d5922d9ce27b61589c07d970796558d417461db7b66e366bc401",
|
||||
"sha256:8eee67dad83ef4b82bbbfa85d51eeb20c79d12b119fe25aa1d27bd602ff82212"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.21"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
||||
148
Software/houston/RobotStreamer.py
Normal file
148
Software/houston/RobotStreamer.py
Normal file
@@ -0,0 +1,148 @@
|
||||
import time
|
||||
import subprocess as sp
|
||||
|
||||
from Xlib import display, X
|
||||
from PIL import Image, ImageFont, ImageDraw
|
||||
|
||||
|
||||
class Streamer:
|
||||
def __init__(self):
|
||||
self.x1, self.y1 = 580, 620
|
||||
|
||||
# Create display
|
||||
self.dsp = display.Display(":0")
|
||||
|
||||
# This is the root of the screen
|
||||
self.root = self.dsp.screen().root
|
||||
|
||||
# ffmpeg command
|
||||
|
||||
# ffmpeg --stream_loop -1 -re -i ~/INPUT_FILE -vcodec libx264 -profile:v main -preset:v medium -r 20 -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 rtmp://rtmp.robotstreamer.com/live/123?key=123"
|
||||
cmd_out = [
|
||||
"ffmpeg",
|
||||
"-f",
|
||||
"image2pipe",
|
||||
"-vcodec",
|
||||
"png",
|
||||
"-r",
|
||||
"5", # FPS
|
||||
"-i",
|
||||
"-", # Indicated input comes from pipe
|
||||
"-vcodec",
|
||||
"libx264",
|
||||
"-profile:v",
|
||||
"main",
|
||||
"-pix_fmt",
|
||||
"yuv420p",
|
||||
"-preset:v",
|
||||
"medium",
|
||||
"-r",
|
||||
"30",
|
||||
"-g",
|
||||
"60",
|
||||
"-keyint_min",
|
||||
"60",
|
||||
"-sc_threshold",
|
||||
"0",
|
||||
"-b:v",
|
||||
"2500k",
|
||||
"-maxrate",
|
||||
"1500k",
|
||||
"-bufsize",
|
||||
"1500k",
|
||||
"-sws_flags",
|
||||
"lanczos+accurate_rnd",
|
||||
"-acodec",
|
||||
"aac",
|
||||
"-b:a",
|
||||
"96k",
|
||||
"-r",
|
||||
"6",
|
||||
"-ar",
|
||||
"48000",
|
||||
"-ac",
|
||||
"2",
|
||||
"-f",
|
||||
"flv",
|
||||
"rtmp://rtmp.robotstreamer.com/live/topkek",
|
||||
]
|
||||
|
||||
# This is the ffmpeg pipe streamer!
|
||||
self.pipe = sp.Popen(cmd_out, stdin=sp.PIPE)
|
||||
|
||||
# Graphics and resources
|
||||
self.font = ImageFont.truetype(r"../../Resources/RadioFont.ttf", 20)
|
||||
|
||||
def getFrame(self):
|
||||
"""
|
||||
Returns a single cropped sstv video frame
|
||||
"""
|
||||
|
||||
raw = self.root.get_image(0, 0, self.x1, self.y1, X.ZPixmap, 0xFFFFFFFF)
|
||||
image = Image.frombytes("RGB", (self.x1, self.y1), raw.data, "raw", "BGRX")
|
||||
|
||||
image = image.crop((0, 182, self.x1, self.y1))
|
||||
|
||||
return image
|
||||
|
||||
def drawGraphics(self, image: Image):
|
||||
"""
|
||||
Draws graphics and sprites over
|
||||
a frame
|
||||
"""
|
||||
|
||||
frame = Image.new(mode="RGB", size=(1280, 720))
|
||||
|
||||
# Scale and paste
|
||||
image = image.resize((960, 720), Image.ANTIALIAS)
|
||||
frame.paste(image)
|
||||
|
||||
# Populate text, normally this should poll or use shared vars!
|
||||
info = f"""
|
||||
KW1FOX-1
|
||||
Online!
|
||||
Volt: N/A
|
||||
Last comm: {int(time.time())}
|
||||
|
||||
KW1FOX-2
|
||||
Offline.
|
||||
Volt: N/A
|
||||
Last comm: N/A
|
||||
|
||||
KW1FOX-3
|
||||
Offline.
|
||||
Volt: N/A
|
||||
Last comm: N/A
|
||||
|
||||
Currently Showing:
|
||||
KW1FOX-1
|
||||
NOCOM
|
||||
NOMETA
|
||||
"""
|
||||
|
||||
# Draw text
|
||||
draw = ImageDraw.Draw(frame)
|
||||
draw.text((960 + 10, 10), info, font=self.font, align="left")
|
||||
|
||||
return frame
|
||||
|
||||
def stream(self):
|
||||
"""
|
||||
Actually streams!
|
||||
"""
|
||||
|
||||
while True:
|
||||
self.drawGraphics(self.getFrame()).save(self.pipe.stdin, "PNG")
|
||||
|
||||
def __del__(self):
|
||||
self.dsp.close()
|
||||
|
||||
self.pipe.stdin.close()
|
||||
self.pipe.wait()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
myStreamer = Streamer()
|
||||
|
||||
# myStreamer.drawGraphics(Image.open("../../Resources/KW1FOX-1_320x240.png")).show()
|
||||
myStreamer.stream()
|
||||
13
Software/houston/notes.md
Normal file
13
Software/houston/notes.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Notes
|
||||
|
||||
Taking some inspiration from this repo: https://github.com/xssfox/sstv-skimmer/blob/main/Dockerfile
|
||||
|
||||
## Installing qsstv and pulseaudio on server
|
||||
|
||||
Requires `houston` user
|
||||
|
||||
as well as qsstv (obvio)
|
||||
|
||||
and i should prolly install `pulseaudio` as well
|
||||
|
||||
Also, i edited the xorg.conf so it never times out.
|
||||
8
Software/houston/qsstv.service
Normal file
8
Software/houston/qsstv.service
Normal file
@@ -0,0 +1,8 @@
|
||||
[Unit]
|
||||
Description=Runs a qsstv instance as houston with houston's config
|
||||
|
||||
[Service]
|
||||
ExecStart=sudo su -l houston -c "/opt/radio/lewis-crawler/Software/houston/sstv.sh"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
199
Software/houston/qsstv_9.0.conf
Normal file
199
Software/houston/qsstv_9.0.conf
Normal file
@@ -0,0 +1,199 @@
|
||||
[CW]
|
||||
cwWPM=12
|
||||
cwtext=
|
||||
cwtone=800
|
||||
|
||||
[DIRECTORIES]
|
||||
audioPath=/home/parallels/qsstv/audio/
|
||||
docURL=http://users.telenet.be/on4qz/qsstv/manual
|
||||
rxDRMImagesPath=/tmp/rx_images
|
||||
rxSSTVImagesPath=/tmp/rx_images
|
||||
saveTXimages=false
|
||||
templatesPath=/home/parallels/qsstv/templates/
|
||||
txDRMImagesPath=/home/parallels/qsstv/tx_drm/
|
||||
txSSTVImagesPath=/home/parallels/qsstv/tx_sstv/
|
||||
txStockImagesPath=/home/parallels/qsstv/tx_stock/
|
||||
|
||||
[DRMPROFILE]
|
||||
drmPF1Bandwidth=0
|
||||
drmPF1Interleave=0
|
||||
drmPF1Mode=0
|
||||
drmPF1Name=Profile 1
|
||||
drmPF1Protection=0
|
||||
drmPF1QAM=0
|
||||
drmPF1ReedSolomon=0
|
||||
drmPF2Bandwidth=0
|
||||
drmPF2Interleave=0
|
||||
drmPF2Mode=0
|
||||
drmPF2Name=Profile 2
|
||||
drmPF2Protection=0
|
||||
drmPF2QAM=0
|
||||
drmPF2ReedSolomon=0
|
||||
drmPF3Bandwidth=0
|
||||
drmPF3Interleave=0
|
||||
drmPF3Mode=0
|
||||
drmPF3Name=Profile 3
|
||||
drmPF3Protection=0
|
||||
drmPF3QAM=0
|
||||
drmPF3ReedSolomon=0
|
||||
|
||||
[FREQSELECT]
|
||||
additionalCommand=
|
||||
additionalCommandHex=false
|
||||
frequencyList=@Invalid()
|
||||
modeList=@Invalid()
|
||||
passBandList=@Invalid()
|
||||
sbModeList=@Invalid()
|
||||
|
||||
[FTPCONFIG]
|
||||
addExtension=false
|
||||
enableFTP=false
|
||||
ftpDefaultImageFormat=png
|
||||
ftpLogin=
|
||||
ftpNumImages=30
|
||||
ftpPassword=
|
||||
ftpPort=21
|
||||
ftpRemoteDRMDirectory=
|
||||
ftpRemoteHost=
|
||||
ftpRemoteSSTVDirectory=
|
||||
ftpSaveFormat=0
|
||||
|
||||
[GUI]
|
||||
backGroundColor=@Variant(\0\0\0\x43\x1\xff\xff\0\0VV\xe6\xe6\0\0)
|
||||
confirmClose=true
|
||||
confirmDeletion=true
|
||||
galleryColumns=4
|
||||
galleryRows=4
|
||||
imageBackGroundColor=@Variant(\0\0\0\x43\x1\xff\xff\x80\x80\x80\x80\x80\x80\0\0)
|
||||
imageStretch=true
|
||||
lowRes=false
|
||||
slowCPU=false
|
||||
|
||||
[HYBRID]
|
||||
enableHybridNotify=true
|
||||
enableHybridRx=true
|
||||
hybridFtpHybridFilesDirectory=HybridFiles1
|
||||
hybridFtpLogin=
|
||||
hybridFtpPassword=
|
||||
hybridFtpPort=21
|
||||
hybridFtpRemoteDirectory=
|
||||
hybridFtpRemoteHost=
|
||||
hybridNotifyDir=RxOkNotifications1
|
||||
onlineStatusDir=OnlineCallsigns1
|
||||
|
||||
[MAIN]
|
||||
transmissionModeIndex=0
|
||||
windowHeight=768
|
||||
windowWidth=1024
|
||||
windowX=0
|
||||
windowY=0
|
||||
|
||||
[PERSONAL]
|
||||
callsign=NOCALL
|
||||
firstname=NOFIRSTNAME
|
||||
lastname=NONAME
|
||||
locator=NOLOCATOR
|
||||
onlinestatusenabled=true
|
||||
onlinestatustext=
|
||||
qth=NOWHERE
|
||||
|
||||
[REPEATER]
|
||||
repeaterAcknowledge=
|
||||
repeaterEnabled=false
|
||||
repeaterIdleTemplate=
|
||||
repeaterIdleTxMode=0
|
||||
repeaterImage1=
|
||||
repeaterImage2=
|
||||
repeaterImage3=
|
||||
repeaterImage4=
|
||||
repeaterImageInterval=10
|
||||
repeaterImageSize=10
|
||||
repeaterTemplate=
|
||||
repeaterTxDelay=5
|
||||
repeaterTxMode=0
|
||||
|
||||
[RX]
|
||||
autoSave=true
|
||||
autoSlantAdjust=true
|
||||
defaultImageFormat=png
|
||||
minCompletion=50
|
||||
sensitivity=2
|
||||
sstvModeIndexRx=10
|
||||
|
||||
[SOUND]
|
||||
alsaSelected=false
|
||||
inputAudioDevice=default -- Playback/recording through the PulseAudio sound server
|
||||
outputAudioDevice=default -- Playback/recording through the PulseAudio sound server
|
||||
pttToneOtherChannel=false
|
||||
pulseSelected=true
|
||||
recordingSize=100
|
||||
rxclock=48000
|
||||
soundRoutingInput=0
|
||||
soundRoutingOutput=0
|
||||
swapChannel=false
|
||||
txclock=48000
|
||||
|
||||
[SPECTRUM]
|
||||
avg=0.9
|
||||
maxdb=-25
|
||||
range=35
|
||||
|
||||
[TX]
|
||||
compressedSize=5000
|
||||
drmBandWith=0
|
||||
drmInterLeaver=0
|
||||
drmProtection=0
|
||||
drmQAM=0
|
||||
drmReedSolomon=0
|
||||
drmRobMode=0
|
||||
sstvModeIndexTx=0
|
||||
templateIndex=-1
|
||||
useCW=false
|
||||
useHybrid=false
|
||||
useTemplate=false
|
||||
useVOX=false
|
||||
|
||||
[WATERFALL]
|
||||
bsrWF=BSR
|
||||
endBinWF=END BIN
|
||||
endPicWF=END PIC
|
||||
endRepeaterWF=END RPT
|
||||
fixWF=FIX
|
||||
sampleString=Sample Text
|
||||
startBinWF=START BIN
|
||||
startPicWF=START PIC
|
||||
startRepeaterWF=START RPT
|
||||
wfBold=false
|
||||
wfFont=Aharoni CLM
|
||||
wfFontSize=12
|
||||
|
||||
[Waterfall]
|
||||
text1=rest
|
||||
text2=
|
||||
text3=
|
||||
text4=
|
||||
|
||||
[logging]
|
||||
deduplicate=true
|
||||
maskBA="@Variant(\0\0\0\r\0\0\0,\0\0\0\0\0\0)"
|
||||
|
||||
[radio1]
|
||||
XMLRPCPort=7362
|
||||
activeDTR=false
|
||||
activeRTS=true
|
||||
baudrate=9600
|
||||
civAddress=
|
||||
databits=8
|
||||
enableCAT=false
|
||||
enableSerialPTT=false
|
||||
enableXMLRPC=false
|
||||
handshake=None
|
||||
nactiveDTR=false
|
||||
nactiveRTS=false
|
||||
parity=None
|
||||
pttSerialPort=/dev/ttyS0
|
||||
pttType=1
|
||||
radioModel="29001 ADAT www.adat.ch,ADT-200A"
|
||||
serialPort=/dev/ttyS0
|
||||
stopbits=1
|
||||
txOnDelay=0
|
||||
9
Software/houston/robotstreamer.service
Normal file
9
Software/houston/robotstreamer.service
Normal file
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Runs the robotstreamer stream
|
||||
|
||||
[Service]
|
||||
ExecStart=sudo su -l houston -c "/opt/radio/lewis-crawler/Software/houston/stream.sh"
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
12
Software/houston/sstv.sh
Executable file
12
Software/houston/sstv.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Runs all the required fluff for spawning qsstv with notifing and stuff.
|
||||
|
||||
# Make tempdirs
|
||||
mkdir -p /tmp/sstv_images
|
||||
|
||||
# Copy config file
|
||||
cp /opt/radio/lewis-crawler/Software/houston/qsstv_9.0.conf ~/.config/ON4QZ/qsstv_9.0.conf
|
||||
|
||||
# Spawn qsstv
|
||||
xinit -geometry =1280x960+0+0 -fn 8x13 -j -fg white -bg black qsstv -- -nocursor
|
||||
5
Software/houston/stream.sh
Executable file
5
Software/houston/stream.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Runs the robotstream
|
||||
cd /opt/radio/lewis-crawler/Software/houston/ && pipenv run python RobotStreamer.py
|
||||
|
||||
15
Software/kw1fox-2/Pipfile
Normal file
15
Software/kw1fox-2/Pipfile
Normal file
@@ -0,0 +1,15 @@
|
||||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
pysstv = "*"
|
||||
pillow = "*"
|
||||
pyaudio = "*"
|
||||
pi-ina219 = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3.10"
|
||||
121
Software/kw1fox-2/Pipfile.lock
generated
Normal file
121
Software/kw1fox-2/Pipfile.lock
generated
Normal file
@@ -0,0 +1,121 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "377233137977bb1db670b363317a6a2619ddd8544f91531a5224826022fa3e23"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.10"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"adafruit-gpio": {
|
||||
"hashes": [
|
||||
"sha256:d6465b92c866c51ca8f3bc1e8f2ec36f5ccdb46d0fd54101c1109756d4a2dcd0"
|
||||
],
|
||||
"version": "==1.0.3"
|
||||
},
|
||||
"adafruit-pureio": {
|
||||
"hashes": [
|
||||
"sha256:2caf22fb07c7f771d83267f331a76cde314723f884a9570ea6f768730c87a879"
|
||||
],
|
||||
"markers": "python_full_version >= '3.5.0'",
|
||||
"version": "==1.1.9"
|
||||
},
|
||||
"mock": {
|
||||
"hashes": [
|
||||
"sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62",
|
||||
"sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==4.0.3"
|
||||
},
|
||||
"pi-ina219": {
|
||||
"hashes": [
|
||||
"sha256:29524cc308c56a5c483f551187923d3e167f2d39a29dc64c731ba7a8e04d022b"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.4.0"
|
||||
},
|
||||
"pillow": {
|
||||
"hashes": [
|
||||
"sha256:01ce45deec9df310cbbee11104bae1a2a43308dd9c317f99235b6d3080ddd66e",
|
||||
"sha256:0c51cb9edac8a5abd069fd0758ac0a8bfe52c261ee0e330f363548aca6893595",
|
||||
"sha256:17869489de2fce6c36690a0c721bd3db176194af5f39249c1ac56d0bb0fcc512",
|
||||
"sha256:21dee8466b42912335151d24c1665fcf44dc2ee47e021d233a40c3ca5adae59c",
|
||||
"sha256:25023a6209a4d7c42154073144608c9a71d3512b648a2f5d4465182cb93d3477",
|
||||
"sha256:255c9d69754a4c90b0ee484967fc8818c7ff8311c6dddcc43a4340e10cd1636a",
|
||||
"sha256:35be4a9f65441d9982240e6966c1eaa1c654c4e5e931eaf580130409e31804d4",
|
||||
"sha256:3f42364485bfdab19c1373b5cd62f7c5ab7cc052e19644862ec8f15bb8af289e",
|
||||
"sha256:3fddcdb619ba04491e8f771636583a7cc5a5051cd193ff1aa1ee8616d2a692c5",
|
||||
"sha256:463acf531f5d0925ca55904fa668bb3461c3ef6bc779e1d6d8a488092bdee378",
|
||||
"sha256:4fe29a070de394e449fd88ebe1624d1e2d7ddeed4c12e0b31624561b58948d9a",
|
||||
"sha256:55dd1cf09a1fd7c7b78425967aacae9b0d70125f7d3ab973fadc7b5abc3de652",
|
||||
"sha256:5a3ecc026ea0e14d0ad7cd990ea7f48bfcb3eb4271034657dc9d06933c6629a7",
|
||||
"sha256:5cfca31ab4c13552a0f354c87fbd7f162a4fafd25e6b521bba93a57fe6a3700a",
|
||||
"sha256:66822d01e82506a19407d1afc104c3fcea3b81d5eb11485e593ad6b8492f995a",
|
||||
"sha256:69e5ddc609230d4408277af135c5b5c8fe7a54b2bdb8ad7c5100b86b3aab04c6",
|
||||
"sha256:6b6d4050b208c8ff886fd3db6690bf04f9a48749d78b41b7a5bf24c236ab0165",
|
||||
"sha256:7a053bd4d65a3294b153bdd7724dce864a1d548416a5ef61f6d03bf149205160",
|
||||
"sha256:82283af99c1c3a5ba1da44c67296d5aad19f11c535b551a5ae55328a317ce331",
|
||||
"sha256:8782189c796eff29dbb37dd87afa4ad4d40fc90b2742704f94812851b725964b",
|
||||
"sha256:8d79c6f468215d1a8415aa53d9868a6b40c4682165b8cb62a221b1baa47db458",
|
||||
"sha256:97bda660702a856c2c9e12ec26fc6d187631ddfd896ff685814ab21ef0597033",
|
||||
"sha256:a325ac71914c5c043fa50441b36606e64a10cd262de12f7a179620f579752ff8",
|
||||
"sha256:a336a4f74baf67e26f3acc4d61c913e378e931817cd1e2ef4dfb79d3e051b481",
|
||||
"sha256:a598d8830f6ef5501002ae85c7dbfcd9c27cc4efc02a1989369303ba85573e58",
|
||||
"sha256:a5eaf3b42df2bcda61c53a742ee2c6e63f777d0e085bbc6b2ab7ed57deb13db7",
|
||||
"sha256:aea7ce61328e15943d7b9eaca87e81f7c62ff90f669116f857262e9da4057ba3",
|
||||
"sha256:af79d3fde1fc2e33561166d62e3b63f0cc3e47b5a3a2e5fea40d4917754734ea",
|
||||
"sha256:c24f718f9dd73bb2b31a6201e6db5ea4a61fdd1d1c200f43ee585fc6dcd21b34",
|
||||
"sha256:c5b0ff59785d93b3437c3703e3c64c178aabada51dea2a7f2c5eccf1bcf565a3",
|
||||
"sha256:c7110ec1701b0bf8df569a7592a196c9d07c764a0a74f65471ea56816f10e2c8",
|
||||
"sha256:c870193cce4b76713a2b29be5d8327c8ccbe0d4a49bc22968aa1e680930f5581",
|
||||
"sha256:c9efef876c21788366ea1f50ecb39d5d6f65febe25ad1d4c0b8dff98843ac244",
|
||||
"sha256:de344bcf6e2463bb25179d74d6e7989e375f906bcec8cb86edb8b12acbc7dfef",
|
||||
"sha256:eb1b89b11256b5b6cad5e7593f9061ac4624f7651f7a8eb4dfa37caa1dfaa4d0",
|
||||
"sha256:ed742214068efa95e9844c2d9129e209ed63f61baa4d54dbf4cf8b5e2d30ccf2",
|
||||
"sha256:f401ed2bbb155e1ade150ccc63db1a4f6c1909d3d378f7d1235a44e90d75fb97",
|
||||
"sha256:fb89397013cf302f282f0fc998bb7abf11d49dcff72c8ecb320f76ea6e2c5717"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==9.1.0"
|
||||
},
|
||||
"pyaudio": {
|
||||
"hashes": [
|
||||
"sha256:0d92f6a294565260a282f7c9a0b0d309fc8cc988b5ee5b50645634ab9e2da7f7",
|
||||
"sha256:259bb9c1363be895b4f9a97e320a6017dd06bc540728c1a04eb4a7b6fe75035b",
|
||||
"sha256:2a19bdb8ec1445b4f3e4b7b109e0e4cec1fd1f1ce588592aeb6db0b58d4fb3b0",
|
||||
"sha256:51b558d1b28c68437b53218279110db44f69f3f5dd3d81859f569a4a96962bdc",
|
||||
"sha256:589bfad2c615dd4b5d3757e763019c42ab82f06fba5cae64ec02fd7f5ae407ed",
|
||||
"sha256:8f89075b4844ea94dde0c951c2937581c989fabd4df09bfd3f075035f50955df",
|
||||
"sha256:93bfde30e0b64e63a46f2fd77e85c41fd51182a4a3413d9edfaf9ffaa26efb74",
|
||||
"sha256:cf1543ba50bd44ac0d0ab5c035bb9c3127eb76047ff12235149d9adf86f532b6",
|
||||
"sha256:f78d543a98b730e64621ebf7f3e2868a79ade0a373882ef51c0293455ffa8e6e"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.2.11"
|
||||
},
|
||||
"pysstv": {
|
||||
"hashes": [
|
||||
"sha256:a0306ff80bb25f28c4455c9dd75dd8cebbb3fa7d77b87af18e6cf2b86ade6b47"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.5.4"
|
||||
},
|
||||
"spidev": {
|
||||
"hashes": [
|
||||
"sha256:8a7f5c289f161ea2ac4697fa8a10918232c990678dd0053084b3c43b1363910d"
|
||||
],
|
||||
"version": "==3.5"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
||||
3
Software/kw1fox-2/README.md
Normal file
3
Software/kw1fox-2/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# KW1FOX-2 Software
|
||||
|
||||
This is the software for KW1FOX-2, the APRS/SSTV relay station.
|
||||
0
Software/kw1fox-2/__init__.py
Normal file
0
Software/kw1fox-2/__init__.py
Normal file
29
Software/kw1fox-2/kw1fox-2.py
Normal file
29
Software/kw1fox-2/kw1fox-2.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from PIL import Image
|
||||
|
||||
from pysstv.color import Robot36
|
||||
|
||||
from tools.pyaudio import PyAudioSSTV
|
||||
|
||||
|
||||
class kw1fox2:
|
||||
def __init__(self, sim=False):
|
||||
# Lets us automate more testing locally by having a program-wide sim mode.
|
||||
self.sim = sim
|
||||
|
||||
img = Image.open("../../Resources/KW1FOX-1_320x240.png")
|
||||
self.sstv = Robot36(img, 44100, 16)
|
||||
self.sstv.vox_enabled = True
|
||||
|
||||
self.sstv.write_wav("Mysstv.wav")
|
||||
|
||||
def run(self):
|
||||
PyAudioSSTV(self.sstv).execute()
|
||||
|
||||
def take_snapshot(self):
|
||||
if not self.sim:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
station = kw1fox2()
|
||||
station.run()
|
||||
0
Software/kw1fox-2/tools/__init__.py
Normal file
0
Software/kw1fox-2/tools/__init__.py
Normal file
43
Software/kw1fox-2/tools/pyaudio.py
Normal file
43
Software/kw1fox-2/tools/pyaudio.py
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Example code from here: https://github.com/dnet/pySSTV/blob/master/pysstv/examples/pyaudio_sstv.py
|
||||
"""
|
||||
|
||||
|
||||
from __future__ import division
|
||||
from pysstv.sstv import SSTV
|
||||
from time import sleep
|
||||
from itertools import islice
|
||||
import struct, pyaudio
|
||||
|
||||
|
||||
class PyAudioSSTV(object):
|
||||
def __init__(self, sstv):
|
||||
self.pa = pyaudio.PyAudio()
|
||||
self.sstv = sstv
|
||||
self.fmt = "<" + SSTV.BITS_TO_STRUCT[sstv.bits]
|
||||
|
||||
def __del__(self):
|
||||
self.pa.terminate()
|
||||
|
||||
def execute(self):
|
||||
self.sampler = self.sstv.gen_samples()
|
||||
stream = self.pa.open(
|
||||
format=self.pa.get_format_from_width(self.sstv.bits // 8),
|
||||
channels=1,
|
||||
rate=self.sstv.samples_per_sec,
|
||||
output=True,
|
||||
stream_callback=self.callback,
|
||||
)
|
||||
stream.start_stream()
|
||||
while stream.is_active():
|
||||
sleep(0.5)
|
||||
stream.stop_stream()
|
||||
stream.close()
|
||||
|
||||
def callback(self, in_data, frame_count, time_info, status):
|
||||
frames = "".join(
|
||||
struct.pack(self.fmt, b) for b in islice(self.sampler, frame_count)
|
||||
)
|
||||
return frames, pyaudio.paContinue
|
||||
@@ -1,23 +0,0 @@
|
||||
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.
Binary file not shown.
@@ -1,70 +0,0 @@
|
||||
### DISCLAIMER
|
||||
### This is an example Makefile and it MUST be configured to suit your needs.
|
||||
### For detailed explanations about all the available options,
|
||||
### please refer to https://github.com/sudar/Arduino-Makefile/blob/master/arduino-mk-vars.md
|
||||
|
||||
### PROJECT_DIR
|
||||
### This is the path to where you have created/cloned your project
|
||||
PROJECT_DIR = $(shell dirname $(shell pwd))
|
||||
|
||||
### ARDMK_DIR
|
||||
### Path to the Arduino-Makefile directory.
|
||||
ARDMK_DIR = $(PROJECT_DIR)/Arduino-Makefile
|
||||
|
||||
### ARDUINO_DIR
|
||||
### Path to the Arduino application and resources directory.
|
||||
ARDUINO_DIR = /usr/share/arduino
|
||||
|
||||
### USER_LIB_PATH
|
||||
### Path to where the your project's libraries are stored.
|
||||
USER_LIB_PATH := $(realpath $(PROJECT_DIR)/lib)
|
||||
|
||||
### BOARD_TAG & BOARD_SUB
|
||||
### 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
|
||||
### The port your board is connected to. Using an '*' tries all the ports and finds the right one. Choose one of the two.
|
||||
MONITOR_PORT = /dev/ttyUSB*
|
||||
# MONITOR_PORT = /dev/ttyACM*
|
||||
|
||||
### MONITOR_BAUDRATE
|
||||
### It must be set to Serial baudrate value you are using.
|
||||
MONITOR_BAUDRATE = 115200
|
||||
|
||||
### AVR_TOOLS_DIR
|
||||
### Path to the AVR tools directory such as avr-gcc, avr-g++, etc.
|
||||
AVR_TOOLS_DIR = /usr
|
||||
|
||||
### 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
|
||||
@@ -1,63 +0,0 @@
|
||||
/* Crawler Slave
|
||||
*
|
||||
* This code runs on the crawler i2c network
|
||||
* and provides a cleaner, less CPU intensive control over PWM devices.
|
||||
*/
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Servo.h>
|
||||
|
||||
// This servo is used to wipe and clean the camera lens
|
||||
Servo windowWiperServo;
|
||||
|
||||
// Variables populated over i2c from master
|
||||
int id;
|
||||
int val;
|
||||
|
||||
void setup() {
|
||||
// For debugging
|
||||
//Serial.begin(115200);
|
||||
|
||||
// Attach the wiper servo to pin 9
|
||||
windowWiperServo.attach(9);
|
||||
|
||||
// This is the address the pi will speak to us at
|
||||
Wire.begin(0x4);
|
||||
|
||||
// Call receiveEvent when data received
|
||||
Wire.onReceive(receiveEvent);
|
||||
|
||||
// Setup LED
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
|
||||
//Serial.println("Started");
|
||||
}
|
||||
|
||||
// Just loop to keep the running code alive, and wait for events to happen.
|
||||
void loop() {
|
||||
delay(50);
|
||||
}
|
||||
|
||||
// This method runs when we receive a message
|
||||
void receiveEvent(int n) {
|
||||
Wire.read(); // Remove smbus trash
|
||||
if (true) { // Dont do anything if this is not true
|
||||
id = Wire.read(); // ID of the servo/device to access
|
||||
val = Wire.read(); // Value to assign
|
||||
|
||||
//Serial.println(id);
|
||||
//Serial.println(val);
|
||||
|
||||
switch(id) {
|
||||
case 1:
|
||||
windowWiperServo.write(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevents a bug where if bytes are left in buffer, arduino crashes.
|
||||
while (Wire.available()) {
|
||||
Wire.read();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
wiper_servo:
|
||||
pin: 17
|
||||
min_pulse: 0.000544
|
||||
max_pulse: 0.0024
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
[Unit]
|
||||
Description=Crawler service overseer, manages running main crawler software
|
||||
After=multi-user.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=always
|
||||
ExecStart=/usr/bin/python /srv/crawler/crawler.py
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,2 +0,0 @@
|
||||
PySSTV
|
||||
picamera
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB |
@@ -1,87 +0,0 @@
|
||||
from shutil import copyfile
|
||||
from PIL import Image, ImageFont, ImageDraw
|
||||
from pysstv import color
|
||||
|
||||
import logging as log
|
||||
|
||||
try:
|
||||
from picamera import PiCamera
|
||||
except ModuleNotFoundError:
|
||||
log.info("Running in simulator mode")
|
||||
|
||||
|
||||
def take_photo():
|
||||
# This def is meant to take a photograph from the robot,
|
||||
# it should include all steps and error checking to raise the mast
|
||||
# Take the photo, and put the mast down.
|
||||
|
||||
# Copy in the test pattern png (if photo process errors out, this will be used instead)
|
||||
log.debug('Copying test pattern.')
|
||||
copyfile('photos/TEST_PATTERN.jpg', 'working/working.jpg')
|
||||
|
||||
# Software to take the photo should be here
|
||||
#copyfile('photos/camera_latest.jpg', 'working/working.jpg')
|
||||
log.debug('Initalizing camera.')
|
||||
try:
|
||||
camera = PiCamera()
|
||||
log.info('Saving photo.')
|
||||
camera.capture('working/working.jpg')
|
||||
except NameError:
|
||||
log.info("Running in simulator mode, not replacing test pattern")
|
||||
|
||||
def mark_photo():
|
||||
log.info('Opening photo for viewing.')
|
||||
raw_img = Image.open("working/working.jpg") # Open the current working image
|
||||
log.info('Resizing image.')
|
||||
img = raw_img.resize((320, 240), Image.ANTIALIAS) # resize it for the radio
|
||||
|
||||
log.info('Drawing on image.')
|
||||
if False:
|
||||
TINT_COLOR = (255, 255, 255) # White text bg
|
||||
TEXT_COLOR = (0,0,0)
|
||||
else:
|
||||
TINT_COLOR = (0, 0, 0) # Black text bg
|
||||
TEXT_COLOR = (255,255,255)
|
||||
TRANSPARENCY = .25 # Degree of transparency, 0-100%
|
||||
OPACITY = int(255 * TRANSPARENCY)
|
||||
overlay = Image.new('RGBA', img.size, TINT_COLOR+(0,))
|
||||
|
||||
draw = ImageDraw.Draw(overlay)
|
||||
#bigfont = ImageFont.truetype(r'C:\Users\System-Pc\Desktop\arial.ttf', 20)
|
||||
#smallfont = ImageFont.truetype(r'C:\Users\System-Pc\Desktop\arial.ttf', 17)
|
||||
|
||||
draw.rectangle(((0, 0), (90, 20)), fill=TINT_COLOR+(OPACITY,))
|
||||
#draw.text((0, 0),"KW1FOX",TEXT_COLOR,font=bigfont) # Draw KW1FOX in the top left
|
||||
|
||||
draw.rectangle(((0, 40), (83, 80)), fill=TINT_COLOR+(OPACITY,))
|
||||
#draw.text((0, 40),"day: 25.2",TEXT_COLOR,font=smallfont)
|
||||
#draw.text((0, 60),"Volt: 13.8",TEXT_COLOR,font=smallfont)
|
||||
#draw.text((0, 80),"Miles: 1.02",TEXT_COLOR,font=smallfont)
|
||||
|
||||
log.info('Converting image color.')
|
||||
img = img.convert("RGBA")
|
||||
img = Image.alpha_composite(img, overlay)
|
||||
img = img.convert("RGB")
|
||||
img.save('working/working.jpg') # Save the working image
|
||||
return img
|
||||
|
||||
if __name__ == "__main__":
|
||||
log.basicConfig(level=log.DEBUG)
|
||||
|
||||
# Take photograph.
|
||||
log.info('Taking Photograph')
|
||||
take_photo() # Saves a photograph to the working/working.jpg location
|
||||
log.info('Done taking photo.')
|
||||
|
||||
# Draw neccicary text on photo
|
||||
log.info('Drawing on photo.')
|
||||
radio_photo = mark_photo() # draws text on working/working.jpg and returns a PIL image
|
||||
log.info('Done drawing on photo.')
|
||||
|
||||
log.info('Creating slowscan.')
|
||||
slowscan = color.Robot36(radio_photo, 48000, 16) # Image, rate, bits
|
||||
#slowscan = color.MartinM1(radio_photo, 48000, 16) # Image, rate, bits
|
||||
log.info('Saving out slowscan.')
|
||||
slowscan.write_wav('working/working.wav')
|
||||
|
||||
#sstv('working/working.png', 'working/radio.wav', mode='Robot36')
|
||||
@@ -1,73 +0,0 @@
|
||||
from discord_webhook import DiscordWebhook
|
||||
from picamera import PiCamera
|
||||
from time import sleep
|
||||
from gps import *
|
||||
from smbus import SMBus
|
||||
import time
|
||||
|
||||
addr = 0x4 # bus address
|
||||
bus = SMBus(1) # indicates /dev/ic2-1
|
||||
|
||||
numb = 1
|
||||
|
||||
def writeData(value):
|
||||
byteValue = StringToBytes(value)
|
||||
bus.write_i2c_block_data(addr,0x00,byteValue) #first byte is 0=command byte.. just is.
|
||||
return -1
|
||||
|
||||
|
||||
def StringToBytes(val):
|
||||
retVal = []
|
||||
for c in val:
|
||||
retVal.append(ord(c))
|
||||
return retVal
|
||||
|
||||
try:
|
||||
for _x in range (0, 2):
|
||||
for i in range(78, 130):
|
||||
writeData("WIPE-" + str(i))
|
||||
time.sleep(0.02)
|
||||
for i in range(130, 78, -1):
|
||||
writeData("WIPE-" + str(i))
|
||||
time.sleep(0.02)
|
||||
except OSError:
|
||||
print("Could not speak to ardujmemo")
|
||||
|
||||
def get_uptime():
|
||||
with open('/proc/uptime', 'r') as f:
|
||||
uptime_seconds = float(f.readline().split()[0])
|
||||
|
||||
return uptime_seconds
|
||||
|
||||
def getPositionData(gps):
|
||||
location = [None]
|
||||
while(location[0] == None):
|
||||
print("Trying again")
|
||||
nx = gpsd.next()
|
||||
# For a list of all supported classes and fields refer to:
|
||||
# https://gpsd.gitlab.io/gpsd/gpsd_json.html
|
||||
if nx['class'] == 'TPV':
|
||||
latitude = getattr(nx,'lat', "Unknown")
|
||||
longitude = getattr(nx,'lon', "Unknown")
|
||||
#print "Your position: lon = " + str(longitude) + ", lat = " + str(latitude)
|
||||
location = [latitude, longitude]
|
||||
return location
|
||||
|
||||
gpsd = gps(mode=WATCH_ENABLE|WATCH_NEWSTYLE)
|
||||
|
||||
loc = getPositionData(gpsd)
|
||||
|
||||
webhookURL = "https://discord.com/api/webhooks/856609966404534272/TR9tnLq2sIGZoOeADNswmGRNlzBcqM5aKihfU6snVTP9WhSSoVVvi7nT6i-ZfZS7Hcqm"
|
||||
|
||||
print(loc[0])
|
||||
print(loc[1])
|
||||
webhook = DiscordWebhook(url=webhookURL, content="Uptime: " + str( round( ((get_uptime() / 60) / 60 ), 2 )) + " hours. Lat is " + str(loc[0]) + ", long is " + str(loc[1]))
|
||||
|
||||
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
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
servoPIN = 17
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setup(servoPIN, GPIO.OUT)
|
||||
|
||||
p = GPIO.PWM(servoPIN, 50) # GPIO 17 for PWM with 50Hz
|
||||
p.start(2.5) # Initialization
|
||||
try:
|
||||
while True:
|
||||
p.ChangeDutyCycle(10)
|
||||
time.sleep(2)
|
||||
p.ChangeDutyCycle(2.5)
|
||||
time.sleep(2)
|
||||
except KeyboardInterrupt:
|
||||
p.stop()
|
||||
GPIO.cleanup()
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import smbus
|
||||
import time
|
||||
import struct
|
||||
|
||||
# for RPI version 1, use bus = smbus.SMBus(0)
|
||||
bus = smbus.SMBus(1)
|
||||
|
||||
# This is the address we setup in the Arduino Program
|
||||
address = 0x04
|
||||
|
||||
try:
|
||||
for _x in range (0, 2):
|
||||
for i in range(78, 130):
|
||||
bus.write_i2c_block_data(address, 0, [1, i])
|
||||
time.sleep(0.02)
|
||||
for i in range(130, 78, -1):
|
||||
bus.write_i2c_block_data(address, 0, [1, i])
|
||||
time.sleep(0.02)
|
||||
except OSError:
|
||||
print("Could not speak to ardujmemo")
|
||||
@@ -1,35 +0,0 @@
|
||||
# Raspberry Pi Master for Arduino Slave
|
||||
# i2c_master_pi.py
|
||||
# Connects to Arduino via I2C
|
||||
|
||||
# DroneBot Workshop 2019
|
||||
# https://dronebotworkshop.com
|
||||
|
||||
from smbus import SMBus
|
||||
import time
|
||||
|
||||
addr = 0x8 # bus address
|
||||
bus = SMBus(1) # indicates /dev/ic2-1
|
||||
|
||||
numb = 1
|
||||
|
||||
print ("Enter num")
|
||||
|
||||
for _x in range (0, 4):
|
||||
for i in range(76, 130):
|
||||
bus.write_byte(addr, i)
|
||||
time.sleep(0.02)
|
||||
for i in range(130, 76, -1):
|
||||
bus.write_byte(addr, i)
|
||||
time.sleep(0.02)
|
||||
|
||||
#while numb == 1:
|
||||
#
|
||||
# ledstate = input(">>>> ")
|
||||
#
|
||||
# if ledstate == "1":
|
||||
# bus.write_byte(addr, 0x1) # switch it on
|
||||
# elif ledstate == "0":
|
||||
# bus.write_byte(addr, 0x0) # switch it on
|
||||
# else:
|
||||
# numb = 0
|
||||
@@ -1,12 +0,0 @@
|
||||
import RPi.GPIO as GPIO # Import Raspberry Pi GPIO library
|
||||
from time import sleep # Import the sleep function from the time module
|
||||
|
||||
GPIO.setwarnings(False) # Ignore warning for now
|
||||
GPIO.setmode(GPIO.BOARD) # Use physical pin numbering
|
||||
GPIO.setup(12, GPIO.OUT, initial=GPIO.LOW) # Set pin 8 to be an output pin and set initial value to low (off)
|
||||
|
||||
while True: # Run forever
|
||||
GPIO.output(12, GPIO.HIGH) # Turn on
|
||||
sleep(1) # Sleep for 1 second
|
||||
GPIO.output(12, GPIO.LOW) # Turn off
|
||||
sleep(1) # Sleep for 1 second
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.7 KiB |
Reference in New Issue
Block a user