Skip to content

Commit b666c69

Browse files
pablogs9jamoralp
andauthored
Crazyflie dual transports demo app (#4)
* Creating a new recconect app and updating CF firmware to newer version * Update -Werror * Added multi AP test * Multimicroros * New transport * Updates * Update * Updates * Removed folder * Fix default radio * Debug disable * Stack and heap size fix * Note on heap and stack * Fix static * Update app * Update transport * Delete unused apps Co-authored-by: Jose Antonio Moral <joseantoniomoralparras@gmail.com>
1 parent 63b8c89 commit b666c69

6 files changed

Lines changed: 467 additions & 40 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"names": {
3+
"rmw_microxrcedds": {
4+
"cmake-args": [
5+
"-DRMW_UXRCE_TRANSPORT=custom_serial",
6+
"-DRMW_UXRCE_MAX_NODES=2",
7+
"-DRMW_UXRCE_MAX_PUBLISHERS=4",
8+
"-DRMW_UXRCE_MAX_SUBSCRIPTIONS=1",
9+
"-DRMW_UXRCE_MAX_SERVICES=0",
10+
"-DRMW_UXRCE_MAX_CLIENTS=0",
11+
"-DRMW_UXRCE_MAX_HISTORY=1",
12+
"-DRMW_UXRCE_MAX_SESSIONS=2",
13+
"-DRMW_UXRCE_XML_BUFFER_LENGTH=400",
14+
"-DRMW_UXRCE_CREATION_MODE=refs"
15+
]
16+
}
17+
}
18+
}

apps/crazyflie_demo/app.c

