Skip to content

This app gives users of the ArduPilot/Plane open source software an intuitive GUI to rival the default dip-switchey looking interface. This was my fifth and final portfolio project submission in the Flatiron School curriculum.

License

Notifications You must be signed in to change notification settings

Richard-Burd/react-redux-portfolio-project

Repository files navigation

React-Redux Portfolio Project

This is a portfolio project submittal for Module 16 of the Full-Stack Web Development program at Flatiron School.  This project makes use of React and Redux together and is meant to show a basic level competency in those two JavaScript libraries.

Getting Started

To run this app locally, you will need to have Rails and Node Package Manager (NPM) already installed.  After that, type this command into your console while inside the app's /client directory, which is the front-end workspace:

  • $ npm install

...this will install the required NPM libraries.  Finally, navigate to the main project directory and run these commands:

  1. $ bundle install ... to install the Ruby Gems.
  2. $ rails db: migrate ... to run the Active Record migrations
  3. $ rails db: seed ... to seed the database with three airframes & their parameters.
  4. $ rails start ... to boot up the server courtesy of: ./lib/tasks/start.rake

The Problem Being Solved

This app is designed to be an interactive parameter editor for the ArduPlane open source software suite.  This software provides autonomous control for unmanned aerial vehicles (UAV's) and has several, customizable parameters that can be adjusted so as to tailor the software to a specific UAV body, or airframe in aviation jargon. 

a team of drone technicians getting ready for takeoff somewhere outside

In order to adjust these parameters, users interact with a not-so intuitive GUI designed for simplicity and parsimony.  Here is an example of what they're looking at:

enter image description here

Because the interface is so basic, users often struggle to keep track of which parameters do what and so they end up making cheat-sheets like this one I put together several years ago: Imgur

So then, this app is designed to be a graphically intuitive, ArduPlane parameter editor guide that does what this 2D graphical checklist above does, but better.  In sum, the app provides a user with graphics that illustrate what each parameter does and how changing that parameter will effect outcomes with responsive, animated graphics.

Currently this is just a v.0.1 demonstrator that would be presented to drone technicians for feedback.  The Arduplane software has somewhere around 90 flight-parameters and all this app does is create, read, update, and delete (CRUD) three of them, along with an associated airframe.  Even with this small delivery, the number of React components used to create this app far exceed the project requirements

User Interface

The app let's a user CRUD an airframe with a name & some basic info.  When an airframe is created, a default set of 3 parameters are also created for, and associated with, that same airframe.  These parameters control the airframe's maximum allowable pitch, roll, and yaw while in an autonomous flight mode

Imgur

The three parameters are edited on the /airframes/:id/params path as shown in the lower right-hand box in the illustration above.  There are three interactive graphics that change orientation as the user manipulates their values. This allows the user to see what their changes are doing rather than having to remember specifics they read way back from the boring documentation

Client - Server Communication

While manipulating these parameters, the user is sending their changes to a local React component state on the front-end, rather than the Redux store. Only when the user saves their changes are those changes sent to the server. The user only grabs data from the server whenever absolutely necessary since they will likely be in a field environment far away from solid internet access: 

Imgur One of my Flatiron School instructors pointed out that, in a situation with poor internet access, it may in fact be optimal to grab all the data you need at once (from the backend) so that when the connection is working, the user can take maximum advantage of that circumstance to effect their changes. In such a case the attitude, PID, and plugins could be populated once a singleAirframe is loaded into the store by altering the show action in ./app/controllers/airframes_controller.rb so that it renders all associated parameter data at the same time that it renders the airframe data.

Application Architecture

This app uses two communication paths as shown below.  First let's discuss the green arrows that say request and subscribed:

Imgur

When rendering back-end data, React functional components (such as AirframeData.js ) send (or more accurately, 'implement') requests to their commensurate Redux action controller (in this case airframeActions.js and the action controller then dispatches the action to the central redux store that is wrapping the commensurate reducer, in this case, airframeReducer.jssince were looking at airframes.  Redux then uses the middleware API to send an asynchronous fetch request to the Rails backend server that returns the appropriate data in the form of JSON. 

When a user persists to the back-end database, the workflow follows the orange arrows that say create, update, & delete.  Here, React container components like Airframe.js & AirframeForm.js that use a React class component's local state send requests to the Redux, action controllers, but bypass the Redux reducers & store altogether and go straight to the back-end server.  This is immediately followed by a page reload at which point the server and store are synced with changes traveling unidirectionally, from server to store and never the other way around.  This makes expansion and manipulation of the code base much easier because we are only keeping track of persistence in one direction as opposed to two.  The philosophy here is: if the user hasn't saved their changes, the store doesn't care to know about it yet.

Project File Structure

├── app
│   ├── controllers
│   │   ├── airframes_controller.rb
│   │   ├── application_controller.rb
│   │   ├── attitudes_controller.rb
│   │   ├── pids_controller.rb
│   │   └── plugins_controller.rb
│   └── models
│       ├── airframe.rb
│       ├── application_record.rb
│       ├── attitude.rb
│       ├── pid.rb
│       └── plugin.rb
├── client
│   ├── public
│   │   ├── index.html
│   │   └── manifest.json
│   ├── src
│   │   ├── components
│   │   │   ├── Airframe.js
│   │   │   ├── AirframeData.js
│   │   │   ├── AirframeForm.js
│   │   │   ├── AirframesContainer.js
│   │   │   ├── AttitudeForm.js
│   │   │   ├── ButtonComponent.js
│   │   │   ├── GraphicComponent.js
│   │   │   ├── LabelAndSelectOption.js
│   │   │   ├── LabelAndTextInput.js
│   │   │   ├── ParametersContainer.js
│   │   │   ├── RasterComponent.js
│   │   │   └── TestComponent.js
│   │   ├── graphics
│   │   │   ├── horizonLine.svg
│   │   │   ├── pitchCircleNarrow.svg
│   │   │   ├── pitchCircleWide.svg
│   │   │   ├── planeFrontView.svg
│   │   │   └── planeSideView.svg
│   │   ├── redux
│   │   │   ├── airframe
│   │   │   │   ├── AirplaneActions.js
│   │   │   │   └── AirplaneReducer.js
│   │   │   ├── attitude
│   │   │   │   ├── AttitudeActions.js
│   │   │   │   └── AttitudeReducer.js
│   │   │   ├── test
│   │   │   │   ├── TestActions.js
│   │   │   │   └── TestReducer.js
│   │   │   ├── index.js
│   │   │   ├── rootReducer.js
│   │   │   ├── store.js
│   │   │   └── urlAndUrns.js
│   │   ├── tests
│   │   │   ├── TestFetches.js
│   │   │   ├── TestLibraries.js
│   │   │   ├── TestPortal.js
│   │   │   ├── TestReduxWorkflow.js
│   │   │   └── TestRouter.js
│   │   ├── App.css
│   │   ├── App.js
│   │   ├── index.js
│   │   ├── NavBar.js
│   │   └── serviceWorker.js
│   ├── gitignore.js  
│   ├── package-lock.json
│   ├── package.json
│   ├── README.md
│   └── yarn.lock
├── config
│   ├── initializers
│   │   └── cors.rb
│   └── application.rb
├── db
│   ├── migrate
│   │   ├── 20200515145624_create_airframes.rb
│   │   ├── 20200515155135_create_attitudes
│   │   ├── 20200515155347_create_pids.rb
│   │   └── 20200515155545_create_plugins.rb
│   ├── development.sqlite3
│   ├── schema.rb
│   └── seeds.rb
├── lib
│   └── tasks
│       ├── .keep
│       └── start.rake
├── log
├── public
├── storage
├── test
├── tmp
├── vendor
├── config.ru
├── Gemfile
├── Gemfile.lock
├── LICENSE
├── Procfile
├── Rakefile
└── README.md

.

About

This app gives users of the ArduPilot/Plane open source software an intuitive GUI to rival the default dip-switchey looking interface. This was my fifth and final portfolio project submission in the Flatiron School curriculum.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published