Skip to content

Commit

Permalink
updating readme again with corrected terminology
Browse files Browse the repository at this point in the history
  • Loading branch information
RCMast3r committed Jan 26, 2024
1 parent bb03ae7 commit a15d427
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 48 deletions.
89 changes: 44 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,3 @@
new MCU code:
- component definition:
an abstract sub-system of the physical car or the code that requires logic to be evaluated by the MCU to determine what input to give it or logic required to handle output from.
- driver definition:
- code required to purely unpack / pack data into internal structs / classes for use by components or logic
- I think the best way to handle the driver level is that all the drivers

- architecture:

- over-arching state machine
- components level
- inverters (multiple)
- pedals
- torque / speed controller
- driver dashboard

- driver level:
- hytech_can driver
- spi drivers: SPI adcs for load cells, steering input, glv, etc.

### outline

Levels represent the layer of abstraction they are on. The reason for keeping track of this is to minimize the layers of abstraction for ease of understanding while also creating logical structure and getting maximum benefit per abstraction.
Expand All @@ -29,23 +9,23 @@ Levels represent the layer of abstraction they are on. The reason for keeping tr


#### level 1: state machine goals for interface design and implementation
- __Reason for abstraction__: allows for easy swapping and adding of different portable components and better [separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns) from [business logic](https://www.techtarget.com/whatis/definition/business-logic) of the car to the business logic of the component.
- __Reason for abstraction__: allows for easy swapping and adding of different portable systems and better [separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns) from [business logic](https://www.techtarget.com/whatis/definition/business-logic) of the car to the business logic of the system.


Any firmware project that needs to have different states needs each component that creates outputs and / or controls real components of the car needs can be thought of as each component being controlled by the state machine. What I am thinking is that in a similar fashion to the shared bus, each component can contain a shared pointer to the state machine. The component can know what state the car is in and based on the state it can determine how to behave. Obviously the state machine also needs to know about what the component is doing as well to determine the state, so the component also needs to be able to pass back data to the state machine.
Any firmware project that needs to have different states needs each system that creates outputs and / or controls real systems of the car needs can be thought of as each system being controlled by the state machine. What I am thinking is that in a similar fashion to the shared bus, each system can contain a shared pointer to the state machine. The system can know what state the car is in and based on the state it can determine how to behave. Obviously the state machine also needs to know about what the system is doing as well to determine the state, so the system also needs to be able to pass back data to the state machine.

For example, our state machine needs to handle understand the state of the pedals component. The pedals dont know about the state of the car, but it does know whether or not the pedals are outputting valid data. Each component can manage their own state and the abstract component base class could contain the set of component-agnostic states through which the statemachine evaluates.
For example, our state machine needs to handle understand the state of the pedals system. The pedals dont know about the state of the car, but it does know whether or not the pedals are outputting valid data. Each system can manage their own state and the abstract system base class could contain the set of system-agnostic states through which the statemachine evaluates.

It is only within the logic of our state machine that the components are allowed to communicate with one another.
It is only within the logic of our state machine that the systems are allowed to communicate with one another.

The main idea is that each firmware project has a specific implementation of a state machine, however the components are portable between firmware projects. Additionally, the components remain as concrete
The main idea is that each firmware project has a specific implementation of a state machine, however the systems are portable between firmware projects. Additionally, the systems remain as concrete




```mermaid
---
title: state machine and component state abstraction
title: state machine and system state abstraction
---
classDiagram
Expand All @@ -59,19 +39,16 @@ classDiagram
}
class StateMachine {
BMSComponent* bms
VectornavComponent* vectornav
PedalsComponent* pedals
DashComponent* dashboard
VectornavSystem* vectornav
PedalsSystem* pedals
DashSystem* dashboard
InverterComponent* left_front
InverterComponent* right_front
InverterComponent* left_rear
InverterComponent* right_rear
DrivetrainSystem* drivetrain
TorqueVectoringControllerComponent* tvc
LaunchControlComponent* launch_control
TorqueVectoringControllerSystem* tvc
LaunchControlSystem* launch_control
car_state state
void init()
Expand All @@ -86,19 +63,19 @@ classDiagram



#### level 2 portable components: interfaces, logic and structure
#### level 2 portable Systems: interfaces, logic and structure

- __Reason for abstraction__: these components allow us to have board portable pieces so that when newer iterations of boards are made, the same components that the previous iteration handled can be kept while only the hardware specific code changes.
- __Reason for abstraction__: these Systems allow us to have board portable pieces so that when newer iterations of boards are made, the same systems that the previous iteration handled can be kept while only the hardware specific code changes.

For instance, when a new MCU board is created with a new steering sensor input, code within the controller components will not need to change, only that a new sensor component will be used within the state machine to feed the controller input.
For instance, when a new MCU board is created with a new steering sensor input, code within the controller systems will not need to change, only that a new sensor system will be used within the state machine to feed the controller input.

below are some hypothetical component class definitions.
below are some hypothetical system class definitions.
```mermaid
---
title: components
title: systems
---
classDiagram
class PedalsComponent{
class PedalsSystem{
-void validate_accel_pedals()
-void validate_brake_pedals()
Expand All @@ -107,7 +84,7 @@ classDiagram
+float get_desired_throttle()
+void validate()
}
class TorqueVectoringControllerComponent{
class TorqueVectoringControllerSystem{
+void init(torque_vectoring_params params)
+void set_state_estimate(car_state state)
Expand All @@ -117,7 +94,7 @@ classDiagram
-void run_pid()
}
class LaunchControlComponent{
class LaunchControlSystem{
+void init(launch_control_params params)
+void set_state_estimate(car_state state)
Expand All @@ -130,7 +107,7 @@ classDiagram

#### level 2 SPI / i2c data bus abstraction from hardware specific implementations

- __Reason for abstraction__: this allows us to create a specific type of component that uses a shared resource, for example multiple sensors on a SPI bus, that each have their own scaling to produce data for feeding other components.
- __Reason for abstraction__: this allows us to create a specific type of system that uses a shared resource, for example multiple sensors on a SPI bus, that each have their own scaling to produce data for feeding other systems.

This is currently aimed at our use of a SPI bus. The read data functions are what convert the data gotten from the shared bus to the real-world values for each one of the sensors. This was being attempted with ADC_SPI versus STEERING_SPI using just copies of the class.

Expand Down Expand Up @@ -193,3 +170,25 @@ stateDiagram-v2
#### running the tests

This repo uses platformio testing for CI unit testing. these tests can be run locally with `pio test -e test_env`. The CI checks to ensure that the code both compiles for the teensy and ensures that the tests are passing.



#### notes
new MCU code:
- system definition:
an abstract sub-system of the physical car or the code that requires logic to be evaluated by the MCU to determine what input to give it or logic required to handle output from.
- interface definition:
- code required to purely unpack / pack data into internal structs / classes for use by systems or logic

- architecture:

- over-arching state machine
- systems level
- inverters (multiple)
- pedals
- torque / speed controller
- dashboard interface

- interface level:
- hytech_can interface
- spi interfaces: SPI adcs for load cells, steering input, glv, etc.
2 changes: 1 addition & 1 deletion test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ void tearDown(void)

int main()
{
// delay(2000); // service delay

UNITY_BEGIN();

RUN_TEST(test_pedal_is_active);
Expand Down
2 changes: 0 additions & 2 deletions test/state_machine_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ class DrivetrainMock

BuzzerController buzzer(500);



DrivetrainMock drivetrain;

DashboardInterface dash_interface;
Expand Down

0 comments on commit a15d427

Please sign in to comment.