Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
main.cpp@1:e79de7ffd211, 2019-12-04 (annotated)
- Committer:
- pmic
- Date:
- Wed Dec 04 10:35:14 2019 +0000
- Revision:
- 1:e79de7ffd211
- Parent:
- 0:937360eb9f8c
- Child:
- 2:27f16e37a176
First test in main successfull.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| pmic | 0:937360eb9f8c | 1 | #include "mbed.h" |
| pmic | 0:937360eb9f8c | 2 | #include "PT1_Controller.h" |
| pmic | 0:937360eb9f8c | 3 | #include "Target_Planer.h" |
| pmic | 0:937360eb9f8c | 4 | #include <vector> |
| pmic | 0:937360eb9f8c | 5 | |
| pmic | 0:937360eb9f8c | 6 | using namespace std; |
| pmic | 0:937360eb9f8c | 7 | |
| pmic | 0:937360eb9f8c | 8 | #define pi 3.141592653589793 |
| pmic | 0:937360eb9f8c | 9 | |
| pmic | 0:937360eb9f8c | 10 | Serial pc(SERIAL_TX, SERIAL_RX); |
| pmic | 0:937360eb9f8c | 11 | |
| pmic | 0:937360eb9f8c | 12 | double kpv = 0.6412; // proportional controller for distance error |
| pmic | 0:937360eb9f8c | 13 | double kpw = 0.6801; // proportional controller for angle error |
| pmic | 0:937360eb9f8c | 14 | double Ts = 1/30.0; // samplingrate 30 Hz |
| pmic | 0:937360eb9f8c | 15 | double Tf = 1/(2.0*pi*4.0); // fg = 4 Hz |
| pmic | 0:937360eb9f8c | 16 | PT1_Controller distance_cntr(kpv, Ts, Tf); |
| pmic | 0:937360eb9f8c | 17 | PT1_Controller angle_cntr(kpw, Ts, Tf); |
| pmic | 0:937360eb9f8c | 18 | |
| pmic | 0:937360eb9f8c | 19 | // (vRx (m/s), wR (rad/s)) -> (vRxRB (unit unknown), wRRB (unit unknown)) |
| pmic | 0:937360eb9f8c | 20 | // Cu2uRB = 2.8070 0 |
| pmic | 0:937360eb9f8c | 21 | // 0 0.9263 |
| pmic | 0:937360eb9f8c | 22 | double kv2RB = 2.8070; // maps desired forward velocity from m/s 2 RB unit |
| pmic | 0:937360eb9f8c | 23 | double kw2RB = 0.9263; // maps desired turn speed from rad/s 2 RB unit |
| pmic | 0:937360eb9f8c | 24 | |
| pmic | 0:937360eb9f8c | 25 | Timer timer; // timer for time measurement |
| pmic | 0:937360eb9f8c | 26 | float dt = 0.0f; |
| pmic | 0:937360eb9f8c | 27 | |
| pmic | 0:937360eb9f8c | 28 | uint32_t i; |
| pmic | 0:937360eb9f8c | 29 | |
| pmic | 0:937360eb9f8c | 30 | // user defined functions |
| pmic | 0:937360eb9f8c | 31 | double quat2psi(double qw, double qx, double qy, double qz); |
| pmic | 0:937360eb9f8c | 32 | double getShortRotation(double ang); |
| pmic | 0:937360eb9f8c | 33 | |
| pmic | 0:937360eb9f8c | 34 | const int N = 4; |
| pmic | 0:937360eb9f8c | 35 | double Pathx[N] = {0, 2, 1, 4}; |
| pmic | 0:937360eb9f8c | 36 | double Pathy[N] = {0, 3, 0 ,1}; |
| pmic | 0:937360eb9f8c | 37 | double R = 0.16; |
| pmic | 0:937360eb9f8c | 38 | Target_Planer target_planer(Pathx, Pathy, (uint16_t)N, R); |
| pmic | 0:937360eb9f8c | 39 | double RobotPosx = 10.1; |
| pmic | 0:937360eb9f8c | 40 | double RobotPosy = 10.1; |
| pmic | 1:e79de7ffd211 | 41 | double TargetPosx = -999.0; |
| pmic | 1:e79de7ffd211 | 42 | double TargetPosy = -999.0; |
| pmic | 1:e79de7ffd211 | 43 | double TargetAng = -999.0; |
| pmic | 0:937360eb9f8c | 44 | |
| pmic | 0:937360eb9f8c | 45 | int main() |
| pmic | 0:937360eb9f8c | 46 | { |
| pmic | 0:937360eb9f8c | 47 | pc.baud(2000000); |
| pmic | 0:937360eb9f8c | 48 | |
| pmic | 0:937360eb9f8c | 49 | timer.start(); |
| pmic | 0:937360eb9f8c | 50 | |
| pmic | 0:937360eb9f8c | 51 | i = 0; |
| pmic | 0:937360eb9f8c | 52 | |
| pmic | 0:937360eb9f8c | 53 | // reset internal filter storage to zero |
| pmic | 0:937360eb9f8c | 54 | distance_cntr.reset(); |
| pmic | 0:937360eb9f8c | 55 | angle_cntr.reset(); |
| pmic | 0:937360eb9f8c | 56 | |
| pmic | 0:937360eb9f8c | 57 | while(1) { |
| pmic | 0:937360eb9f8c | 58 | |
| pmic | 0:937360eb9f8c | 59 | dt = timer.read(); |
| pmic | 0:937360eb9f8c | 60 | timer.reset(); |
| pmic | 0:937360eb9f8c | 61 | |
| pmic | 0:937360eb9f8c | 62 | /* |
| pmic | 0:937360eb9f8c | 63 | double phiR = quat2psi(double qw, double qx, double qy, double qz); // transform actual robot orientation (quaternioni) into turning angle |
| pmic | 0:937360eb9f8c | 64 | // it is assumed that target_ang and phiR both lie between -pi and pi |
| pmic | 0:937360eb9f8c | 65 | double e_ang = getShortRotation(target_angle - phiR); |
| pmic | 0:937360eb9f8c | 66 | // update angle controller |
| pmic | 0:937360eb9f8c | 67 | */ |
| pmic | 0:937360eb9f8c | 68 | // double qw = 0.984005578673161; |
| pmic | 0:937360eb9f8c | 69 | // double qx = 0.009063618716137; |
| pmic | 0:937360eb9f8c | 70 | // double qy = 0.177899336159591; |
| pmic | 0:937360eb9f8c | 71 | // double qz = 0.001629344754243; |
| pmic | 0:937360eb9f8c | 72 | |
| pmic | 0:937360eb9f8c | 73 | if(i < 4) { |
| pmic | 0:937360eb9f8c | 74 | // pc.printf("%i; %.12f; %.12f; %0.12f; %.6f;\r\n", i, quat2psi(qw, qx, qy, qz), qx*qy + qw*qz, 0.5 - (qy*qy + qz*qz), dt); |
| pmic | 0:937360eb9f8c | 75 | // pc.printf("%i; %i; %.6f;\r\n", i, target_planer.returnPathLength(), dt); |
| pmic | 1:e79de7ffd211 | 76 | // pc.printf("%i; %.12f; %.12f; %i; %i; %.6f;\r\n", i, target_planer.returnPathxAtIndex(i), target_planer.returnPathyAtIndex(i), target_planer.returnPathLength(), target_planer.returnClosestPointOnPath(RobotPosx, RobotPosy), dt); |
| pmic | 1:e79de7ffd211 | 77 | // pc.printf("%i; %.12f; %.12f;;\r\n", i, TargetPosx, TargetPosy); |
| pmic | 1:e79de7ffd211 | 78 | // target_planer.update(RobotPosx, RobotPosx); |
| pmic | 1:e79de7ffd211 | 79 | // target_planer.readTargetPos(&TargetPosx, &TargetPosy); |
| pmic | 1:e79de7ffd211 | 80 | pc.printf("%i; %.12f; %.12f; %.12f; %.6f;\r\n", i, TargetPosx, TargetPosy, TargetAng, dt); |
| pmic | 1:e79de7ffd211 | 81 | target_planer.updateAndReturnTarget(RobotPosx, RobotPosy, &TargetPosx, &TargetPosy, &TargetAng); |
| pmic | 0:937360eb9f8c | 82 | } |
| pmic | 0:937360eb9f8c | 83 | |
| pmic | 0:937360eb9f8c | 84 | i++; |
| pmic | 0:937360eb9f8c | 85 | wait_us(33333); |
| pmic | 0:937360eb9f8c | 86 | } |
| pmic | 0:937360eb9f8c | 87 | } |
| pmic | 0:937360eb9f8c | 88 | |
| pmic | 0:937360eb9f8c | 89 | /* |
| pmic | 0:937360eb9f8c | 90 | function psi = quat2psi(q) |
| pmic | 0:937360eb9f8c | 91 | % q = [qw qx qy qz] (= [q0, q1, q2, q3] = [qr, qi, qj, qk]) |
| pmic | 0:937360eb9f8c | 92 | for i = 1:length(q) % restore norm |
| pmic | 0:937360eb9f8c | 93 | q(i,:) = q(i,:) / sqrt(q(i,1)^2 + q(i,2)^2 + q(i,3)^2 + q(i,4)^2); |
| pmic | 0:937360eb9f8c | 94 | end |
| pmic | 0:937360eb9f8c | 95 | psi = atan2( (q(:,2).*q(:,3) + q(:,1).*q(:,4) ), 1/2 - (q(:,3).^2 + q(:,4).^2) ); |
| pmic | 0:937360eb9f8c | 96 | end |
| pmic | 0:937360eb9f8c | 97 | */ |
| pmic | 0:937360eb9f8c | 98 | double quat2psi(double qw, double qx, double qy, double qz) |
| pmic | 0:937360eb9f8c | 99 | { |
| pmic | 0:937360eb9f8c | 100 | double s = 1/(qw*qw + qx*qx + qy*qy + qz*qz); |
| pmic | 0:937360eb9f8c | 101 | return atan2(s*(qx*qy + qw*qz), 0.5 - s*(qy*qy + qz*qz)); |
| pmic | 0:937360eb9f8c | 102 | } |
| pmic | 0:937360eb9f8c | 103 | |
| pmic | 0:937360eb9f8c | 104 | double getShortRotation(double ang) |
| pmic | 0:937360eb9f8c | 105 | { |
| pmic | 0:937360eb9f8c | 106 | // we maybe need to introduce a threshold in case the angle is noisy and around +/-pi (180° rotation) |
| pmic | 0:937360eb9f8c | 107 | return atan2(sin(ang), cos(ang)); |
| pmic | 0:937360eb9f8c | 108 | } |
| pmic | 0:937360eb9f8c | 109 |