diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 276b28d..a48ad77 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,7 +7,7 @@ on: branches: [ master ] jobs: - build: + build_linux: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -15,6 +15,8 @@ jobs: run: curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh - name: Build firmware run: make + - name: Check c_cpp_properties.json + run: tools/check_c_cpp_properties.py build_macos: runs-on: macos-latest @@ -24,6 +26,8 @@ jobs: run: brew install arduino-cli - name: Build firmware run: make + - name: Check c_cpp_properties.json + run: tools/check_c_cpp_properties.py build_windows: runs-on: windows-latest @@ -35,6 +39,8 @@ jobs: run: choco install make - name: Build firmware run: make + - name: Check c_cpp_properties.json + run: python3 tools/check_c_cpp_properties.py build_simulator: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index f7a56be..1057537 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,10 @@ build/ tools/log/ .dependencies +.vscode/* +!.vscode/settings.json +!.vscode/c_cpp_properties.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/intellisense.h diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..68bab82 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,144 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/flix", + "${workspaceFolder}/gazebo", + "~/.arduino15/packages/esp32/hardware/esp32/3.0.3/cores/**", + "~/.arduino15/packages/esp32/hardware/esp32/3.0.3/libraries/**", + "~/.arduino15/packages/esp32/tools/esp32-arduino-libs/idf-release_v5.1-dc859c1e67/esp32/**", + "~/.arduino15/packages/esp32/tools/esp32-arduino-libs/idf-release_v5.1-dc859c1e67/esp32/dio_qspi/include", + "~/Arduino/libraries/**", + "/usr/include/**" + ], + "forcedInclude": [ + "${workspaceFolder}/.vscode/intellisense.h", + "~/.arduino15/packages/esp32/hardware/esp32/3.0.3/cores/esp32/Arduino.h", + "~/.arduino15/packages/esp32/hardware/esp32/3.0.3/variants/d1_mini32/pins_arduino.h", + "${workspaceFolder}/flix/cli.ino", + "${workspaceFolder}/flix/control.ino", + "${workspaceFolder}/flix/estimate.ino", + "${workspaceFolder}/flix/flix.ino", + "${workspaceFolder}/flix/imu.ino", + "${workspaceFolder}/flix/led.ino", + "${workspaceFolder}/flix/log.ino", + "${workspaceFolder}/flix/mavlink.ino", + "${workspaceFolder}/flix/motors.ino", + "${workspaceFolder}/flix/rc.ino", + "${workspaceFolder}/flix/time.ino", + "${workspaceFolder}/flix/util.ino", + "${workspaceFolder}/flix/wifi.ino" + ], + "compilerPath": "~/.arduino15/packages/esp32/tools/esp-x32/2302/bin/xtensa-esp32-elf-g++", + "cStandard": "c11", + "cppStandard": "c++17", + "defines": [ + "F_CPU=240000000L", + "ARDUINO=10607", + "ARDUINO_D1_MINI32", + "ARDUINO_ARCH_ESP32", + "ARDUINO_BOARD=D1_MINI32", + "ARDUINO_VARIANT=d1_mini32", + "ARDUINO_PARTITION_default", + "ESP32", + "CORE_DEBUG_LEVEL=0", + "ARDUINO_USB_CDC_ON_BOOT=" + ] + }, + { + "name": "Mac", + "includePath": [ + "${workspaceFolder}/flix", + "${workspaceFolder}/gazebo", + "~/Library/Arduino15/packages/esp32/hardware/esp32/3.0.3/cores/esp32", + "~/Library/Arduino15/packages/esp32/hardware/esp32/3.0.3/libraries/**", + "~/Library/Arduino15/packages/esp32/tools/esp32-arduino-libs/idf-release_v5.1-dc859c1e67/esp32/include/**", + "~/Library/Arduino15/packages/esp32/tools/esp32-arduino-libs/idf-release_v5.1-dc859c1e67/esp32/dio_qspi/include", + "~/Documents/Arduino/libraries/**", + "/opt/homebrew/include/**" + ], + "forcedInclude": [ + "${workspaceFolder}/.vscode/intellisense.h", + "~/Library/Arduino15/packages/esp32/hardware/esp32/3.0.3/cores/esp32/Arduino.h", + "~/Library/Arduino15/packages/esp32/hardware/esp32/3.0.3/variants/d1_mini32/pins_arduino.h", + "${workspaceFolder}/flix/flix.ino", + "${workspaceFolder}/flix/cli.ino", + "${workspaceFolder}/flix/control.ino", + "${workspaceFolder}/flix/estimate.ino", + "${workspaceFolder}/flix/imu.ino", + "${workspaceFolder}/flix/led.ino", + "${workspaceFolder}/flix/log.ino", + "${workspaceFolder}/flix/mavlink.ino", + "${workspaceFolder}/flix/motors.ino", + "${workspaceFolder}/flix/rc.ino", + "${workspaceFolder}/flix/time.ino", + "${workspaceFolder}/flix/util.ino", + "${workspaceFolder}/flix/wifi.ino" + ], + "compilerPath": "~/Library/Arduino15/packages/esp32/tools/esp-x32/2302/bin/xtensa-esp32-elf-g++", + "cStandard": "c11", + "cppStandard": "c++17", + "defines": [ + "F_CPU=240000000L", + "ARDUINO=10607", + "ARDUINO_D1_MINI32", + "ARDUINO_ARCH_ESP32", + "ARDUINO_BOARD=D1_MINI32", + "ARDUINO_VARIANT=d1_mini32", + "ARDUINO_PARTITION_default", + "ARDUINO_FQBN=esp32:esp32:d1_mini32", + "ESP32", + "CORE_DEBUG_LEVEL=0", + "ARDUINO_USB_CDC_ON_BOOT=" + ] + }, + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/flix", + "${workspaceFolder}/gazebo", + "~/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.0.3/cores/**", + "~/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.0.3/libraries/**", + "~/AppData/Local/Arduino15/packages/esp32/tools/esp32-arduino-libs/idf-release_v5.1-dc859c1e67/esp32/**", + "~/AppData/Local/Arduino15/packages/esp32/tools/esp32-arduino-libs/idf-release_v5.1-dc859c1e67/esp32/dio_qspi/include", + "~/Documents/Arduino/libraries/**" + ], + "forcedInclude": [ + "${workspaceFolder}/.vscode/intellisense.h", + "~/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.0.3/cores/esp32/Arduino.h", + "~/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.0.3/variants/d1_mini32/pins_arduino.h", + "${workspaceFolder}/flix/cli.ino", + "${workspaceFolder}/flix/control.ino", + "${workspaceFolder}/flix/estimate.ino", + "${workspaceFolder}/flix/flix.ino", + "${workspaceFolder}/flix/imu.ino", + "${workspaceFolder}/flix/led.ino", + "${workspaceFolder}/flix/log.ino", + "${workspaceFolder}/flix/mavlink.ino", + "${workspaceFolder}/flix/motors.ino", + "${workspaceFolder}/flix/rc.ino", + "${workspaceFolder}/flix/time.ino", + "${workspaceFolder}/flix/util.ino", + "${workspaceFolder}/flix/wifi.ino" + ], + "compilerPath": "~/AppData/Local/Arduino15/packages/esp32/tools/esp-x32/2302/bin/xtensa-esp32-elf-g++.exe", + "cStandard": "c11", + "cppStandard": "c++17", + "defines": [ + "F_CPU=240000000L", + "ARDUINO=10607", + "ARDUINO_D1_MINI32", + "ARDUINO_ARCH_ESP32", + "ARDUINO_BOARD=D1_MINI32", + "ARDUINO_VARIANT=d1_mini32", + "ARDUINO_PARTITION_default", + "ARDUINO_FQBN=esp32:esp32:d1_mini32", + "ESP32", + "CORE_DEBUG_LEVEL=0", + "ARDUINO_USB_CDC_ON_BOOT=" + ] + } + ], + "version": 4 +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..75d92b2 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. + "recommendations": [ + "ms-vscode.cpptools", + "twxs.cmake", + "ms-vscode.cmake-tools", + "ms-python.python" + ], + "unwantedRecommendations": [] +} diff --git a/.vscode/intellisense.h b/.vscode/intellisense.h new file mode 100644 index 0000000..223bdd1 --- /dev/null +++ b/.vscode/intellisense.h @@ -0,0 +1,5 @@ +#ifdef __INTELLISENSE__ + #pragma diag_suppress 144, 513 + // diag 144: a value of type "enum " cannot be used to initialize an entity of type "enum "C/C++ + // diag 513: a value of type "enum " cannot be assigned to an entity of type "enum "C/C++ +#endif diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..efeb62d --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug simulation", + "type": "cppdbg", + "request": "launch", + "program": "/usr/bin/gzserver", + "osx": { + "program": "/opt/homebrew/bin/gzserver", + "MIMode": "lldb", + }, + "args": ["--verbose", "${workspaceFolder}/gazebo/flix.world"], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [ + {"name": "GAZEBO_MODEL_PATH", "value": "${workspaceFolder}/gazebo/models"}, + {"name": "GAZEBO_PLUGIN_PATH", "value": "${workspaceFolder}/gazebo/build"} + ], + "MIMode": "gdb", + "preLaunchTask": "Build simulator", + "externalConsole": true, + }, + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..cb6fab8 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "C_Cpp.intelliSenseEngineFallback": "enabled", + "files.associations": { + "*.sdf": "xml", + "*.ino": "cpp", + "*.h": "cpp" + } +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..d715e1e --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,31 @@ +{ + "tasks": [ + { + "label": "Build firmware", + "type": "shell", + "command": "make", + "problemMatcher": [ "$gcc" ], + "presentation": { "clear": true, "showReuseMessage": false }, + }, + { + "label": "Upload firmware", + "type": "shell", + "command": "make upload", + "problemMatcher": [ "$gcc" ], + "presentation": { "clear": true, "showReuseMessage": false } + }, + { + "label": "Build simulator", + "type": "shell", + "command": "make build_simulator", + "problemMatcher": [ "$gcc" ], + "presentation": { "clear": true, "showReuseMessage": false } + }, + { + "label": "Clean", + "type": "shell", + "command": "make clean", + } + ], + "version": "2.0.0" +} diff --git a/tools/check_c_cpp_properties.py b/tools/check_c_cpp_properties.py new file mode 100755 index 0000000..8860881 --- /dev/null +++ b/tools/check_c_cpp_properties.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 + +import os +import platform +import json +import re + +path = '.vscode/c_cpp_properties.json' if os.path.exists('./.vscode/c_cpp_properties.json') else '../.vscode/c_cpp_properties.json' +txt = open(path).read() +# remove comments +txt = re.sub(r'//.*', '', txt) +props = json.loads(txt) + +env = props.get('env', {}) +env['workspaceFolder'] = '.' + +def check_path(s): + source = s + # replace env + for key, value in env.items(): + s = s.replace('${' + key + '}', value) + # remove globs from the end + if s.endswith('**'): + s = s[:-2] + elif s.endswith('*'): + s = s[:-1] + s = os.path.expanduser(s) + if s == '': + s = '.' + print('Check', source, '->', s) + assert os.path.exists(s), 'Path does not exist: ' + s + +# linux, macos or windows: +platform = platform.system().lower() +if platform == 'darwin': + platform = 'mac' +elif platform == 'windows': + platform = 'win32' +elif platform == 'linux': + pass +else: + raise Exception('Unknown platform: ' + platform) + +for configuration in props['configurations']: + if platform not in configuration['name'].lower(): + print('Skip configuration', configuration['name']) + continue + + print('Check configuration', configuration['name']) + + for include_path in configuration.get('includePath', []): + check_path(include_path) + + for forced_include in configuration.get('forcedInclude', []): + check_path(forced_include) + + for browse in configuration.get('browse', {}).get('path', []): + check_path(browse) + + if 'compilerPath' in configuration: + check_path(configuration['compilerPath'])