-
Notifications
You must be signed in to change notification settings - Fork 8
PI sync May 10th, full suit working #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Binary file added
BIN
+1 KB
MAY_10_FULL_SUIT_WORKING/control/FSM_general_controller/.ActiveState.cpp.swp
Binary file not shown.
46 changes: 46 additions & 0 deletions
46
MAY_10_FULL_SUIT_WORKING/control/FSM_general_controller/.vscode/settings.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| { | ||
| "files.associations": { | ||
| "atomic": "cpp", | ||
| "bit": "cpp", | ||
| "cctype": "cpp", | ||
| "clocale": "cpp", | ||
| "cmath": "cpp", | ||
| "compare": "cpp", | ||
| "concepts": "cpp", | ||
| "cstddef": "cpp", | ||
| "cstdint": "cpp", | ||
| "cstdio": "cpp", | ||
| "cstdlib": "cpp", | ||
| "cstring": "cpp", | ||
| "ctime": "cpp", | ||
| "cwchar": "cpp", | ||
| "exception": "cpp", | ||
| "initializer_list": "cpp", | ||
| "ios": "cpp", | ||
| "iosfwd": "cpp", | ||
| "iostream": "cpp", | ||
| "istream": "cpp", | ||
| "iterator": "cpp", | ||
| "limits": "cpp", | ||
| "memory": "cpp", | ||
| "new": "cpp", | ||
| "ostream": "cpp", | ||
| "stdexcept": "cpp", | ||
| "streambuf": "cpp", | ||
| "system_error": "cpp", | ||
| "tuple": "cpp", | ||
| "type_traits": "cpp", | ||
| "typeinfo": "cpp", | ||
| "utility": "cpp", | ||
| "xfacet": "cpp", | ||
| "xiosbase": "cpp", | ||
| "xlocale": "cpp", | ||
| "xlocinfo": "cpp", | ||
| "xlocnum": "cpp", | ||
| "xmemory": "cpp", | ||
| "xstddef": "cpp", | ||
| "xstring": "cpp", | ||
| "xtr1common": "cpp", | ||
| "xutility": "cpp" | ||
| } | ||
| } |
212 changes: 212 additions & 0 deletions
212
MAY_10_FULL_SUIT_WORKING/control/FSM_general_controller/ActiveState.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,212 @@ | ||
| #include "ActiveState.h" | ||
| #include <iostream> | ||
| #include "../Joint_Estimator/JointEstimator.h" | ||
| #include "../Torque_Controller/TorqueController.h" | ||
| #include "../IMU_DataLoader/IMUDataLoader.h" | ||
| #include "../../motors/motor_api.h" | ||
|
|
||
| #include <iostream> | ||
| #include <cmath> | ||
| #include <chrono> | ||
| #include <thread> | ||
| #include <fstream> | ||
| #include "StateParameters.h" | ||
| #include "Timer.h" | ||
| #define MAX_THRESHOLD_TIME 5.0f | ||
| #define MIN_KNEE_ANGLE -15.0 | ||
| #define MAX_KNEE_ANGLE 130.0 | ||
| #define MAX_HIP_ANGLE 120 | ||
| #define MIN_HIP_ANGLE -30 | ||
| const double RATED_TORQUE = 0.64; // Nm | ||
| const double SIMULATION_TIME = 9.99; | ||
| const double GEAR_RATIO = 30.0; // CHANGE: What is gear ratio? | ||
| const bool SIMULATION = false; | ||
|
|
||
| using namespace IMUDataLoader; | ||
|
|
||
| // Constructor | ||
| ActiveState::ActiveState() | ||
| { | ||
| } | ||
|
|
||
| // Destructor | ||
| ActiveState::~ActiveState() | ||
| { | ||
| } | ||
|
|
||
| void ActiveState::enter() | ||
| { | ||
| cout << "\nNow in Active State \n"; | ||
| // activate motors | ||
| } | ||
|
|
||
| void ActiveState::leave() | ||
| { | ||
| cout << "\nleaving Active State\n"; | ||
| } | ||
|
|
||
| void ActiveState::update() | ||
| { | ||
| TorqueController::ModelParameters params = StateParameters::initializeModelParams(); // moved to stateparameters file | ||
| TorqueController controller(params); | ||
|
|
||
| // Load IMU Data | ||
| //JointData knee_data = loadJointData("joint_data.json", "Right Knee"); | ||
| //const std::vector<double>& timestamps = knee_data.timestamps; | ||
| //const std::vector<double>& knee_angles = knee_data.angles_rad; | ||
|
|
||
| // Simulated knee joint angle - ranges from 0 to 45 degrees w/ frequency=1 | ||
| const double dt = 0.1; | ||
| const double freq = 1.0; | ||
| const double amplitude_deg = 45.0; | ||
| std::vector<double> timestamps, knee_angles; | ||
|
|
||
| for (double t = 0.0; t <= 10.0; t += dt) { | ||
| timestamps.push_back(t); | ||
| double angle_deg = amplitude_deg * (std::sin(2 * M_PI * freq * t - M_PI / 2) + 1.0) / 2.0; | ||
| knee_angles.push_back(angle_deg * M_PI / 180.0); // convert to radians | ||
| } | ||
|
|
||
| // Testing paramters to verify how acceleartion, coriolis & gravity terms affect the torque output | ||
| double hip_m_acc, hip_c_vel, hip_g; | ||
| double knee_m_acc, knee_c_vel, knee_g; | ||
|
|
||
| JointEstimator hip_estimator; | ||
| JointEstimator knee_estimator; | ||
|
|
||
| knee_estimator.prime(knee_angles[0]); | ||
| hip_estimator.prime(0); | ||
|
|
||
| // Setup logging | ||
| std::ofstream log("Testing/log_output.csv"); | ||
| log << "time,hip_angle,hip_velocity,hip_acceleration," | ||
| "hip_m_acc,hip_c_vel,hip_g,hip_torque," | ||
| "knee_angle,knee_velocity,knee_acceleration," | ||
| "knee_m_acc,knee_c_vel,knee_g,knee_torque," | ||
| "knee_scaled_torque\n"; | ||
|
|
||
| Motor motor("/dev/ttyUSB0", 1); // CHANGE: Adjust device path and ID | ||
| // Initialize Motor | ||
| if (!SIMULATION) | ||
| { | ||
|
|
||
| if (!motor.initializeMotor()) { | ||
| std::cerr << "Failed to initialize motor. Aborting...\n"; | ||
| leave(); | ||
| current = error; | ||
| return; | ||
| } | ||
|
|
||
| motor.setMaxTorque(1000); | ||
| motor.setOperationMode(4); // Torque Profile Mode | ||
| } | ||
|
|
||
| ///////////////////////////////////////////////////////////////////////////// | ||
| for (size_t i = 1; i < knee_angles.size(); ++i) | ||
| { | ||
| double t = timestamps[i]; | ||
| double dt = timestamps[i] - timestamps[i - 1]; | ||
|
|
||
| // retreive timer pointer | ||
| Timer *timer = Timer::instance(); | ||
| timer->Reset(); | ||
|
|
||
| // Run simulation for 10 seconds for testing purposes | ||
| if (t >= SIMULATION_TIME) { | ||
| if (!SIMULATION) | ||
| { | ||
| motor.stopMotor(); | ||
| motor.disconnectMotor(); | ||
| } | ||
| std::cout << "Finished " << SIMULATION_TIME << "-second test.\n"; | ||
| leave(); | ||
| current = idle; | ||
| return; | ||
| } | ||
| timer->Tick(); // time measurement | ||
|
|
||
| // assumption is thigh is held vertical and fixed | ||
| double hip_angle = 0; | ||
| double knee_angle = knee_angles[i]; | ||
|
|
||
| // Update speed, acceleration estimator | ||
| hip_estimator.update(hip_angle, dt); | ||
| knee_estimator.update(knee_angle, dt); | ||
|
|
||
| TorqueController::JointState hip = { | ||
| .angle = hip_angle, | ||
| .velocity = hip_estimator.getVelocity(), | ||
| .acceleration = hip_estimator.getAcceleration()}; | ||
|
|
||
| TorqueController::JointState knee = { | ||
| .angle = knee_angle, | ||
| .velocity = knee_estimator.getVelocity(), | ||
| .acceleration = knee_estimator.getAcceleration()}; | ||
|
|
||
| // Compute torque | ||
| double hip_torque = 0.0, knee_torque = 0.0; | ||
| controller.computeTorque( | ||
| hip, knee, | ||
| hip_torque, knee_torque, | ||
| hip_m_acc, hip_c_vel, hip_g, | ||
| knee_m_acc, knee_c_vel, knee_g); | ||
|
|
||
| // STATE TRANSITIONS | ||
|
|
||
| // error state | ||
| if (knee_torque > Sensor::getMaxSensorReading() || knee_angle > MAX_KNEE_ANGLE || knee_angle < MIN_KNEE_ANGLE || hip_angle > MAX_HIP_ANGLE || hip_angle < MIN_HIP_ANGLE) | ||
| { | ||
| if (!SIMULATION) | ||
| { | ||
| motor.stopMotor(); | ||
| motor.disconnectMotor(); | ||
| } | ||
| leave(); | ||
| current = error; | ||
| cout << "\n\nTorque sensor value or angle value is too large. Possible error. Move to error state.\n\n"; | ||
| return; | ||
| } | ||
|
|
||
| // idle state | ||
| if (knee_torque < Sensor::getMinSensorReading() && hip_torque < Sensor::getMinSensorReading()) | ||
| { | ||
| timer->Tick(); // time measurement | ||
|
|
||
| if (timer->DeltaTime() > MAX_THRESHOLD_TIME) | ||
| { | ||
| leave(); | ||
| current = idle; | ||
| cout << "\n\nmax_threshold_time expired. Moving to idle state.\n\n"; | ||
| return; | ||
| } | ||
| } | ||
| else | ||
| { | ||
| // last_movement_time = 0 since we are continuing in the active state | ||
| timer->Reset(); | ||
| } | ||
|
|
||
| // Scale torque to correct units | ||
| double scaled_knee_torque = knee_torque / GEAR_RATIO; | ||
| double scaled_hip_torque = hip_torque / GEAR_RATIO; | ||
| int16_t torque_permille = static_cast<int16_t>((scaled_knee_torque *0.85 / RATED_TORQUE) * 1000.0); | ||
|
|
||
| // Send command to motor | ||
| if (!SIMULATION) | ||
| motor.setTargetTorque(torque_permille); | ||
|
|
||
| // Output torque values to the console | ||
| std::cout << "Time: " << t << "\tScaled Hip Torque: " << scaled_hip_torque << "\tScaled Knee Torque: " << scaled_knee_torque << "\n"; | ||
|
|
||
| // Log to CSV | ||
| log << t << "," | ||
| << hip.angle << "," << hip.velocity << "," << hip.acceleration << "," | ||
| << hip_m_acc << "," << hip_c_vel << "," << hip_g << "," << hip_torque << "," | ||
| << knee.angle << "," << knee.velocity << "," << knee.acceleration << "," | ||
| << knee_m_acc << "," << knee_c_vel << "," << knee_g << "," << knee_torque << "," | ||
| << scaled_knee_torque << "\n"; | ||
|
|
||
| // std::this_thread::sleep_for(std::chrono::duration<double>(dt)); | ||
| std::this_thread::sleep_for(std::chrono::milliseconds(500)); | ||
| } | ||
| } | ||
18 changes: 18 additions & 0 deletions
18
MAY_10_FULL_SUIT_WORKING/control/FSM_general_controller/ActiveState.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| #ifndef ACTIVE_STATE_H | ||
| #define ACTIVE_STATE_H | ||
|
|
||
| #include "State.h" | ||
| #include "Sensor.h" | ||
|
|
||
| class ActiveState : public State | ||
| { | ||
|
|
||
| public: | ||
| ActiveState(); | ||
| virtual ~ActiveState(); | ||
| void enter(); | ||
| void leave(); | ||
| void update(); | ||
| }; | ||
|
|
||
| #endif |
48 changes: 48 additions & 0 deletions
48
MAY_10_FULL_SUIT_WORKING/control/FSM_general_controller/ErrorState.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| #include "ErrorState.h" | ||
|
|
||
| ErrorState::ErrorState() | ||
| { | ||
| } | ||
|
|
||
| ErrorState::~ErrorState() | ||
| { | ||
| } | ||
|
|
||
| void ErrorState::enter() | ||
| { | ||
| cout << "\nNow in Error State \n"; | ||
| } | ||
|
|
||
| void ErrorState::update() | ||
| { | ||
| // loop | ||
| while (true) | ||
| { | ||
| cout << "1. active\n2. idle \n3. exit\n"; | ||
| int sensorReading; | ||
| cin >> sensorReading; // replace with sensor reading(s) | ||
| switch (sensorReading) | ||
| { | ||
|
|
||
| // replace cases with conditionals | ||
|
|
||
| case 1: | ||
| leave(); | ||
| current = active; | ||
| return; | ||
|
|
||
| case 2: | ||
| leave(); | ||
| current = idle; | ||
| return; | ||
|
|
||
| case 3: | ||
| exit(0); // exit program with 0 status (immediate shut down case) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| void ErrorState::leave() | ||
| { | ||
| cout << "\nleaving Error State \n"; | ||
| } |
17 changes: 17 additions & 0 deletions
17
MAY_10_FULL_SUIT_WORKING/control/FSM_general_controller/ErrorState.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| #ifndef ERROR_STATE_H | ||
| #define ERROR_STATE_H | ||
|
|
||
| #include "State.h" | ||
|
|
||
| class ErrorState : public State | ||
| { | ||
|
|
||
| public: | ||
| ErrorState(); | ||
| virtual ~ErrorState(); | ||
| void enter(); | ||
| void leave(); | ||
| void update(); | ||
| }; | ||
|
|
||
| #endif |
48 changes: 48 additions & 0 deletions
48
MAY_10_FULL_SUIT_WORKING/control/FSM_general_controller/IdleState.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| #include "IdleState.h" | ||
|
|
||
| IdleState::IdleState() | ||
| { | ||
| } | ||
|
|
||
| IdleState::~IdleState() | ||
| { | ||
| } | ||
|
|
||
| void IdleState::enter() | ||
| { | ||
| cout << "\nNow in Idle State \n"; | ||
| } | ||
|
|
||
| void IdleState::update() | ||
| { | ||
| while (true) | ||
| { | ||
|
|
||
| cout << "1. active\n2. error \n3. exit\n"; | ||
| int num; | ||
| cin >> num; // replace with sensor reading(s) | ||
| switch (num) | ||
| { | ||
|
|
||
| // replace cases with conditionals | ||
|
|
||
| case 1: | ||
| leave(); | ||
| current = active; | ||
| return; | ||
|
|
||
| case 2: | ||
| leave(); | ||
| current = error; | ||
| return; | ||
|
|
||
| case 3: | ||
| exit(0); // exit program with 0 status (fatal subModule failure) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| void IdleState::leave() | ||
| { | ||
| cout << "\nleaving Idle State\n"; | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd run for at least 12 seconds
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just approve it
