Skip to content

Commit a3989c5

Browse files
committed
- Added detailed instructions for installing gcc using pacman.
- Added IS_USING_CODEGEN option to CMakeLists. - Added "Codegen-" version of Filter1stOrder class that uses MATLAB generated code.
1 parent 2865262 commit a3989c5

12 files changed

+165
-100
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
build/**
2+
dat/**
23
*.s
34

45
# Created by https://www.toptal.com/developers/gitignore/api/git,c++,cmake,matlab,visualstudiocode,jupyternotebooks

CMakeLists.txt

+72-51
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
#****************************************#
22
#* Cmake, language and compiler options *#
33
#****************************************#
4-
cmake_minimum_required(VERSION 3.13)
5-
set(CMAKE_C_COMPILER "gcc")
6-
set(CMAKE_CXX_COMPILER "g++")
7-
set(CMAKE_CXX_STANDARD 17)
8-
set(CMAKE_CXX_STANDARD_REQUIRED ON)
9-
set(CMAKE_CXX_EXTENSIONS OFF)
104

5+
#* cmake and compiler requirements
6+
cmake_minimum_required( VERSION 3.13 )
7+
set( CMAKE_C_COMPILER "gcc" )
8+
set( CMAKE_CXX_COMPILER "g++" )
9+
set( CMAKE_CXX_STANDARD 17 )
10+
set( CMAKE_CXX_STANDARD_REQUIRED ON )
11+
set( CMAKE_CXX_EXTENSIONS OFF )
12+
13+
#* set global compile options
14+
#* use target_compile_options() for target compile options
1115
add_compile_options(
1216
-fdiagnostics-color=always
1317
-fmessage-length=0
@@ -19,89 +23,106 @@ add_compile_options(
1923
-fno-common #* declare globals once
2024
-ffreestanding #* standard library may be unavailable
2125
#-fstack-protector-strong #* stack guard, costs one write and read per function, needs canary
22-
-Wall #* all warnings
23-
-Wextra
24-
-Wpedantic
2526
#-Wno-unused-variable
2627
#-Wno-unused-parameter
2728
#-Wno-unused-but-set-parameter
28-
)
29+
-Wall #* all warnings
30+
-Wextra
31+
-Wpedantic )
2932

3033
#* force debug mode in case CMAKE_BUILD_TYPE was not set
31-
if(NOT CMAKE_BUILD_TYPE)
32-
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING
33-
"Default build type: Debug" FORCE)
34+
if( NOT CMAKE_BUILD_TYPE )
35+
set( CMAKE_BUILD_TYPE "Debug" CACHE STRING
36+
"Default build type: Debug" FORCE )
3437
endif()
3538

3639
#* set up directories for binary, library, data and parameter files
37-
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
38-
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
39-
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
40-
file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/dat)
41-
file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/param)
40+
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
41+
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
42+
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
43+
file( MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/param )
44+
file( MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/dat )
4245

4346
#* where to look for the project header and source files
44-
set(INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/include)
45-
set(SRC_DIR ${CMAKE_CURRENT_LIST_DIR}/src)
47+
set( INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/include )
48+
set( SRC_DIR ${CMAKE_CURRENT_LIST_DIR}/src )
49+
50+
option( IS_USING_CODEGEN "Use MATLAB codegen generated code" ON )
51+
52+
if(IS_USING_CODEGEN)
53+
set(CODEGEN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/matlab/codegen )
54+
endif(IS_USING_CODEGEN)
4655

4756
#* set the number of CPUs
48-
include(ProcessorCount)
49-
ProcessorCount(N)
57+
include( ProcessorCount )
58+
ProcessorCount( N )
5059

51-
if(NOT N EQUAL 0)
52-
set(CTEST_BUILD_FLAGS -j${N})
53-
set(ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${N})
60+
if( NOT N EQUAL 0 )
61+
set( CTEST_BUILD_FLAGS -j${N} )
62+
set( ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${N} )
5463
endif()
55-
message("> Number of cores set to ${N}")
64+
message( "> Number of cores set to ${N}" )
5665

5766

5867
#***********#
5968
#* Project *#
6069
#***********#
61-
project(OG_OC VERSION 0.1.0 LANGUAGES CXX)
70+
project( OG_OC VERSION 0.1.0 LANGUAGES CXX )
6271

6372
#* build Filter1stOrder
64-
add_library(Filter1stOrder STATIC
65-
${SRC_DIR}/Filter1stOrder.cpp
66-
${SRC_DIR}/MatrixIO.cpp)
67-
68-
target_include_directories(Filter1stOrder
69-
PUBLIC
70-
${INCLUDE_DIR}
71-
)
73+
if( IS_USING_CODEGEN )
74+
75+
if( NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/matlab/codegen/filter_1st_order.cpp )
76+
message( FATAL_ERROR "> filter_1st_order.cpp has not been generated, please run matlab/codegen__filter_1st_order first" )
77+
endif( NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/matlab/codegen/filter_1st_order.cpp )
78+
79+
add_library( Filter1stOrder STATIC
80+
${SRC_DIR}/Codegen-Filter1stOrder.cpp
81+
${SRC_DIR}/MatrixIO.cpp
82+
${CODEGEN_DIR}/filter_1st_order.cpp )
83+
84+
target_include_directories( Filter1stOrder
85+
PUBLIC
86+
${INCLUDE_DIR}
87+
${CODEGEN_DIR} )
88+
else()
89+
add_library( Filter1stOrder STATIC
90+
${SRC_DIR}/Filter1stOrder.cpp
91+
${SRC_DIR}/MatrixIO.cpp )
92+
93+
target_include_directories( Filter1stOrder
94+
PUBLIC
95+
${INCLUDE_DIR} )
96+
endif( IS_USING_CODEGEN )
7297

7398
#* build ParametersToFile.hpp
74-
add_executable(ParametersToFile ${SRC_DIR}/ParametersToFile.cpp)
99+
add_executable( ParametersToFile ${SRC_DIR}/ParametersToFile.cpp )
75100

76-
target_include_directories(ParametersToFile
101+
target_include_directories( ParametersToFile
77102
PUBLIC
78-
${INCLUDE_DIR}
79-
)
103+
${INCLUDE_DIR} )
80104

81105
#* call ParametersToFile.exe after build
82106
add_custom_command(
83107
TARGET ParametersToFile
84108
POST_BUILD
85109
COMMAND ParametersToFile
86-
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
87-
)
88-
110+
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} )
89111

90112
#***********#
91113
#* Testing *#
92114
#***********#
93115
enable_testing()
94116

95117
#* add or remove tests
96-
set(TEST_NAMES
97-
test_filter
98-
)
118+
set( TEST_NAMES
119+
test-filter )
99120

100121
#* loops through all tests
101-
foreach(ELEMENT ${TEST_NAMES})
102-
add_executable(${ELEMENT} test/${ELEMENT}.cpp)
103-
target_link_libraries(${ELEMENT} Filter1stOrder)
104-
add_test(NAME ${ELEMENT}
122+
foreach( ELEMENT ${TEST_NAMES} )
123+
add_executable( ${ELEMENT} test/${ELEMENT}.cpp )
124+
target_link_libraries( ${ELEMENT} Filter1stOrder )
125+
add_test( NAME ${ELEMENT}
105126
COMMAND ${ELEMENT}
106-
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
107-
endforeach(ELEMENT ${TEST_NAMES})
127+
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} )
128+
endforeach( ELEMENT ${TEST_NAMES} )

README.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,11 @@ These instructions are for using Visual Studio Code.
126126
2. Install the following extensions for VS Code:
127127
- [C/C++](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
128128
- [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) (You may follow [these instructions](https://code.visualstudio.com/docs/cpp/cmake-linux))
129-
3. Install [CMake](https://cmake.org/) and add to path.
130-
4. For Windows, install [Msys2](https://www.msys2.org/). (You may follow [these instructions](https://code.visualstudio.com/docs/cpp/config-mingw)). For other platforms, make sure [gcc](https://gcc.gnu.org/) is installed.
131-
5. Open the project root folder in VS Code (where the top ```CMakeLists.txt``` lives). By default CMake Tools will configure the project for you, creating a ```build``` folder. You may build and run tests using the task bar on the bottom of your screen.
129+
3. Install [CMake](https://cmake.org/) and add to path during installation.
130+
4. For Windows, install [Msys2](https://www.msys2.org/). (You may follow [these instructions](https://code.visualstudio.com/docs/cpp/config-mingw)) and add ```C:\msys64\mingw64\bin``` to path. Open an Msys2 terminal type, in ```pacman -Syu``` and ```pacman -S --needed base-devel mingw-w64-x86_64-toolchain```. For other platforms, make sure [gcc](https://gcc.gnu.org/) is installed.
131+
5. Verify g++ installation by typing ```g++ --version``` in an Msys2 terminal. It should display the current version.
132+
6. Open the project root folder in VS Code (where the top ```CMakeLists.txt``` lives). By default CMake Tools will configure the project for you, creating a ```build``` folder. You may build and run tests using the task bar on the bottom of your screen.
133+
7. If CMake tools fails to find prefered generator, set ```"cmake.generator": "C:\msys64\mingw64\bin"``` in VS Code settings.
132134

133135
You will need a C++ compiler to compile ```.cpp``` files. You can use [VS Code with gcc](https://code.visualstudio.com/docs/languages/cpp) for this task.
134136

include/Codegen-Filter1stOrder.hpp

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef CODEGEN_FILTER1STORDER_HPP_CINARAL_220317_1312
2+
#define CODEGEN_FILTER1STORDER_HPP_CINARAL_220317_1312
3+
4+
#include "Parameters.hpp"
5+
#include "filter_1st_order.h"
6+
7+
class Filter1stOrder
8+
{
9+
private:
10+
float y_prev_ = 0.F;
11+
float x_prev_ = 0.F;
12+
13+
public:
14+
float filter(float x);
15+
};
16+
17+
#endif

include/Filter1stOrder.hpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
#ifndef FILTER1STORDER_HPP_CINARAL_220213_1456
22
#define FILTER1STORDER_HPP_CINARAL_220213_1456
33

4-
#include "MatrixIO.hpp"
54
#include "Parameters.hpp"
65

76
class Filter1stOrder
87
{
98
private:
10-
double y_1_ = 0.0;
11-
double x_1_ = 0.0;
9+
float y_prev_ = 0.F;
10+
float x_prev_ = 0.F;
1211

1312
public:
14-
double filter(double);
15-
matrix test(matrix);
13+
float filter(float x);
1614
};
1715

1816
#endif

matlab/codegen__filter_1st_order.m

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
%* function y = filter_1st_order(y_prev, x, x_prev, T, tau)
2+
precision = 'single';
3+
4+
x_dim = 1;
5+
scalar_t = coder.newtype(precision, [1, 1]);
6+
x_t = coder.newtype(precision, [x_dim, 1]);
7+
y_t = coder.newtype(precision, [x_dim, 1]);
8+
x_prev_t = coder.newtype(precision, [x_dim, 1]);
9+
y_prev_t = coder.newtype(precision, [x_dim, 1]);
10+
11+
cfg = coder.config('lib');
12+
13+
cfg.HardwareImplementation.TargetHWDeviceType = 'Intel->x86-64 (Windows64)';
14+
15+
codegen filter_1st_order -d codegen\ -args {y_prev_t, x_t, x_prev_t, scalar_t, scalar_t} -config cfg -lang:c++ -c -report

matlab/filter_1st_order.m

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
function y_0 = filter_1st_order(y_1, x_0, x_1, T, tau)
1+
function y = filter_1st_order(y_prev, x, x_prev, T, tau)
22
%* Practical differentiator with first order filter
3-
%* y_0 = filter_1st_order(x, T, tau)
4-
%* y_0 - filtered x at the current time step
5-
%* y_1 - filtered x at the previous time step
6-
%* x_0 - x at the current time step
7-
%* x_1 - x at the previous time step
8-
%* T - time step
9-
%* tau - time constant
3+
%* y = filter_1st_order(x, T, tau)
4+
%* y - filtered x at the current time step
5+
%* y_prev - filtered x at the previous time step
6+
%* x - x at the current time step
7+
%* x_prev - x at the previous time step
8+
%* T - time step
9+
%* tau - time constant
1010
%*
1111
%* Let y(t) be the filtered version of x(t):
1212
%* Y(s) 1
@@ -21,6 +21,6 @@
2121
%*
2222
%* cinaral 2022-02-12
2323

24-
y_0 = ((T*x_0 + T*x_1) - (T - 2*tau)*y_1)/(T + 2*tau);
24+
y = ((T*x + T*x_prev) - (T - 2*tau)*y_prev)/(T + 2*tau);
2525

2626
end

src/Codegen-Filter1stOrder.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include "Codegen-Filter1stOrder.hpp"
2+
3+
using namespace Parameters;
4+
5+
float
6+
Filter1stOrder::filter(float x)
7+
{
8+
float y = filter_1st_order(y_prev_, x, x_prev_, time_step, time_const);
9+
x_prev_ = x;
10+
y_prev_ = y;
11+
return y;
12+
}

src/Filter1stOrder.cpp

+6-18
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,11 @@
22

33
using namespace Parameters;
44

5-
double
6-
Filter1stOrder::filter(double x_0)
5+
float
6+
Filter1stOrder::filter(float x)
77
{
8-
double y_0 = ((time_step*x_0 + time_step*x_1_) - (time_step - 2*time_const)*y_1_)/(time_step + 2*time_const);
9-
x_1_ = x_0;
10-
y_1_ = y_0;
11-
return y_0;
12-
}
13-
14-
matrix
15-
Filter1stOrder::test(matrix x_arr)
16-
{
17-
matrix y_arr = x_arr;
18-
19-
for (int i = 0; i < x_arr.t_dim; i++) {
20-
y_arr.val[i] = Filter1stOrder::filter(x_arr.val[i]);
21-
}
22-
23-
return y_arr;
8+
float y = ((time_step*x + time_step*x_prev_) - (time_step - 2*time_const)*y_prev_)/(time_step + 2*time_const);
9+
x_prev_ = x;
10+
y_prev_ = y;
11+
return y;
2412
}

test/matlab/run_all_tests.m

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1 @@
1-
if ~exist('../../build/bin/test_filter.exe', 'file')
2-
error('test_filter.exe is missing. You need to build it.')
3-
else
4-
test_filter
5-
end
6-
1+
test__filter

test/matlab/test_filter.m renamed to test/matlab/test__filter.m

+17-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
11
%************************%
22
%* Read test parameters *%
33
%************************%
4+
5+
%* setup path and IO dirs
6+
addpath('../../matlab');
7+
48
bin_dname = '../../build/bin';
59
param_dname = append(bin_dname, '/', 'param');
6-
dat_dname = append(bin_dname, '/', 'dat');
7-
addpath('../../matlab');
10+
dat_dname = '../../dat';
11+
delimiter = ',';
12+
13+
test_name = 'test-filter';
14+
prefix = append(dat_dname, '/');
15+
x_arr_fname = append(prefix, 'x_arr.dat');
16+
y_arr_fname = append(prefix, 'y_arr.dat');
17+
exe_name = append(test_name, '.exe');
818

19+
%* read the parameters
920
param_file = fopen(append(param_dname, '/', 'Scalars'), 'r');
1021

1122
while ~feof(param_file)
@@ -66,19 +77,19 @@
6677
%***************%
6778

6879
%* x_arr is an input to test_filter.exe
69-
writematrix(x_arr, append(dat_dname, '/', 'x_arr.dat'), 'Delimiter', delimiter);
80+
writematrix(x_arr, x_arr_fname, 'Delimiter', delimiter);
7081

7182
%* run test_filter.exe
7283
prev_pwd = pwd;
7384
cd(bin_dname);
74-
if system('test_filter.exe') > 0
75-
error('Could not open test_filter.exe');
85+
if system(exe_name) > 0
86+
error(append('Could not open ', bin_dname, '/', exe_name));
7687
end
7788
cd(prev_pwd);
7889

7990
%* read the output of test_filter.exe
8091
try
81-
y_cpp_arr = readmatrix(append(dat_dname, '/', 'y_arr.dat'), 'Delimiter', delimiter);
92+
y_cpp_arr = readmatrix(y_arr_fname, 'Delimiter', delimiter);
8293
catch
8394
error('Could not open y_arr.dat');
8495
end

0 commit comments

Comments
 (0)