Lines changed: 348 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,348 @@
1+
/*FreeRtos includes*/
2+
#include "FreeRTOS.h"
3+
#include "task.h"
4+
#include "static_mem.h"
5+
6+
#include <rcl/rcl.h>
7+
#include <sensor_msgs/msg/laser_echo.h>
8+
#include <std_msgs/msg/float32.h>
9+
#include <geometry_msgs/msg/point32.h>
10+
11+
#include <rcutils/allocator.h>
12+
#include <rmw_uros/options.h>
13+
14+
15+
#include "config.h"
16+
#include "log.h"
17+
#include "crc.h"
18+
#include "worker.h"
19+
#include "num.h"
20+
#include "debug.h"
21+
#include "radiolink.h"
22+
#include <time.h>
23+
24+
#include "microrosapp.h"
25+
26+
#include "crtp.h"
27+
#include "configblock.h"
28+
29+
#define RCCHECK(clean) if((rc != RCL_RET_OK)){DEBUG_PRINT("Failed status on line %d: %d. Aborting.\n",__LINE__,(int)rc); goto clean;}
30+
#define RCSOFTCHECK() if((rc != RCL_RET_OK)){DEBUG_PRINT("Failed status on line %d: %d. Continuing.\n",__LINE__,(int)rc);}
31+
32+
void microros_primary(void * params);
33+
void microros_secondary(void * params);
34+
35+
float sensor_data[2];
36+
sensor_msgs__msg__LaserEcho sensor_topic;
37+
static bool sensor_data_ready;
38+
39+
static int pitchid, rollid, yawid;
40+
static int Xid, Yid, Zid;
41+
42+
// Note: please set APP_STACKSIZE = 100 and CFLAGS += -DFREERTOS_HEAP_SIZE=12100 in Makefile before build
43+
44+
STATIC_MEM_TASK_ALLOC(microros_primary, 1000);
45+
STATIC_MEM_TASK_ALLOC(microros_secondary, 1000);
46+
static bool created_primary = false;
47+
48+
void appMain(){
49+
BaseType_t rc __attribute__((unused));
50+
// TaskHandle_t task_primary, task_secondary;
51+
52+
absoluteUsedMemory = 0;
53+
usedMemory = 0;
54+
55+
rcl_allocator_t freeRTOS_allocator = rcutils_get_zero_initialized_allocator();
56+
freeRTOS_allocator.allocate = __crazyflie_allocate;
57+
freeRTOS_allocator.deallocate = __crazyflie_deallocate;
58+
freeRTOS_allocator.reallocate = __crazyflie_reallocate;
59+
freeRTOS_allocator.zero_allocate = __crazyflie_zero_allocate;
60+
61+
if (!rcutils_set_default_allocator(&freeRTOS_allocator)) {
62+
DEBUG_PRINT("Error on default allocators (line %d)\n",__LINE__);
63+
vTaskSuspend( NULL );
64+
}
65+
66+
67+
sensor_topic.echoes.capacity = 2;
68+
sensor_topic.echoes.size = 2;
69+
sensor_topic.echoes.data = sensor_data;
70+
71+
STATIC_MEM_TASK_CREATE(microros_primary, microros_primary, "microROSprimary", NULL, 3);
72+
STATIC_MEM_TASK_CREATE(microros_secondary, microros_secondary, "microROSsecondary", NULL, 3);
73+
}
74+
75+
void microros_primary(void * params){
76+
while(1){
77+
78+
// ####################### RADIO INIT #######################
79+
80+
int radio_connected = logGetVarId("radio", "isConnected");
81+
while(!logGetUint(radio_connected)) vTaskDelay(100);
82+
// DEBUG_PRINT("Radio connected\n");
83+
84+
// ####################### MICROROS INIT #######################
85+
86+
DEBUG_PRINT("Free heap pre uROS: %d bytes\n", xPortGetFreeHeapSize());
87+
vTaskDelay(50);
88+
89+
rcl_context_t context;
90+
rcl_init_options_t init_options;
91+
rcl_ret_t rc;
92+
rcl_ret_t rc_aux __attribute__((unused));
93+
94+
init_options = rcl_get_zero_initialized_init_options();
95+
rc = rcl_init_options_init(&init_options, rcutils_get_default_allocator());
96+
RCCHECK(clean1)
97+
98+
rmw_init_options_t* rmw_options = rcl_init_options_get_rmw_init_options(&init_options);
99+
rc = rmw_uros_options_set_serial_device("65", rmw_options);
100+
rc = rmw_uros_options_set_client_key(0xBA5EBA11, rmw_options);
101+
102+
context = rcl_get_zero_initialized_context();
103+
104+
rc = rcl_init(0, NULL, &init_options, &context);
105+
rc_aux = rcl_init_options_fini(&init_options);
106+
RCCHECK(clean1)
107+
108+
rcl_node_t node = rcl_get_zero_initialized_node();
109+
rcl_node_options_t node_ops = rcl_node_get_default_options();
110+
111+
rc = rcl_node_init(&node, "crazyflie_node_1", "", &context, &node_ops);
112+
RCCHECK(clean1)
113+
114+
// Create publisher 1
115+
rcl_publisher_t pub_sensors_temp = rcl_get_zero_initialized_publisher();
116+
rcl_publisher_options_t pub_opt_sensors_temp = rcl_publisher_get_default_options();
117+
pub_opt_sensors_temp.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT;
118+
119+
rc = rcl_publisher_init(
120+
&pub_sensors_temp,
121+
&node,
122+
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Float32),
123+
"/weather_station/temperature",
124+
&pub_opt_sensors_temp);
125+
126+
if(rc != RCL_RET_OK){
127+
rc_aux = rcl_node_fini(&node);
128+
}
129+
RCCHECK(clean1)
130+
131+
// Create publisher 2
132+
rcl_publisher_t pub_sensors_hum = rcl_get_zero_initialized_publisher();
133+
rcl_publisher_options_t pub_opt_sensors_hum = rcl_publisher_get_default_options();
134+
pub_opt_sensors_hum.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT;
135+
136+
rc = rcl_publisher_init(
137+
&pub_sensors_hum,
138+
&node,
139+
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Float32),
140+
"/weather_station/humidity",
141+
&pub_opt_sensors_hum);
142+
143+
if(rc != RCL_RET_OK){
144+
rc_aux = rcl_node_fini(&node);
145+
}
146+
RCCHECK(clean1)
147+
148+
// Create publisher 3
149+
rcl_publisher_t pub_odom = rcl_get_zero_initialized_publisher();
150+
rcl_publisher_options_t pub_opt_odom = rcl_publisher_get_default_options();
151+
pub_opt_odom.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT;
152+
153+
rc = rcl_publisher_init(
154+
&pub_odom,
155+
&node,
156+
ROSIDL_GET_MSG_TYPE_SUPPORT(geometry_msgs, msg, Point32),
157+
"/drone/odometry",
158+
&pub_opt_odom);
159+
RCCHECK(clean1)
160+
161+
// Create publisher 4
162+
rcl_publisher_t pub_attitude = rcl_get_zero_initialized_publisher();
163+
rcl_publisher_options_t pub_opt_att = rcl_publisher_get_default_options();
164+
pub_opt_att.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT;
165+
166+
rc = rcl_publisher_init(
167+
&pub_attitude,
168+
&node,
169+
ROSIDL_GET_MSG_TYPE_SUPPORT(geometry_msgs, msg, Point32),
170+
"/drone/attitude",
171+
&pub_opt_att);
172+
RCCHECK(clean1)
173+
174+
DEBUG_PRINT("Free heap post uROS configuration: %d bytes\n", xPortGetFreeHeapSize());
175+
DEBUG_PRINT("uROS Used Memory %d bytes\n", usedMemory);
176+
DEBUG_PRINT("uROS Absolute Used Memory %d bytes\n", absoluteUsedMemory);
177+
178+
created_primary = true;
179+
// ####################### MAIN LOOP #######################
180+
181+
// Init messages
182+
geometry_msgs__msg__Point32 pose;
183+
geometry_msgs__msg__Point32__init(&pose);
184+
geometry_msgs__msg__Point32 odom;
185+
geometry_msgs__msg__Point32__init(&odom);
186+
187+
//Get pitch, roll and yaw value
188+
pitchid = logGetVarId("stateEstimate", "pitch");
189+
rollid = logGetVarId("stateEstimate", "roll");
190+
yawid = logGetVarId("stateEstimate", "yaw");
191+
192+
//Get X,Y and Z value
193+
Xid = logGetVarId("stateEstimate", "x");
194+
Yid = logGetVarId("stateEstimate", "y");
195+
Zid = logGetVarId("stateEstimate", "z");
196+
197+
while(1){
198+
199+
if(sensor_data_ready){
200+
std_msgs__msg__Float32 aux_msg;
201+
202+
aux_msg.data = sensor_topic.echoes.data[0];
203+
rc = rcl_publish( &pub_sensors_temp, (const void *) &aux_msg, NULL);
204+
205+
aux_msg.data = sensor_topic.echoes.data[1];
206+
rc = rcl_publish( &pub_sensors_hum, (const void *) &aux_msg, NULL);
207+
208+
sensor_data_ready = 0;
209+
}
210+
211+
pose.x = logGetFloat(pitchid);
212+
pose.y = logGetFloat(rollid);
213+
pose.z = logGetFloat(yawid);
214+
odom.x = logGetFloat(Xid);
215+
odom.y = logGetFloat(Yid);
216+
odom.z = logGetFloat(Zid);
217+
218+
rc = rcl_publish( &pub_attitude, (const void *) &pose, NULL);
219+
RCSOFTCHECK()
220+
221+
rc = rcl_publish( &pub_odom, (const void *) &odom, NULL);
222+
RCSOFTCHECK()
223+
224+
vTaskDelay(100/portTICK_RATE_MS);
225+
}
226+
227+
rc = rcl_node_fini(&node);
228+
clean1:
229+
rc = rcl_shutdown(&context);
230+
DEBUG_PRINT("Connection lost on primary, retriying\n");
231+
}
232+
233+
vTaskSuspend( NULL );
234+
}
235+
236+
void microros_secondary(void * params){
237+
while(!created_primary){
238+
vTaskDelay(100);
239+
}
240+
241+
while(1){
242+
// ####################### RADIO INIT #######################
243+
244+
int radio_connected = logGetVarId("radio", "isConnected");
245+
while(!logGetUint(radio_connected)) vTaskDelay(100);
246+
// DEBUG_PRINT("Radio connected\n");
247+
248+
// ####################### MICROROS INIT #######################
249+
250+
DEBUG_PRINT("Free heap pre uROS: %d bytes\n", xPortGetFreeHeapSize());
251+
vTaskDelay(50);
252+
253+
rcl_context_t context;
254+
rcl_init_options_t init_options;
255+
rcl_ret_t rc;
256+
rcl_ret_t rc_aux __attribute__((unused));
257+
258+
init_options = rcl_get_zero_initialized_init_options();
259+
rc = rcl_init_options_init(&init_options, rcutils_get_default_allocator());
260+
RCCHECK(clean2)
261+
262+
rmw_init_options_t* rmw_options = rcl_init_options_get_rmw_init_options(&init_options);
263+
rc = rmw_uros_options_set_serial_device("30", rmw_options);
264+
rc = rmw_uros_options_set_client_key(0xDEADBEEF, rmw_options);
265+
266+
context = rcl_get_zero_initialized_context();
267+
268+
rc = rcl_init(0, NULL, &init_options, &context);
269+
rc_aux = rcl_init_options_fini(&init_options);
270+
RCCHECK(clean2)
271+
272+
rcl_node_t node = rcl_get_zero_initialized_node();
273+
rcl_node_options_t node_ops = rcl_node_get_default_options();
274+
275+
rc = rcl_node_init(&node, "crazyflie_node_2", "", &context, &node_ops);
276+
RCCHECK(clean2)
277+
278+
// Create subscription 2
279+
const char * echo_topic_name = "Float__Sequence";
280+
281+
rcl_subscription_t sub_sensors = rcl_get_zero_initialized_subscription();
282+
const rosidl_message_type_support_t * sub_type_support = ROSIDL_GET_MSG_TYPE_SUPPORT(sensor_msgs, msg, LaserEcho);
283+
rcl_subscription_options_t subscription_ops = rcl_subscription_get_default_options();
284+
subscription_ops.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT;
285+
286+
rc = rcl_subscription_init(
287+
&sub_sensors,
288+
&node,
289+
sub_type_support,
290+
echo_topic_name,
291+
&subscription_ops);
292+
RCCHECK(clean2)
293+
294+
// Create wait set
295+
rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set();
296+
rc = rcl_wait_set_init(&wait_set, 1, 0, 0, 0, 0, 0, &context, rcl_get_default_allocator());
297+
RCCHECK(clean2)
298+
299+
if(rc != RCL_RET_OK){
300+
rc_aux = rcl_node_fini(&node);
301+
}
302+
RCCHECK(clean2)
303+
304+
DEBUG_PRINT("Free heap post uROS configuration: %d bytes\n", xPortGetFreeHeapSize());
305+
DEBUG_PRINT("uROS Used Memory %d bytes\n", usedMemory);
306+
DEBUG_PRINT("uROS Absolute Used Memory %d bytes\n", absoluteUsedMemory);
307+
308+
// ####################### MAIN LOOP #######################
309+
310+
while(1){
311+
312+
rc = rcl_wait_set_clear(&wait_set);
313+
RCSOFTCHECK()
314+
315+
rc = rcl_wait_set_add_subscription(&wait_set, &sub_sensors, NULL);
316+
RCSOFTCHECK()
317+
318+
rc = rcl_wait(&wait_set, RCL_MS_TO_NS(10));
319+
// RCSOFTCHECK()
320+
321+
if (wait_set.subscriptions[0]){
322+
sensor_msgs__msg__LaserEcho rcv;
323+
float rcv_data[2];
324+
325+
rcv.echoes.capacity = 2;
326+
rcv.echoes.size = 2;
327+
rcv.echoes.data = rcv_data;
328+
329+
rc = rcl_take(&sub_sensors, &rcv, NULL, NULL);
330+
331+
if (rc == RCL_RET_OK) {
332+
memcpy(&sensor_topic, &rcv, sizeof(sensor_msgs__msg__LaserEcho));
333+
sensor_data_ready = 1;
334+
}
335+
}
336+
337+
vTaskDelay(100/portTICK_RATE_MS);
338+
}
339+
340+
rc = rcl_subscription_fini(&sub_sensors, &node);
341+
rc = rcl_node_fini(&node);
342+
clean2:
343+
rc = rcl_shutdown(&context);
344+
DEBUG_PRINT("Connection lost on secondary, retriying\n");
345+
}
346+
347+
vTaskSuspend( NULL );
348+
}

