├── .gitignore ├── .gitmodules ├── BBBSetup ├── BeagleboneBlackP8HeaderTable.pdf ├── BeagleboneBlackP9HeaderTable.pdf ├── README.md ├── adc_testing │ ├── README.md │ ├── generic_buffer.c │ ├── generic_buffer.c.orig │ ├── generic_buffer.patch │ ├── iio_utils.c │ ├── iio_utils.h │ └── simplified_buffer.c ├── beaglebone-black-pinout.jpg ├── copyAll ├── device_tree_overlays │ ├── BB-ADC-00A0.dts │ ├── BB-DCAN1-00A0.dts │ ├── BB-GPIO-01-00A0.dts │ ├── BB-PRU-01-00A0.dts │ ├── BB-PWM1-00A0.dts │ ├── BB-SPI-M-01-00A0.dts │ └── w1.dts ├── halt │ ├── .ccsproject │ ├── .cproject │ ├── .project │ ├── .settings │ │ ├── org.eclipse.cdt.codan.core.prefs │ │ └── org.eclipse.cdt.debug.core.prefs │ ├── AM335x_PRU.cmd │ ├── Debug │ │ └── halt.out │ ├── main.c │ └── resource_table_empty.h ├── initADC ├── initCAN ├── initGPIO ├── initPRU ├── pru-icss-5.1.0 │ ├── .gitignore │ ├── Makefile │ ├── ReadMe.txt │ ├── include │ │ ├── ReadMe.txt │ │ ├── am335x │ │ │ ├── pru_cfg.h │ │ │ ├── pru_ctrl.h │ │ │ ├── pru_ecap.h │ │ │ ├── pru_iep.h │ │ │ ├── pru_intc.h │ │ │ ├── pru_uart.h │ │ │ ├── sys_mailbox.h │ │ │ ├── sys_mcspi.h │ │ │ └── sys_pwmss.h │ │ ├── pru_rpmsg.h │ │ ├── pru_types.h │ │ ├── pru_virtio_ids.h │ │ ├── pru_virtio_ring.h │ │ ├── pru_virtqueue.h │ │ ├── rsc_types.h │ │ └── types.h │ └── lib │ │ ├── rpmsg_lib.lib │ │ └── src │ │ ├── Makefile │ │ └── rpmsg_lib │ │ ├── .ccsproject │ │ ├── .cproject │ │ ├── .project │ │ ├── .settings │ │ ├── org.eclipse.cdt.codan.core.prefs │ │ └── org.eclipse.cdt.debug.core.prefs │ │ ├── Makefile │ │ ├── pru_rpmsg.c │ │ └── pru_virtqueue.c ├── pru_encoder │ ├── .ccsproject │ ├── .cproject │ ├── .project │ ├── .settings │ │ ├── org.eclipse.cdt.codan.core.prefs │ │ └── org.eclipse.cdt.debug.core.prefs │ ├── AM335x_PRU.cmd │ ├── Debug │ │ └── pru_encoder.out │ ├── main.c │ ├── optical.h │ ├── resource_table_1.h │ └── targetConfigs │ │ ├── BeagleBone_Black.ccxml │ │ └── readme.txt ├── rpmsg_pru_user_space_echo.c └── setupOverlay ├── BaseStation ├── Backend │ ├── backend │ │ ├── __init__.py │ │ ├── settings.py │ │ ├── urls.py │ │ └── wsgi.py │ ├── db.sqlite3 │ ├── manage.py │ ├── podconnect │ │ ├── __init__.py │ │ ├── actions_logic.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── data_logic.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_auto_20190503_2002.py │ │ │ ├── 0003_auto_20190504_0202.py │ │ │ ├── 0004_auto_20190713_1727.py │ │ │ ├── 0005_auto_20190715_1948.py │ │ │ ├── 0006_auto_20190716_1821.py │ │ │ ├── 0007_auto_20190716_2159.py │ │ │ ├── 0008_auto_20190717_0051.py │ │ │ ├── 0009_auto_20190718_0022.py │ │ │ ├── 0010_connecteddata.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── space_x_packet.py │ │ ├── stats_helper.py │ │ ├── tcphelper.py │ │ ├── tcpsaver.py │ │ ├── tcpserver.py │ │ ├── tests.py │ │ ├── udp_dev.py │ │ ├── udpserver.py │ │ └── urls.py │ └── requirements.txt ├── README.md ├── frontend │ ├── .editorconfig │ ├── .gitignore │ ├── README.md │ ├── angular.json │ ├── browserslist │ ├── e2e │ │ ├── protractor.conf.js │ │ ├── src │ │ │ ├── app.e2e-spec.ts │ │ │ └── app.po.ts │ │ └── tsconfig.json │ ├── karma.conf.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── app-routing.module.ts │ │ │ ├── app.component.css │ │ │ ├── app.component.html │ │ │ ├── app.component.spec.ts │ │ │ ├── app.component.ts │ │ │ ├── app.module.ts │ │ │ ├── components │ │ │ │ ├── battery │ │ │ │ │ ├── battery.component.css │ │ │ │ │ ├── battery.component.html │ │ │ │ │ ├── battery.component.spec.ts │ │ │ │ │ └── battery.component.ts │ │ │ │ ├── buttons │ │ │ │ │ ├── buttons.component.css │ │ │ │ │ ├── buttons.component.html │ │ │ │ │ ├── buttons.component.spec.ts │ │ │ │ │ └── buttons.component.ts │ │ │ │ ├── diagnostics │ │ │ │ │ ├── diagnostics.component.css │ │ │ │ │ ├── diagnostics.component.html │ │ │ │ │ ├── diagnostics.component.spec.ts │ │ │ │ │ └── diagnostics.component.ts │ │ │ │ ├── launch │ │ │ │ │ ├── launch.component.css │ │ │ │ │ ├── launch.component.html │ │ │ │ │ ├── launch.component.spec.ts │ │ │ │ │ └── launch.component.ts │ │ │ │ ├── position │ │ │ │ │ ├── position.component.css │ │ │ │ │ ├── position.component.html │ │ │ │ │ ├── position.component.spec.ts │ │ │ │ │ └── position.component.ts │ │ │ │ ├── state │ │ │ │ │ ├── state.component.css │ │ │ │ │ ├── state.component.html │ │ │ │ │ ├── state.component.spec.ts │ │ │ │ │ └── state.component.ts │ │ │ │ ├── stats │ │ │ │ │ ├── stats.component.css │ │ │ │ │ ├── stats.component.html │ │ │ │ │ ├── stats.component.spec.ts │ │ │ │ │ └── stats.component.ts │ │ │ │ └── warning │ │ │ │ │ ├── warning.component.css │ │ │ │ │ ├── warning.component.html │ │ │ │ │ ├── warning.component.spec.ts │ │ │ │ │ └── warning.component.ts │ │ │ ├── models │ │ │ │ ├── battery.ts │ │ │ │ ├── diagnostics.ts │ │ │ │ ├── position.ts │ │ │ │ ├── stat.ts │ │ │ │ └── warning.ts │ │ │ └── services │ │ │ │ ├── battery.service.spec.ts │ │ │ │ ├── battery.service.ts │ │ │ │ ├── buttons.service.spec.ts │ │ │ │ ├── buttons.service.ts │ │ │ │ ├── diagnostics.service.spec.ts │ │ │ │ ├── diagnostics.service.ts │ │ │ │ ├── position.service.spec.ts │ │ │ │ ├── position.service.ts │ │ │ │ ├── state.service.spec.ts │ │ │ │ ├── state.service.ts │ │ │ │ ├── stats.service.spec.ts │ │ │ │ ├── stats.service.ts │ │ │ │ ├── warning.service.spec.ts │ │ │ │ └── warning.service.ts │ │ ├── assets │ │ │ ├── .gitkeep │ │ │ └── images │ │ │ │ └── Hyperloop.png │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── polyfills.ts │ │ ├── styles.css │ │ └── test.ts │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.spec.json │ └── tslint.json ├── install_requirements.sh ├── package-lock.json └── tools │ ├── bms_readout.py │ └── tcphelper.py ├── CentralComputing ├── .gitignore ├── ADCManager.cpp ├── ADCManager.h ├── Brakes.cpp ├── Brakes.h ├── CANManager.cpp ├── CANManager.h ├── Command.cpp ├── Command.h ├── Configurator.cpp ├── Configurator.h ├── Defines.hpp ├── Documentation │ ├── Topology.png │ └── Topology.xml ├── Event.cpp ├── Event.h ├── I2CManager.cpp ├── I2CManager.h ├── Makefile ├── MotionModel.cpp ├── MotionModel.h ├── Motor.cpp ├── Motor.h ├── PRUManager.cpp ├── PRUManager.h ├── Pod.cpp ├── Pod.h ├── Pod_State.cpp ├── Pod_State.h ├── README.md ├── SafeQueue.hpp ├── Simulator.cpp ├── Simulator.h ├── SourceManager.cpp ├── SourceManager.h ├── SourceManagerBase.hpp ├── StateMachineCompact │ ├── StateMachine.cpp │ └── StateMachine.h ├── TCPManager.cpp ├── TCPManager.h ├── UDPManager.cpp ├── UDPManager.h ├── Utils.cpp ├── Utils.h ├── commandtest.py ├── defaultConfig.txt ├── defaultFlightPlan.txt ├── navigationConfig.txt ├── navigationFlightPlan.txt ├── scenarios │ ├── Scenario.hpp │ ├── ScenarioRealLong.cpp │ ├── ScenarioRealLong.h │ ├── ScenarioTestTimeouts.cpp │ └── ScenarioTestTimeouts.h └── tests │ ├── AutoTests.cpp │ ├── ConfiguratorTest.cpp │ ├── ErrorFlagTests.cpp │ ├── MotionTests.cpp │ ├── MotorTest.cpp │ ├── PodTest.cpp │ ├── README.md │ ├── SafetyCriticalErrorTests.cpp │ ├── SensorDataErrorTests.cpp │ ├── StateTest.cpp │ ├── UtilsTest.cpp │ ├── VelocityTest.cpp │ ├── basicFlightPlan.txt │ ├── basicFlightPlan1.txt │ ├── duty_cycle │ ├── enable │ ├── realFlightPlan.txt │ ├── test.txt │ ├── velocity_basic.txt │ └── velocity_low_pass.txt ├── LICENSE.txt ├── README.md ├── Watchdog ├── Tiny_QuickRef_v2_2.pdf └── Watchdog.ino └── models └── numerical_integration ├── Emrax_Efficiency_Map.m ├── Motor_Dynamics.m ├── Plot_Torque_Curve.m ├── README.md ├── Torque_curve_reader.m ├── emrax_only.m ├── emrax_tp100.m └── purdue_model.m /.gitignore: -------------------------------------------------------------------------------- 1 | #Specific ignores 2 | build 3 | builds/ 4 | Release/ 5 | build 6 | dbuild 7 | sbuild 8 | cross 9 | dcross 10 | scross 11 | cross-nm 12 | cross-na 13 | dcross-nm 14 | dcross-na 15 | 16 | # Ignore vs code 17 | .vscode/ 18 | 19 | # Allowing .out files for PRU stuff 20 | BBBSetup/halt/Debug/* 21 | BBBSetup/pru_encoder/Debug/* 22 | !BBBSetup/halt/Debug/halt.out 23 | !BBBSetup/pru_encoder/Debug/pru_encoder.out 24 | 25 | # Visual Studio Code 26 | .vscode 27 | 28 | 29 | # Byte-compiled / optimized / DLL files 30 | __pycache__/ 31 | *.py[cod] 32 | *$py.class 33 | 34 | # C extensions 35 | *.so 36 | 37 | # Distribution / packaging 38 | .Python 39 | env/ 40 | build/ 41 | develop-eggs/ 42 | dist/ 43 | downloads/ 44 | eggs/ 45 | .eggs/ 46 | lib64/ 47 | parts/ 48 | sdist/ 49 | var/ 50 | *.egg-info/ 51 | .installed.cfg 52 | *.egg 53 | 54 | # PyInstaller 55 | # Usually these files are written by a python script from a template 56 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 57 | *.manifest 58 | *.spec 59 | 60 | # Installer logs 61 | pip-log.txt 62 | pip-delete-this-directory.txt 63 | 64 | # Unit test / coverage reports 65 | htmlcov/ 66 | .tox/ 67 | .coverage 68 | .coverage.* 69 | .cache 70 | nosetests.xml 71 | coverage.xml 72 | *,cover 73 | .hypothesis/ 74 | 75 | # Translations 76 | *.mo 77 | *.pot 78 | 79 | # Django stuff: 80 | *.log 81 | 82 | # Sphinx documentation 83 | docs/_build/ 84 | 85 | # PyBuilder 86 | target/ 87 | 88 | #Ipython Notebook 89 | .ipynb_checkpoints 90 | 91 | #MAC 92 | .DS_Store 93 | 94 | 95 | 96 | # Prerequisites 97 | *.d 98 | 99 | # Compiled Object files 100 | *.slo 101 | *.lo 102 | *.o 103 | *.obj 104 | *.dep 105 | 106 | # Precompiled Headers 107 | *.gch 108 | *.pch 109 | 110 | # Compiled Dynamic libraries 111 | *.so 112 | *.dylib 113 | *.dll 114 | 115 | # Fortran module files 116 | *.mod 117 | *.smod 118 | 119 | # Compiled Static libraries 120 | *.lai 121 | *.la 122 | *.a 123 | 124 | # Executables 125 | *.exe 126 | # *.out #disable to allow for pru execuitables 127 | *.app 128 | build 129 | build-debug 130 | build-test 131 | cross 132 | cross-debug 133 | cross-test 134 | 135 | # Other 136 | .depend 137 | *.swp 138 | BaseStation/Backend/db.sqlite3 139 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "CentralComputing/googletest"] 2 | path = CentralComputing/googletest 3 | url = https://github.com/google/googletest.git 4 | [submodule "CentralComputing/cpplint"] 5 | path = CentralComputing/cpplint 6 | url = https://github.com/google/styleguide 7 | -------------------------------------------------------------------------------- /BBBSetup/BeagleboneBlackP8HeaderTable.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/BBBSetup/BeagleboneBlackP8HeaderTable.pdf -------------------------------------------------------------------------------- /BBBSetup/BeagleboneBlackP9HeaderTable.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/BBBSetup/BeagleboneBlackP9HeaderTable.pdf -------------------------------------------------------------------------------- /BBBSetup/adc_testing/README.md: -------------------------------------------------------------------------------- 1 | This part of the guide assumes that the device trees are all appropriatly installed. 2 | 3 | The best technical guide will be the [Newest TI Reference.](http://processors.wiki.ti.com/index.php/Linux_Core_ADC_Users_Guide) However, the device tree was developed from the [older reference here.](https://www.teachmemicro.com/beaglebone-black-adc/) Although the installation steps are now wrong, the device tree should still be the same. 4 | 5 | ## Running the test application 6 | 7 | These are the development steps I took to figure out how to use the ADC properly. 8 | 9 | The 'older refernce' had some source code for a test executable that could setup and read from the ADCs streaming buffer. This is implemented through `generic_buffer.c`, which the site says was in kernel source at: `drivers/staging/iio/Documentation/`. They also provide a patch that removes hardware triggering. I could not find the origin of these files, but I did find this version of [generic_buffer.c](https://github.com/torvalds/linux/blob/6f0d349d922ba44e4348a17a78ea51b7135965b1/tools/iio/iio_generic_buffer.c), which seems to match pretty closely. Moral of the story: no idea where the site's `generic_buffer.c` and the patch came from. 10 | * `generic_buffer.c` contains the correct patched version 11 | * `generic_buffer.c.orig` contains the unpatched version 12 | * `generic_buffer.patch` is the patch file 13 | 14 | The old site also uses the following kernal files, which are also included in this directory. 15 | * [iio_utils.c](https://github.com/torvalds/linux/blob/master/tools/iio/iio_utils.c) 16 | * [iio_utils.h](https://github.com/torvalds/linux/blob/master/tools/iio/iio_utils.h) 17 | 18 | The executable should be able to be compiled with: 19 | * `gcc --static generic_buffer.c iio_utils.c -o generic_buffer` 20 | And run with: 21 | * `echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltageX_en` where X can be `0` through `6`. Setting multiple of these to `1` enables multiple channels to stream at once. 22 | * `echo 100 > /sys/bus/iio/devices/iio\:device0/buffer/length` sets buffer length. Although I believe the following executable overwrites this value, it seems to be needed to set on a fresh restart. 23 | * `echo 0 > /sys/bus/iio/devices/iio\:device0/buffer/enable` will disable the buffer. If this is set to `1` the following executable will not work. This is because it will try to modify `buffer/length` which fails if `enable` is set to `1`. 24 | * `sudo ./generic_buffer -n TI-am335x-adc -l 5 -c 3` where `l` specifies buffer size, and `c` specifies number of iterations 25 | 26 | ## Development Progress 27 | * `simplified_buffer.c` is a stripped down version of `generic_buffer.c`, or maybe you could call it a specific buffer. This was done to increase my understanding as to what was actually going on. 28 | * Now development is shifting to the CentralComputing library 29 | 30 | 31 | ## NEW untested approach 32 | 33 | Upon setting up this README and putting it onto git I realize that there is a new TI reference page (I had initially found the deprecated version), so now all the TI links are correct. At the bottom of their page they list a method to create a similar `generic_buffer` executable using the new kernal example source code. These instructions are at the bottom of the [newest TI reference.](http://processors.wiki.ti.com/index.php/Linux_Core_ADC_Users_Guide) 34 | -------------------------------------------------------------------------------- /BBBSetup/adc_testing/iio_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef _IIO_UTILS_H_ 2 | #define _IIO_UTILS_H_ 3 | 4 | /* IIO - useful set of util functionality 5 | * 6 | * Copyright (c) 2008 Jonathan Cameron 7 | * 8 | * This program is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License version 2 as published by 10 | * the Free Software Foundation. 11 | */ 12 | 13 | #include 14 | 15 | /* Made up value to limit allocation sizes */ 16 | #define IIO_MAX_NAME_LENGTH 64 17 | 18 | #define FORMAT_SCAN_ELEMENTS_DIR "%s/scan_elements" 19 | #define FORMAT_TYPE_FILE "%s_type" 20 | 21 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) 22 | 23 | extern const char *iio_dir; 24 | 25 | /** 26 | * struct iio_channel_info - information about a given channel 27 | * @name: channel name 28 | * @generic_name: general name for channel type 29 | * @scale: scale factor to be applied for conversion to si units 30 | * @offset: offset to be applied for conversion to si units 31 | * @index: the channel index in the buffer output 32 | * @bytes: number of bytes occupied in buffer output 33 | * @bits_used: number of valid bits of data 34 | * @shift: amount of bits to shift right data before applying bit mask 35 | * @mask: a bit mask for the raw output 36 | * @be: flag if data is big endian 37 | * @is_signed: is the raw value stored signed 38 | * @location: data offset for this channel inside the buffer (in bytes) 39 | **/ 40 | struct iio_channel_info { 41 | char *name; 42 | char *generic_name; 43 | float scale; 44 | float offset; 45 | unsigned index; 46 | unsigned bytes; 47 | unsigned bits_used; 48 | unsigned shift; 49 | uint64_t mask; 50 | unsigned be; 51 | unsigned is_signed; 52 | unsigned location; 53 | }; 54 | 55 | static inline int iioutils_check_suffix(const char *str, const char *suffix) 56 | { 57 | return strlen(str) >= strlen(suffix) && 58 | strncmp(str+strlen(str)-strlen(suffix), 59 | suffix, strlen(suffix)) == 0; 60 | } 61 | 62 | int iioutils_break_up_name(const char *full_name, char **generic_name); 63 | int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used, 64 | unsigned *shift, uint64_t *mask, unsigned *be, 65 | const char *device_dir, const char *name, 66 | const char *generic_name); 67 | int iioutils_get_param_float(float *output, const char *param_name, 68 | const char *device_dir, const char *name, 69 | const char *generic_name); 70 | void bsort_channel_array_by_index(struct iio_channel_info *ci_array, int cnt); 71 | int build_channel_array(const char *device_dir, 72 | struct iio_channel_info **ci_array, int *counter); 73 | int find_type_by_name(const char *name, const char *type); 74 | int write_sysfs_int(const char *filename, const char *basedir, int val); 75 | int write_sysfs_int_and_verify(const char *filename, const char *basedir, 76 | int val); 77 | int write_sysfs_string_and_verify(const char *filename, const char *basedir, 78 | const char *val); 79 | int write_sysfs_string(const char *filename, const char *basedir, 80 | const char *val); 81 | int read_sysfs_posint(const char *filename, const char *basedir); 82 | int read_sysfs_float(const char *filename, const char *basedir, float *val); 83 | int read_sysfs_string(const char *filename, const char *basedir, char *str); 84 | 85 | #endif /* _IIO_UTILS_H_ */ 86 | -------------------------------------------------------------------------------- /BBBSetup/beaglebone-black-pinout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/BBBSetup/beaglebone-black-pinout.jpg -------------------------------------------------------------------------------- /BBBSetup/copyAll: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Sorry, you are going to have to type the password multiple times" 3 | echo "And before you ask why I didn't do it another way, like using 'expect' or 'sshpass', its because this is a one time thing, and those packages aren't always readily avaliable to everyone. They weren't even installed by default on my version of Ubuntu." 4 | 5 | bbb=bbb1 6 | addr=128.174.163.125 7 | 8 | scp device_tree_overlays/BB-ADC-00A0.dts $bbb@$addr:~/ 9 | scp device_tree_overlays/BB-DCAN1-00A0.dts $bbb@$addr:~/ 10 | scp device_tree_overlays/BB-GPIO-01-00A0.dts $bbb@$addr:~/ 11 | scp device_tree_overlays/BB-PRU-01-00A0.dts $bbb@$addr:~/ 12 | scp device_tree_overlays/BB-PWM1-00A0.dts $bbb@$addr:~/ 13 | scp device_tree_overlays/w1.dts $bbb@$addr:~/ 14 | scp pru_encoder/Debug/pru_encoder.out $bbb@$addr:~/ 15 | scp halt/Debug/halt.out $bbb@$addr:~/ 16 | scp initPRU $bbb@$addr:~/ 17 | scp initCAN $bbb@$addr:~/ 18 | scp initGPIO $bbb@$addr:~/ 19 | scp initADC $bbb@$addr:~/ 20 | scp setupOverlay $bbb@$addr:~/ 21 | -------------------------------------------------------------------------------- /BBBSetup/device_tree_overlays/BB-ADC-00A0.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | */ 8 | /dts-v1/; 9 | /plugin/; 10 | 11 | / { 12 | compatible = "ti,beaglebone", "ti,beaglebone-black", "ti,beaglebone-green"; 13 | 14 | // identification 15 | part-number = "BB-ADC"; 16 | version = "00A0"; 17 | 18 | // resources this cape uses 19 | exclusive-use = 20 | "P9.39", // AIN0 21 | "P9.40", // AIN1 22 | "P9.37", // AIN2 23 | "P9.38", // AIN3 24 | "P9.33", // AIN4 25 | "P9.36", // AIN5 26 | "P9.35", // AIN6 27 | 28 | "tscadc"; // hardware ip used 29 | 30 | 31 | fragment@0 { 32 | target = <&tscadc>; 33 | __overlay__ { 34 | 35 | status = "okay"; 36 | adc { 37 | ti,adc-channels = <0 1 2 3 4 5 6>; 38 | ti,chan-step-avg = <0x16 0x16 0x16 0x16 0x16 0x16 0x16>; 39 | ti,chan-step-opendelay = <0x98 0x98 0x98 0x98 0x98 0x98 0x98>; 40 | ti,chan-step-sampledelay = <0x0 0x0 0x0 0x0 0x0 0x0 0x0>; 41 | }; 42 | }; 43 | }; 44 | }; 45 | -------------------------------------------------------------------------------- /BBBSetup/device_tree_overlays/BB-DCAN1-00A0.dts: -------------------------------------------------------------------------------- 1 | /dts-v1/; 2 | /plugin/; 3 | 4 | / { 5 | compatible = "ti,beaglebone", "ti,beaglebone-black"; 6 | 7 | /* identification */ 8 | part-number = "dcan1pinmux"; 9 | 10 | fragment@0 { 11 | target = <&am33xx_pinmux>; 12 | __overlay__ { 13 | dcan1_pins_s0: dcan1_pins_s0 { 14 | pinctrl-single,pins = < 15 | 0x180 0x12 /* d_can1_tx, SLEWCTRL_FAST | INPUT_PULLUP | MODE2 */ 16 | 0x184 0x32 /* d_can1_rx, SLEWCTRL_FAST | RECV_ENABLE | INPUT_PULLUP | MODE2 */ 17 | >; 18 | }; 19 | }; 20 | }; 21 | 22 | fragment@1 { 23 | target = <&dcan1>; 24 | __overlay__ { 25 | #address-cells = <1>; 26 | #size-cells = <0>; 27 | 28 | status = "okay"; 29 | pinctrl-names = "default"; 30 | pinctrl-0 = <&dcan1_pins_s0>; 31 | }; 32 | }; 33 | }; 34 | 35 | -------------------------------------------------------------------------------- /BBBSetup/device_tree_overlays/BB-GPIO-01-00A0.dts: -------------------------------------------------------------------------------- 1 | /dts-v1/; 2 | /plugin/; 3 | 4 | /{ 5 | compatible = "ti,beaglebone", "ti,beaglebone-black"; 6 | part_number = "BB-GPIO-01"; 7 | 8 | exclusive-use = 9 | "P8.07", "P8.08", "P8.09", "P8.10", "gpio2_2", "gpio2_3", "gpio2_5", "gpio2_4" ; 10 | 11 | fragment@0 { 12 | target = <&am33xx_pinmux>; 13 | __overlay__ { 14 | gpio_pins: pinmux_gpio_pins { 15 | pinctrl-single,pins = < 16 | 0x090 0x0f /* P8_07, MODE7 | GPIO | 0001111 */ 17 | 0x094 0x0f /* P8_07, MODE7 | GPIO | 0001111 */ 18 | 0x09c 0x0f /* P8_07, MODE7 | GPIO | 0001111 */ 19 | 0x098 0x0f /* P8_07, MODE7 | GPIO | 0001111 */ 20 | >; 21 | }; 22 | }; 23 | }; 24 | 25 | fragment@1 { 26 | target = <&ocp>; 27 | __overlay__ { 28 | //bs_pinmode_P9_12_0x27_pinmux { 29 | //compatible = "bone-pinmux-helper"; 30 | status = "okay"; 31 | pinctrl-names = "default"; 32 | pinctrl-0 = <&gpio_pins>; 33 | //}; 34 | }; 35 | }; 36 | }; 37 | 38 | -------------------------------------------------------------------------------- /BBBSetup/device_tree_overlays/BB-PRU-01-00A0.dts: -------------------------------------------------------------------------------- 1 | /dts-v1/; 2 | /plugin/; 3 | 4 | / { 5 | compatible = "ti,beaglebone", "ti,beaglebone-black"; 6 | 7 | part-number = "BB-PRU-01"; 8 | version = "00A0"; 9 | 10 | /* This overlay uses the following resources */ 11 | exclusive-use = 12 | "P8.27", "P8.28", "P8.29", "P8.39", "P8.40", "P8.41", "P8.42", "P8.43", "P8.44", "P8.45", "P8.46", "pru0", "pru1"; 13 | 14 | fragment@0 { 15 | target = <&am33xx_pinmux>; 16 | __overlay__ { 17 | 18 | pru_pru_pins: pinmux_pru_pru_pins { // The PRU pin modes 19 | pinctrl-single,pins = < 20 | 0x0e0 0x26 /* P8_27 pr1_pru1_pru_r31_8, MODE6 | INPUT | 0100110 */ 21 | 0x0e8 0x26 /* P8_28 pr1_pru1_pru_r31_10, MODE6 | INPUT | 0100110 */ 22 | 0x0e4 0x26 /* P8_29 pr1_pru1_pru_r31_9, MODE6 | INPUT | 0100110 */ 23 | 0x0b8 0x26 /* P8_39 pr1_pru1_pru_r31_6, MODE6 | INPUT | 0100110 */ 24 | 0x0bc 0x26 /* P8_40 pr1_pru1_pru_r31_7, MODE6 | INPUT | 0100110 */ 25 | 0x0b0 0x26 /* P8_41 pr1_pru1_pru_r31_4, MODE6 | INPUT | 0100110 */ 26 | 0x0b4 0x26 /* P8_42 pr1_pru1_pru_r31_5, MODE6 | INPUT | 0100110 */ 27 | 0x0a8 0x26 /* P8_43 pr1_pru1_pru_r31_2, MODE6 | INPUT | 0100110 */ 28 | 0x0ac 0x26 /* P8_44 pr1_pru1_pru_r31_3, MODE6 | INPUT | 0100110 */ 29 | 0x0a0 0x26 /* P8_45 pr1_pru1_pru_r31_0, MODE6 | INPUT | 0100110 */ 30 | 0x0a4 0x26 /* P8_46 pr1_pru1_pru_r31_1, MODE6 | INPUT | 0100110 */ 31 | >; 32 | }; 33 | }; 34 | }; 35 | 36 | fragment@1 { // Enable the PRUSS 37 | target = <&pruss>; 38 | __overlay__ { 39 | status = "okay"; 40 | pinctrl-names = "default"; 41 | pinctrl-0 = <&pru_pru_pins>; 42 | }; 43 | }; 44 | 45 | }; 46 | -------------------------------------------------------------------------------- /BBBSetup/device_tree_overlays/BB-PWM1-00A0.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Seeed Studio. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | */ 8 | /dts-v1/; 9 | /plugin/; 10 | /{ 11 | compatible = "ti,beaglebone", "ti,beaglebone-black", "ti,beaglebone-green"; 12 | part-number = "BB-PWM1"; 13 | version = "00A0"; 14 | 15 | fragment@0 { 16 | target = <&am33xx_pinmux>; 17 | __overlay__ { 18 | pinctrl_spec: Panel_Pins { 19 | pinctrl-single,pins = < 0x48 0x06 /* (U14) gpmc_a2.ehrpwm1A */ 0x4c 0x06 /* (T14) gpmc_a3.ehrpwm1B */ >; 20 | }; 21 | }; 22 | }; 23 | fragment@1 { 24 | target = <&ocp>; 25 | __overlay__ { 26 | test_helper: helper { 27 | status = "okay"; 28 | compatible = "bone-pinmux-helper"; 29 | pinctrl-names = "default"; 30 | pinctrl-0 = <&pinctrl_spec>; 31 | }; 32 | }; 33 | }; 34 | fragment@2 { 35 | target = <&epwmss1>; 36 | __overlay__ { 37 | status = "okay"; 38 | }; 39 | }; 40 | fragment@3 { 41 | target = <&ehrpwm1>; 42 | __overlay__ { 43 | status = "okay"; 44 | }; 45 | }; 46 | }; 47 | -------------------------------------------------------------------------------- /BBBSetup/device_tree_overlays/BB-SPI-M-01-00A0.dts: -------------------------------------------------------------------------------- 1 | /dts-v1/; 2 | /plugin/; 3 | 4 | / { 5 | compatible = "ti,beaglebone", "ti,beaglebone-black"; 6 | 7 | /* identification */ 8 | part-number = "spimultiple"; 9 | version = "00A0"; 10 | 11 | fragment@0 { 12 | target = <&am33xx_pinmux>; 13 | __overlay__ { 14 | bb_spi1_pins: pinmux_bb_spi1_pins { 15 | pinctrl-single,pins = < 16 | 0x190 0x33 /* mcasp0_aclkx.spi1_sclk, INPUT_PULLUP | MODE3 */ 17 | 0x194 0x33 /* mcasp0_fsx.spi1_d0, INPUT_PULLUP | MODE3 */ 18 | 0x198 0x13 /* mcasp0_axr0.spi1_d1, OUTPUT_PULLUP | MODE3 */ 19 | 0x19c 0x13 /* mcasp0_ahclkr.spi1_cs0, OUTPUT_PULLUP | MODE3 */ 20 | 0x164 0x12 /* eCAP0_in_PWM0_out.spi1_cs1 OUTPUT_PULLUP | MODE2 */ 21 | >; 22 | }; 23 | 24 | }; 25 | }; 26 | fragment@1 { 27 | target = <&spi1>; 28 | __overlay__ { 29 | 30 | #address-cells = <1>; 31 | #size-cells = <0>; 32 | status = "okay"; 33 | pinctrl-names = "default"; 34 | pinctrl-0 = <&bb_spi1_pins>; 35 | 36 | num-cs = <2>; 37 | 38 | spidev@1 { 39 | spi-max-frequency = <24000000>; 40 | reg = <0>; 41 | compatible = "linux,spidev"; 42 | }; 43 | 44 | spidev@2 { 45 | spi-max-frequency = <24000000>; 46 | reg = <1>; 47 | compatible = "linux,spidev"; 48 | }; 49 | 50 | /* 51 | spi1@0 { 52 | #address-cells = <1>; 53 | #size-cells = <0>; 54 | compatible = "linux,spidev"; 55 | reg = <0>; 56 | spi-max-frequency = <16000000>; 57 | spi-cpol; 58 | spi-cpha; 59 | }; 60 | 61 | spi1@1 { 62 | #address-cells = <1>; 63 | #size-cells = <0>; 64 | compatible = "linux,spidev"; 65 | reg = <1>; 66 | spi-max-frequency = <16000000>; 67 | spi-cpol; 68 | spi-cpha; 69 | }; 70 | */ 71 | 72 | 73 | }; 74 | }; 75 | }; 76 | -------------------------------------------------------------------------------- /BBBSetup/device_tree_overlays/w1.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * Modified by Russell Senior from the weather cape's DTS file. 9 | * Minor formatting by C W Rose. 10 | */ 11 | /dts-v1/; 12 | /plugin/; 13 | 14 | / { 15 | compatible = "ti,beaglebone", "ti,beaglebone-black"; 16 | part-number = "BB-W1"; 17 | version = "00A0"; 18 | 19 | exclusive-use = "P8.12"; 20 | 21 | fragment@0 { 22 | target = <&am33xx_pinmux>; 23 | __overlay__ { 24 | bb_w1_pins: pinmux_bb_w1_pins { 25 | pinctrl-single,pins = <0x34 0x37 /* gpmc_ad13.gpio1_13, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE7 - w1-gpio */ >; 26 | }; 27 | }; 28 | }; 29 | 30 | fragment@1 { 31 | target = <&ocp>; 32 | __overlay__ { 33 | onewire@0 { 34 | status = "okay"; 35 | compatible = "w1-gpio"; 36 | pinctrl-names = "default"; 37 | pinctrl-0 = <&bb_w1_pins>; 38 | 39 | gpios = <&gpio1 13 0>; 40 | }; 41 | }; 42 | }; 43 | }; 44 | -------------------------------------------------------------------------------- /BBBSetup/halt/.ccsproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /BBBSetup/halt/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | halt 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 15 | full,incremental, 16 | 17 | 18 | 19 | 20 | 21 | com.ti.ccstudio.core.ccsNature 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 24 | org.eclipse.cdt.core.ccnature 25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 26 | 27 | 28 | -------------------------------------------------------------------------------- /BBBSetup/halt/.settings/org.eclipse.cdt.codan.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | inEditor=false 3 | onBuild=false 4 | -------------------------------------------------------------------------------- /BBBSetup/halt/.settings/org.eclipse.cdt.debug.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.cdt.debug.core.toggleBreakpointModel=com.ti.ccstudio.debug.CCSBreakpointMarker 3 | -------------------------------------------------------------------------------- /BBBSetup/halt/AM335x_PRU.cmd: -------------------------------------------------------------------------------- 1 | /****************************************************************************/ 2 | /* AM335x_PRU.cmd */ 3 | /* Copyright (c) 2015 Texas Instruments Incorporated */ 4 | /* */ 5 | /* Description: This file is a linker command file that can be used for */ 6 | /* linking PRU programs built with the C compiler and */ 7 | /* the resulting .out file on an AM335x device. */ 8 | /****************************************************************************/ 9 | 10 | -cr /* Link using C conventions */ 11 | 12 | /* Specify the System Memory Map */ 13 | MEMORY 14 | { 15 | PAGE 0: 16 | PRU_IMEM : org = 0x00000000 len = 0x00002000 /* 8kB PRU0 Instruction RAM */ 17 | 18 | PAGE 1: 19 | 20 | /* RAM */ 21 | 22 | PRU_DMEM_0_1 : org = 0x00000000 len = 0x00002000 CREGISTER=24 /* 8kB PRU Data RAM 0_1 */ 23 | PRU_DMEM_1_0 : org = 0x00002000 len = 0x00002000 CREGISTER=25 /* 8kB PRU Data RAM 1_0 */ 24 | 25 | PAGE 2: 26 | PRU_SHAREDMEM : org = 0x00010000 len = 0x00003000 CREGISTER=28 /* 12kB Shared RAM */ 27 | 28 | DDR : org = 0x80000000 len = 0x00000100 CREGISTER=31 29 | L3OCMC : org = 0x40000000 len = 0x00010000 CREGISTER=30 30 | 31 | 32 | /* Peripherals */ 33 | 34 | PRU_CFG : org = 0x00026000 len = 0x00000044 CREGISTER=4 35 | PRU_ECAP : org = 0x00030000 len = 0x00000060 CREGISTER=3 36 | PRU_IEP : org = 0x0002E000 len = 0x0000031C CREGISTER=26 37 | PRU_INTC : org = 0x00020000 len = 0x00001504 CREGISTER=0 38 | PRU_UART : org = 0x00028000 len = 0x00000038 CREGISTER=7 39 | 40 | DCAN0 : org = 0x481CC000 len = 0x000001E8 CREGISTER=14 41 | DCAN1 : org = 0x481D0000 len = 0x000001E8 CREGISTER=15 42 | DMTIMER2 : org = 0x48040000 len = 0x0000005C CREGISTER=1 43 | PWMSS0 : org = 0x48300000 len = 0x000002C4 CREGISTER=18 44 | PWMSS1 : org = 0x48302000 len = 0x000002C4 CREGISTER=19 45 | PWMSS2 : org = 0x48304000 len = 0x000002C4 CREGISTER=20 46 | GEMAC : org = 0x4A100000 len = 0x0000128C CREGISTER=9 47 | I2C1 : org = 0x4802A000 len = 0x000000D8 CREGISTER=2 48 | I2C2 : org = 0x4819C000 len = 0x000000D8 CREGISTER=17 49 | MBX0 : org = 0x480C8000 len = 0x00000140 CREGISTER=22 50 | MCASP0_DMA : org = 0x46000000 len = 0x00000100 CREGISTER=8 51 | MCSPI0 : org = 0x48030000 len = 0x000001A4 CREGISTER=6 52 | MCSPI1 : org = 0x481A0000 len = 0x000001A4 CREGISTER=16 53 | MMCHS0 : org = 0x48060000 len = 0x00000300 CREGISTER=5 54 | SPINLOCK : org = 0x480CA000 len = 0x00000880 CREGISTER=23 55 | TPCC : org = 0x49000000 len = 0x00001098 CREGISTER=29 56 | UART1 : org = 0x48022000 len = 0x00000088 CREGISTER=11 57 | UART2 : org = 0x48024000 len = 0x00000088 CREGISTER=12 58 | 59 | RSVD10 : org = 0x48318000 len = 0x00000100 CREGISTER=10 60 | RSVD13 : org = 0x48310000 len = 0x00000100 CREGISTER=13 61 | RSVD21 : org = 0x00032400 len = 0x00000100 CREGISTER=21 62 | RSVD27 : org = 0x00032000 len = 0x00000100 CREGISTER=27 63 | 64 | } 65 | 66 | /* Specify the sections allocation into memory */ 67 | SECTIONS { 68 | /* Forces _c_int00 to the start of PRU IRAM. Not necessary when loading 69 | an ELF file, but useful when loading a binary */ 70 | .text:_c_int00* > 0x0, PAGE 0 71 | 72 | .text > PRU_IMEM, PAGE 0 73 | .stack > PRU_DMEM_0_1, PAGE 1 74 | .bss > PRU_DMEM_0_1, PAGE 1 75 | .cio > PRU_DMEM_0_1, PAGE 1 76 | .data > PRU_DMEM_0_1, PAGE 1 77 | .switch > PRU_DMEM_0_1, PAGE 1 78 | .sysmem > PRU_DMEM_0_1, PAGE 1 79 | .cinit > PRU_DMEM_0_1, PAGE 1 80 | .rodata > PRU_DMEM_0_1, PAGE 1 81 | .rofardata > PRU_DMEM_0_1, PAGE 1 82 | .farbss > PRU_DMEM_0_1, PAGE 1 83 | .fardata > PRU_DMEM_0_1, PAGE 1 84 | 85 | .resource_table > PRU_DMEM_0_1, PAGE 1 86 | } 87 | -------------------------------------------------------------------------------- /BBBSetup/halt/Debug/halt.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/BBBSetup/halt/Debug/halt.out -------------------------------------------------------------------------------- /BBBSetup/halt/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource_table_empty.h" 3 | 4 | 5 | /** 6 | * main.c 7 | */ 8 | int main(void) 9 | { 10 | /* Your code goes here */ 11 | 12 | __halt(); 13 | 14 | /* Should never return */ 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /BBBSetup/halt/resource_table_empty.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 3 | * 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * * Neither the name of Texas Instruments Incorporated nor the names of 18 | * its contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | 34 | /* 35 | * ======== resource_table_empty.h ======== 36 | * 37 | * Define the resource table entries for all PRU cores. This will be 38 | * incorporated into corresponding base images, and used by the remoteproc 39 | * on the host-side to allocated/reserve resources. Note the remoteproc 40 | * driver requires that all PRU firmware be built with a resource table. 41 | * 42 | * This file contains an empty resource table. It can be used either as: 43 | * 44 | * 1) A template, or 45 | * 2) As-is if a PRU application does not need to configure PRU_INTC 46 | * or interact with the rpmsg driver 47 | * 48 | */ 49 | 50 | #ifndef _RSC_TABLE_PRU_H_ 51 | #define _RSC_TABLE_PRU_H_ 52 | 53 | #include 54 | #include 55 | 56 | struct my_resource_table { 57 | struct resource_table base; 58 | 59 | uint32_t offset[1]; /* Should match 'num' in actual definition */ 60 | }; 61 | 62 | #pragma DATA_SECTION(pru_remoteproc_ResourceTable, ".resource_table") 63 | #pragma RETAIN(pru_remoteproc_ResourceTable) 64 | struct my_resource_table pru_remoteproc_ResourceTable = { 65 | 1, /* we're the first version that implements this */ 66 | 0, /* number of entries in the table */ 67 | 0, 0, /* reserved, must be zero */ 68 | 0, /* offset[0] */ 69 | }; 70 | 71 | #endif /* _RSC_TABLE_PRU_H_ */ 72 | -------------------------------------------------------------------------------- /BBBSetup/initADC: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo 0 > /sys/bus/iio/devices/iio\:device0/buffer/enable 4 | 5 | echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage0_en 6 | echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage1_en 7 | echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage2_en 8 | echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage3_en 9 | echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage4_en 10 | echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage5_en 11 | echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage6_en 12 | 13 | echo 1 > /sys/bus/iio/devices/iio\:device0/buffer/length 14 | 15 | echo 1 > /sys/bus/iio/devices/iio\:device0/buffer/enable 16 | 17 | -------------------------------------------------------------------------------- /BBBSetup/initCAN: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ip link set can0 up type can bitrate 500000 4 | -------------------------------------------------------------------------------- /BBBSetup/initGPIO: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo 66 > /sys/class/gpio/export 3 | echo "in" > /sys/class/gpio/gpio66/direction 4 | echo 26 > /sys/class/gpio/export 5 | echo "in" > /sys/class/gpio/gpio26/direction 6 | echo 46 > /sys/class/gpio/export 7 | echo "in" > /sys/class/gpio/gpio46/direction 8 | echo 65 > /sys/class/gpio/export 9 | echo "in" > /sys/class/gpio/gpio65/direction 10 | echo 61 > /sys/class/gpio/export 11 | echo "in" > /sys/class/gpio/gpio61/direction 12 | echo 45 > /sys/class/gpio/export 13 | echo "out" > /sys/class/gpio/gpio45/direction 14 | echo 68 > /sys/class/gpio/export 15 | echo "out" > /sys/class/gpio/gpio68/direction 16 | echo 69 > /sys/class/gpio/export 17 | echo "out" > /sys/class/gpio/gpio69/direction 18 | -------------------------------------------------------------------------------- /BBBSetup/initPRU: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Copying firmware to /lib/firmware/am335x_pru0_fw" 4 | cp halt.out /lib/firmware/am335x_pru0_fw 5 | 6 | echo "Copying firmware to /lib/firmware/am335x_pru1_fw" 7 | cp pru_encoder.out /lib/firmware/am335x_pru1_fw 8 | 9 | echo "Rebooting pru core 0" 10 | echo 'stop' > /sys/class/remoteproc/remoteproc1/state 11 | echo 'am335x_pru0_fw' > /sys/class/remoteproc/remoteproc1/firmware 12 | echo 'start' > /sys/class/remoteproc/remoteproc1/state 13 | pru1Stat=$? 14 | echo "pru core 0 is now loaded" 15 | 16 | echo "Rebooting pru core 1" 17 | echo 'stop' > /sys/class/remoteproc/remoteproc2/state 18 | echo 'am335x_pru1_fw' > /sys/class/remoteproc/remoteproc2/firmware 19 | echo 'start' > /sys/class/remoteproc/remoteproc2/state 20 | pru2Stat=$? 21 | echo "pru core 1 is now loaded" 22 | chmod 777 /dev/rpmsg_pru31 23 | 24 | if [ $pru1Stat -eq 0 ] && [ $pru2Stat -eq 0 ] 25 | then 26 | exit 0 27 | else 28 | exit 1 29 | fi 30 | 31 | 32 | -------------------------------------------------------------------------------- /BBBSetup/pru-icss-5.1.0/.gitignore: -------------------------------------------------------------------------------- 1 | Debug/ 2 | Release/ 3 | gen/ 4 | *.core.resources.prefs 5 | *~ 6 | 7 | -------------------------------------------------------------------------------- /BBBSetup/pru-icss-5.1.0/Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS=examples pru_cape lib/src labs 2 | 3 | all: $(SUBDIRS) 4 | 5 | $(SUBDIRS): 6 | @$(MAKE) -C $@ 7 | 8 | clean: 9 | @for d in $(SUBDIRS); do (cd $$d; $(MAKE) clean ); done 10 | 11 | .PHONY: all clean $(SUBDIRS) 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /BBBSetup/pru-icss-5.1.0/ReadMe.txt: -------------------------------------------------------------------------------- 1 | Programmable Real-time Unit (PRU) Software Support Package release 5.0 2 | 3 | 4 | DESCRIPTION 5 | 6 | The PRU Software Support Package is an add-on package that provides a framework 7 | and examples for developing software for the Programmable Real-time Unit 8 | sub-system and Industrial Communication Sub-System (PRU-ICSS) in the supported 9 | TI processors. The PRU-ICSS achieves deterministic, real-time processing, direct 10 | access to I/Os and meets ultra-low-latency requirements. 11 | 12 | This software package contains example PRU firmware code as well as application 13 | loader code for the host OS. The examples demonstrate the PRU capabilities to 14 | interact with and control the system and its resources. 15 | 16 | For more details about the PRU, visit 17 | 18 | http://processors.wiki.ti.com/index.php/PRU-ICSS 19 | 20 | 21 | 22 | WHAT's INCLUDED? 23 | 24 | This package includes the following resources: 25 | 26 | DIRECTORY CONTENTS 27 | --------- -------- 28 | examples Basic PRU examples 29 | include PRU firmware header files 30 | labs Source code for step-by-step labs 31 | lib PRU library files and library source files 32 | pru_cape Demo software for the BeagleBone PRU Cape 33 | 34 | 35 | 36 | ADDITIONAL RESOURCES 37 | 38 | For more information about the PRU, visit: 39 | 40 | PRU-ICSS Wiki - http://processors.wiki.ti.com/index.php/PRU-ICSS 41 | PRU Training Slides - http://www.ti.com/sitarabootcamp 42 | PRU Evaluation Hardware - http://www.ti.com/tool/PRUCAPE 43 | Support - http://e2e.ti.com 44 | 45 | -------------------------------------------------------------------------------- /BBBSetup/pru-icss-5.1.0/include/ReadMe.txt: -------------------------------------------------------------------------------- 1 | Programmable Real-time Unit (PRU) Software Support Package 2 | ------------------------------------------------------------ 3 | ============================================================ 4 | INCLUDE 5 | ============================================================ 6 | 7 | DESCRIPTION 8 | 9 | This directory provides header files for PRU firmware. 10 | 11 | For more details about these header files, visit: 12 | 13 | http://processors.wiki.ti.com/index.php/PRU-ICSS_Header_Files 14 | 15 | 16 | 17 | ADDITIONAL RESOURCES 18 | 19 | For more information about the PRU, visit: 20 | 21 | PRU-ICSS Wiki - http://processors.wiki.ti.com/index.php/PRU-ICSS 22 | PRU Training Slides - http://www.ti.com/sitarabootcamp 23 | PRU Evaluation Hardware - http://www.ti.com/tool/PRUCAPE 24 | Support - http://e2e.ti.com 25 | 26 | -------------------------------------------------------------------------------- /BBBSetup/pru-icss-5.1.0/include/pru_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 3 | * 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * * Neither the name of Texas Instruments Incorporated nor the names of 18 | * its contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | 34 | #ifndef _PRU_TYPES_H_ 35 | #define _PRU_TYPES_H_ 36 | 37 | /* Custom Resource info: Must match drivers/remoteproc/pru_rproc.h */ 38 | #define TYPE_PRU_INTS 1 39 | 40 | /** 41 | * struct ch_map - sysevts-to-channel mapping 42 | * 43 | * @evt: the number of the sysevt 44 | * @ch: channel number assigned to a given @sysevt 45 | * 46 | * PRU system events are mapped to channels, and these channels are mapped to 47 | * hosts. Events can be mapped to channels in a one-to-one or many-to-one ratio 48 | * (multiple events per channel), and channels can be mapped to hosts in a 49 | * one-to-one or many-to-one ratio (multiple events per channel). 50 | * 51 | * @evt is the number of the sysevt, and @ch is the number of the channel to be 52 | * mapped. 53 | */ 54 | 55 | struct ch_map { 56 | uint8_t evt; 57 | uint8_t ch; 58 | }; 59 | 60 | /** 61 | * struct fw_rsc_custom_ints - custom resource to define PRU interrupts 62 | * @version: revision number of the custom ints type 63 | * @channel_host: assignment of PRU channels to hosts 64 | * @num_evts: device address of INTC 65 | * @event_channel: mapping of sysevts to channels 66 | * 67 | * PRU system events are mapped to channels, and these channels are mapped to 68 | * hosts. Events can be mapped to channels in a one-to-one or many-to-one ratio 69 | * (multiple events per channel), and channels can be mapped to hosts in a 70 | * one-to-one or many-to-one ratio (multiple events per channel). 71 | * 72 | * @da is the device address of the interrupt controller, @channel_map is 73 | * used to specify to which channel, if any, an event is mapped, and @host_map 74 | * specifies to which host, if any, a channel is mapped. 75 | */ 76 | struct fw_rsc_custom_ints { 77 | uint16_t version; 78 | uint8_t channel_host[10]; 79 | uint32_t num_evts; 80 | struct ch_map *event_channel; 81 | }; 82 | 83 | #endif /* _PRU_TYPES_H_ */ 84 | -------------------------------------------------------------------------------- /BBBSetup/pru-icss-5.1.0/include/pru_virtio_ids.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_VIRTIO_IDS_H 2 | #define _LINUX_VIRTIO_IDS_H 3 | /* 4 | * Virtio IDs 5 | * 6 | * This header is BSD licensed so anyone can use the definitions to implement 7 | * compatible drivers/servers. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 3. Neither the name of IBM nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE 24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 | * SUCH DAMAGE. */ 31 | 32 | #define VIRTIO_ID_NET 1 /* virtio net */ 33 | #define VIRTIO_ID_BLOCK 2 /* virtio block */ 34 | #define VIRTIO_ID_CONSOLE 3 /* virtio console */ 35 | #define VIRTIO_ID_RNG 4 /* virtio rng */ 36 | #define VIRTIO_ID_BALLOON 5 /* virtio balloon */ 37 | #define VIRTIO_ID_RPMSG 7 /* virtio remote processor messaging */ 38 | #define VIRTIO_ID_SCSI 8 /* virtio scsi */ 39 | #define VIRTIO_ID_9P 9 /* 9p virtio console */ 40 | #define VIRTIO_ID_RPROC_SERIAL 11 /* virtio remoteproc serial link */ 41 | 42 | #endif /* _LINUX_VIRTIO_IDS_H */ 43 | -------------------------------------------------------------------------------- /BBBSetup/pru-icss-5.1.0/include/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * types.h - standard redefined types 3 | */ 4 | 5 | #ifndef _TYPES_H_ 6 | #define _TYPES_H_ 7 | 8 | typedef uint8_t __u8; 9 | typedef uint16_t __u16; 10 | typedef uint32_t __u32; 11 | typedef uint64_t __u64; 12 | 13 | typedef uint8_t u8; 14 | typedef uint16_t u16; 15 | typedef uint32_t u32; 16 | typedef uint64_t u64; 17 | 18 | #endif /* _TYPES_H_ */ 19 | -------------------------------------------------------------------------------- /BBBSetup/pru-icss-5.1.0/lib/rpmsg_lib.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/BBBSetup/pru-icss-5.1.0/lib/rpmsg_lib.lib -------------------------------------------------------------------------------- /BBBSetup/pru-icss-5.1.0/lib/src/Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS=rpmsg_lib 2 | 3 | all: $(SUBDIRS) 4 | 5 | $(SUBDIRS): 6 | @$(MAKE) -C $@ 7 | 8 | clean: 9 | @for d in $(SUBDIRS); do (cd $$d; $(MAKE) clean ); done 10 | 11 | .PHONY: all clean $(SUBDIRS) 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /BBBSetup/pru-icss-5.1.0/lib/src/rpmsg_lib/.ccsproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /BBBSetup/pru-icss-5.1.0/lib/src/rpmsg_lib/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | rpmsg_lib 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 15 | full,incremental, 16 | 17 | 18 | 19 | 20 | 21 | com.ti.ccstudio.core.ccsNature 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 24 | org.eclipse.cdt.core.ccnature 25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 26 | 27 | 28 | -------------------------------------------------------------------------------- /BBBSetup/pru-icss-5.1.0/lib/src/rpmsg_lib/.settings/org.eclipse.cdt.codan.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | inEditor=false 3 | onBuild=false 4 | -------------------------------------------------------------------------------- /BBBSetup/pru-icss-5.1.0/lib/src/rpmsg_lib/.settings/org.eclipse.cdt.debug.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.cdt.debug.core.toggleBreakpointModel=com.ti.ccstudio.debug.CCSBreakpointMarker 3 | -------------------------------------------------------------------------------- /BBBSetup/pru-icss-5.1.0/lib/src/rpmsg_lib/Makefile: -------------------------------------------------------------------------------- 1 | # PRU_CGT environment variable must point to the TI PRU code gen tools directory. E.g.: 2 | #(Desktop Linux) export PRU_CGT=/path/to/pru/code/gen/tools/ti-cgt-pru_2.1.2 3 | #(Windows) set PRU_CGT=C:/path/to/pru/code/gen/tools/ti-cgt-pru_2.1.2 4 | #(ARM Linux*) export PRU_CGT=/usr/share/ti/cgt-pru 5 | # 6 | # *ARM Linux also needs to create a symbolic link to the /usr/bin/ directory in 7 | # order to use the same Makefile 8 | #(ARM Linux) ln -s /usr/bin/ /usr/share/ti/cgt-pru/bin 9 | 10 | ifndef PRU_CGT 11 | define ERROR_BODY 12 | 13 | ******************************************************************************* 14 | PRU_CGT environment variable is not set. Examples given: 15 | (Desktop Linux) export PRU_CGT=/path/to/pru/code/gen/tools/ti-cgt-pru_2.1.2 16 | (Windows) set PRU_CGT=C:/path/to/pru/code/gen/tools/ti-cgt-pru_2.1.2 17 | (ARM Linux*) export PRU_CGT=/usr/share/ti/cgt-pru 18 | 19 | *ARM Linux also needs to create a symbolic link to the /usr/bin/ directory in 20 | order to use the same Makefile 21 | (ARM Linux) ln -s /usr/bin/ /usr/share/ti/cgt-pru/bin 22 | ******************************************************************************* 23 | 24 | endef 25 | $(error $(ERROR_BODY)) 26 | endif 27 | 28 | MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) 29 | CURRENT_DIR := $(notdir $(patsubst %/,%,$(dir $(MKFILE_PATH)))) 30 | PROJ_NAME=$(CURRENT_DIR) 31 | INCLUDE=--include_path=../../../include 32 | GEN_DIR=gen 33 | 34 | #Common compiler flags (Defined in 'PRU Optimizing C/C++ Compiler User's Guide) 35 | CFLAGS=-v3 -O2 --display_error_number --endian=little --hardware_mac=on --obj_directory=$(GEN_DIR) --pp_directory=$(GEN_DIR) -ppd -ppa 36 | 37 | TARGET=$(GEN_DIR)/$(PROJ_NAME).lib 38 | SOURCES=$(wildcard *.c) 39 | #Using .object instead of .obj in order to not conflict with the CCS build process 40 | OBJECTS=$(patsubst %,$(GEN_DIR)/%,$(SOURCES:.c=.object)) 41 | 42 | all: printStart $(TARGET) printEnd 43 | 44 | printStart: 45 | @echo '' 46 | @echo '************************************************************' 47 | @echo 'Building project: $(PROJ_NAME)' 48 | 49 | printEnd: 50 | @echo '' 51 | @echo 'Finished building project: $(PROJ_NAME)' 52 | @echo '************************************************************' 53 | @echo '' 54 | 55 | # Invokes the archiver to make the .lib file 56 | $(TARGET): $(OBJECTS) 57 | @echo '' 58 | @echo 'Building target: $@' 59 | @echo 'Invoking: PRU Archiver' 60 | $(PRU_CGT)/bin/arpru r $(TARGET) $(OBJECTS) 61 | @echo 'Finished building target: $@' 62 | @echo '' 63 | @echo 'Output files can be found in the "$(GEN_DIR)" directory' 64 | 65 | # Invokes the compiler on all c files in the directory to create the object files 66 | $(GEN_DIR)/%.object: %.c 67 | @mkdir -p $(GEN_DIR) 68 | @echo '' 69 | @echo 'Building file: $<' 70 | @echo 'Invoking: PRU Compiler' 71 | $(PRU_CGT)/bin/clpru --include_path=$(PRU_CGT)/include $(INCLUDE) $(CFLAGS) -fe $@ $< 72 | 73 | .PHONY: all clean 74 | 75 | # Remove the $(GEN_DIR) directory 76 | clean: 77 | @echo '' 78 | @echo '************************************************************' 79 | @echo 'Cleaning project: $(PROJ_NAME)' 80 | @echo '' 81 | @echo 'Removing files in the "$(GEN_DIR)" directory' 82 | @rm -rf $(GEN_DIR) 83 | @echo '' 84 | @echo 'Finished cleaning project: $(PROJ_NAME)' 85 | @echo '************************************************************' 86 | @echo '' 87 | 88 | # Includes the dependencies that the compiler creates (-ppd and -ppa flags) 89 | -include $(OBJECTS:%.object=%.pp) 90 | 91 | -------------------------------------------------------------------------------- /BBBSetup/pru_encoder/.ccsproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /BBBSetup/pru_encoder/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | pru_encoder 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 15 | full,incremental, 16 | 17 | 18 | 19 | 20 | 21 | com.ti.ccstudio.core.ccsNature 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 24 | org.eclipse.cdt.core.ccnature 25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 26 | 27 | 28 | -------------------------------------------------------------------------------- /BBBSetup/pru_encoder/.settings/org.eclipse.cdt.codan.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | inEditor=false 3 | onBuild=false 4 | -------------------------------------------------------------------------------- /BBBSetup/pru_encoder/.settings/org.eclipse.cdt.debug.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.cdt.debug.core.toggleBreakpointModel=com.ti.ccstudio.debug.CCSBreakpointMarker 3 | -------------------------------------------------------------------------------- /BBBSetup/pru_encoder/Debug/pru_encoder.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/BBBSetup/pru_encoder/Debug/pru_encoder.out -------------------------------------------------------------------------------- /BBBSetup/pru_encoder/optical.h: -------------------------------------------------------------------------------- 1 | /* 2 | * optical.h 3 | * 4 | * Created on: Jun 24, 2018 5 | * Author: rgw3d 6 | */ 7 | 8 | #ifndef OPTICAL_H_ 9 | #define OPTICAL_H_ 10 | 11 | #define TWO_THOUSAND_HZ 100000 12 | 13 | 14 | extern uint32_t htime_ctr; 15 | 16 | extern uint32_t counts[11]; //Number of times we have seen the signal 17 | extern uint32_t htime[11]; //upper 32 bits of last time there was a high or low signal 18 | extern uint32_t ltime[11]; //lower 32 bits of last time there was a high or low signal 19 | 20 | extern uint32_t hdecay[11]; 21 | extern uint32_t ldecay[11]; // These are what the time deltas are based off of. 22 | 23 | extern uint32_t hdelta[11]; //time between the most recently seen signal and the signal before that one. 24 | extern uint32_t ldelta[11]; 25 | 26 | extern uint8_t isHigh[11]; //Signal is currently high, need it to go low. 27 | 28 | uint32_t htime_diff = 0; 29 | uint32_t ltime_diff = 0; 30 | uint32_t cur_time = 0; 31 | 32 | /* 33 | #define diff_time(htime_diff, ltime_diff, htime, ltime) {\ 34 | htime_diff = htime_ctr - htime;\ 35 | ltime_diff = CT_IEP.TMR_CNT - ltime;\ 36 | int overflow = CT_IEP.TMR_GLB_STS_bit.CNT_OVF;\ 37 | if(overflow != 0){\ 38 | htime_diff ++;\ 39 | ltime_diff = UINT32_MAX - ltime_diff;\ 40 | CT_IEP.TMR_GLB_STS_bit.CNT_OVF = 1;\ 41 | htime_ctr ++;\ 42 | }\ 43 | } 44 | */ 45 | 46 | //htime_ctr - htime > 1 then set max 47 | //htime_ctr - htime == 1 and curtime > 48 | //#define diff_time_new(htime_diff, ltime_diff, htime, ltime) {\ 49 | 50 | //} 51 | 52 | 53 | 54 | inline 55 | void debounce(const uint32_t mask, const uint32_t i) { 56 | 57 | // Grab the current time 58 | cur_time = CT_IEP.TMR_CNT; 59 | hdecay[i] = htime_ctr - htime[i]; 60 | 61 | // Check if there was an overflow 62 | if(CT_IEP.TMR_GLB_STS_bit.CNT_OVF != 0){ 63 | CT_IEP.TMR_GLB_STS_bit.CNT_OVF = 1; 64 | hdecay[i] ++; 65 | htime_ctr ++; 66 | } 67 | 68 | // Set the decay 69 | if(hdecay[i] > 1){ 70 | ldecay[i] = UINT32_MAX; 71 | } 72 | else if(hdecay[i] == 1 && cur_time > ltime[i] ){ 73 | ldecay[i] = UINT32_MAX; 74 | } 75 | else{ 76 | ldecay[i] = cur_time - ltime[i]; 77 | } 78 | 79 | 80 | // Do the debounce update 81 | if(!isHigh[i]){ 82 | if((__R31 & mask) == mask){ // signal is high 83 | if(ltime_diff > TWO_THOUSAND_HZ){ // debounce 84 | isHigh[i] = 1; 85 | counts[i]++; 86 | 87 | hdelta[i] = hdecay[i]; 88 | ldelta[i] = ldecay[i]; 89 | 90 | 91 | htime[i] = htime_ctr; 92 | ltime[i] = CT_IEP.TMR_CNT; 93 | } 94 | } 95 | } 96 | else{ 97 | 98 | if((__R31 & mask) != mask){ // signal is low 99 | if(ltime_diff > TWO_THOUSAND_HZ){ // debounce 100 | isHigh[i]=0; 101 | 102 | htime[i] = htime_ctr; 103 | ltime[i] = CT_IEP.TMR_CNT;; 104 | } 105 | } 106 | } 107 | } 108 | 109 | 110 | 111 | #endif /* OPTICAL_H_ */ 112 | -------------------------------------------------------------------------------- /BBBSetup/pru_encoder/targetConfigs/BeagleBone_Black.ccxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /BBBSetup/pru_encoder/targetConfigs/readme.txt: -------------------------------------------------------------------------------- 1 | The 'targetConfigs' folder contains target-configuration (.ccxml) files, automatically generated based 2 | on the device and connection settings specified in your project on the Properties > General page. 3 | 4 | Please note that in automatic target-configuration management, changes to the project's device and/or 5 | connection settings will either modify an existing or generate a new target-configuration file. Thus, 6 | if you manually edit these auto-generated files, you may need to re-apply your changes. Alternatively, 7 | you may create your own target-configuration file for this project and manage it manually. You can 8 | always switch back to automatic target-configuration management by checking the "Manage the project's 9 | target-configuration automatically" checkbox on the project's Properties > General page. -------------------------------------------------------------------------------- /BBBSetup/setupOverlay: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Compiling the overlays from .dts to .dtbo" 4 | dtc -O dtb -o BB-DCAN1-00A0.dtbo -b 0 -@ BB-DCAN1-00A0.dts 5 | dtc -O dtb -o BB-ADC-00A0.dtbo -b 0 -@ BB-ADC-00A0.dts 6 | dtc -O dtb -o BB-PWM1-00A0.dtbo -b 0 -@ BB-PWM1-00A0.dts 7 | dtc -O dtb -o BB-PRU-01-00A0.dtbo -b 0 -@ BB-PRU-01-00A0.dts 8 | dtc -O dtb -o BB-GPIO-01-00A0.dtbo -b 0 -@ BB-GPIO-01-00A0.dts 9 | dtc -O dtb -o w1-00A0.dtbo -b 0 -@ w1.dts 10 | 11 | echo "Copying the overlays into /lib/firmware" 12 | cp BB-DCAN1-00A0.dtbo /lib/firmware 13 | cp BB-ADC-00A0.dtbo /lib/firmware 14 | cp BB-PWM1-00A0.dtbo /lib/firmware 15 | cp BB-PRU-01-00A0.dtbo /lib/firmware 16 | cp BB-GPIO-01-00A0.dtbo /lib/firmware 17 | cp w1-00A0.dtbo /lib/firmware 18 | 19 | rm *.dtbo 20 | 21 | echo "Complete. Remember to include these overlays in the /boot/uEnv.txt file." 22 | echo "Once included in the uEnv.txt file, they will automatically be loaded" 23 | 24 | exit 0 25 | -------------------------------------------------------------------------------- /BaseStation/Backend/backend/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/BaseStation/Backend/backend/__init__.py -------------------------------------------------------------------------------- /BaseStation/Backend/backend/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for backend project. 3 | 4 | Generated by 'django-admin startproject' using Django 2.1.3. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.1/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/2.1/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'n*)$h)r4^xd8s0)3ul0$5@lw%jo#7e(qd)o!ukrga2u$sk3msg' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'podconnect', 35 | 'corsheaders', 36 | 'django.contrib.admin', 37 | 'django.contrib.auth', 38 | 'django.contrib.contenttypes', 39 | 'django.contrib.sessions', 40 | 'django.contrib.messages', 41 | 'django.contrib.staticfiles', 42 | ] 43 | 44 | MIDDLEWARE = [ 45 | 'corsheaders.middleware.CorsMiddleware', 46 | 'django.middleware.security.SecurityMiddleware', 47 | 'django.contrib.sessions.middleware.SessionMiddleware', 48 | 'django.middleware.common.CommonMiddleware', 49 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 50 | 'django.contrib.messages.middleware.MessageMiddleware', 51 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 52 | ] 53 | 54 | ROOT_URLCONF = 'backend.urls' 55 | 56 | TEMPLATES = [ 57 | { 58 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 59 | 'DIRS': [], 60 | 'APP_DIRS': True, 61 | 'OPTIONS': { 62 | 'context_processors': [ 63 | 'django.template.context_processors.debug', 64 | 'django.template.context_processors.request', 65 | 'django.contrib.auth.context_processors.auth', 66 | 'django.contrib.messages.context_processors.messages', 67 | ], 68 | }, 69 | }, 70 | ] 71 | 72 | WSGI_APPLICATION = 'backend.wsgi.application' 73 | 74 | 75 | # Database 76 | # https://docs.djangoproject.com/en/2.1/ref/settings/#databases 77 | 78 | DATABASES = { 79 | 'default': { 80 | 'ENGINE': 'django.db.backends.sqlite3', 81 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 82 | } 83 | } 84 | 85 | 86 | # Password validation 87 | # https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators 88 | 89 | AUTH_PASSWORD_VALIDATORS = [ 90 | { 91 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 92 | }, 93 | { 94 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 95 | }, 96 | { 97 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 98 | }, 99 | { 100 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 101 | }, 102 | ] 103 | 104 | 105 | # Internationalization 106 | # https://docs.djangoproject.com/en/2.1/topics/i18n/ 107 | 108 | LANGUAGE_CODE = 'en-us' 109 | 110 | TIME_ZONE = 'UTC' 111 | 112 | USE_I18N = True 113 | 114 | USE_L10N = True 115 | 116 | USE_TZ = True 117 | 118 | 119 | # Static files (CSS, JavaScript, Images) 120 | # https://docs.djangoproject.com/en/2.1/howto/static-files/ 121 | 122 | STATIC_URL = '/static/' 123 | 124 | CORS_ORIGIN_ALLOW_ALL = True -------------------------------------------------------------------------------- /BaseStation/Backend/backend/urls.py: -------------------------------------------------------------------------------- 1 | """backend URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.1/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import include, path 18 | 19 | urlpatterns = [ 20 | path('api/', include('podconnect.urls')), 21 | path('admin/', admin.site.urls), 22 | ] 23 | -------------------------------------------------------------------------------- /BaseStation/Backend/backend/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for backend project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /BaseStation/Backend/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/BaseStation/Backend/db.sqlite3 -------------------------------------------------------------------------------- /BaseStation/Backend/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == '__main__': 6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings') 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( "Couldn't import Django. Are you sure it's installed and " 11 | "available on your PYTHONPATH environment variable? Did you " 12 | "forget to activate a virtual environment?" 13 | ) from exc 14 | execute_from_command_line(sys.argv) 15 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/BaseStation/Backend/podconnect/__init__.py -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ReceiverConfig(AppConfig): 5 | name = 'receiver' 6 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/data_logic.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | from . import models, tcpserver, udpserver, stats_helper 3 | from django.http import HttpResponse, HttpRequest, JsonResponse 4 | from django.core.serializers import serialize 5 | import pickle 6 | import struct 7 | 8 | from threading import Lock 9 | import json 10 | 11 | def state(request): 12 | state_data = models.State.objects.latest("date_time") 13 | toReturn = state_data.state 14 | return HttpResponse(toReturn) 15 | 16 | def stats(request): 17 | toReturn = stats_helper.getStats() 18 | return JsonResponse(toReturn, safe=False) 19 | 20 | def battery(request): 21 | can_data = models.CANData.objects.latest("date_time") 22 | toReturn = { 23 | "value": can_data.pack_soc 24 | } 25 | print(can_data.pack_soc) 26 | return JsonResponse(toReturn) 27 | 28 | def position(request): 29 | motion_data = models.MotionData.objects.latest("date_time") 30 | toReturn = { 31 | "currentDistance":motion_data.position, 32 | "totalDistance":1200 33 | } 34 | return JsonResponse(toReturn) 35 | 36 | def stopPressed(request): 37 | if request.method == "POST": 38 | print("STOPPING") 39 | return HttpResponse() 40 | 41 | def readyPressed(request): 42 | if request.method == "POST": 43 | print("Ready!") 44 | return HttpResponse() 45 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.1.3 on 2019-01-22 03:58 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | initial = True 9 | 10 | dependencies = [ 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='DataPacket', 16 | fields=[ 17 | ('date_time', models.DateTimeField(auto_now=True, primary_key=True, serialize=False)), 18 | ('velocity', models.IntegerField(null=True)), 19 | ('acceleration', models.IntegerField(null=True)), 20 | ('position', models.IntegerField(null=True)), 21 | ], 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/migrations/0003_auto_20190504_0202.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.1 on 2019-05-04 02:02 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('podconnect', '0002_auto_20190503_2002'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='candata', 15 | old_name='fail_safe_sate', 16 | new_name='fail_safe_state', 17 | ), 18 | migrations.RenameField( 19 | model_name='candata', 20 | old_name='low_cell_voltge', 21 | new_name='low_cell_voltage', 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/migrations/0005_auto_20190715_1948.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.1.3 on 2019-07-15 19:48 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('podconnect', '0004_auto_20190713_1727'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='adcdata', 15 | old_name='data', 16 | new_name='data_0', 17 | ), 18 | migrations.AddField( 19 | model_name='adcdata', 20 | name='data_1', 21 | field=models.IntegerField(default=0), 22 | ), 23 | migrations.AddField( 24 | model_name='adcdata', 25 | name='data_2', 26 | field=models.IntegerField(default=0), 27 | ), 28 | migrations.AddField( 29 | model_name='adcdata', 30 | name='data_3', 31 | field=models.IntegerField(default=0), 32 | ), 33 | migrations.AddField( 34 | model_name='adcdata', 35 | name='data_4', 36 | field=models.IntegerField(default=0), 37 | ), 38 | migrations.AddField( 39 | model_name='adcdata', 40 | name='data_5', 41 | field=models.IntegerField(default=0), 42 | ), 43 | migrations.AddField( 44 | model_name='adcdata', 45 | name='data_6', 46 | field=models.IntegerField(default=0), 47 | ), 48 | ] 49 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/migrations/0006_auto_20190716_1821.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.1.3 on 2019-07-16 18:21 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('podconnect', '0005_auto_20190715_1948'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='motiondata', 15 | name='brake_state', 16 | field=models.IntegerField(default=0), 17 | ), 18 | migrations.AddField( 19 | model_name='motiondata', 20 | name='motor_state', 21 | field=models.IntegerField(default=0), 22 | ), 23 | migrations.AddField( 24 | model_name='motiondata', 25 | name='motor_target_torque', 26 | field=models.IntegerField(default=0), 27 | ), 28 | migrations.AddField( 29 | model_name='motiondata', 30 | name='relay_state_buff_0', 31 | field=models.CharField(default='', max_length=1), 32 | ), 33 | migrations.AddField( 34 | model_name='motiondata', 35 | name='relay_state_buff_1', 36 | field=models.CharField(default='', max_length=1), 37 | ), 38 | migrations.AddField( 39 | model_name='motiondata', 40 | name='relay_state_buff_2', 41 | field=models.CharField(default='', max_length=1), 42 | ), 43 | migrations.AddField( 44 | model_name='motiondata', 45 | name='relay_state_buff_3', 46 | field=models.CharField(default='', max_length=1), 47 | ), 48 | ] 49 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/migrations/0007_auto_20190716_2159.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.1.3 on 2019-07-16 21:59 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('podconnect', '0006_auto_20190716_1821'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='motiondata', 15 | name='relay_state_buff_0', 16 | field=models.IntegerField(default=0), 17 | ), 18 | migrations.AlterField( 19 | model_name='motiondata', 20 | name='relay_state_buff_1', 21 | field=models.IntegerField(default=0), 22 | ), 23 | migrations.AlterField( 24 | model_name='motiondata', 25 | name='relay_state_buff_2', 26 | field=models.IntegerField(default=0), 27 | ), 28 | migrations.AlterField( 29 | model_name='motiondata', 30 | name='relay_state_buff_3', 31 | field=models.IntegerField(default=0), 32 | ), 33 | ] 34 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/migrations/0008_auto_20190717_0051.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.1.3 on 2019-07-17 00:51 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('podconnect', '0007_auto_20190716_2159'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='motiondata', 15 | name='relay_state_buff_0', 16 | field=models.CharField(default=0, max_length=1), 17 | ), 18 | migrations.AlterField( 19 | model_name='motiondata', 20 | name='relay_state_buff_1', 21 | field=models.CharField(default=0, max_length=1), 22 | ), 23 | migrations.AlterField( 24 | model_name='motiondata', 25 | name='relay_state_buff_2', 26 | field=models.CharField(default=0, max_length=1), 27 | ), 28 | migrations.AlterField( 29 | model_name='motiondata', 30 | name='relay_state_buff_3', 31 | field=models.CharField(default=0, max_length=1), 32 | ), 33 | ] 34 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/migrations/0009_auto_20190718_0022.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.1.3 on 2019-07-18 00:22 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('podconnect', '0008_auto_20190717_0051'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='motiondata', 15 | name='a_counter', 16 | field=models.IntegerField(default=0), 17 | ), 18 | migrations.AddField( 19 | model_name='motiondata', 20 | name='a_timeout', 21 | field=models.IntegerField(default=0), 22 | ), 23 | migrations.AddField( 24 | model_name='motiondata', 25 | name='b_counter', 26 | field=models.IntegerField(default=0), 27 | ), 28 | migrations.AddField( 29 | model_name='motiondata', 30 | name='b_timeout', 31 | field=models.IntegerField(default=0), 32 | ), 33 | migrations.AddField( 34 | model_name='motiondata', 35 | name='c_counter', 36 | field=models.IntegerField(default=0), 37 | ), 38 | migrations.AddField( 39 | model_name='motiondata', 40 | name='c_timeout', 41 | field=models.IntegerField(default=0), 42 | ), 43 | migrations.AddField( 44 | model_name='motiondata', 45 | name='p_counter', 46 | field=models.IntegerField(default=0), 47 | ), 48 | migrations.AddField( 49 | model_name='motiondata', 50 | name='p_timeout', 51 | field=models.IntegerField(default=0), 52 | ), 53 | ] 54 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/migrations/0010_connecteddata.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.1.3 on 2019-07-20 17:56 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('podconnect', '0009_auto_20190718_0022'), 10 | ] 11 | 12 | operations = [ 13 | migrations.CreateModel( 14 | name='ConnectedData', 15 | fields=[ 16 | ('date_time', models.DateTimeField(auto_now=True, primary_key=True, serialize=False)), 17 | ('tcp_connected', models.IntegerField(default=0)), 18 | ('udp_connected', models.IntegerField(default=0)), 19 | ], 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/BaseStation/Backend/podconnect/migrations/__init__.py -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/space_x_packet.py: -------------------------------------------------------------------------------- 1 | from . import models 2 | import numpy as np 3 | 4 | TEAM_ID = np.uint8(0) 5 | 6 | def makeSpaceXPacket(): 7 | to_send = b'' 8 | to_send += TEAM_ID 9 | to_send += getStatus() 10 | to_send += getMotionData() 11 | to_send += getBatteryData() 12 | 13 | def getStatus(): 14 | return 0 15 | 16 | # Get position in centimeters 17 | def getMotionData(): 18 | return 0 19 | 20 | # Voltage Current Temperature 21 | def getBatteryData(): 22 | return 0 23 | 24 | def getPotTemp(): 25 | return 0 -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/tcphelper.py: -------------------------------------------------------------------------------- 1 | # Converts bytes to integer values uint32 2 | def bytes_to_int(bytes, length): 3 | new_bytes = [] 4 | for x in range(0, length): 5 | new_bytes.append(int.from_bytes( 6 | bytes[(x*4):(x*4+4)], byteorder='little', signed=False)) 7 | return new_bytes 8 | 9 | # int16 10 | def bytes_to_int16(bytes, length): 11 | new_bytes = [] 12 | for x in range(0, length): 13 | new_bytes.append(int.from_bytes( 14 | bytes[(x*2):(x*2+2)], byteorder='little', signed=True)) 15 | return new_bytes 16 | 17 | def bytes_to_signed_int32(bytes, length): 18 | new_bytes = [] 19 | for x in range(0, length): 20 | new_bytes.append(int.from_bytes( 21 | bytes[(x*4):(x*4+4)], byteorder='little', signed=True)) 22 | return new_bytes 23 | 24 | def bytes_to_signed_int64(bytes, length): 25 | new_bytes = [] 26 | for x in range(0, length): 27 | new_bytes.append(int.from_bytes( 28 | bytes[(x*8):(x*8+8)], byteorder='little', signed=True)) 29 | return new_bytes 30 | 31 | def bytes_to_char(bytes, length): 32 | new_bytes = [] 33 | for x in range(0, length): 34 | new_bytes.append(int.from_bytes( 35 | bytes[(x):(x+1)], byteorder='little')) 36 | return new_bytes 37 | 38 | def bytes_to_uint8(bytes, length): 39 | new_bytes = [] 40 | for x in range(0, length): 41 | new_bytes.append(int.from_bytes( 42 | bytes[(x):(x+1)], byteorder='little', signed=False)) 43 | return new_bytes -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/udp_dev.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import time 3 | UDP_IP = "127.0.0.1" 4 | UDP_PORT = 5005 5 | MESSAGE = "PING" 6 | 7 | print "UDP target IP:", UDP_IP 8 | print "UDP target port:", UDP_PORT 9 | 10 | sock2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP 11 | sock2.bind((UDP_IP, 5004)) 12 | 13 | sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP 14 | 15 | sock2.settimeout(1.5) #if socket gets nothin in x seconds, throws an error 16 | 17 | while True: 18 | sock.sendto(MESSAGE, (UDP_IP, 5005)) 19 | try: 20 | data, addr = sock2.recvfrom(1024) # buffer size is 1024 bytes 21 | print "SENDERE: received message:", data 22 | time.sleep(.9) 23 | except: 24 | print "Never received message" 25 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/udpserver.py: -------------------------------------------------------------------------------- 1 | from threading import Thread, Lock, Event 2 | import numpy as np 3 | from . import models 4 | import time, socket, queue 5 | 6 | # Initialize command queue 7 | COMMAND_QUEUE = queue.Queue() 8 | 9 | send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP 10 | UDP_RECV_IP = '' 11 | UDP_SEND_IP = '192.168.6.2' # 192.168.6.2 12 | UDP_SEND_PORT = 5005 13 | UDP_RECV_PORT = 5004 14 | MSG_TO_SEND = "PING" 15 | MSG_TO_RECV = "ACK" 16 | 17 | def getPodIPAndPort(): 18 | global UDP_SEND_IP, UDP_SEND_PORT 19 | return UDP_SEND_IP, UDP_SEND_PORT 20 | 21 | def serve(): 22 | global send_sock, UDP_RECV_IP, UDP_SEND_IP, UDP_SEND_PORT, UDP_RECV_PORT, MSG_TO_RECV, MSG_TO_SEND 23 | 24 | 25 | e = Event() # Used instead of time.sleep() 26 | 27 | recv_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP 28 | recv_sock.bind((UDP_RECV_IP, UDP_RECV_PORT)) 29 | recv_sock.settimeout(0.2) # Set timeout of recvfrom 30 | 31 | 32 | 33 | print("UDP Send Addr= {addr}:{port}".format(addr=UDP_SEND_IP,port=UDP_SEND_PORT)) 34 | while (True): 35 | send_sock.sendto(MSG_TO_SEND.encode(), (UDP_SEND_IP, UDP_SEND_PORT)) 36 | try: 37 | data, addr = recv_sock.recvfrom(1024) # buffer size is 1024 bytes 38 | if data.decode() == MSG_TO_RECV: 39 | # wait a small ammount of time, as to not cause a flood of messages back and forth 40 | e.wait( timeout=0.020); 41 | #print ("UDP: (comment me out) received correct message: ", data.decode()) 42 | else: 43 | print ("UDP: received incorrect message: ", data.decode()) 44 | # # TODO: Determine what to do in this case! 45 | # # TODO: Does it mean the network is bad? 46 | # # TODO: Should we throw an error?? 47 | except Exception as f: 48 | #print(f) 49 | pass 50 | 51 | def sendData(): 52 | global send_sock, COMMAND_QUEUE, UDP_SEND_IP, UDP_SEND_PORT 53 | # Sending data 54 | while True: 55 | if not COMMAND_QUEUE.empty(): 56 | command = COMMAND_QUEUE.get() 57 | try: 58 | print("Sending " + str(command)) 59 | for message in command: 60 | convmessage = np.uint32(message) 61 | send_sock.sendto(convmessage, (UDP_SEND_IP, UDP_SEND_PORT)) 62 | except Exception as e: 63 | print(e) 64 | #COMMAND_QUEUE.put(command) 65 | 66 | time.sleep(0.2) 67 | 68 | # Starts thread for tcp server and processor 69 | def start(): 70 | t1 = Thread(target=serve) 71 | t1.start() 72 | t2 = Thread(target=sendData) 73 | t2.start() 74 | 75 | def addToCommandQueue(toSend): 76 | print(str(toSend) + " Added to Queue") 77 | COMMAND_QUEUE.put(toSend) 78 | -------------------------------------------------------------------------------- /BaseStation/Backend/podconnect/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from . import data_logic, actions_logic 4 | 5 | urlpatterns = [ 6 | path('data/battery', data_logic.battery, name="data-latest"), 7 | #path('data/warnings', data_logic.warnings, name="data-warnings"), 8 | path('data/state', data_logic.state, name="state"), 9 | path('data/stats', data_logic.stats, name="data-stats"), 10 | #path('data/stats/essential', data_logic.essential_stats, name="data-essential-stats"), 11 | path('data/position', data_logic.position, name="data-position"), 12 | path('commands/button', actions_logic.buttonPressed, name="command-button"), 13 | path('commands/dev', actions_logic.devCommand, name="command-dev"), 14 | path('commands/servers', actions_logic.startupServers, name="startServers"), 15 | ] -------------------------------------------------------------------------------- /BaseStation/Backend/requirements.txt: -------------------------------------------------------------------------------- 1 | django 2 | django-cors-headers 3 | numpy 4 | -------------------------------------------------------------------------------- /BaseStation/README.md: -------------------------------------------------------------------------------- 1 | # How to automatically start everything 2 | * Make sure you have pip3 and nodejs installed 3 | * run `./install_requirements.sh` to install requirements 4 | * run `./start_basestation.sh` to start everything 5 | * run `./kill_basestation.sh` to kill everything 6 | 7 | # How to start the backend manually 8 | * First navigate to the Backend folder 9 | * Make sure all requirements are installed by running `pip install -r requirements.txt` 10 | * Then run `python manage.py runserver` 11 | 12 | This will spawn the HTTP server. 13 | By default the HTTP server will run on port 8000. 14 | 15 | # How to start the frontend manually3 16 | * Navigate to the frontend folder 17 | * Make sure you have npm installed 18 | * Run `npm install` (you might need to run `npm install -g @angular/cli` as well) 19 | * Run `npm start` 20 | 21 | # Information about data storage 22 | * Data is stored in a sqlite3 database named db.sqlite3. This database will store every tcp command received and will 23 | * To delete all data simply `rm db.sqlite3`, then run `python manage.py migrate`. Then you can start the server again with no issues 24 | 25 | # ToDo 26 | * UDP port is not detecting if it is in use. Needs to be fixed. 27 | * [Issue 101 on github](https://github.com/IlliniHyperloopComputing/Pod/issues/101) has data that needs to be processed. 28 | * More stats need to be shown 29 | * Name the state 30 | * Stat danger calculations 31 | * Finish command code implementation 32 | * Testing on heavy load 33 | * Beautify 34 | -------------------------------------------------------------------------------- /BaseStation/frontend/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /BaseStation/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events.json 15 | speed-measure-plugin.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /BaseStation/frontend/README.md: -------------------------------------------------------------------------------- 1 | # ToDo 2 | 3 | * Implement warnings indicator as well as buttons 4 | * Get live updating information 5 | 6 | # Frontend 7 | 8 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.0.3. 9 | 10 | ## Development server 11 | 12 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 13 | 14 | ## Code scaffolding 15 | 16 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 17 | 18 | ## Build 19 | 20 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 21 | 22 | ## Running unit tests 23 | 24 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 25 | 26 | ## Running end-to-end tests 27 | 28 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 29 | 30 | ## Further help 31 | 32 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 33 | -------------------------------------------------------------------------------- /BaseStation/frontend/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /BaseStation/frontend/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | 'browserName': 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 31 | } 32 | }; -------------------------------------------------------------------------------- /BaseStation/frontend/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('Welcome to frontend!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /BaseStation/frontend/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root h1')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /BaseStation/frontend/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /BaseStation/frontend/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/frontend'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /BaseStation/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e" 11 | }, 12 | "private": true, 13 | "dependencies": { 14 | "@angular/animations": "~8.0.1", 15 | "@angular/common": "~8.0.1", 16 | "@angular/compiler": "~8.0.1", 17 | "@angular/core": "~8.0.1", 18 | "@angular/forms": "~8.0.1", 19 | "@angular/platform-browser": "~8.0.1", 20 | "@angular/platform-browser-dynamic": "~8.0.1", 21 | "@angular/router": "~8.0.1", 22 | "rxjs": "~6.4.0", 23 | "tslib": "^1.9.0", 24 | "zone.js": "~0.9.1" 25 | }, 26 | "devDependencies": { 27 | "@angular-devkit/build-angular": "^0.800.3", 28 | "@angular/cli": "~8.0.3", 29 | "@angular/compiler-cli": "~8.0.1", 30 | "@angular/language-service": "~8.0.1", 31 | "@types/jasmine": "~3.3.8", 32 | "@types/jasminewd2": "~2.0.3", 33 | "@types/node": "~8.9.4", 34 | "codelyzer": "^5.0.0", 35 | "jasmine-core": "~3.4.0", 36 | "jasmine-spec-reporter": "~4.2.1", 37 | "karma": "~4.1.0", 38 | "karma-chrome-launcher": "~2.2.0", 39 | "karma-coverage-istanbul-reporter": "~2.0.1", 40 | "karma-jasmine": "~2.0.1", 41 | "karma-jasmine-html-reporter": "^1.4.0", 42 | "protractor": "~5.4.0", 43 | "ts-node": "~7.0.0", 44 | "tslint": "~5.15.0", 45 | "typescript": "~3.4.3" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | 4 | const routes: Routes = []; 5 | 6 | @NgModule({ 7 | imports: [RouterModule.forRoot(routes)], 8 | exports: [RouterModule] 9 | }) 10 | export class AppRoutingModule { } 11 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | .main { 2 | position: absolute; 3 | left: 30%; 4 | width: 40%; 5 | } 6 | 7 | .warning { 8 | float: right; 9 | } -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | Angular Logo 6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { RouterTestingModule } from '@angular/router/testing'; 3 | import { AppComponent } from './app.component'; 4 | 5 | describe('AppComponent', () => { 6 | beforeEach(async(() => { 7 | TestBed.configureTestingModule({ 8 | imports: [ 9 | RouterTestingModule 10 | ], 11 | declarations: [ 12 | AppComponent 13 | ], 14 | }).compileComponents(); 15 | })); 16 | 17 | it('should create the app', () => { 18 | const fixture = TestBed.createComponent(AppComponent); 19 | const app = fixture.debugElement.componentInstance; 20 | expect(app).toBeTruthy(); 21 | }); 22 | 23 | it(`should have as title 'frontend'`, () => { 24 | const fixture = TestBed.createComponent(AppComponent); 25 | const app = fixture.debugElement.componentInstance; 26 | expect(app.title).toEqual('frontend'); 27 | }); 28 | 29 | it('should render title in a h1 tag', () => { 30 | const fixture = TestBed.createComponent(AppComponent); 31 | fixture.detectChanges(); 32 | const compiled = fixture.debugElement.nativeElement; 33 | expect(compiled.querySelector('h1').textContent).toContain('Welcome to frontend!'); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { HttpClient, HttpHeaders } from '@angular/common/http'; 3 | 4 | @Component({ 5 | selector: 'app-root', 6 | templateUrl: './app.component.html', 7 | styleUrls: ['./app.component.css'] 8 | }) 9 | export class AppComponent { 10 | title = 'frontend'; 11 | 12 | httpOptions = { 13 | headers: new HttpHeaders({ 14 | 'Content-Type': 'application/json' 15 | }) 16 | } 17 | 18 | constructor(private http: HttpClient) { } 19 | 20 | ngOnInit() { 21 | this.startServers(); 22 | } 23 | 24 | startServers() { 25 | return this.http.post("http://localhost:8000/api/commands/servers", null, this.httpOptions).subscribe(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { AppRoutingModule } from './app-routing.module'; 5 | import { AppComponent } from './app.component'; 6 | import { BatteryComponent } from './components/battery/battery.component'; 7 | import { PositionComponent } from './components/position/position.component'; 8 | import { DiagnosticsComponent } from './components/diagnostics/diagnostics.component'; 9 | import { WarningComponent } from './components/warning/warning.component'; 10 | import { StatsComponent } from './components/stats/stats.component'; 11 | import { ButtonsComponent } from './components/buttons/buttons.component'; 12 | import { HttpClientModule } from '@angular/common/http'; 13 | import { StateComponent } from './components/state/state.component'; 14 | 15 | @NgModule({ 16 | declarations: [ 17 | AppComponent, 18 | BatteryComponent, 19 | PositionComponent, 20 | DiagnosticsComponent, 21 | WarningComponent, 22 | StatsComponent, 23 | ButtonsComponent, 24 | StateComponent 25 | ], 26 | imports: [ 27 | BrowserModule, 28 | AppRoutingModule, 29 | HttpClientModule 30 | ], 31 | providers: [], 32 | bootstrap: [AppComponent] 33 | }) 34 | export class AppModule { } 35 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/battery/battery.component.css: -------------------------------------------------------------------------------- 1 | progress[value] { 2 | -webkit-appearance: none; 3 | appearance: none; 4 | 5 | position: absolute; 6 | top: 1%; 7 | width: 20%; 8 | height: 2.5%; 9 | } 10 | 11 | .batteryTitle { 12 | position: absolute; 13 | top: 3.5%; 14 | } -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/battery/battery.component.html: -------------------------------------------------------------------------------- 1 | 2 |
Battery {{ battery.value }}%
-------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/battery/battery.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { BatteryComponent } from './battery.component'; 4 | 5 | describe('BatteryComponent', () => { 6 | let component: BatteryComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ BatteryComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(BatteryComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/battery/battery.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { interval } from 'rxjs'; 3 | 4 | import { BatteryService } from '../../services/battery.service'; 5 | import { Battery } from '../../models/battery'; 6 | 7 | @Component({ 8 | selector: 'app-battery', 9 | templateUrl: './battery.component.html', 10 | styleUrls: ['./battery.component.css'] 11 | }) 12 | export class BatteryComponent implements OnInit { 13 | battery:Battery = { "value": 0 }; 14 | 15 | constructor(private batteryService: BatteryService) { 16 | interval(50).subscribe(x => { 17 | this.getValue(); 18 | }) 19 | } 20 | 21 | ngOnInit() { 22 | this.getValue(); 23 | } 24 | 25 | getValue() { 26 | this.batteryService.getBatteryStatus().subscribe((data: Battery) => this.battery = { ...data }) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/buttons/buttons.component.css: -------------------------------------------------------------------------------- 1 | .leftButton { 2 | position: absolute; 3 | bottom: 8px; 4 | left: 16px; 5 | width: 10%; 6 | height: 10%; 7 | border-radius: 7%; 8 | cursor: pointer; 9 | background-color:lightgreen; 10 | } 11 | 12 | .rightButton { 13 | position: absolute; 14 | bottom: 8px; 15 | right: 16px; 16 | width: 10%; 17 | height: 10%; 18 | border-radius: 7%; 19 | cursor: pointer; 20 | background-color:red; 21 | } -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/buttons/buttons.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
-------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/buttons/buttons.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ButtonsComponent } from './buttons.component'; 4 | 5 | describe('ButtonsComponent', () => { 6 | let component: ButtonsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ButtonsComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ButtonsComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/buttons/buttons.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import { ButtonsService } from '../../services/buttons.service'; 4 | 5 | import { interval } from 'rxjs'; 6 | 7 | @Component({ 8 | selector: 'app-buttons', 9 | templateUrl: './buttons.component.html', 10 | styleUrls: ['./buttons.component.css'] 11 | }) 12 | export class ButtonsComponent implements OnInit { 13 | leftButtonName:string = "Ready"; 14 | rightButtonName:string = "E-Stop"; 15 | constructor(private bs: ButtonsService) { } 16 | 17 | ngOnInit() { 18 | interval(100).subscribe(x => { 19 | this.setInitialName(); 20 | }) 21 | } 22 | 23 | setInitialName() { 24 | this.bs.getState().subscribe((data:number) => this.leftButtonName = this.stateToName(data)) 25 | 26 | } 27 | 28 | clickLeft() { 29 | this.bs.clickLeft().subscribe((data:number) => this.leftButtonName = this.stateToName(data)) 30 | } 31 | 32 | clickRight() { 33 | this.bs.clickRight().subscribe() 34 | } 35 | 36 | stateToName(state:number):string { 37 | if (state == 0) { 38 | return "Test Outside" 39 | } 40 | else if (state == 1) { 41 | return "Loading" 42 | } 43 | else if (state == 2) { 44 | return "Test Inside" 45 | } 46 | else if (state == 3) { 47 | return "Ready" 48 | } 49 | else if (state == 4) { 50 | return "Launch" 51 | } 52 | else { 53 | return "NO USE" 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/diagnostics/diagnostics.component.css: -------------------------------------------------------------------------------- 1 | .value { 2 | position: absolute; 3 | bottom: 1%; 4 | width: 10%; 5 | height: 3.5%; 6 | left: 45%; 7 | color: gray; 8 | } 9 | 10 | .commands { 11 | position: absolute; 12 | bottom: 1%; 13 | width: 10%; 14 | height: 4%; 15 | left: 35%; 16 | border-radius: 2px; 17 | } 18 | 19 | .submit { 20 | position: absolute; 21 | bottom: 1%; 22 | width: 5%; 23 | height: 4%; 24 | left: 55.5%; 25 | } 26 | 27 | .sentText { 28 | position: absolute; 29 | bottom: 5%; 30 | left: 40%; 31 | } -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/diagnostics/diagnostics.component.html: -------------------------------------------------------------------------------- 1 |
2 |
{{sentText}}
3 | 8 | 9 | 10 |
11 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/diagnostics/diagnostics.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { DiagnosticsComponent } from './diagnostics.component'; 4 | 5 | describe('DiagnosticsComponent', () => { 6 | let component: DiagnosticsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ DiagnosticsComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DiagnosticsComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/diagnostics/diagnostics.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import { Diagnostics, Command } from '../../models/diagnostics'; 4 | import { DiagnosticsService } from '../../services/diagnostics.service'; 5 | 6 | @Component({ 7 | selector: 'app-diagnostics', 8 | templateUrl: './diagnostics.component.html', 9 | styleUrls: ['./diagnostics.component.css'] 10 | }) 11 | export class DiagnosticsComponent implements OnInit { 12 | data:Diagnostics; 13 | sentText:string = ""; 14 | 15 | constructor(private ds: DiagnosticsService) { } 16 | 17 | ngOnInit() { 18 | this.data = { 19 | "commands": [{ 20 | "name":"TRANS_SAFE_MODE", 21 | "value":0 22 | }, 23 | { 24 | "name":"TRANS_FUNCTIONAL_TEST_OUTSIDE", 25 | "value":1 26 | }, 27 | { 28 | "name":"TRANS_LOADING", 29 | "value":2 30 | }, 31 | { 32 | "name":"TRANS_FUNCTIONAL_TEST_INSIDE", 33 | "value":3 34 | }, 35 | { 36 | "name":"TRANS_LAUNCH_READY", 37 | "value":4 38 | }, 39 | { 40 | "name":"TRANS_FLIGHT_ACCEL", 41 | "value":5 42 | }, 43 | { 44 | "name":"ENABLE_MOTOR", 45 | "value":6 46 | }, 47 | { 48 | "name":"DISABLE_MOTOR", 49 | "value":7 50 | }, 51 | { 52 | "name":"SET_MOTOR_SPEED", 53 | "value":8 54 | }, 55 | { 56 | "name":"ENABLE_BRAKE", 57 | "value":9 58 | }, 59 | { 60 | "name":"DISABLE_BRAKE", 61 | "value":10 62 | }, 63 | { 64 | "name":"TRANS_FLIGHT_COAST", 65 | "value":11 66 | }, 67 | { 68 | "name":"TRANS_FLIGHT_BRAKE", 69 | "value":12 70 | }, 71 | { 72 | "name":"TRANS_ABORT", 73 | "value":13 74 | }, 75 | { 76 | "name":"SET_ADC_ERROR", 77 | "value":14 78 | }, 79 | { 80 | "name":"SET_CAN_ERROR", 81 | "value":15 82 | }, 83 | { 84 | "name":"TSET_I2C_ERROR", 85 | "value":16 86 | }, 87 | { 88 | "name":"SET_PRU_ERROR", 89 | "value":17 90 | }, 91 | { 92 | "name":"SET_NETWORK_ERROR", 93 | "value":18 94 | }, 95 | { 96 | "name":"SET_OTHER_ERROR", 97 | "value":19 98 | }, 99 | { 100 | "name":"CLR_ADC_ERROR", 101 | "value":20 102 | }, 103 | { 104 | "name":"CLR_CAN_ERROR", 105 | "value":21 106 | }, 107 | { 108 | "name":"CLR_I2C_ERROR", 109 | "value":22 110 | }, 111 | { 112 | "name":"CLR_PRU_ERROR", 113 | "value":23 114 | }, 115 | { 116 | "name":"CLR_NETWORK_ERROR", 117 | "value":24 118 | }, 119 | { 120 | "name":"CLR_OTHER_ERROR", 121 | "value":25 122 | }, 123 | { 124 | "name":"SET_HV_RELAY_HV_POLE", 125 | "value":26 126 | }, 127 | { 128 | "name":"SET_HV_RELAY_LV_POLE", 129 | "value":27 130 | }, 131 | { 132 | "name":"SET_HV_RELAY_PRE_CHARGE", 133 | "value":28 134 | }, 135 | { 136 | "name":"CALC_ACCEL_ZERO_G", 137 | "value":29 138 | }], 139 | "currValue": 0, 140 | "currCommand": 1 141 | } 142 | } 143 | 144 | onSelect(value:number) { 145 | this.data.currCommand = value; 146 | } 147 | 148 | onEvent(currValue:number) { 149 | this.data.currValue = currValue; 150 | } 151 | 152 | onSubmit() { 153 | this.ds.sendStatus(this.data); 154 | this.sentText = "Sent: " + this.data.currCommand + ": " + this.data.currValue; 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/launch/launch.component.css: -------------------------------------------------------------------------------- 1 | .launch { 2 | width: 200px; 3 | height: 100px; 4 | background-color: rgb(24, 113, 143); 5 | cursor: pointer; 6 | border-radius: 15px; 7 | font-weight: bold; 8 | } -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/launch/launch.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/launch/launch.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { LaunchComponent } from './launch.component'; 4 | 5 | describe('LaunchComponent', () => { 6 | let component: LaunchComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ LaunchComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(LaunchComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/launch/launch.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-launch', 5 | templateUrl: './launch.component.html', 6 | styleUrls: ['./launch.component.css'] 7 | }) 8 | export class LaunchComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/position/position.component.css: -------------------------------------------------------------------------------- 1 | .positionBar { 2 | position: absolute; 3 | bottom: 10%; 4 | left: 15%; 5 | width: 70%; 6 | } 7 | 8 | .positionTitle { 9 | position: absolute; 10 | bottom: 5%; 11 | left: 17.5%; 12 | } -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/position/position.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |

4 | Position: {{position.currentDistance}}m/{{position.totalDistance}}m 5 |

6 |
-------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/position/position.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { PositionComponent } from './position.component'; 4 | 5 | describe('PositionComponent', () => { 6 | let component: PositionComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ PositionComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(PositionComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/position/position.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { interval } from 'rxjs'; 3 | 4 | import { PositionService } from '../../services/position.service'; 5 | import { Position } from '../../models/position'; 6 | @Component({ 7 | selector: 'app-position', 8 | templateUrl: './position.component.html', 9 | styleUrls: ['./position.component.css'] 10 | }) 11 | export class PositionComponent implements OnInit { 12 | position: Position = { currentDistance:0, totalDistance:100}; 13 | 14 | constructor(private positionService: PositionService) { 15 | interval(500).subscribe(x => { 16 | this.getPosition(); 17 | }) 18 | } 19 | 20 | ngOnInit() { 21 | this.getPosition() 22 | } 23 | 24 | getPosition() { 25 | this.positionService.getPositionStatus().subscribe((data: Position) => this.position = data) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/state/state.component.css: -------------------------------------------------------------------------------- 1 | .stateName { 2 | position: absolute; 3 | right:1%; 4 | top:0%; 5 | } -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/state/state.component.html: -------------------------------------------------------------------------------- 1 |

State: {{stateName}}

2 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/state/state.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { StateComponent } from './state.component'; 4 | 5 | describe('StateComponent', () => { 6 | let component: StateComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ StateComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(StateComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/state/state.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import { StateService } from '../../services/state.service'; 4 | import { interval } from 'rxjs'; 5 | 6 | @Component({ 7 | selector: 'app-state', 8 | templateUrl: './state.component.html', 9 | styleUrls: ['./state.component.css'] 10 | }) 11 | export class StateComponent implements OnInit { 12 | stateName:string = "Disconnected"; 13 | 14 | constructor(private stateService: StateService) { 15 | interval(100).subscribe(x => { 16 | this.getValues(); 17 | }) 18 | } 19 | 20 | ngOnInit() { 21 | } 22 | 23 | getValues() { 24 | this.stateService.getState().subscribe( 25 | (data:string) => this.stateName = this.convertNumToName(data), 26 | error => this.stateName = "Disconnected" 27 | ) 28 | } 29 | 30 | convertNumToName(stateNum:string):string { 31 | var toRet = ""; 32 | if (stateNum == "0") { 33 | toRet = "SAFE_MODE" 34 | } 35 | else if (stateNum == "1") { 36 | toRet = "FUNCTIONAL_TEST_OUTSIDE" 37 | } 38 | else if (stateNum == "2") { 39 | toRet = "LOADING" 40 | } 41 | else if (stateNum == "3") { 42 | toRet = "FUNCTIONAL_TEST_INSIDE" 43 | } 44 | else if (stateNum == "4") { 45 | toRet = "LAUNCH_READY" 46 | } 47 | else if (stateNum == "5") { 48 | toRet = "FLIGHT_ACCEL" 49 | } 50 | else if (stateNum == "6") { 51 | toRet = "FLIGHT_COAST" 52 | } 53 | else if (stateNum == "7") { 54 | toRet = "FLIGHT_BRAKE" 55 | } 56 | else if (stateNum == "8") { 57 | toRet = "FLIGHT_ABORT" 58 | } 59 | else { 60 | toRet = "STATE OVERFLOW" 61 | } 62 | return toRet 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/stats/stats.component.css: -------------------------------------------------------------------------------- 1 | .table1 { 2 | border-collapse: collapse; 3 | position: absolute; 4 | top: 10%; 5 | left: 1%; 6 | } 7 | 8 | .table2 { 9 | border-collapse: collapse; 10 | position: absolute; 11 | top: 10%; 12 | left: 26%; 13 | } 14 | 15 | .table3 { 16 | border-collapse: collapse; 17 | position: absolute; 18 | top: 10%; 19 | left: 47.5%; 20 | } 21 | 22 | .table4 { 23 | border-collapse: collapse; 24 | position: absolute; 25 | top: 10%; 26 | left: 70%; 27 | } 28 | 29 | tr, td, th { 30 | border: 1px solid black; 31 | } -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/stats/stats.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 7 | 10 | 13 | 16 | 19 | 20 | 21 | 24 | 27 | 30 | 33 | 36 | 37 |
5 | Name 6 | 8 | Low 9 | 11 | Value 12 | 14 | High 15 | 17 | Units 18 |
22 | {{ stat.name }} 23 | 25 | {{ stat.low }} 26 | 28 | {{ stat.value }} 29 | 31 | {{ stat.high }} 32 | 34 | {{ stat.units }} 35 |
38 | 39 | 40 | 43 | 46 | 49 | 52 | 55 | 56 | 57 | 60 | 63 | 66 | 69 | 72 | 73 |
41 | Name 42 | 44 | Low 45 | 47 | Value 48 | 50 | High 51 | 53 | Units 54 |
58 | {{ stat.name }} 59 | 61 | {{ stat.low }} 62 | 64 | {{ stat.value }} 65 | 67 | {{ stat.high }} 68 | 70 | {{ stat.units }} 71 |
74 | 75 | 76 | 79 | 82 | 85 | 88 | 91 | 92 | 93 | 96 | 99 | 102 | 105 | 108 | 109 |
77 | Name 78 | 80 | Low 81 | 83 | Value 84 | 86 | High 87 | 89 | Units 90 |
94 | {{ stat.name }} 95 | 97 | {{ stat.low }} 98 | 100 | {{ stat.value }} 101 | 103 | {{ stat.high }} 104 | 106 | {{ stat.units }} 107 |
110 | 111 | 112 | 115 | 118 | 121 | 124 | 127 | 128 | 129 | 132 | 135 | 138 | 141 | 144 | 145 |
113 | Name 114 | 116 | Low 117 | 119 | Value 120 | 122 | High 123 | 125 | Units 126 |
130 | {{ stat.name }} 131 | 133 | {{ stat.low }} 134 | 136 | {{ stat.value }} 137 | 139 | {{ stat.high }} 140 | 142 | {{ stat.units }} 143 |
146 |
-------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/stats/stats.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { StatsComponent } from './stats.component'; 4 | 5 | describe('StatsComponent', () => { 6 | let component: StatsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ StatsComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(StatsComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/stats/stats.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { interval } from 'rxjs'; 3 | 4 | import { StatsService } from '../../services/stats.service'; 5 | import { Row } from '../../models/stat'; 6 | 7 | @Component({ 8 | selector: 'app-stats', 9 | templateUrl: './stats.component.html', 10 | styleUrls: ['./stats.component.css'] 11 | }) 12 | export class StatsComponent implements OnInit { 13 | stats:Row[]; 14 | 15 | constructor(private statsService: StatsService) { 16 | interval(50).subscribe(x => { 17 | this.getValues(); 18 | }) 19 | } 20 | 21 | ngOnInit() { 22 | this.getValues(); 23 | } 24 | 25 | getValues() { 26 | this.statsService.getStatStatus().subscribe((data: Row[]) => this.stats = data) 27 | } 28 | 29 | applyStyle(color:string) { 30 | return {"background-color": color}; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/warning/warning.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/BaseStation/frontend/src/app/components/warning/warning.component.css -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/warning/warning.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/warning/warning.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { WarningComponent } from './warning.component'; 4 | 5 | describe('WarningComponent', () => { 6 | let component: WarningComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ WarningComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(WarningComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/components/warning/warning.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import { warningInfo } from '../../models/warning'; 4 | import { WarningService } from '../../services/warning.service'; 5 | 6 | @Component({ 7 | selector: 'app-warning', 8 | templateUrl: './warning.component.html', 9 | styleUrls: ['./warning.component.css'] 10 | }) 11 | export class WarningComponent implements OnInit { 12 | value:warningInfo; 13 | constructor(private warningService: WarningService) { } 14 | 15 | ngOnInit() { 16 | this.getValue(); 17 | } 18 | 19 | getValue() { 20 | this.warningService.getWarningStatus().subscribe(value => this.value = value); 21 | } 22 | 23 | setMyStyles() { 24 | let styles = { 25 | 'background-color': this.value.warningColor, 26 | 'color': this.value.textColor, 27 | 'cursor': 'pointer' 28 | } 29 | 30 | return styles; 31 | } 32 | 33 | onClick() { 34 | alert(this.value.warnings); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/models/battery.ts: -------------------------------------------------------------------------------- 1 | export class Battery { 2 | value: number 3 | } -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/models/diagnostics.ts: -------------------------------------------------------------------------------- 1 | export class Diagnostics { 2 | commands: Command[]; 3 | currValue: number; 4 | currCommand: number; 5 | } 6 | 7 | export class Command { 8 | "name":string; 9 | "value":number; 10 | } -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/models/position.ts: -------------------------------------------------------------------------------- 1 | export class Position { 2 | currentDistance: number; 3 | totalDistance: number; 4 | } -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/models/stat.ts: -------------------------------------------------------------------------------- 1 | export class Stat { 2 | name:string; 3 | value:number; 4 | color:string; 5 | low:string; 6 | high:string; 7 | units:string; 8 | } 9 | 10 | export class Row { 11 | stats:Stat[]; 12 | } -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/models/warning.ts: -------------------------------------------------------------------------------- 1 | export class warningInfo { 2 | warnings:string[]; 3 | topWarning:string; 4 | warningColor:string; 5 | textColor:string; 6 | } -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/services/battery.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { BatteryService } from './battery.service'; 4 | 5 | describe('BatteryService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: BatteryService = TestBed.get(BatteryService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/services/battery.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Observable, of } from 'rxjs'; 3 | import { HttpClient } from '@angular/common/http'; 4 | 5 | import { Battery } from '../models/battery'; 6 | 7 | @Injectable({ 8 | providedIn: 'root' 9 | }) 10 | export class BatteryService { 11 | 12 | constructor(private http: HttpClient) { } 13 | 14 | getBatteryStatus(): Observable { 15 | return this.http.get("http://localhost:8000/api/data/battery"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/services/buttons.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { ButtonsService } from './buttons.service'; 4 | 5 | describe('ButtonsService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: ButtonsService = TestBed.get(ButtonsService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/services/buttons.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { HttpClient, HttpHeaders } from '@angular/common/http'; 4 | 5 | @Injectable({ 6 | providedIn: 'root' 7 | }) 8 | export class ButtonsService { 9 | httpOptions = { 10 | headers: new HttpHeaders({ 11 | 'Content-Type': 'application/json' 12 | }) 13 | } 14 | 15 | constructor(private http: HttpClient) { } 16 | 17 | clickLeft() { 18 | const toSend = { 19 | "button":"ready" 20 | } 21 | console.log(toSend) 22 | return this.http.post("http://localhost:8000/api/commands/button", toSend, this.httpOptions); 23 | } 24 | 25 | clickRight() { 26 | const toSend = { 27 | "button":"e-stop" 28 | } 29 | return this.http.post("http://localhost:8000/api/commands/button", toSend, this.httpOptions); 30 | } 31 | 32 | getState() { 33 | return this.http.get("http://localhost:8000/api/data/state"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/services/diagnostics.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { DiagnosticsService } from './diagnostics.service'; 4 | 5 | describe('DiagnosticsService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: DiagnosticsService = TestBed.get(DiagnosticsService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/services/diagnostics.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { HttpClient, HttpHeaders } from '@angular/common/http'; 3 | import { Diagnostics } from '../models/diagnostics'; 4 | 5 | @Injectable({ 6 | providedIn: 'root' 7 | }) 8 | export class DiagnosticsService { 9 | httpOptions = { 10 | headers: new HttpHeaders({ 11 | 'Content-Type': 'application/json' 12 | })} 13 | 14 | constructor(private http:HttpClient) { } 15 | 16 | sendStatus(diagnostic:Diagnostics) { 17 | const toSend = { 18 | "command":diagnostic.currCommand, 19 | "value":diagnostic.currValue 20 | } 21 | console.log(toSend) 22 | this.http.post("http://localhost:8000/api/commands/dev", toSend, this.httpOptions).subscribe(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/services/position.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { PositionService } from './position.service'; 4 | 5 | describe('PositionService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: PositionService = TestBed.get(PositionService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/services/position.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Observable } from 'rxjs'; 3 | import { HttpClient } from '@angular/common/http'; 4 | 5 | import { Position } from '../models/position'; 6 | 7 | @Injectable({ 8 | providedIn: 'root' 9 | }) 10 | export class PositionService { 11 | 12 | constructor(private http: HttpClient) {} 13 | 14 | getPositionStatus(): Observable { 15 | return this.http.get("http://localhost:8000/api/data/position"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/services/state.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { StateService } from './state.service'; 4 | 5 | describe('StateService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: StateService = TestBed.get(StateService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/services/state.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { HttpClient } from '@angular/common/http'; 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class StateService { 8 | 9 | constructor(private http: HttpClient) { } 10 | 11 | getState() { 12 | return this.http.get("http://localhost:8000/api/data/state") 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/services/stats.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { StatsService } from './stats.service'; 4 | 5 | describe('StatsService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: StatsService = TestBed.get(StatsService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/services/stats.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Observable } from 'rxjs'; 3 | import { HttpClient } from '@angular/common/http'; 4 | 5 | import { Row } from '../models/stat'; 6 | 7 | @Injectable({ 8 | providedIn: 'root' 9 | }) 10 | export class StatsService { 11 | 12 | constructor(private http: HttpClient) {} 13 | 14 | getStatStatus(): Observable { 15 | return this.http.get("http://localhost:8000/api/data/stats"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/services/warning.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { WarningService } from './warning.service'; 4 | 5 | describe('WarningService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: WarningService = TestBed.get(WarningService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/app/services/warning.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Observable, of } from 'rxjs'; 3 | 4 | import { warningInfo } from '../models/warning'; 5 | 6 | @Injectable({ 7 | providedIn: 'root' 8 | }) 9 | export class WarningService { 10 | 11 | constructor() { } 12 | 13 | getWarningStatus(): Observable { 14 | const warn:warningInfo = { 15 | warnings: ["Something", "Not so bad!"], 16 | topWarning: "Not so bad!", 17 | warningColor: "LimeGreen", 18 | textColor: "black" 19 | } 20 | 21 | return of(warn); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/BaseStation/frontend/src/assets/.gitkeep -------------------------------------------------------------------------------- /BaseStation/frontend/src/assets/images/Hyperloop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/BaseStation/frontend/src/assets/images/Hyperloop.png -------------------------------------------------------------------------------- /BaseStation/frontend/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/BaseStation/frontend/src/favicon.ico -------------------------------------------------------------------------------- /BaseStation/frontend/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Midwest Hyperloop 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags.ts'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /BaseStation/frontend/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /BaseStation/frontend/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "include": [ 8 | "src/**/*.ts" 9 | ], 10 | "exclude": [ 11 | "src/test.ts", 12 | "src/**/*.spec.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /BaseStation/frontend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "importHelpers": true, 14 | "target": "es2015", 15 | "typeRoots": [ 16 | "node_modules/@types" 17 | ], 18 | "lib": [ 19 | "es2018", 20 | "dom" 21 | ] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /BaseStation/frontend/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /BaseStation/frontend/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rules": { 4 | "array-type": false, 5 | "arrow-parens": false, 6 | "deprecation": { 7 | "severity": "warn" 8 | }, 9 | "component-class-suffix": true, 10 | "contextual-lifecycle": true, 11 | "directive-class-suffix": true, 12 | "directive-selector": [ 13 | true, 14 | "attribute", 15 | "app", 16 | "camelCase" 17 | ], 18 | "component-selector": [ 19 | true, 20 | "element", 21 | "app", 22 | "kebab-case" 23 | ], 24 | "import-blacklist": [ 25 | true, 26 | "rxjs/Rx" 27 | ], 28 | "interface-name": false, 29 | "max-classes-per-file": false, 30 | "max-line-length": [ 31 | true, 32 | 140 33 | ], 34 | "member-access": false, 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-consecutive-blank-lines": false, 47 | "no-console": [ 48 | true, 49 | "debug", 50 | "info", 51 | "time", 52 | "timeEnd", 53 | "trace" 54 | ], 55 | "no-empty": false, 56 | "no-inferrable-types": [ 57 | true, 58 | "ignore-params" 59 | ], 60 | "no-non-null-assertion": true, 61 | "no-redundant-jsdoc": true, 62 | "no-switch-case-fall-through": true, 63 | "no-use-before-declare": true, 64 | "no-var-requires": false, 65 | "object-literal-key-quotes": [ 66 | true, 67 | "as-needed" 68 | ], 69 | "object-literal-sort-keys": false, 70 | "ordered-imports": false, 71 | "quotemark": [ 72 | true, 73 | "single" 74 | ], 75 | "trailing-comma": false, 76 | "no-conflicting-lifecycle": true, 77 | "no-host-metadata-property": true, 78 | "no-input-rename": true, 79 | "no-inputs-metadata-property": true, 80 | "no-output-native": true, 81 | "no-output-on-prefix": true, 82 | "no-output-rename": true, 83 | "no-outputs-metadata-property": true, 84 | "template-banana-in-box": true, 85 | "template-no-negated-async": true, 86 | "use-lifecycle-interface": true, 87 | "use-pipe-transform-interface": true 88 | }, 89 | "rulesDirectory": [ 90 | "codelyzer" 91 | ] 92 | } -------------------------------------------------------------------------------- /BaseStation/install_requirements.sh: -------------------------------------------------------------------------------- 1 | cd Backend 2 | pip3 install -r requirements.txt 3 | cd ../frontend 4 | npm install 5 | cd .. -------------------------------------------------------------------------------- /BaseStation/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1 3 | } 4 | -------------------------------------------------------------------------------- /BaseStation/tools/tcphelper.py: -------------------------------------------------------------------------------- 1 | # Converts bytes to integer values uint32 2 | def bytes_to_uint(bytes, length): 3 | new_bytes = [] 4 | for x in range(0, length): 5 | new_bytes.append(int.from_bytes( 6 | bytes[(x*4):(x*4+4)], byteorder='little', signed=False)) 7 | return new_bytes 8 | 9 | # int16 10 | def bytes_to_int16(bytes, length): 11 | new_bytes = [] 12 | for x in range(0, length): 13 | new_bytes.append(int.from_bytes( 14 | bytes[(x*2):(x*2+2)], byteorder='little', signed=True)) 15 | return new_bytes 16 | 17 | def bytes_to_uint16(bytes, length): 18 | new_bytes = [] 19 | for x in range(0, length): 20 | new_bytes.append(int.from_bytes( 21 | bytes[(x*2):(x*2+2)], byteorder='little', signed=False)) 22 | return new_bytes 23 | 24 | def bytes_to_signed_int32(bytes, length): 25 | new_bytes = [] 26 | for x in range(0, length): 27 | new_bytes.append(int.from_bytes( 28 | bytes[(x*4):(x*4+4)], byteorder='little', signed=True)) 29 | return new_bytes 30 | 31 | def bytes_to_signed_int64(bytes, length): 32 | new_bytes = [] 33 | for x in range(0, length): 34 | new_bytes.append(int.from_bytes( 35 | bytes[(x*8):(x*8+8)], byteorder='little', signed=True)) 36 | return new_bytes 37 | 38 | def bytes_to_char(bytes, length): 39 | new_bytes = [] 40 | for x in range(0, length): 41 | new_bytes.append(int.from_bytes( 42 | bytes[(x):(x+1)], byteorder='little')) 43 | return new_bytes 44 | 45 | def bytes_to_int8(bytes, length): 46 | new_bytes = [] 47 | for x in range(0, length): 48 | new_bytes.append(int.from_bytes( 49 | bytes[(x):(x+1)], byteorder='little', signed=True)) 50 | return new_bytes 51 | 52 | def bytes_to_uint8(bytes, length): 53 | new_bytes = [] 54 | for x in range(0, length): 55 | new_bytes.append(int.from_bytes( 56 | bytes[(x):(x+1)], byteorder='little', signed=False)) 57 | return new_bytes 58 | -------------------------------------------------------------------------------- /CentralComputing/.gitignore: -------------------------------------------------------------------------------- 1 | .ycm* 2 | -------------------------------------------------------------------------------- /CentralComputing/ADCManager.h: -------------------------------------------------------------------------------- 1 | #ifndef ADCMANAGER_H_ 2 | #define ADCMANAGER_H_ 3 | 4 | #include "SourceManagerBase.hpp" 5 | #include "Defines.hpp" 6 | #include "Command.h" 7 | #include 8 | #include 9 | using std::ifstream; 10 | 11 | class ADCManager : public SourceManagerBase { 12 | public: 13 | void calculate_zero_g(); 14 | 15 | private: 16 | bool initialize_source(); 17 | void stop_source(); 18 | std::shared_ptr refresh(); 19 | std::shared_ptr refresh_sim(); 20 | 21 | int64_t calculate_zero_g_timeout; // Calculate the zero g for X ammount of seconds 22 | int64_t calculate_zero_g_time; // variable used in timer 23 | int64_t zero_g_sum[2]; // used while calculating average 24 | int64_t zero_g_num_samples; // used while calculating average 25 | int64_t num_samples_zero_g; 26 | bool do_calculate_zero_g; 27 | int32_t default_zero_g; 28 | 29 | 30 | int16_t accel1_zero_g; 31 | int16_t accel2_zero_g; 32 | 33 | int adc_axis_0; 34 | int adc_axis_1; 35 | 36 | int adc_dir_flip; 37 | 38 | int32_t adc_san_positive; 39 | int32_t adc_san_negative; 40 | 41 | int32_t adc_san_counter_error; // 42 | 43 | int32_t adc0_san_positive_counter; 44 | int32_t adc0_san_negative_counter; 45 | int32_t adc1_san_positive_counter; 46 | int32_t adc1_san_negative_counter; 47 | 48 | int32_t error_accel_diff; 49 | int32_t error_pneumatic_1_over_pressure; 50 | int32_t error_pneumatic_2_over_pressure; 51 | int32_t error_pneumatic_3_over_pressure; 52 | int32_t error_pneumatic_4_over_pressure; 53 | int32_t error_battery_box_over_pressure; 54 | int32_t error_battery_box_under_pressure; 55 | int32_t accel_diff_counter_error; 56 | int32_t accel_diff_counter; 57 | std::string name() { 58 | return "adc"; 59 | } 60 | 61 | std::string fileName; 62 | ifstream inFile; 63 | 64 | public: 65 | // Public for testing purposes 66 | void initialize_sensor_error_configs(); 67 | void check_for_sensor_error(const std::shared_ptr &, E_States state); 68 | }; 69 | 70 | #endif // ADCMANAGER_H_ 71 | -------------------------------------------------------------------------------- /CentralComputing/Brakes.cpp: -------------------------------------------------------------------------------- 1 | #include "Brakes.h" 2 | 3 | Brakes::Brakes() { 4 | // Do nothing here. At the time the constructor is called, 5 | // this class can't do anything, since the sensors/ controls are not 6 | // yet connected 7 | } 8 | 9 | void Brakes::enable_brakes() { 10 | #ifdef SIM 11 | SimulatorManager::sim.sim_brake_enable(); 12 | #else 13 | #ifdef NO_ACTION 14 | print(LogLevel::LOG_INFO, "NO_ACTION: Brakes Enabled\n"); 15 | #else 16 | 17 | #ifdef BBB 18 | bool is_brake_set = Utils::set_GPIO(Utils::BRAKE_GPIO, false); 19 | if (!is_brake_set) { 20 | Command::set_error_flag(Command::Network_Command_ID::SET_OTHER_ERROR, OTHERErrors::GPIO_SWITCH_ERROR); 21 | } 22 | #endif 23 | 24 | print(LogLevel::LOG_DEBUG, "Brakes Enabled\n"); 25 | #endif 26 | #endif 27 | std::lock_guard guard(mutex); 28 | enabled = true; 29 | } 30 | 31 | void Brakes::disable_brakes() { 32 | #ifdef SIM 33 | SimulatorManager::sim.sim_brake_disable(); 34 | #else 35 | #ifdef NO_ACTION 36 | print(LogLevel::LOG_INFO, "NO_ACTION: Brakes Disabled\n"); 37 | #else 38 | 39 | #ifdef BBB 40 | bool is_brake_set = Utils::set_GPIO(Utils::BRAKE_GPIO, true); 41 | if (!is_brake_set) { 42 | Command::set_error_flag(Command::Network_Command_ID::SET_OTHER_ERROR, OTHERErrors::GPIO_SWITCH_ERROR); 43 | } 44 | #endif 45 | 46 | print(LogLevel::LOG_DEBUG, "Brakes Disabled\n"); 47 | #endif 48 | #endif 49 | std::lock_guard guard(mutex); 50 | enabled = false; 51 | } 52 | 53 | void Brakes::set_enable(bool enable) { 54 | enabled = enable; 55 | } 56 | 57 | bool Brakes::is_enabled() { 58 | std::lock_guard guard(mutex); 59 | return enabled; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /CentralComputing/Brakes.h: -------------------------------------------------------------------------------- 1 | #ifndef BRAKES_H_ 2 | #define BRAKES_H_ 3 | 4 | #include "Utils.h" 5 | #include "Simulator.h" 6 | #include 7 | 8 | 9 | class Brakes { 10 | public: 11 | /** 12 | * Constructor 13 | * Setup the PWM pins 14 | */ 15 | Brakes(); 16 | 17 | /** 18 | * Arms the motors 19 | */ 20 | void enable_brakes(); 21 | 22 | /** 23 | * Disarms the motors 24 | */ 25 | void disable_brakes(); 26 | 27 | /** 28 | * is_enabled returns enabled variable 29 | */ 30 | bool is_enabled(); 31 | 32 | private: 33 | void set_enable(bool enable); 34 | 35 | double integral; 36 | std::mutex mutex; 37 | 38 | bool enabled; 39 | }; 40 | 41 | #endif // BRAKES_H_ 42 | -------------------------------------------------------------------------------- /CentralComputing/Command.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMAND_H_ 2 | #define COMMAND_H_ 3 | 4 | #include "Utils.h" 5 | #include "SafeQueue.hpp" 6 | #include "Event.h" 7 | #include "Defines.hpp" 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include // NOLINT 16 | #include 17 | #include 18 | 19 | namespace Command { 20 | 21 | extern SafeQueue command_queue; 22 | struct Network_Command; 23 | void put(uint32_t id, uint32_t value); 24 | bool get(Network_Command * com); 25 | void wait_for_empty(); 26 | void flush(); 27 | 28 | enum Network_Command_ID { 29 | // state transitions 30 | TRANS_SAFE_MODE = 0, 31 | TRANS_FUNCTIONAL_TEST_OUTSIDE = 1, 32 | TRANS_LOADING = 2, 33 | TRANS_FUNCTIONAL_TEST_INSIDE = 3, 34 | TRANS_LAUNCH_READY = 4, 35 | TRANS_FLIGHT_ACCEL = 5, 36 | ENABLE_MOTOR = 6, 37 | DISABLE_MOTOR = 7, 38 | SET_MOTOR_SPEED = 8, 39 | ENABLE_BRAKE = 9, 40 | DISABLE_BRAKE = 10, 41 | TRANS_FLIGHT_COAST = 11, 42 | TRANS_FLIGHT_BRAKE = 12, 43 | TRANS_ABORT = 13, // Move to either safe mode, or flight abort 44 | SET_ADC_ERROR = 14, // SET_XXX_ERROR defines must be one after another, in one block 45 | SET_CAN_ERROR = 15, 46 | SET_I2C_ERROR = 16, 47 | SET_PRU_ERROR = 17, 48 | SET_NETWORK_ERROR = 18, 49 | SET_OTHER_ERROR = 19, 50 | CLR_ADC_ERROR = 20, // CLR_XXX_ERROR defines must be one after another, in one block 51 | CLR_CAN_ERROR = 21, 52 | CLR_I2C_ERROR = 22, 53 | CLR_PRU_ERROR = 23, 54 | CLR_NETWORK_ERROR = 24, 55 | CLR_OTHER_ERROR = 25, 56 | SET_HV_RELAY_HV_POLE = 26, 57 | SET_HV_RELAY_LV_POLE = 27, 58 | SET_HV_RELAY_PRE_CHARGE = 28, 59 | CALC_ACCEL_ZERO_G = 29, 60 | RESET_PRU = 30, 61 | SENTINEL = 31, // Any Command above this value is an invalid command 62 | // MUST ADD THESE TO TRANSITION LIST 63 | // Update the get_string() function bellow with additional commands, or suffer segfaults 64 | }; 65 | 66 | // enum specifying what data is sent 67 | // [1 byte Data ID][4 byte size][size byte chunk] 68 | enum Network_Data_ID { 69 | POD_STATE, 70 | BRAKE_STATUS, 71 | MOTOR_STATUS, 72 | POSITION, 73 | VELOCITY, 74 | ACCELERATION, 75 | TEMPERATURE 76 | }; 77 | 78 | struct Network_Command { 79 | // state transtitions 80 | uint32_t id; // id is a Network_Command_ID 81 | uint32_t value; // value of a command 82 | }; 83 | 84 | // returns the string name for command value 85 | std::string get_network_command_ID_string(uint command); 86 | 87 | // Parses the value of a command, returns string 88 | std::string get_network_command_value_string(Network_Command * com); 89 | 90 | // To make error flag setting easy, this helper functionn is defined 91 | // Why use this instead of just calling Command::put() ? 92 | // This function is "safe" and will not spam the queue. 93 | // Say something is faulting every cycle. Initially it will set the error flag 94 | // But then it send another command to the Unified Queue once every second. 95 | // This helper function, and the int64_t array of timers makes that possible 96 | #define FLAGS_PER_ERROR 32 97 | extern int64_t error_flag_timers[FLAGS_PER_ERROR * 6]; // 32 flags per error ID, 6 errors 98 | extern std::mutex error_flag_mutex; 99 | void set_error_flag(Network_Command_ID id, uint32_t value); 100 | 101 | } // namespace Command 102 | 103 | #endif // COMMAND_H_ 104 | -------------------------------------------------------------------------------- /CentralComputing/Configurator.cpp: -------------------------------------------------------------------------------- 1 | #include "Configurator.h" 2 | #include 3 | 4 | Configurator ConfiguratorManager::config; 5 | 6 | bool Configurator::openConfigFile(const string& fileName, bool is_flight_plan) { 7 | inFile.open(fileName); 8 | if (!inFile) { 9 | return false; 10 | } 11 | 12 | // If Loading a flight plan, only allow ONE flight plan at a time. 13 | if (is_flight_plan) { 14 | flightPlan.clear(); 15 | } 16 | 17 | loadValues(is_flight_plan); 18 | 19 | inFile.close(); 20 | return true; 21 | } 22 | 23 | void Configurator::loadValues(bool is_flight_plan) { 24 | string varName; 25 | string val; 26 | 27 | // Parse the file. Uses nice C++ syntax. 28 | while (inFile >> varName) { 29 | inFile >> val; 30 | 31 | if (is_flight_plan) { 32 | // In case of flight plan, add times to flightPlan array 33 | flightPlan.push_back(std::make_pair(std::stoll(varName), (int16_t)std::stoi(val))); 34 | } else { 35 | // Normal case, just add pair to map 36 | mapVals.insert(pair (varName, val)); 37 | } 38 | 39 | // This ignores characters at the end of the line. allows for comments! 40 | inFile.ignore(200, '\n'); 41 | } 42 | } 43 | 44 | void Configurator::clear() { 45 | flightPlan.clear(); 46 | mapVals.clear(); 47 | } 48 | 49 | bool Configurator::getValue(const string& varName, string& value) { 50 | if (mapVals.find(varName) == mapVals.end()) { 51 | return false; 52 | } 53 | value = mapVals.find(varName)->second; 54 | return true; 55 | } 56 | 57 | bool Configurator::getValue(const string& varName, int64_t& value) { 58 | if (mapVals.find(varName) == mapVals.end()) { 59 | return false; 60 | } 61 | value = std::stoll(mapVals.find(varName)->second); 62 | return true; 63 | } 64 | 65 | bool Configurator::getValue(const string& varName, int32_t& value) { 66 | if (mapVals.find(varName) == mapVals.end()) { 67 | return false; 68 | } 69 | value = std::stoll(mapVals.find(varName)->second); 70 | return true; 71 | } 72 | 73 | bool Configurator::getValue(const string& varName, float& value) { 74 | if (mapVals.find(varName) == mapVals.end()) { 75 | return false; 76 | } 77 | value = std::stod(mapVals.find(varName)->second); 78 | return true; 79 | } 80 | 81 | bool Configurator::getValue(const string& varName, double& value) { 82 | if (mapVals.find(varName) == mapVals.end()) { 83 | return false; 84 | } 85 | value = std::stod(mapVals.find(varName)->second); 86 | return true; 87 | } 88 | 89 | int16_t Configurator::getFlightPlan(int64_t time, unsigned int * start_index) { 90 | int16_t candidate = 0; 91 | // Iterate over the flight plan to find the appropriate motor setting 92 | for (unsigned int i = *start_index; i < flightPlan.size(); i++) { 93 | pair & el = flightPlan[i]; 94 | if (el.first <= time) { 95 | // We are greater than or equal to this time index 96 | // This is a possible motor speed 97 | candidate = el.second; 98 | // This is improves performance. 99 | // dont have to iterate over the entire list next time 100 | *start_index = i; 101 | } else { 102 | // We found the highest acceptable time 103 | break; 104 | } 105 | } 106 | return candidate; 107 | } 108 | 109 | -------------------------------------------------------------------------------- /CentralComputing/Configurator.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIGURATOR_H_ 2 | #define CONFIGURATOR_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using std::string; 11 | using std::ifstream; 12 | using std::map; 13 | using std::vector; 14 | using std::pair; 15 | 16 | class Configurator { 17 | public: 18 | bool openConfigFile(const string&, bool is_flight_plan); 19 | void clear(); 20 | bool getValue(const string&, string&); 21 | bool getValue(const string&, int64_t&); 22 | bool getValue(const string&, int32_t&); 23 | bool getValue(const string&, float&); 24 | bool getValue(const string&, double&); 25 | int16_t getFlightPlan(int64_t time, unsigned int * start_index); 26 | 27 | private: 28 | void loadValues(bool is_flight_plan); 29 | ifstream inFile; 30 | map mapVals; 31 | vector > flightPlan; 32 | }; 33 | 34 | namespace ConfiguratorManager { 35 | extern Configurator config; 36 | } // namespace ConfiguratorManager 37 | 38 | #endif // CONFIGURATOR_H_ 39 | -------------------------------------------------------------------------------- /CentralComputing/Documentation/Topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/CentralComputing/Documentation/Topology.png -------------------------------------------------------------------------------- /CentralComputing/Documentation/Topology.xml: -------------------------------------------------------------------------------- 1 | 3V1Lc9s2EP41unoIgiDAo+04bWfqjFs30+TUYSRYYiOLGoqK7f76UhJAkQuQlEQQhJNLJGj5wO7i2yfgCb59fv0li9eL+3TGlxPfm71O8IeJ7yOMaPHfbuTtMMIoOQzMs2QmiI4Dj8l/XAx6YnSbzPimRpin6TJP1vXBabpa8WleG4uzLH2pkz2ly/pT1/GcKwOP03gpR6/IcfzvZJYvxDgKo+MPv/JkvhAPZ76Y8rd4+n2epduVeOLEx0/7f4efn2N5LzHVzSKepS+VIXw3wbdZmuaHT8+vt3y5465k3OG6jw2/lvPJ+Co/5QIciPfI3+Ts+axghviaZvkinaereHl3HL3Zz4/v7uAV3xb587L4iIqPxUOzty+78YKD4utXQfYvz/M3Iet4m6fF0PHuv6fpWtzj8D67l2ickhjapNtsKqiwL/QkzuZckGFcMrRQVZ4+8+J1CpqML+M8+VG/fyx0Zl7SHblWfBCMa+C6RwbhIqrxcM9S+1yMbHFRPvxHvNyKuz7mcc7v4+kiWfGrxcQPl8VL3XzLik/zvJxlhetHnu6Y8LJIcv64jvfTeymwqs5n8Tie5fy1nUvq7MUFIRHrWCKdhLCXCmrItb6oAEboGWAYbmfYdL1+DyxjVMKtDaYFnsKB9wl4oQbwIktLNcA/LxMD3xYT2TBMtG40dEykPZm4v/Q6y+K3CsE6TVb5pnLnh93AEVqIX4cW3wPOTwd96AH5HV7gKM1yJicJmPlGBfya5IdF4hPx9auTsmcN+D+s7DGUPW6XPaQPwnZ6eb9L6alvWLkiC8rl1dHZdwCeWV9kORWeI7M+fcngZv66sHijYIzFG6D6YkGoY3H1I/c61i4K+16AqNnVLkVVcfU/58lyswuKRvbnMfDn5dTthEBRA1/cjH0gr7BnkVfUrDsyWpIikCnBCmyFo/gc7EyfA9ITZBYl6DBpKO+KWjb8OhFTW3ko+XCYVtkjw9XCSWCJALD4NoEl+klSKoGval1vd/MiYEEAKDA2CxRyplUVj5/4H1u+FRo+sj6XTsQYhjIIfxJ9DlR9DogtFDUbn44XhGq5OA4qYBgmibpTY1iiXtBKTyhrIe+NOtEg+TD5+eh+NjouaBRlsZaxkA+voPrdj+Jt3UB0DBNiNos+pIEzUxc543sWWRMOFTPYhmmqrjwySlQYAnHiqB11Q6+VvjfshnQYCVuP+3US7lvxvKzOBMwqph12FdBTw+58aNbXKlPVtLnQ5MLyHifpExK/LvwOp4oGXht9/6SP2WhF61VR4pzwSd900EXCj+BKDs3K0ixUn1IxdkKWfYPSi2RJQbTTYaYhedCR7I1ACuNcetKBK8jDrRf0rzCbTevprQqoMEeBX3crPJ/JgQeeJcXr82w8PR0l7A8JrskZdvRCvUC4jb5/7lAwppo73PPtPl7Fc57dxBs3cogEGl5NCpEMFFUxsw1yJwG57SKN5N34vT+UkbpV7vDHA6AZ59KHHfS4nb5/Ik1K473X+bQqNArIMgRUqMMbQKSVvr+IB/HqnQrpdMIfp/2IyYqP9AQ71rcPqq2R4fUtb99kYp0wrxSsgDDS2NfBelns+6a2011kiDaXU/krH17RwIc/P7ukftC7I8Si+oVD7ZqzboCxqmTE0zPebmaFdIQ5LCBt9P0xWN1cdXv9yaUVwGDjJbZYNiLD9EhYbyaURszoAjiZiWpZ8q/7B5d0TElK2URZajbMOSkBZR2Ah6hrnKx/airn+sOtS/qHPNAJR202goVmvcwGV5JaQLnIFTNfRgllKbS9hamDvr+ZVzcQ/OY7tQQI7JuxuQKYWUdXQnCtuOiD4qLtBr9QE2j1zmOeDDFqoHWf5km62p+q4oQChqyugAGzCcHqxidVI1ez692pL8W36TLebJJpMfFNIc5cHT5TGzX+6IUIrEl2NbUnVfiqq0/IsfOAWkVW4NqVYpa3OLy+uKoFoikw0WX/k7zRYc7KjS5pdGHDaUNDHrRjd6w5bWjy+uxoAwU7GMPgQm1gMI6PBtMGOlQWxrYFoposzDjNTciDOxS7uiJgK5zpOojZQzK6e8atZyB0wh+nDIIQsPSyjtncagAuML7vmapZuI/JMt+55i7uwgPBCrZ5GhS1YRvVxdHSMGjONjY13tixjRFsF4Am7VTbCPWDQiNrzjYizwJwgrbQunL4w0Mn00RuvY+ruwg68ZlpDUjPiNm0BlPDypss/s43ju5fhhV1q8VkNlCvhTutFkxT5bCW4ogGampua2WxncbXMXiko3SUM806ettggp119Lb1pEdyGTc21yg+pemTs9Sq22PyvC2EkrqR8YXtg2Wrgw0wRJ7GbXyP28WYprI2jnNQNvPJdrGuo+MAPTMcVDG17PeJ5y9p9t2pugfosdO1bwcDLYJIDTsf0tk/+2NgnIw8IYozu5AxSDdePdY4K5xoLbVeBieRZme/GThRTSbIzEcnholnBy3KqXuiIeB003z+BR3eAgn7XcCY2UBKir1en3PEUUARZK/dZT/MES/oykMgC+sxLAfs7gJDniY7a+0kMoQG6oBq3kaENIA5AouttUCVT39Pp70hHx6PNeC6L74e/xzJAUGPf/UF3/0P -------------------------------------------------------------------------------- /CentralComputing/Event.cpp: -------------------------------------------------------------------------------- 1 | #include "Event.h" 2 | 3 | void Event::wait() { 4 | std::unique_lock lk(mutex); 5 | cond.wait(lk, [&]{ return condition; }); 6 | lk.unlock(); 7 | } 8 | 9 | void Event::wait_for(int64_t micros) { 10 | std::unique_lock lk(mutex); 11 | cond.wait_for(lk, std::chrono::microseconds(micros), [&]{ return condition; }); 12 | lk.unlock(); 13 | } 14 | 15 | void Event::invoke() { 16 | std::unique_lock lk(mutex); 17 | condition = true; 18 | lk.unlock(); 19 | cond.notify_all(); 20 | } 21 | 22 | void Event::reset() { 23 | std::unique_lock lk(mutex); 24 | condition = false; 25 | lk.unlock(); 26 | } 27 | -------------------------------------------------------------------------------- /CentralComputing/Event.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_H_ 2 | #define EVENT_H_ 3 | 4 | #include // NOLINT 5 | #include // NOLINT 6 | 7 | 8 | // The Event object helps manage the pod's threads and is useful to wait for something to occur 9 | // It's a pretty basic wrapper on a mutex/condition variable 10 | // You can reuse an event by calling reset() 11 | class Event { 12 | public: 13 | /* 14 | * Causes this thread to wait for another thread to invoke the event 15 | */ 16 | void wait(); 17 | 18 | /* 19 | * Causes this thread to wait for a time period or until the event is invoked 20 | */ 21 | void wait_for(int64_t micros); 22 | 23 | /* 24 | * Wakes up all waiting threads 25 | */ 26 | void invoke(); 27 | 28 | /* 29 | * Reset Event 30 | */ 31 | void reset(); 32 | 33 | private: 34 | std::mutex mutex; 35 | std::condition_variable cond; 36 | bool condition = false; 37 | }; 38 | #endif // EVENT_H_ 39 | -------------------------------------------------------------------------------- /CentralComputing/I2CManager.h: -------------------------------------------------------------------------------- 1 | #ifndef I2CMANAGER_H_ 2 | #define I2CMANAGER_H_ 3 | 4 | #include "SourceManagerBase.hpp" 5 | #include "Defines.hpp" 6 | #include "Configurator.h" 7 | #include 8 | #include // I2C bus definitions 9 | 10 | #define ANC0 0x4 // 0b100 11 | #define ANC1 0x5 // 0b101 12 | #define ANC2 0x6 // 0b110 13 | #define ANC3 0x7 // 0b111 14 | 15 | class I2CManager : public SourceManagerBase { 16 | private: 17 | bool initialize_source(); 18 | void stop_source(); 19 | std::shared_ptr refresh(); 20 | std::shared_ptr refresh_sim(); 21 | bool single_shot(int fd, int port, int16_t * value); 22 | bool open_i2c(int * fd); 23 | bool set_i2c_addr(int fd, int addr); 24 | 25 | int32_t error_general_1_over_temp; 26 | int32_t error_general_2_over_temp; 27 | int32_t error_general_3_over_temp; 28 | std::shared_ptr old_data; 29 | 30 | bool dps310_setup; 31 | uint8_t dps310_coef_buf[18]; 32 | // pressure coefs 33 | int32_t dps310_coef_c00; // is a 20 bit number 34 | int32_t dps310_coef_c10; // is a 20 bit number 35 | int16_t dps310_coef_c01; // is a 16 bit number 36 | int16_t dps310_coef_c11; // is a 16 bit number 37 | int16_t dps310_coef_c20; // is a 16 bit number 38 | int16_t dps310_coef_c21; // is a 16 bit number 39 | int16_t dps310_coef_c30; // is a 16 bit number 40 | 41 | // temperature coefs 42 | int16_t dps310_coef_c0; // is a 12 bit number 43 | int16_t dps310_coef_c1; // is a 12 bit number 44 | 45 | // coef source: 46 | // Highest bit is used. 47 | // 0 = ASCI temperature, internal. 1 = External temperature 48 | uint8_t dps310_coef_source; 49 | 50 | bool dps310_read_coef(int fd, uint8_t * read_buf); 51 | bool dps310_write_config_register(int fd, uint8_t reg, uint8_t value); 52 | bool dps310_get_temp_and_pressure(int fd, int32_t *temp, int32_t * pressure); 53 | 54 | 55 | std::string name() { 56 | return "i2c"; 57 | } 58 | 59 | int i = 0; 60 | int j = 0; 61 | int i2c_fd = 0; 62 | 63 | unsigned char buffer[NUM_TMP]; 64 | 65 | public: 66 | // Public for testing purposes 67 | void initialize_sensor_error_configs(); 68 | void check_for_sensor_error(const std::shared_ptr &, E_States state); 69 | }; 70 | 71 | #endif // I2CMANAGER_H_ 72 | -------------------------------------------------------------------------------- /CentralComputing/MotionModel.cpp: -------------------------------------------------------------------------------- 1 | #include "MotionModel.h" 2 | 3 | using Utils::print; 4 | using Utils::LogLevel; 5 | using Utils::microseconds; 6 | using Utils::clamp; 7 | 8 | MotionModel::MotionModel() { 9 | if (!(ConfiguratorManager::config.getValue("low_pass_filter_velocity", lpfv) && 10 | ConfiguratorManager::config.getValue("low_pass_filter_acceleration", lpfa) && 11 | ConfiguratorManager::config.getValue("adc_axis_0", adc_axis_0) && 12 | ConfiguratorManager::config.getValue("adc_axis_1", adc_axis_1) && 13 | ConfiguratorManager::config.getValue("motor_distance_clamp", motor_distance_clamp))) { 14 | print(LogLevel::LOG_ERROR, "CONFIG FILE ERROR: MOTION_MODEL Missing necessary configuration\n"); 15 | exit(1); 16 | } 17 | } 18 | 19 | // Orange tape sensor: Counts orange strips every 100 feet (41 stips in total). Position and velocity 20 | // Could undershoot, not overshoot. Assume 21 | // Assume no "overcounting" of orange tape. Assume it could miss 22 | // Wheel encoder: Counts rotations of the back suspension wheel, uses an optical encoder. Pos. and Vel. 23 | // Could undershoot, not overshoot. 24 | // Assume wheel does not slip, or slips very little. 25 | // Assume no "overcounting" of rotations. Assume it could miss 26 | // Emrax (motor): Rotations and RPM (velocity) of the Emrax motor. Slip possible. 27 | // Could overshoot, not undershoot, due to slip while powered. 28 | // 29 | // Trust Orange tape and Wheel Encoder distances the most. 30 | // Motor can add a bounded ammount of extra distance 31 | // We trust the wheel encoder velocity the most 32 | void MotionModel::calculate(UnifiedState * state) { 33 | // POSITION 34 | int32_t orange_dist = std::max(state->pru_data->orange_distance[0], state->pru_data->orange_distance[1]); 35 | int32_t wheel_dist = std::max(state->pru_data->wheel_distance[0], state->pru_data->wheel_distance[1]); 36 | 37 | // Take our minimum distance to be the maximum orange and wheel dist 38 | int32_t dist = std::max(orange_dist, wheel_dist); 39 | // Will accept that the motor is outputing a higher value, up to a certain limit 40 | 41 | // VELOCITY 42 | // TODO: Refine this further. Incorporate other sensor inputs?? 43 | // int32_t orange_vel = (state->pru_data->orange_velocity[0] + state->pru_data->orange_velocity[1]) / 2; // average 44 | int32_t wheel_vel = (state->pru_data->wheel_velocity[0] + state->pru_data->wheel_velocity[1]) / 2; // average 45 | // int32_t motor_vel = state->can_data->drive_wheel_velocity; 46 | // This is using low_pass_filter as a weighted average. 47 | // int32_t vel = low_pass_filter(wheel_vel, orange_vel, 0.90); 48 | // vel = low_pass_filter(vel, motor_vel, 0.90); 49 | int32_t vel = wheel_vel; 50 | 51 | // ACCELERATION 52 | // Simply take the AVERAGE 53 | int32_t accl = (state->adc_data->data[adc_axis_0] + state->adc_data->data[adc_axis_1]) / 2; 54 | 55 | // Set state 56 | state->motion_data->x[0] = dist; 57 | state->motion_data->x[1] = vel; 58 | state->motion_data->x[2] = low_pass_filter(state->motion_data->x[2], accl, lpfa); 59 | } 60 | 61 | // get MotionData object 62 | void MotionModel::calculate_sim(UnifiedState * state) { 63 | #ifdef SIM 64 | state->motion_data = SimulatorManager::sim.sim_get_motion(this, state); 65 | #endif 66 | } 67 | 68 | float MotionModel::low_pass_filter(float t_old, float t_new, float lowpass_percent) { 69 | return t_old * lowpass_percent + t_new * (static_cast(1.0) - lowpass_percent); 70 | } 71 | 72 | template 73 | T MotionModel::Median(T * input, unsigned size) { 74 | // Is even. Need to find two indicies, 75 | // and then take the mean 76 | if (size % 2 == 0) { 77 | std::nth_element(input, input+size/2, input + size); 78 | std::nth_element(input + size/2, input+size/2, input+size); 79 | T sum = input[size/2] + input[size/2+1]; 80 | return sum/2; 81 | } else { 82 | std::nth_element(input, input+size/2, input + size); 83 | return input[size/2]; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /CentralComputing/MotionModel.h: -------------------------------------------------------------------------------- 1 | #ifndef MOTIONMODEL_H_ 2 | #define MOTIONMODEL_H_ 3 | 4 | #include "Utils.h" 5 | #include "Defines.hpp" 6 | #include "Simulator.h" 7 | #include "Configurator.h" 8 | #include 9 | 10 | // Class pre-defined in Defines.hpp, FYI 11 | class MotionModel { 12 | public: 13 | // Used to read variables in from config file 14 | MotionModel(); 15 | 16 | // Source Manager methods 17 | void calculate(UnifiedState * state); 18 | void calculate_sim(UnifiedState * state); 19 | 20 | // Basic digital lowpass filter. 21 | // A higher lowpass_percent means you take less of the new value 22 | // into account when calculating the output. 23 | // EX: lowpass_percent = 1.00 means the output == t_old 24 | // EX: lowpass_percent = 0.00 means the output == t_new 25 | // Usually something like 0.90 (90%) is used, but it depends on how 26 | // frequently this function is called. 27 | float low_pass_filter(float t_old, float t_new, float lowpass_percent); 28 | 29 | template 30 | T Median(T * input, unsigned size); 31 | 32 | private: 33 | // Weights used in position calculation 34 | float lpfv, lpfa; 35 | int32_t motor_distance_clamp; // used while calculating distance. See calculate() 36 | int adc_axis_0, adc_axis_1; 37 | }; 38 | 39 | #endif // MOTIONMODEL_H_ 40 | 41 | -------------------------------------------------------------------------------- /CentralComputing/Motor.cpp: -------------------------------------------------------------------------------- 1 | #include "Motor.h" 2 | using Utils::print; 3 | using Utils::LogLevel; 4 | 5 | Motor::Motor() { 6 | // Do nothing here. At the time the constructor is called, 7 | // the motor class can't do anything, since the sensors/ controls are not 8 | // yet connected 9 | 10 | relay_state_buf[0] = 0; 11 | relay_state_buf[1] = 0; 12 | relay_state_buf[2] = 0; 13 | } 14 | 15 | void Motor::enable_motors() { 16 | set_throttle(MOTOR_OFF); 17 | set_motor_state(true); 18 | } 19 | 20 | void Motor::disable_motors() { 21 | set_throttle(MOTOR_OFF); 22 | set_motor_state(false); 23 | } 24 | 25 | void Motor::set_motor_state(bool enable) { 26 | std::lock_guard guard(mutex); 27 | enabled = enable; 28 | #ifdef SIM 29 | SimulatorManager::sim.sim_motor_state(enable); 30 | #else 31 | #if defined(NO_ACTION) || defined(NO_MOTOR) 32 | print(LogLevel::LOG_INFO, "NO_ACTION: Motors: %s\n", enable?"Enabled":"Disabled"); 33 | #else 34 | SourceManager::CAN.set_motor_state(enable); 35 | print(LogLevel::LOG_INFO, "Motors: %s\n", enable?"Enabled":"Disabled"); 36 | #endif 37 | #endif 38 | } 39 | 40 | bool Motor::is_enabled() { 41 | std::lock_guard guard(mutex); 42 | return enabled; 43 | } 44 | 45 | int16_t Motor::get_throttle() { 46 | std::lock_guard guard(mutex); 47 | return throttle; 48 | } 49 | 50 | void Motor::set_throttle(int16_t value) { 51 | std::lock_guard guard(mutex); 52 | if (enabled) { 53 | throttle = value; 54 | #ifdef SIM 55 | SimulatorManager::sim.sim_motor_set_throttle(value); 56 | #else 57 | #if defined(NO_ACTION) || defined(NO_MOTOR) 58 | print(LogLevel::LOG_INFO, "NO_ACTION: Setting motor throttle: %d\n", value); 59 | #else 60 | SourceManager::CAN.set_motor_throttle(value); 61 | print(LogLevel::LOG_INFO, "Setting motor throttle: %d\n", value); 62 | #endif 63 | #endif 64 | } 65 | } 66 | 67 | void Motor::set_relay_state(HV_Relay_Select relay, HV_Relay_State state) { 68 | std::lock_guard guard(mutex); 69 | #if defined(NO_ACTION) || defined(NO_MOTOR) 70 | #ifdef SIM 71 | SimulatorManager::sim.sim_relay_state(relay, state); 72 | #else 73 | print(LogLevel::LOG_DEBUG, "NO_ACTION: Relay %d %s\n", relay, state?"Enabled":"Disabled"); 74 | #endif 75 | #else 76 | SourceManager::CAN.set_relay_state(relay, state); 77 | print(LogLevel::LOG_DEBUG, "Relay %d %s\n", relay, state?"Enabled":"Disabled"); 78 | #endif 79 | 80 | relay_state_buf[relay] = state; 81 | } 82 | 83 | void Motor::get_relay_state(char * buf) { 84 | std::lock_guard guard(mutex); 85 | buf[0] = relay_state_buf[0]; 86 | buf[1] = relay_state_buf[1]; 87 | buf[2] = relay_state_buf[2]; 88 | } 89 | -------------------------------------------------------------------------------- /CentralComputing/Motor.h: -------------------------------------------------------------------------------- 1 | #ifndef MOTOR_H_ 2 | #define MOTOR_H_ 3 | 4 | #include "Utils.h" 5 | #include "SourceManager.h" 6 | #include "Simulator.h" 7 | #include 8 | 9 | #define MOTOR_OFF 0 10 | 11 | class Motor { 12 | public: 13 | /* 14 | * Constructor 15 | */ 16 | Motor(); 17 | 18 | /* 19 | * Arms the motors 20 | */ 21 | void enable_motors(); 22 | 23 | /* 24 | * Disarms the motors 25 | */ 26 | void disable_motors(); 27 | 28 | /* 29 | * is_enabled returns enabled variable 30 | */ 31 | bool is_enabled(); 32 | 33 | int16_t get_throttle(); 34 | 35 | /* 36 | * Sets the motor throttle to a specific value 37 | */ 38 | void set_throttle(int16_t value); 39 | 40 | 41 | void set_relay_state(HV_Relay_Select, HV_Relay_State); 42 | 43 | void get_relay_state(char * buf); 44 | 45 | private: 46 | void set_motor_state(bool enable); 47 | 48 | bool enabled; 49 | char relay_state_buf[3]; 50 | std::mutex mutex; 51 | 52 | int16_t throttle; 53 | }; 54 | 55 | #endif // MOTOR_H_ 56 | -------------------------------------------------------------------------------- /CentralComputing/PRUManager.h: -------------------------------------------------------------------------------- 1 | #ifndef PRUMANAGER_H_ 2 | #define PRUMANAGER_H_ 3 | 4 | #include "SourceManagerBase.hpp" 5 | #include "SourceManager.h" 6 | #include "Defines.hpp" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define DEVICE_NAME "/dev/rpmsg_pru31" 14 | #define MAX_BUFFER_SIZE 512 15 | 16 | #define HUNDRED_FEET_IN_MM (30480) 17 | #define WHEEL_CIRCUMFRENCE_IN_MM (319) 18 | 19 | #define CLOCK_TO_SEC ((double)21.474836475 / (double)4294967295.0) 20 | 21 | struct RawPRUData { 22 | uint32_t counts[11]; 23 | uint32_t decays[11]; 24 | uint32_t deltas[11]; 25 | }; 26 | 27 | class PRUManager : public SourceManagerBase { 28 | private: 29 | bool initialize_source(); 30 | void stop_source(); 31 | std::shared_ptr refresh(); 32 | std::shared_ptr refresh_sim(); 33 | 34 | int32_t convert_to_velocity(uint32_t decay, uint32_t delta, uint32_t distance); 35 | 36 | std::string name(); 37 | 38 | uint8_t readBuf[MAX_BUFFER_SIZE]; 39 | struct pollfd pollfds[1]; 40 | 41 | // Variables used for pru processing 42 | const int orange_idx[NUM_ORANGE_INPUTS] = {3, 3}; 43 | const uint32_t orange_map[NUM_ORANGE_INPUTS] = {WHEEL_CIRCUMFRENCE_IN_MM, WHEEL_CIRCUMFRENCE_IN_MM}; 44 | const int wheel_idx[NUM_WHEEL_INPUTS] = {0, 1}; //p8_45 and p8_46 45 | const uint32_t wheel_map[NUM_WHEEL_INPUTS] = {HUNDRED_FEET_IN_MM, HUNDRED_FEET_IN_MM}; 46 | 47 | int32_t error_orange_diff; 48 | int32_t error_orange_diff_count; 49 | int32_t error_encoder_wheel_diff; 50 | int32_t error_encoder_wheel_diff_count; 51 | int32_t error_watchdog_heartbeat_min_hz; 52 | 53 | 54 | int32_t orange_diff_counter; 55 | int32_t wheel_diff_counter; 56 | 57 | bool do_reset = 0; 58 | int64_t reset_timeout_start; 59 | std::mutex reset_mutex; 60 | 61 | public: 62 | 63 | void reset_pru(); 64 | // Public for testing purposes 65 | void initialize_sensor_error_configs(); 66 | void check_for_sensor_error(const std::shared_ptr &, E_States state); 67 | }; 68 | 69 | #endif // PRUMANAGER_H_ 70 | -------------------------------------------------------------------------------- /CentralComputing/Pod.h: -------------------------------------------------------------------------------- 1 | #ifndef POD_H_ 2 | #define POD_H_ 3 | 4 | #include "TCPManager.h" 5 | #include "Command.h" 6 | #include "UDPManager.h" 7 | #include "Event.h" 8 | #include "Pod_State.h" 9 | #include "Configurator.h" 10 | #include "MotionModel.h" 11 | #include "SourceManager.h" 12 | #include "Defines.hpp" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #pragma GCC diagnostic push 18 | #pragma GCC diagnostic ignored "-Wctor-dtor-privacy" 19 | #include "gtest/gtest.h" 20 | #pragma GCC diagnostic pop 21 | 22 | class Pod { 23 | public: 24 | explicit Pod(const std::string & config_to_open, const std::string & flight_plan_to_open); 25 | 26 | ~Pod(); 27 | 28 | void run(); 29 | void trigger_shutdown(); 30 | 31 | std::shared_ptr state_machine; 32 | std::shared_ptr motion_model; 33 | std::atomic running; 34 | UnifiedState unified_state; 35 | Event ready; 36 | Event processing_command; 37 | Event processing_error; 38 | Event closing; 39 | Event tcp_fully_setup; 40 | Event udp_fully_setup; 41 | 42 | private: 43 | void logic_loop(); 44 | void update_unified_state(); 45 | // IF the command is an error command, set the unified state appropriatly 46 | void set_error_code(Command::Network_Command * com); 47 | bool switchVal; 48 | string tcp_port; 49 | string tcp_addr; 50 | string udp_send; // port we send packets to 51 | string udp_recv; // port we recv packets from 52 | string udp_addr; 53 | int64_t logic_loop_timeout; // logic_loop sleep (timeout) value 54 | }; 55 | 56 | namespace podtest_global { 57 | extern std::string config_to_open; 58 | extern std::string flight_plan_to_open; 59 | } // namespace podtest_global 60 | 61 | void signal_handler(int signal); 62 | 63 | #endif // POD_H_ 64 | -------------------------------------------------------------------------------- /CentralComputing/SafeQueue.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SAFEQUEUE_H_ 2 | #define SAFEQUEUE_H_ 3 | 4 | #include "Utils.h" 5 | #include 6 | #include // NOLINT 7 | #include // NOLINT 8 | 9 | template 10 | class SafeQueue { 11 | public: 12 | /* 13 | * Constructs an SafeQueue object 14 | */ 15 | SafeQueue() { 16 | m_queue = std::queue(); 17 | } 18 | 19 | /* 20 | * Dequeues the object 21 | * @return the oldest object on the queue or nullptr if the queue is empty 22 | */ 23 | 24 | bool dequeue(T * val) { 25 | std::lock_guard guard(m_mutex); 26 | if (m_queue.empty()) { 27 | return false; 28 | } else { 29 | *val = m_queue.front(); 30 | m_queue.pop(); 31 | return true; 32 | } 33 | } 34 | 35 | /* 36 | * Enqueues an object 37 | * @param the object to enqueue 38 | */ 39 | void enqueue(T object) { 40 | std::lock_guard guard(m_mutex); 41 | m_queue.push(object); 42 | } 43 | 44 | int size() { 45 | std::lock_guard guard(m_mutex); 46 | return m_queue.size(); 47 | } 48 | 49 | private: 50 | std::queue m_queue; 51 | std::mutex m_mutex; 52 | }; 53 | 54 | #endif // SAFEQUEUE_H_ 55 | -------------------------------------------------------------------------------- /CentralComputing/SourceManager.cpp: -------------------------------------------------------------------------------- 1 | #include "SourceManager.h" 2 | 3 | PRUManager SourceManager::PRU; 4 | CANManager SourceManager::CAN; 5 | ADCManager SourceManager::ADC; 6 | I2CManager SourceManager::I2C; 7 | 8 | -------------------------------------------------------------------------------- /CentralComputing/SourceManager.h: -------------------------------------------------------------------------------- 1 | #ifndef SOURCEMANAGER_H_ 2 | #define SOURCEMANAGER_H_ 3 | 4 | #include "PRUManager.h" 5 | #include "CANManager.h" 6 | #include "ADCManager.h" 7 | #include "I2CManager.h" 8 | 9 | // Include stubbs to allow Managers to 10 | // include this .hpp in their files 11 | class PRUManager; 12 | class CANManager; 13 | class ADCManager; 14 | class I2CManager; 15 | 16 | namespace SourceManager { 17 | extern PRUManager PRU; 18 | extern CANManager CAN; 19 | extern ADCManager ADC; 20 | extern I2CManager I2C; 21 | } 22 | 23 | #endif // SOURCEMANAGER_H_ 24 | -------------------------------------------------------------------------------- /CentralComputing/StateMachineCompact/StateMachine.cpp: -------------------------------------------------------------------------------- 1 | #include "StateMachine.h" 2 | 3 | StateMachine::StateMachine(unsigned char maxStates) : 4 | currentState(0), 5 | _maxStates(maxStates), 6 | _eventGenerated(false), 7 | _pEventData(NULL) 8 | { 9 | } 10 | // returns the current state of the StateMachine 11 | unsigned char StateMachine::getCurrentState() { 12 | std::lock_guard guard(_mutex); 13 | return currentState; 14 | } 15 | // generates an external event. called once per external event 16 | // to start the state machine executing 17 | void StateMachine::ExternalEvent(unsigned char newState, 18 | EventData* pData) 19 | { 20 | // if we are supposed to ignore this event 21 | if (newState == EVENT_IGNORED) { 22 | // just delete the event data, if any 23 | if (pData) 24 | delete pData; 25 | } 26 | else { 27 | 28 | // generate the event and execute the state engine 29 | InternalEvent(newState, pData); 30 | StateEngine(); 31 | 32 | } 33 | } 34 | 35 | // generates an internal event. called from within a state 36 | // function to transition to a new state 37 | void StateMachine::InternalEvent(unsigned char newState, 38 | EventData* pData) 39 | { 40 | std::lock_guard guard(_mutex); // Mutex lock for thread safety 41 | if (pData == NULL) 42 | pData = new EventData(); 43 | 44 | _pEventData = pData; 45 | _eventGenerated = true; 46 | currentState = newState; 47 | } 48 | 49 | // the state engine executes the state machine states 50 | void StateMachine::StateEngine(void) 51 | { 52 | EventData* pDataTemp = NULL; 53 | 54 | // while events are being generated keep executing states 55 | while (_eventGenerated) { 56 | pDataTemp = _pEventData; // copy of event data pointer 57 | _pEventData = NULL; // event data used up, reset ptr 58 | _eventGenerated = false; // event used up, reset flag 59 | 60 | // assert(currentState < _maxStates); 61 | // We should avoid assert because it will casue a crash 62 | if (currentState < _maxStates) { 63 | // GO TO ERROR STATE MUST BE IMPLEMENTED 64 | } 65 | 66 | // get state map 67 | const StateStruct* pStateMap = GetStateMap(); 68 | 69 | // execute the state passing in event data, if any 70 | (this->*pStateMap[currentState].pStateFunc)(pDataTemp); 71 | 72 | // if event data was used, then delete it 73 | if (pDataTemp) { 74 | delete pDataTemp; 75 | pDataTemp = NULL; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /CentralComputing/StateMachineCompact/StateMachine.h: -------------------------------------------------------------------------------- 1 | #ifndef _STATE_MACHINE_H 2 | #define _STATE_MACHINE_H 3 | #include 4 | #include 5 | 6 | class EventData 7 | { 8 | public: 9 | virtual ~EventData() {}; 10 | }; 11 | 12 | struct StateStruct; 13 | 14 | // base class for state machines 15 | class StateMachine 16 | { 17 | public: 18 | StateMachine(unsigned char maxStates); 19 | unsigned char getCurrentState(); 20 | virtual ~StateMachine() {} 21 | protected: 22 | enum { EVENT_IGNORED = 0xFE, CANNOT_HAPPEN }; 23 | unsigned char currentState; 24 | void ExternalEvent(unsigned char, EventData* = NULL); 25 | void InternalEvent(unsigned char, EventData* = NULL); 26 | virtual const StateStruct* GetStateMap() = 0; 27 | private: 28 | const unsigned char _maxStates; 29 | bool _eventGenerated; 30 | EventData* _pEventData; 31 | void StateEngine(void); 32 | std::mutex _mutex; 33 | }; 34 | 35 | typedef void (StateMachine::*StateFunc)(EventData *); 36 | struct StateStruct 37 | { 38 | StateFunc pStateFunc; 39 | }; 40 | 41 | #define BEGIN_STATE_MAP \ 42 | public:\ 43 | const StateStruct* GetStateMap() {\ 44 | static const StateStruct StateMap[] = { 45 | 46 | #define STATE_MAP_ENTRY(stateFunc)\ 47 | { reinterpret_cast(stateFunc) }, 48 | 49 | #define END_STATE_MAP \ 50 | }; \ 51 | return &StateMap[0]; } 52 | 53 | #define BEGIN_TRANSITION_MAP \ 54 | static const unsigned char TRANSITIONS[] = {\ 55 | 56 | #define TRANSITION_MAP_ENTRY(entry)\ 57 | entry, 58 | 59 | #define END_TRANSITION_MAP(data) \ 60 | 0 };\ 61 | ExternalEvent(TRANSITIONS[currentState], data); 62 | 63 | #endif //STATE_MACHINE_H 64 | -------------------------------------------------------------------------------- /CentralComputing/TCPManager.h: -------------------------------------------------------------------------------- 1 | #ifndef TCPMANAGER_H_ 2 | #define TCPMANAGER_H_ 3 | 4 | #include "Configurator.h" 5 | #include "Defines.hpp" 6 | #include "Utils.h" 7 | #include "SafeQueue.hpp" 8 | #include "SourceManager.h" 9 | #include "Event.h" 10 | #include "Simulator.h" 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include // NOLINT 19 | #include 20 | #include // NOLINT 21 | #include 22 | 23 | #define SETUP_FAILURE -1 24 | #define SETUP_SUCCESS 0 25 | 26 | #define WRITE_FAILURE -1 27 | 28 | namespace TCPManager { 29 | 30 | struct TCPSendIDs { 31 | uint8_t adc_id = 7; 32 | uint8_t can_id = 1; 33 | uint8_t i2c_id = 2; 34 | uint8_t pru_id = 3; 35 | uint8_t motion_id = 4; 36 | uint8_t error_id = 5; 37 | uint8_t state_id = 6; 38 | uint8_t bms_id = 9; 39 | }; 40 | 41 | extern TCPSendIDs TCPID; 42 | 43 | extern int socketfd; 44 | extern std::atomic running; 45 | 46 | extern UnifiedState * unified_state; 47 | extern ADCData adc_data; 48 | extern CANData can_data; 49 | extern BMSCells bms_data; 50 | extern I2CData i2c_data; 51 | extern PRUData pru_data; 52 | extern MotionData motion_data; 53 | extern Errors error_data; 54 | extern E_States state; 55 | extern int64_t stagger_times[4]; // Used to stagger how frequently data is sent to tcp server 56 | extern int64_t last_sent_times[4]; // Used to store the last time a data type was sent 57 | extern std::mutex data_mutex; 58 | extern int64_t write_loop_timeout; 59 | 60 | extern Event connected; // Used within Simulator to check when TCP is connected 61 | extern Event closing; // Used to wait between writes in the write_loop() 62 | extern std::mutex setup_shutdown_mutex; // Used to eliminate TSan errors 63 | 64 | int connect_to_server(const char * hostname, const char * port); 65 | 66 | /** 67 | * Reads from socketfd, parses read bytes into a Network_Command struct 68 | * Note: blocking command, will wait on read until something is sent or FD is closed 69 | * @param buffer a pointer to the network command that was read 70 | * @return the number of bytes read 71 | **/ 72 | int read_command(uint32_t * ID, uint32_t * Command); 73 | /** 74 | * Collects data from sensor, writes to socket 75 | * @param times timings for when to send specific data 76 | * @return bytes written or -1 if failed 77 | **/ 78 | int write_data(); 79 | 80 | /** 81 | * Thread function, continually reads commands from the socket and 82 | * pushes them onto the queue 83 | */ 84 | void read_loop(); 85 | 86 | /** 87 | * Thread function, continually gets most recent state/motor/brake/sensor 88 | * data and sends a packet 89 | */ 90 | void write_loop(); 91 | 92 | /** 93 | * Thread function, handles connecting to new clients and starting read/write loop 94 | * @param hostname the IP address to connect to 95 | * @param port the port to connect to 96 | **/ 97 | void tcp_loop(const char * hostname, const char * port, UnifiedState * unified_state); 98 | 99 | /** 100 | * Closes the socket, ending all transmission 101 | **/ 102 | void close_client(); 103 | 104 | } // namespace TCPManager 105 | 106 | #endif // TCPMANAGER_H_ 107 | -------------------------------------------------------------------------------- /CentralComputing/UDPManager.h: -------------------------------------------------------------------------------- 1 | #ifndef UDPMANAGER_H_ 2 | #define UDPMANAGER_H_ 3 | 4 | #include "Utils.h" 5 | #include "Command.h" 6 | #include "Defines.hpp" 7 | #include "Configurator.h" 8 | #include "SafeQueue.hpp" 9 | #include "Event.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include // NOLINT 18 | #include 19 | #include // NOLINT 20 | #include 21 | 22 | namespace UDPManager { 23 | 24 | enum Connection_Status{ 25 | NOT_YET_CONNECTED, 26 | CONNECTED, 27 | DISCONNECTED 28 | }; 29 | 30 | extern int send_socketfd; 31 | extern int recv_socketfd; 32 | extern std::atomic running; 33 | extern Connection_Status connection_status; 34 | extern struct addrinfo hints, *sendinfo, *recvinfo; 35 | 36 | extern Event setup; 37 | extern std::mutex mutex; 38 | 39 | /** 40 | * Starts UDP server 41 | * @param hostname the IP address 42 | * @param what port are we sending to 43 | * @param what port are we recieving on 44 | * @return socket that is created 45 | **/ 46 | bool start_udp(const char * hostname, const char * send_port, const char * recv_port); 47 | 48 | int udp_recv(uint8_t* recv_buf, uint8_t len); // receives data and is put into a buffer 49 | int udp_send(uint8_t* buf, uint8_t len); // send data from the buffer passed in 50 | bool udp_parse(uint8_t* buf, uint8_t len); // parse the data in the buffer 51 | /** 52 | * Uses the UDP port setup by start_udp to monitor connection status 53 | **/ 54 | void connection_monitor(const char * hostname, const char * send_port, const char * recv_port); 55 | 56 | /** 57 | * Closes the socket, ending all transmission 58 | **/ 59 | void close_client(); 60 | 61 | } // namespace UDPManager 62 | 63 | #endif // UDPMANAGER_H_ 64 | -------------------------------------------------------------------------------- /CentralComputing/Utils.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_H_ 2 | #define UTILS_H_ 3 | #include 4 | #include 5 | #include // NOLINT 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace Utils { 20 | 21 | const int HEARTBEAT_GPIO = 68; 22 | const int WATCH_DOG_RESET_GPIO = 69; 23 | const int BRAKE_GPIO = 45; 24 | 25 | /** 26 | * Gets the current time since program startup 27 | * @return a long long representing the number of microseconds since startup 28 | **/ 29 | int64_t microseconds(); 30 | 31 | // Set GPIO to specific value 32 | bool set_GPIO(int GPIONumber, bool switchVal); 33 | 34 | uint32_t cast_to_u32(int offset, int bytes_per_item, unsigned char* bufferArray); 35 | void busyWait(int64_t microseconds); 36 | enum LogLevel { 37 | LOG_EDEBUG = 0, // excesive debug 38 | LOG_DEBUG = 1, // debug 39 | LOG_INFO = 2, 40 | LOG_ERROR = 3 41 | }; 42 | 43 | extern LogLevel loglevel; 44 | 45 | void print(LogLevel level, const char * format, ...); 46 | 47 | /** 48 | * Prints errno, with user defined message prepended 49 | **/ 50 | #define PRINT_ERRNO(S) \ 51 | {\ 52 | char err_buf[500];\ 53 | char* err_str = strerror_r(errno, err_buf, (size_t)500);\ 54 | print(LogLevel::LOG_ERROR, "%s errno: %s\n", S, err_str);\ 55 | } 56 | 57 | /** 58 | * Define utility clamp function 59 | **/ 60 | template 61 | T clamp(T v, T l, T h) { 62 | if (v < l) { 63 | return l; 64 | } else if (v > h) { 65 | return h; 66 | } else { 67 | return v; 68 | } 69 | } 70 | 71 | ssize_t write_all_to_socket(int socket, uint8_t * buffer, size_t count); 72 | 73 | } // namespace Utils 74 | 75 | #endif // UTILS_H_ 76 | -------------------------------------------------------------------------------- /CentralComputing/commandtest.py: -------------------------------------------------------------------------------- 1 | from ctypes import * 2 | commandlib = CDLL("./commandlib.so") 3 | commandlib.connect() 4 | 5 | print(vars(commandlib)) 6 | print(commandlib.Command) 7 | print(commandlib.get_network_command_ID_string()) 8 | -------------------------------------------------------------------------------- /CentralComputing/defaultFlightPlan.txt: -------------------------------------------------------------------------------- 1 | 0 0 2 | 1000000 0 # 1 second 3 | 2000000 0 # 2 seconds 4 | 3000000 0 # 3 seconds 5 | 4000000 0 # 4 seconds 6 | 5000000 0 # 5 seconds 7 | 6000000 0 # 6 seconds 8 | 7000000 0 # 7 seconds 9 | 8000000 0 # 8 seconds 10 | 9000000 0 # 9 seconds 11 | 10000000 0 # 10 seconds 12 | -------------------------------------------------------------------------------- /CentralComputing/navigationFlightPlan.txt: -------------------------------------------------------------------------------- 1 | 0 0 2 | 1000 0 # 1 second 3 | 2000 0 # 2 seconds 4 | 3000 0 # 3 seconds 5 | 4000 0 # 4 seconds 6 | 5000 0 # 5 seconds 7 | 6000 0 # 6 seconds 8 | 7000 0 # 7 seconds 9 | 8000 0 # 8 seconds 10 | 9000 0 # 9 seconds 11 | 10000 0 # 10 seconds 12 | -------------------------------------------------------------------------------- /CentralComputing/scenarios/ScenarioRealLong.h: -------------------------------------------------------------------------------- 1 | #ifndef SCENARIOREALNOFAULT2_H_ 2 | #define SCENARIOREALNOFAULT2_H_ 3 | #include "Scenario.hpp" 4 | 5 | class ScenarioRealLong : public Scenario { 6 | public: 7 | ScenarioRealLong(); 8 | 9 | virtual std::shared_ptr sim_get_adc(); 10 | virtual std::shared_ptr sim_get_can(); 11 | virtual std::shared_ptr sim_get_i2c(); 12 | virtual std::shared_ptr sim_get_pru(); 13 | 14 | virtual void true_motion(); 15 | int64_t pru_delta_seconds, can_delta_seconds, rolling_counter; 16 | int32_t adc_axis_0, adc_axis_1, adc_dir_flip; 17 | }; 18 | #endif -------------------------------------------------------------------------------- /CentralComputing/scenarios/ScenarioTestTimeouts.cpp: -------------------------------------------------------------------------------- 1 | #ifdef SIM 2 | #include "ScenarioTestTimeouts.h" 3 | #include "Utils.h" 4 | 5 | ScenarioTestTimeouts::ScenarioTestTimeouts() { 6 | } 7 | 8 | // Just do nothing 9 | void ScenarioTestTimeouts::true_motion() { 10 | acceleration = 0; 11 | } 12 | 13 | 14 | #endif -------------------------------------------------------------------------------- /CentralComputing/scenarios/ScenarioTestTimeouts.h: -------------------------------------------------------------------------------- 1 | #ifndef SCENARIOTESTTIMEOUTS_H_ 2 | #define SCENARIOTESTTIMEOUTS_H_ 3 | #include "ScenarioRealLong.h" 4 | 5 | class ScenarioTestTimeouts: public ScenarioRealLong { 6 | public: 7 | ScenarioTestTimeouts(); 8 | virtual void true_motion(); 9 | }; 10 | #endif -------------------------------------------------------------------------------- /CentralComputing/tests/MotorTest.cpp: -------------------------------------------------------------------------------- 1 | #ifdef SIM // Only compile if building test executable 2 | #include "PodTest.cpp" 3 | 4 | void check_test_eq(std::string file, std::string val); 5 | 6 | void check_test_eq(std::string file, std::string val){ 7 | std::ifstream in(file); 8 | std::string line; 9 | std::getline(in, line); 10 | in.close(); 11 | EXPECT_EQ(line, val); 12 | } 13 | 14 | 15 | TEST_F(PodTest, MotorTest) { 16 | MoveState(Command::Network_Command_ID::TRANS_FUNCTIONAL_TEST_OUTSIDE, E_States::ST_FUNCTIONAL_TEST_OUTSIDE, true); 17 | 18 | //Enable motors 19 | SendCommand(Command::Network_Command_ID::ENABLE_MOTOR, 0); 20 | EXPECT_EQ(pod->state_machine->motor.is_enabled(), true); 21 | 22 | //Disable motors 23 | SendCommand(Command::Network_Command_ID::DISABLE_MOTOR, 0); 24 | EXPECT_EQ(pod->state_machine->motor.is_enabled(), false); 25 | 26 | //Enable motors 27 | SendCommand(Command::Network_Command_ID::ENABLE_MOTOR, 0); 28 | EXPECT_EQ(pod->state_machine->motor.is_enabled(), true); 29 | 30 | //Disable motors 31 | SendCommand(Command::Network_Command_ID::DISABLE_MOTOR, 0); 32 | EXPECT_EQ(pod->state_machine->motor.is_enabled(), false); 33 | 34 | //Enable motors 35 | SendCommand(Command::Network_Command_ID::ENABLE_MOTOR, 0); 36 | EXPECT_EQ(pod->state_machine->motor.is_enabled(), true); 37 | 38 | 39 | //Try setting motor values 40 | SendCommand(Command::Network_Command_ID::SET_MOTOR_SPEED, 0); 41 | EXPECT_EQ(pod->state_machine->motor.get_throttle(), 0); 42 | 43 | SendCommand(Command::Network_Command_ID::SET_MOTOR_SPEED, 125); 44 | EXPECT_EQ(pod->state_machine->motor.get_throttle(), 125); 45 | 46 | SendCommand(Command::Network_Command_ID::SET_MOTOR_SPEED, 250); 47 | EXPECT_EQ(pod->state_machine->motor.get_throttle(), 250); 48 | 49 | //Disable again 50 | SendCommand(Command::Network_Command_ID::DISABLE_MOTOR, 0); 51 | EXPECT_EQ(pod->state_machine->motor.is_enabled(), false); 52 | EXPECT_EQ(pod->state_machine->motor.get_throttle(), 0); 53 | 54 | } 55 | #endif 56 | -------------------------------------------------------------------------------- /CentralComputing/tests/VelocityTest.cpp: -------------------------------------------------------------------------------- 1 | #ifdef SIM // Only compile if building test executable 2 | #include "PodTest.cpp" 3 | 4 | TEST_F(PodTest, VelocitySanity) { 5 | 6 | } 7 | #endif 8 | -------------------------------------------------------------------------------- /CentralComputing/tests/basicFlightPlan.txt: -------------------------------------------------------------------------------- 1 | 0 100 2 | 3 | -------------------------------------------------------------------------------- /CentralComputing/tests/basicFlightPlan1.txt: -------------------------------------------------------------------------------- 1 | 0 105 2 | 200 200 3 | 300 400 4 | 400 300 5 | 500 900 6 | -------------------------------------------------------------------------------- /CentralComputing/tests/duty_cycle: -------------------------------------------------------------------------------- 1 | 950000 -------------------------------------------------------------------------------- /CentralComputing/tests/enable: -------------------------------------------------------------------------------- 1 | 0 -------------------------------------------------------------------------------- /CentralComputing/tests/realFlightPlan.txt: -------------------------------------------------------------------------------- 1 | 000000 50 #Assuimg rated torque of 230Nm -> 50 throttle == 11.5Nm 2 | 050000 100 #Target_torque = rated_torqe * throttle / 1000 3 | 100000 150 4 | 150000 200 5 | 200000 250 6 | 250000 300 7 | 300000 350 8 | 350000 400 9 | 400000 450 10 | 450000 500 11 | 500000 550 12 | 550000 600 13 | 600000 650 14 | 650000 700 15 | 700000 750 16 | 750000 800 17 | 800000 850 18 | 850000 900 19 | 900000 950 20 | 1000000 1000 #1 seconds in, full power 21 | 22 | 7000000 860 #7 seconds in, start reducing power 23 | 24 | 8000000 650 #8 seconds in 25 | 26 | 9000000 625 #9 seconds in 27 | 10000000 600 # Continue decreasing power 28 | 11000000 575 29 | 12000000 550 30 | 13000000 525 31 | 14000000 500 32 | 33 | 15000000 450 #15 seconds in 34 | 35 | -------------------------------------------------------------------------------- /CentralComputing/tests/test.txt: -------------------------------------------------------------------------------- 1 | Variable 12 // test comment 2 | Variable1 -12 // test comment 3 | Number 2342 // test comment 4 | MaxAccel 1231.23 5 | MaxAccel1 -1231.23 //what 6 | MaxDecel 231 7 | motor_distance_clamp 10 wow 8 | low_pass_filter_velocity 0.90 9 | low_pass_filter_acceleration 0.90 10 | adc_axis_0 1 11 | adc_axis_1 2 12 | -------------------------------------------------------------------------------- /CentralComputing/tests/velocity_basic.txt: -------------------------------------------------------------------------------- 1 | motor_distance_clamp 10 2 | low_pass_filter_velocity 0.00 3 | low_pass_filter_acceleration 0.00 4 | adc_axis_0 1 5 | adc_axis_1 2 6 | -------------------------------------------------------------------------------- /CentralComputing/tests/velocity_low_pass.txt: -------------------------------------------------------------------------------- 1 | motor_distance_clamp 10 2 | low_pass_filter_velocity 0.70 3 | low_pass_filter_acceleration 0.90 4 | adc_axis_0 0 5 | adc_axis_1 1 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Illini Hyperloop Pod Electrical System 2 | 3 | ## Repo layout: 4 | 1. Default branch is `pod4`, and pull requests must be made to merge into it 5 | 2. There are tags for older versions of the pod code 6 | 3. `master` branch will only be used for correct, working code. A pull request must be made to merge 7 | 8 | 9 | ### This Repo Includes: 10 | 1. Flight control software for the BeagleBone Black 11 | * Network Communication 12 | * State machine 13 | * Communication to peripheral devices and sensors 14 | 2. BeagleBone Black setup 15 | * General device setup and configuration guide 16 | * Setup for device tree overlays 17 | * PRU code 18 | 3. Watchdog 19 | * Arduino based code for a simple watchdog controller 20 | 4. BaseStation 21 | * GUI basestation for display and control of the Pod 22 | -------------------------------------------------------------------------------- /Watchdog/Tiny_QuickRef_v2_2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlliniHyperloopComputing/Pod/0e61078ea69a729a19b0b637d76338732b7a6f41/Watchdog/Tiny_QuickRef_v2_2.pdf -------------------------------------------------------------------------------- /Watchdog/Watchdog.ino: -------------------------------------------------------------------------------- 1 | int inPin = 1; //whatever the input pin is 2 | int outPin = 0; //output to tell other hardware if software failed 3 | int heartBeat = 0; //output value, start LOW 4 | int lastBeat = 0; //to check for changing vals 5 | 6 | //wait for X amount of signal changes (heart beats) within a short 7 | //time period (to make sure power cycles or other transients doesn't 8 | //accidentally turn it on) 9 | //no idea what these should be 10 | int changeCounter = 0; //just looking for changes 11 | int waitPeriod = 0; 12 | int startTime = 0; 13 | int currTime = 0; 14 | int goal = 0; 15 | int state = 0; 16 | 17 | 18 | void setup() { 19 | waitPeriod = 260; 20 | goal = 5; 21 | pinMode(outPin, OUTPUT); 22 | pinMode(inPin, INPUT); 23 | //START LOW 24 | digitalWrite(outPin, 0); 25 | } 26 | 27 | void setupState1(){ 28 | changeCounter = 0; 29 | waitPeriod = 52; 30 | startTime = millis(); 31 | goal = 1; 32 | state = 1; 33 | } 34 | 35 | void reset(){ 36 | startTime = millis(); 37 | changeCounter = 0; 38 | } 39 | 40 | void checkHeartBeat(){ 41 | heartBeat = digitalRead(inPin); 42 | currTime = millis(); 43 | //check for change in hearbeat 44 | 45 | if (heartBeat != lastBeat){ changeCounter++; } 46 | 47 | lastBeat = heartBeat; 48 | } 49 | 50 | 51 | void loop() { 52 | //START STATE 53 | if (state == 0){ 54 | checkHeartBeat(); 55 | //if we get 5 changes in a span of 260ms continue to healthy state 56 | if (changeCounter > goal){ 57 | setupState1(); 58 | } 59 | 60 | //reset counters to continue waiting 61 | if (currTime - startTime > waitPeriod){ 62 | reset(); 63 | } 64 | } 65 | 66 | //HEALTHY STATE 67 | if (state == 1){ 68 | digitalWrite(outPin, 1); 69 | checkHeartBeat(); 70 | if (currTime - startTime >= waitPeriod){ 71 | if (changeCounter < goal){ 72 | state = 2; 73 | } 74 | reset(); 75 | } 76 | } 77 | 78 | //DEAD STATE 79 | if (state == 2){ 80 | digitalWrite(outPin, 0); 81 | while (1){ 82 | //DO NOTHING 83 | } 84 | } 85 | } 86 | 87 | -------------------------------------------------------------------------------- /models/numerical_integration/Emrax_Efficiency_Map.m: -------------------------------------------------------------------------------- 1 | function [efficiency] = Emrax_Efficiency_Map(torque, rpm) 2 | % Where x==RPM y==Torque 3 | global poly_96_x; 4 | global poly_96_y; 5 | global poly_95_x; 6 | global poly_95_y; 7 | global poly_94_x; 8 | global poly_94_y; 9 | 10 | global poly_90_x; 11 | global poly_90_y; 12 | 13 | global poly_86_x; 14 | global poly_86_y; 15 | 16 | poly_96_x = [1500 1750 3200 3550 2100 1900 1500]; 17 | poly_96_y = [125 130 120 110 80 85 125]; 18 | poly_95_x = [1900 1400 1200 2500 4000 4250 4000 1900]; 19 | poly_95_y = [60 100 150 165 152 125 100 60]; 20 | poly_94_x = [4000 3500 1500 1000 1000 1100 2000 5000 5000 4000]; 21 | poly_94_y = [70 60 60 70 140 165 200 195 150 70]; 22 | 23 | poly_90_x = [5000 5000 3500 1500 1000 600 1400 5000]; 24 | poly_90_y = [230 120 45 45 55 110 235 230]; 25 | 26 | poly_86_x = [5000 5000 3600 1000 300 400 1200 5000]; 27 | poly_86_y = [245 105 26 25 50 150 240 245]; 28 | 29 | 30 | in_96 = inpolygon(rpm, torque, poly_96_x, poly_96_y); 31 | in_95 = inpolygon(rpm, torque, poly_95_x, poly_95_y); 32 | in_94 = inpolygon(rpm, torque, poly_94_x, poly_94_y); 33 | in_90 = inpolygon(rpm, torque, poly_90_x, poly_90_y); 34 | in_86 = inpolygon(rpm, torque, poly_86_x, poly_86_y); 35 | 36 | if(in_96) 37 | efficiency = 0.96; 38 | elseif(in_95) 39 | efficiency = 0.95; 40 | elseif(in_94) 41 | efficiency = 0.94; 42 | elseif(in_90) 43 | efficiency = 0.90; 44 | elseif(in_86) 45 | efficiency = 0.86; 46 | else 47 | efficiency = 0.80; 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /models/numerical_integration/Motor_Dynamics.m: -------------------------------------------------------------------------------- 1 | 2 | function [Torque, MechPower, MotorInputPower, ControllerInputPower, Current] ... 3 | = Motor_Dynamics (RPM, MechPowerTarget, PeakTorque, MaxAmps, MaxRPM, ControllerEfficiency... 4 | ,BatteryVoltage, BatteryResistance, BatteryMaxPower, isEmrax) 5 | 6 | MechPowerTarget = min(MechPowerTarget, 0.96*ControllerEfficiency*BatteryMaxPower); 7 | MechPowerTarget = MechPowerTarget+0.1; %measured in kw, this is adding 100w 8 | BatteryPower = BatteryMaxPower*1000 *2; %this gets overwritten, justs needs to be initally higher than BatteryMaxPower 9 | Current = MaxAmps+1; % Just need to define this... gets overwritten 10 | 11 | %This function will determine the maximum torque that can be applied, 12 | %such that the battery output is no higher than the given maximum. 13 | %Essentially, this is the "lazy" way of doing this by just repeatedly 14 | %trying a bunch of values. 15 | % 16 | %This alg is _Really_ slow if MechPowerTarget == BatteryMaxPower, since 17 | %it will have to iterate downward. 18 | % 19 | %I didn't spend any time trying to optimize 20 | 21 | while(BatteryPower > BatteryMaxPower*1000) 22 | while(Current > MaxAmps) 23 | MechPowerTarget = MechPowerTarget - 0.05; 24 | 25 | [Torque, MechPower] = Torque_curve_reader(RPM, MechPowerTarget, PeakTorque, MaxRPM); %rpm, Motor Power (kW), Max Torque (Nm), Max RPM, gear ratio 26 | 27 | if(isEmrax) 28 | Efficiency = Emrax_Efficiency_Map(Torque, RPM); 29 | else 30 | %BIG assumption here, but I believe it is a safe one 31 | Efficiency = 0.8; 32 | end 33 | 34 | MotorInputPower = MechPower/Efficiency; 35 | ControllerInputPower = MotorInputPower/ControllerEfficiency; 36 | 37 | % Solve for Current using from this formula: 38 | % P = V_pack*I_out - I_out^2*R_pack 39 | Current = (BatteryVoltage - sqrt(BatteryVoltage^2 - 4*BatteryResistance * ControllerInputPower))/(2*BatteryResistance); 40 | 41 | BatteryPower = Current * BatteryVoltage; 42 | end 43 | end 44 | 45 | end 46 | -------------------------------------------------------------------------------- /models/numerical_integration/Plot_Torque_Curve.m: -------------------------------------------------------------------------------- 1 | 2 | function [] = Plot_Torque_Curve () 3 | 4 | poly_96_x = [1500 1750 3200 3550 2100 1900 1500]; 5 | poly_96_y = [125 130 120 110 80 85 125]; 6 | poly_95_x = [1900 1400 1200 2500 4000 4250 4000 1900]; 7 | poly_95_y = [60 100 150 165 152 125 100 60]; 8 | poly_94_x = [4000 3500 1500 1000 1000 1100 2000 5000 5000 4000]; 9 | poly_94_y = [70 60 60 70 140 165 200 195 150 70]; 10 | 11 | poly_90_x = [5000 5000 3500 1500 1000 600 1400 5000]; 12 | poly_90_y = [230 120 45 45 55 110 235 230]; 13 | 14 | poly_86_x = [5000 5000 3600 1000 300 400 1200 5000]; 15 | poly_86_y = [245 105 26 25 50 150 240 245]; 16 | 17 | hold on; 18 | plot(poly_96_x, poly_96_y, ':', 'color', 'g'); 19 | plot(poly_95_x, poly_95_y, ':', 'color', 'b'); 20 | plot(poly_94_x, poly_94_y, ':', 'color', 'm'); 21 | plot(poly_90_x, poly_90_y, ':', 'color', 'k'); 22 | plot(poly_86_x, poly_86_y, ':', 'color', 'r'); 23 | 24 | 25 | end 26 | -------------------------------------------------------------------------------- /models/numerical_integration/README.md: -------------------------------------------------------------------------------- 1 | # Numerical Integration scripts for modeling Pod Dynamics 2 | 3 | The most important file is `emrax_only.m`. Not only is this the most up to date model (when compared to `emrax_tp100.m` and `purdue_model.m`), but it is also the most accurate. 4 | - `Emrax_Efficiency_Map.m` takes the established efficiency regions of the EMRAX 228 motor from the datasheet, and graphs it. This allows for the calling script to input an RPM and Torque, and get the efficiency percent back 5 | - `Motor_Dynamics.m` Helps to determines the maximum torque that can be applied, based on the input parameters, like maximum operating power and Amperage. This is slow because it wasn't optimized. 6 | - `Plot_Torque_curve.m` Just plots the EMRAX efficiency regions. It's a helper function. 7 | - `Torque_curve_reader.m` was a predecesor to `Motor_Dynamics.m` and isn't used right now 8 | 9 | This script is setup such that parameters can be optimized. Originally, the gear ratio was the parameter most in question (which is what is iterated over in the `purdue_model.m`). In my effort to make this script more functional, other parameters can be iterated over as well ( like battery resistance, and overall power output). However, I must warn that this script can go quite slow, and there isn't a progress bar. It is especially slow when the MaxMechanicalPower == MaxBatteryPower, because of how poorly the `Motor_Dynamics.m` is optimized (it isn't optimized). 10 | 11 | 12 | I will appologize ahead of time if it is confusing how the script even works. I (Richard Wendel) modified the original `purdue_model.m` to fit what I wanted. I added much more details about power and efficiency. 13 | 14 | Hopefully this is usefull to someone in the future, even if the lead time to being able to fully use it is a bit long. 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /models/numerical_integration/Torque_curve_reader.m: -------------------------------------------------------------------------------- 1 | function [torque, power] = Torque_curve_reader(Given_RPM, Power_Kw, Torque_max, RPM_max) 2 | Power = Power_Kw*1000; 3 | critical_w = (Power)/Torque_max; 4 | 5 | w = (Given_RPM.*2.*pi)./60; 6 | w_max = (RPM_max.*2.*pi)./60; 7 | 8 | if w w_max 11 | torque = 0; 12 | else 13 | torque = Power./w; 14 | end 15 | 16 | power = w .* torque; 17 | end --------------------------------------------------------------------------------