-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathacado_node2.cpp
146 lines (110 loc) · 3.97 KB
/
acado_node2.cpp
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
#include "acado_node2.hpp"
/* Some convenient definitions. */
#define NX ACADO_NX /* Number of differential state variables. */
#define NU ACADO_NU /* Number of control inputs. */
#define N ACADO_N /* Number of intervals in the horizon. */
#define NUM_STEPS 8 /* Number of real-time iterations. */
#define VERBOSE 1 /* Show iterations: 1, silent: 0. */
/* Global variables used by the solver. */
ACADOvariables acadoVariables;
ACADOworkspace acadoWorkspace;
void ACADO_Node::filterCallback(const sensor_msgs::MultiDOFJointState::ConstPtr &msg)
{
acado_state.theta = msg->twist.back().angular.x;
acado_state.phi = msg->twist.back().angular.y;
acado_state.gamma = msg->twist.back().angular.z;
if(!is_initialized())
initialize();
}
ACADO_Node::ACADO_Node(const ros::NodeHandle &_nh )
{
/** initialize subscribers and publishers */
nh = std::make_shared<ros::NodeHandle>(_nh);
control_pub = nh->advertise<openkite::aircraft_controls>("kite_controls", 100);
traj_pub = nh->advertise<sensor_msgs::MultiDOFJointState>("/opt_traj", 10);
diagnostic_pub = nh->advertise<openkite::mpc_diagnostic>("/mpc_diagnostic", 10);
std::string state_topic = "/kite_state";
state_sub = nh->subscribe(state_topic, 100, &ACADO_Node::filterCallback, this);
m_initialized = false;
comp_time_ms = 0.0;
}
void ACADO_Node::publish()
{
openkite::aircraft_controls control_msg;
control = acado_getVariablesU();
control_msg.header.stamp = ros::Time::now();
control_msg.thrust = 0;
control_msg.elevator = 0;
control_msg.rudder = control[0];
/** publish current control */
control_pub.publish(control_msg);
}
/** publish diagnostic info */
void ACADO_Node::publish_mpc_diagnostic()
{
openkite::mpc_diagnostic diag_msg;
diag_msg.header.stamp = ros::Time::now();
diag_msg.pos_error = acado_getObjective();
diag_msg.comp_time_ms = comp_time_ms * 1000;
diag_msg.virt_state = 0.0;
diag_msg.vel_error = 0.0;
/** dummy output */
diag_msg.cost = 0;
diagnostic_pub.publish(diag_msg);
}
void ACADO_Node::compute_control()
{
/** update intial state */
real_t *x = acado_getVariablesX();
acadoVariables.x0[ 0 ] = acado_state.theta;
acadoVariables.x0[ 1 ] = acado_state.phi;
acadoVariables.x0[ 2 ] = acado_state.gamma;
acadoVariables.x0[ 3 ] = x[3];
acadoVariables.x0[ 4 ] = x[4];
acadoVariables.x0[ 5 ] = 0;
for(int iter = 0; iter < NUM_STEPS; ++iter)
{
/* Perform the feedback step. */
acado_feedbackStep( );
if( VERBOSE ) printf("\tReal-Time Iteration %d: KKT Tolerance = %.3e\n\n", iter, acado_getKKT() );
/* Prepare for the next step. */
acado_preparationStep();
}
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "acado_node2");
ros::NodeHandle nh;
/* Some temporary variables. */
int i, iter;
acado_timer timer;
//ros::Publisher pb = n.advertise<openkite::aircraft_controls>("kite_controls", 100);
/* Initialize the solver. */
acado_initializeSolver();
/* Initialize the states and controls. */
for (i = 0; i < NX * (N + 1); ++i) acadoVariables.x[ i ] = 1.0;
for (i = 0; i < NU * N; ++i) acadoVariables.u[ i ] = 1.0;
ACADO_Node tracker(nh);
ros::Rate loop_rate(100); /** 18 Hz */
bool broadcast_trajectory = true;
while (ros::ok())
{
ros::spinOnce();
if(tracker.is_initialized())
{
double start = ros::Time::now().toSec();
tracker.compute_control();
double finish = ros::Time::now().toSec();
tracker.publish();
tracker.publish_mpc_diagnostic();
tracker.comp_time_ms = finish - start;
std::cout << "Control computational delay: " << finish - start << "\n";
loop_rate.sleep();
}
else
{
loop_rate.sleep();
}
}
return 0;
}