microros_crazyflie21_extensions/Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ MICROROS_INCLUDES += -I$(EXTENSIONS_DIR)/include/private
2828
MICROROS_INCLUDES += -I$(EXTENSIONS_DIR)/FreeRTOS-Plus-POSIX/include
2929
MICROROS_INCLUDES += -I$(EXTENSIONS_DIR)/FreeRTOS-Plus-POSIX/include/portable
3030
MICROROS_INCLUDES += -I$(EXTENSIONS_DIR)/FreeRTOS-Plus-POSIX/include/portable/crazyflie
31-
MICROROS_INCLUDES += -I$(CRAZYFLIE_BASE)/src/lib/FreeRTOS/include
32-
3331
MICROROS_LIBRARIES = libmicroros.a
3432

3533
MICROROS_POSIX_FREERTOS_OBJECTS_VPATH += $(EXTENSIONS_DIR)/FreeRTOS-Plus-POSIX/source
@@ -50,6 +48,10 @@ COLCON_INCLUDES += $(CRAZYFLIE_BASE)/src/modules/interface
5048
COLCON_INCLUDES += $(CRAZYFLIE_BASE)/src/utils/interface
5149
COLCON_INCLUDES += $(CRAZYFLIE_BASE)/src/config
5250
COLCON_INCLUDES += $(CRAZYFLIE_BASE)/src/drivers/interface
51+
COLCON_INCLUDES += $(CRAZYFLIE_BASE)/src/drivers/interface
52+
COLCON_INCLUDES += $(CRAZYFLIE_BASE)/vendor/FreeRTOS/include
53+
COLCON_INCLUDES += $(CRAZYFLIE_BASE)/vendor/FreeRTOS/portable/GCC/ARM_CM4F
54+
5355
COLCON_INCLUDES_STR := $(foreach x,$(COLCON_INCLUDES),$(x)\n)
5456

5557

0 commit comments

Comments
 (0)