Skip to content

Porting acados' example ocp_qp_hpmpc to ARM Cortex M4 microcontroller TM4C129

doanminhdang edited this page Jul 20, 2017 · 1 revision

Hardware for testing:

http://www.ti.com/tool/ek-tm4c1294xl

Tiva C Series TM4C1294 Connected LaunchPad Evaluation Kit (the kit we used is indeed Rev. A of this board)

Code:

https://github.com/doanminhdang/acados/tree/ti_tm4c129/experimental/dang/tm4c129/ocp_qp_hpmpc, at commit ffac9de

Results:

The second test in the code (partial condensing) could not finish due to large memory requirement, the first test (full sparse HPMPC) finished successfully, with output:

HPMPC -- Library for High-Performance implementation of solvers for MPC. Copyright (C) 2014-2015 by Technical University of Denmark. All rights reserved.

HPMPC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

Test problem: mass-spring system with 4 masses and 3 controls.

MPC problem size: 8 states, 3 inputs, 15 horizon length, 11 two-sided box constraints, 0 two-sided general constraints.

IP method parameters: predictor-corrector IP, double precision, 10 maximum iterations, 1.0e-08 exit tolerance in duality measure.

work space size: 112348 bytes

ACADOS status: solution found in 8 iterations

u = 0.15667 -0.50000 -0.50000

0.50000 0.25181 -0.50000

0.50000 0.50000 -0.50000

0.50000 0.50000 -0.50000

0.44444 0.24107 0.37914

-0.50000 -0.09610 0.50000

-0.50000 -0.41883 0.50000

-0.50000 -0.50000 0.50000

-0.50000 -0.50000 0.07756

-0.03450 -0.50000 -0.14724

0.46227 -0.48597 -0.21080

0.46297 0.36571 -0.27691

0.20041 0.50000 -0.37781

-0.02661 0.50000 -0.42720

-0.07827 0.40142 -0.35408

x =

2.31152 2.23938 0.33223 0.10497 -1.03596 -1.28640 0.95970 0.13887

1.68032 1.55471 0.98834 0.30509 -1.73239 -1.63471 1.21310 0.39214

0.79556 0.89504 1.54824 0.65274 -2.00532 -1.22029 0.60584 0.69597

-0.07104 0.52703 1.67354 1.10828 -1.63794 -0.55265 -0.41813 0.76863

-0.59944 0.42646 1.42596 1.48468 -0.68669 -0.19861 -0.80687 0.36103

-0.68458 0.39262 1.10092 1.54841 0.06611 -0.26584 -0.73588 -0.43597

-0.41034 0.26626 0.87033 1.19466 0.68243 -0.51447 -0.48841 -1.23052

0.06194 0.06655 0.73248 0.53771 0.81864 -0.52212 -0.41251 -1.58984

0.46131 -0.04995 0.50676 -0.14439 0.41020 -0.20928 -0.82014 -1.33437

0.62615 0.00753 0.04003 -0.58201 -0.06518 0.10403 -1.30029 -0.67355

0.60450 0.14383 -0.56957 -0.67513 -0.29758 0.06463 -1.33157 -0.02656

0.49676 0.25414 -1.03931 -0.51927 -0.39731 0.00899 -0.74555 0.29232

0.34817 0.27191 -1.10552 -0.29617 -0.46212 -0.25925 0.21230 0.26527

0.17463 0.15501 -0.70020 -0.12722 -0.50445 -0.46905 1.04501 0.12486

-0.00000 -0.00000 0.00000 0.00000 -0.46964 -0.38038 1.33528 0.13041

inf norm res: 4.699943e-09, 1.152566e-11, 5.010791e-13, 5.716404e-08, 2.394717e-10

Average solution time over 10 runs: 8.61e-01 seconds

For comparison, the same code executed on laptop Dell XPS 9350 (Intel Core i7-6560U 2.2 GHz) with Ubuntu 14.04: Average solution time over 1000 runs: 2.71e-04 seconds

Procedure to port acados code on TI's TM4C129 with TivaWare C in IDE CCSv7:

The main modifications include:

  • Do not use posix_memalign in d_aux_extern_depend_lib.c
  • Provide a function gettimeofday() so that acados uses for measuring computational time.

Detailed steps that have been done for this example:

  • Add clock-arch.h, linux_time.h, linux_time.c (using SysTick and interrupt for measuring time, can switch to Timer0 instead of SysTick)

  • In Project Build_settings:

    • General: Choose Connection = Stellaris In-Circuit Debug Interface, tick "Manage the project's target-configuration automatically Compiler version: TI v16.9.1.LTS
    • ARM Compiler / Optimization: Optimization level 2 -- Global Optimizations. Speed vs size trade-off: seems not affect much on the speed (leave it default = 2)
    • ARM Compiler / Include Options: "${PROJECT_ROOT}" "${PROJECT_ROOT}/include" "${CG_TOOL_ROOT}/include" path_to_folder/TivaWare_C_Series-2.1.3.156
    • ARM Compiler / ULP Advisor: None
    • ARM Compiler / Advanced Options / Language Options: Choose C Dialect = C99
    • ARM Linker / Basic Options: Heap size for C/C++ dynamic memory allocation: 0x2fa00 (this can be up to 0x3fa00) Set C system stack size: 1024
    • ARM Linker / File Search Path: Include library files: libc.a path_to_folder/TivaWare_C_Series-2.1.3.156/driverlib/ccs/Debug/driverlib.lib
  • Change the CCS generated file tm4c129encpdt_startup_ccs.c (or startup_ccs.c):

    • Add: extern void SysTickIntHandler(void);
    • Change the vector of interrupt handlers: use "SysTickIntHandler"
  • Change some code in acados project (here is the summary for ocp_qp_hpmpc example as of 2017.05.05):

    • In function main(), add: // // Set the clocking to run directly from the crystal at 120MHz. // g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); // // Enable the GPIO port that is used for the on-board LEDs. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);

      // // Enable processor interrupts. // IntMasterEnable();

      // // Set SysTick timer to CLOCK_CONF_SECOND rounds per round. // SysTickPeriodSet(g_ui32SysClock/CLOCK_CONF_SECOND-1);

      // // Enable the SysTick Interrupt. // SysTickIntEnable();

      // // Enable SysTick timer // printf("Start SysTick counter\n"); SysTickEnable();

    • In file d_aux_extern_depend_lib.c: avoid running the posix_memalign() function, as it is not supported in ARM Cortex M4 non-eabi

    • In file include/timing.h: instead of libraries <sys/stat.h> and <sys/time.h>, use: #include "linux_time.h"

  • Compile the Debug build, and run the Debug on the dev board.