-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmainwindow.cpp
More file actions
393 lines (309 loc) · 10.8 KB
/
Copy pathmainwindow.cpp
File metadata and controls
393 lines (309 loc) · 10.8 KB
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <vector>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//! OpenGl output to verify.
myOpenGl = new opengl();
//! Graph scale.
myOpenGl->setScale(20,20);
//! Simple motion planner class.
mySmp=new smp();
//! Simple curve planner class.
myScp=new scp();
//! Startup calculation.
//! on_pushButton_pressed();
//! Timer to simulate servo cycle.
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(thread()));
timer->start(1);
}
MainWindow::~MainWindow()
{
delete ui;
}
//! Parameters used by the live motion planner.
smp::smp_data datas;
double vo=0; //! Velocity begin.
double vm=0; //! Velocity max, cruise speed.
double ve=0; //! Velocity end.
double a=0; //! Acceleration.
double dtg=0; //! Distance to go.
double motion_timer=0; //! Current time of motion.
double position=0; //! Overall position.
bool go=0;
bool start=0, stop=0, stop_init=0;
bool reverse=0;
//! Parameters used by the scurve motion planner.
bool sc_go=0;
double sc_vo=10; //! Velocity begin.
double sc_ve=0; //! Velocity end.
double sc_a=2; //! Acceleration.
double sc_ai=0; //! Acceleration interpolated, current.
double sc_vi=0; //! Velocity interpolated.
double sc_ti=0; //! Time interpolated.
double sc_si=0; //! Displacment interpolated.
double sc_init=0; //! Init motion block.
double sc_ttot=0; //! Time of motion block.
double sc_stot=0; //! Total displacment of motion block.
double sc_th=0; //! Ttot * 0.5
double sc_jm=0; //! Jm of current motion block.
//! Scurve live parameters.
bool sc_live_go=0;
bool sc_live_init=0;
smp::smp_data ld;
double s=0;
bool done=0;
double t=0, si=0, vi=0,ai=0;
bool interupt=0;
std::vector<double> xpos,ypos;
//! Live motion planner start button.
void MainWindow::on_pushButton_start_pressed()
{
vo=ui->doubleSpinBox_vo->value();
vm=ui->doubleSpinBox_vm->value();
ve=ui->doubleSpinBox_ve->value();
a=ui->doubleSpinBox_a->value();
dtg=ui->doubleSpinBox_s->value();
dtg-=position;
if(dtg<0){ //! Keep positive.
dtg=abs(dtg);
reverse=true;
} else {
reverse=false;
}
start=true;
timer=0;
}
//! Live motion planner stop or pause button.
void MainWindow::on_pushButton_stop_pressed()
{
stop=true;
}
//! This function simulates the servo cycle. And is called every 1 millisecond.
void MainWindow::thread(){
//! Scurve live motion test.
if(sc_live_go){
//! Init the motion.
if(!sc_live_init){
xpos.clear();
ypos.clear();
xpos.push_back(0);
ypos.push_back(0);
vo=ui->doubleSpinBox_vo->value();
vm=ui->doubleSpinBox_vm->value();
ve=ui->doubleSpinBox_ve->value();
a=ui->doubleSpinBox_a->value();
dtg=ui->doubleSpinBox_s->value();
done=false;
smp().calculate_offline_motion(vo,vm,ve,a,dtg,ld,true);
t=0;
sc_live_init=true;
}
//! Check for interupts, stop for now.
if(interupt){
std::cout<<"incoming interupt from vm, current scurve values:"<<std::endl;
scp().print(si,vi,ai,t);
dtg-=si;
std::cout<<"new dtg:"<<dtg<<" new vm:"<<vm<<std::endl;
//! Calculate new periods, print them, then compare a new scurve period t1 with it.
std::cout<<"new smp motion block:"<<std::endl;
smp().calculate_offline_motion(vi,vm,ve,a,dtg,ld,true);
std::cout<<"t1 to investegate for fit scurve:"<<ld.t1<<std::endl;
std::cout<<"s1 to investegate for fit scurve:"<<ld.s1<<std::endl;
std::cout<<"scurve starts with a:"<<ai<<std::endl;
double ttot=0;
scp().calculate_curve_time_given_acs_ace_for_dcc_curve(vi,ve,a,ai,0,ttot,false);
std::cout<<"scurve needs ttot:"<<ttot<<std::endl;
timer->stop();
}
if(!interupt){
//! Perform the motion.
if(scp().calculate_scurve_live_motion(ld,t,si,vi,ai)){
if(!done){
scp().print(si,vi,ai,t);
t+=0.001;
//! Draw trapezium curve opengl.
if(ld.t1>0 && ld.t2==0 && ld.t3==0){
myOpenGl->set1Vec({0,ld.t1},{ld.vo,ld.ve});
}
if(ld.t1>0 && ld.t2>0 && ld.t3==0){
myOpenGl->set1Vec({0,ld.t1,ld.t1+ld.t2},{ld.vo,ld.vm,ld.ve});
}
if(ld.t1>=0 && ld.t2>0 && ld.t3>0){
myOpenGl->set1Vec({0,ld.t1,ld.t1+ld.t2,ld.t1+ld.t2+ld.t3},{ld.vo,ld.vm,ld.vm,ld.ve});
}
//! Draw scurve opengl.
xpos.push_back(t);
ypos.push_back(vi); //! Add 1 to avoid double lines by opengl.
myOpenGl->set2Vec(xpos,ypos);
}
if(si>=dtg){
done=true;
//! Reset flag.
sc_live_init=false;
sc_live_go=false;
}
} else {
//! Stop when error.
sc_live_go=false;
}
}
}
//! Test a scurve of type deceleration.
if(sc_go){
if(!sc_init){
scp().calculate_scurve_total_s_t_jm(sc_vo,sc_ve,sc_a,sc_stot,sc_ttot,sc_jm);
std::cout<<"ttot"<<sc_ttot<<std::endl;
sc_init=1;
}
if(!scp().calculate_dcc_curve_s_v_a_given_time_point(sc_vo,sc_ve,sc_a,sc_ti,sc_si,sc_vi,sc_ai)){
std::cerr<<"error."<<std::endl;
}
scp().print(sc_si,sc_vi,sc_ai,sc_ti);
if(sc_ti<=sc_ttot){
sc_ti+=0.001;
}
}
//! Perform a stop sequence.
if(stop){
//! Function to calculate distance needed to stop motion.
dtg=smp().dtg_to_stop(vo,a);
//! Set velocity end to zero when request a motion stop.
ve=0;
std::cerr<<"dtg to stop:"<<dtg<<std::endl;
//! Reset flag.
stop=0;
}
//! Execute motion.
if(start){
//! Get the current "vm" velocity max value.
vm=ui->doubleSpinBox_vm->value();
//! Calculate motion, get results for the 0.001s interval.
if(smp().calculate_live_motion(vo,vm,ve,a,dtg,datas,0.001,false)){
//! Update values for next servo cycle.
vo=datas.vi;
//! Update distance to go, dtg.
dtg-=datas.si;
//! If user requests a negative displacment "s".
if(!reverse){
position+=datas.si;
} else {
position-=datas.si;
}
//! Terminal output.
std::cout<<std::fixed<<"time:"<<motion_timer<<" v:"<<datas.vi<<" dtg:"<<dtg<<" position:"<<position<<" performance ms:"<<datas.performance_ms<<std::endl;
motion_timer+=0.001;
if(dtg==0){
//! Reset flag.
start=0;
std::cerr<<"motion complete."<<std::endl;
}
} else {
//! Reset flag.
start=0;
std::cerr<<"error from function calculate live motion."<<std::endl;
}
}
}
//! Standard motion calculation example.
void MainWindow::on_pushButton_pressed()
{
smp::smp_data d;
//! calculate_motion(double vo, double vm, double ve, double a, double s, smp_data &d, double at_time, bool debug_standard){
if(!smp().calculate_offline_motion(ui->doubleSpinBox_vo->value(),
ui->doubleSpinBox_vm->value(),
ui->doubleSpinBox_ve->value(),
ui->doubleSpinBox_a->value(),
abs(ui->doubleSpinBox_s->value()),d,true)){
std::cerr<<"error from function calculate motion."<<std::endl;
}
//! By reference &d outputs.
if(d.t1>0 && d.t2==0 && d.t3==0){
myOpenGl->set1Vec({0,d.t1},{d.vo,d.ve});
}
if(d.t1>0 && d.t2>0 && d.t3==0){
myOpenGl->set1Vec({0,d.t1,d.t1+d.t2},{d.vo,d.vm,d.ve});
}
if(d.t1>=0 && d.t2>0 && d.t3>0){
myOpenGl->set1Vec({0,d.t1,d.t1+d.t2,d.t1+d.t2+d.t3},{d.vo,d.vm,d.vm,d.ve});
}
}
//! Update values imidiate.
void MainWindow::on_doubleSpinBox_s_valueChanged(double arg1)
{
//on_pushButton_pressed();
}
void MainWindow::on_doubleSpinBox_ve_valueChanged(double arg1)
{
//on_pushButton_pressed();
}
void MainWindow::on_doubleSpinBox_vo_valueChanged(double arg1)
{
//on_pushButton_pressed();
}
void MainWindow::on_doubleSpinBox_a_valueChanged(double arg1)
{
// on_pushButton_pressed();
}
void MainWindow::on_doubleSpinBox_vm_valueChanged(double arg1)
{
//on_pushButton_pressed();
}
void MainWindow::on_pushButton_scurve_pressed()
{
sc_go=true;
//! myScp->example_try_if_curve_fits_displacement();
}
void MainWindow::on_pushButton_calculate_scurve_motion_pressed()
{
smp::smp_data d;
smp().calculate_offline_motion(ui->doubleSpinBox_vo->value(),
ui->doubleSpinBox_vm->value(),
ui->doubleSpinBox_ve->value(),
ui->doubleSpinBox_a->value(),
ui->doubleSpinBox_s->value(),d, true);
//! By reference &d outputs.
if(d.t1>0 && d.t2==0 && d.t3==0){
myOpenGl->set1Vec({0,d.t1},{d.vo,d.ve});
}
if(d.t1>0 && d.t2>0 && d.t3==0){
myOpenGl->set1Vec({0,d.t1,d.t1+d.t2},{d.vo,d.vm,d.ve});
}
if(d.t1>=0 && d.t2>0 && d.t3>0){
myOpenGl->set1Vec({0,d.t1,d.t1+d.t2,d.t1+d.t2+d.t3},{d.vo,d.vm,d.vm,d.ve});
}
}
void MainWindow::on_pushButton_scurve_live_motion_pressed()
{
sc_live_go=true;
}
void MainWindow::on_pushButton_interupt_pressed()
{
interupt=1;
}
void MainWindow::on_pushButton_acs_ace_pressed()
{
//! scp().example_calculate_curve_times_using_acs_ace_for_acc_curve();
//! scp().example_calculate_curve_times_using_acs_ace_for_dcc_curve();
double vo=0;
double ve=10;
double a=2;
double acs=1;
double ace=1;
double debug=true;
double sl=0, sm=0, sr=0;
double v1=0, v2=0, t1=0, t2=0, a1=0, a2=0, stot=0, ttot=0;
//! Acc request.
scp().calculate_curve_time_given_acs_ace_for_acc_dcc_curve(vo,ve,a,acs,ace,debug,sl,sm,sr,v1,v2,t1,t2,a1,a2,stot,ttot);
//! Dcc request.
vo=10;
ve=0;
scp().calculate_curve_time_given_acs_ace_for_acc_dcc_curve(vo,ve,a,acs,ace,debug,sl,sm,sr,v1,v2,t1,t2,a1,a2,stot,ttot);
}