├── .clang-format ├── .clang-tidy ├── .github └── workflows │ ├── build-raspi.yml │ ├── build-stm32.yml │ ├── clang-format.yml │ ├── copybara.yml │ ├── github-pages.yml │ ├── python-format.yml │ ├── ssh_key_copybara.pub │ └── unittests.yml ├── .gitignore ├── .gitlab-ci.yml ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── README.md ├── actuator-firmware ├── .gdbinit ├── .gitignore ├── Makefile ├── README.md ├── app_src.mk.jinja ├── linker │ ├── STM32F302x8.ld │ └── STM32F302x8_bootloader.ld ├── openocd.cfg ├── package.yml ├── src │ ├── analog_input.c │ ├── analog_input.h │ ├── assert.h │ ├── board.c │ ├── board.h │ ├── bootloader_config.c │ ├── bootloader_config.h │ ├── chconf.h │ ├── debug.c │ ├── debug.h │ ├── halconf.h │ ├── main.c │ ├── main.h │ ├── mcuconf.h │ ├── pressure_sensor.c │ ├── pressure_sensor.h │ ├── pressure_sensor_interface.c │ ├── pressure_sensor_interface.h │ ├── pump.c │ ├── pump.h │ ├── pwm.c │ ├── pwm.h │ ├── safety.c │ ├── safety.h │ ├── servo.c │ ├── servo.h │ └── uavcan │ │ ├── Command_handler.cpp │ │ ├── Command_handler.hpp │ │ ├── feedback_publisher.cpp │ │ ├── feedback_publisher.h │ │ ├── node.cpp │ │ └── node.h └── tests │ └── pressure_sensor_driver_test.cpp ├── can-io-firmware ├── .gdbinit ├── .gitignore ├── Makefile ├── README.md ├── app_src.mk.jinja ├── linker │ ├── STM32F302x8.ld │ └── STM32F302x8_bootloader.ld ├── openocd.cfg ├── package.yml ├── read_inputs.py ├── send_pwm.py ├── set_servo.py └── src │ ├── assert.h │ ├── board.c │ ├── board.h │ ├── bootloader_config.c │ ├── bootloader_config.h │ ├── chconf.h │ ├── debug.c │ ├── debug.h │ ├── halconf.h │ ├── main.c │ ├── main.h │ ├── mcuconf.h │ ├── pwm.c │ ├── pwm.h │ ├── servo.c │ ├── servo.h │ └── uavcan │ ├── DigitalInput_pub.cpp │ ├── DigitalInput_pub.hpp │ ├── ServoPWM_handler.cpp │ ├── ServoPWM_handler.hpp │ ├── node.cpp │ └── node.h ├── ci └── Dockerfile ├── cmake ├── AddCCompilerFlag.cmake ├── AddCXXCompilerFlag.cmake ├── ChibiOS │ └── 18.2 │ │ ├── ChibiOS.cmake │ │ ├── ChibiOS_HAL.cmake │ │ └── ChibiOS_RTOS.cmake ├── FindChibiOS.cmake ├── FindSDL2.cmake ├── cvra.cmake ├── gcc_stm32.cmake ├── gcc_stm32f0.cmake ├── gcc_stm32f1.cmake ├── gcc_stm32f2.cmake ├── gcc_stm32f3.cmake ├── gcc_stm32f4.cmake ├── gcc_stm32f7.cmake ├── gcc_stm32l0.cmake ├── gcc_stm32l1.cmake ├── gcc_stm32l4.cmake ├── master.cmake ├── stm32_common.cmake └── uwb-beacon.cmake ├── config_chaos.yaml ├── config_order.yaml ├── config_simulation.yaml ├── docs ├── architecture │ ├── archi2020.graffle │ ├── hardware2020.md │ ├── hardware2020.png │ ├── history.md │ ├── life-of-a-motion.md │ └── life-of-a-motion.png ├── can │ ├── adapter.md │ ├── beacon.md │ ├── bootloader.md │ ├── images │ │ ├── beacon-board.jpg │ │ ├── bootloader.png │ │ ├── can-adapter.jpg │ │ ├── io-board.jpg │ │ ├── motor-board.jpg │ │ ├── positioning_diagram.png │ │ ├── sensor-board-1.jpg │ │ └── sensor-board.jpg │ ├── intro.md │ ├── io.md │ ├── motor.md │ ├── positioning.md │ └── sensor.md ├── design │ └── linux-master.md ├── howto │ ├── add_a_uavcan_message.md │ ├── calibrate-odometry.md │ ├── install_arm_gcc.md │ ├── odometry-wheel-difference-error.png │ └── odometry-wheel-difference-trajectory.png ├── index.md ├── styles.css └── ytvideo.css ├── embedded-computer ├── README.md └── nuc_setup │ ├── Vagrantfile │ └── salt │ ├── minion │ └── roots │ ├── can │ ├── init.sls │ └── slcan.service │ ├── core │ ├── init.sls │ ├── passwordless_sudo │ └── release-upgrades │ ├── dev │ ├── python.sls │ ├── realsense.sls │ └── ros.sls │ ├── grub │ ├── default │ └── init.sls │ ├── http │ ├── init.sls │ └── server.conf │ ├── sound.sls │ ├── top.sls │ ├── users │ ├── cvra.keys │ └── cvra.sls │ └── wifi │ ├── dnsmasq.conf │ ├── hostapd.conf │ ├── hostapd_defaults │ ├── init.sls │ └── wlan_config.yaml ├── hitl ├── .gitignore ├── CMakeLists.txt ├── OpponentRobot.cpp ├── OpponentRobot.h ├── PhysicsCup.cpp ├── PhysicsCup.h ├── PhysicsRobot.cpp ├── PhysicsRobot.h ├── ProximityBeaconEmulator.cpp ├── ProximityBeaconEmulator.h ├── README.md ├── actuator_board_emulator.cpp ├── actuator_board_emulator.h ├── logging.cpp ├── logging.h ├── main.cpp ├── main.h ├── motor_board_emulator.cpp ├── motor_board_emulator.h ├── png_loader.cpp ├── png_loader.h ├── sensor_board_emulator.cpp ├── sensor_board_emulator.h ├── servo_board_emulator.cpp ├── servo_board_emulator.h ├── table.png ├── tests │ └── box2d.cpp ├── uavcan_node.h ├── viewer.cpp ├── viewer.h ├── voltage_injector.cpp ├── wheel_encoders_emulator.cpp └── wheel_encoders_emulator.h ├── lib ├── .gitignore ├── CMakeLists.txt ├── arm-cortex-tools │ ├── CMakeLists.txt │ ├── LICENSE │ ├── README.md │ ├── fault.c │ ├── fault_tests.c │ ├── fault_v6m.s │ ├── fault_v7m.s │ ├── include │ │ └── arm-cortex-tools │ │ │ ├── fault.h │ │ │ └── mpu.h │ ├── mpu.c │ └── package.yml ├── aversive │ ├── CMakeLists.txt │ ├── blocking_detection_manager │ │ └── blocking_detection_manager.cpp │ ├── control_system_manager │ │ ├── README.md │ │ ├── control_system_manager.c │ │ ├── general_architecture.png │ │ └── implementation.png │ ├── include │ │ └── aversive │ │ │ ├── blocking_detection_manager │ │ │ └── blocking_detection_manager.h │ │ │ ├── control_system_manager │ │ │ └── control_system_manager.h │ │ │ ├── math │ │ │ ├── geometry │ │ │ │ ├── circles.h │ │ │ │ ├── discrete_circles.h │ │ │ │ ├── lines.h │ │ │ │ ├── polygon.h │ │ │ │ └── vect_base.h │ │ │ └── vect2 │ │ │ │ └── vect2.h │ │ │ ├── obstacle_avoidance │ │ │ └── obstacle_avoidance.h │ │ │ ├── position_manager │ │ │ └── position_manager.h │ │ │ ├── robot_system │ │ │ ├── angle_distance.h │ │ │ └── robot_system.h │ │ │ └── trajectory_manager │ │ │ ├── trajectory_manager.h │ │ │ ├── trajectory_manager_core.h │ │ │ └── trajectory_manager_utils.h │ ├── math │ │ ├── geometry │ │ │ ├── circles.c │ │ │ ├── discrete_circles.c │ │ │ ├── lines.c │ │ │ ├── polygon.c │ │ │ └── vect_base.c │ │ └── vect2 │ │ │ └── vect2.c │ ├── obstacle_avoidance │ │ ├── benchmark │ │ │ ├── .gitignore │ │ │ ├── build.sh │ │ │ └── main.cpp │ │ └── obstacle_avoidance.c │ ├── package.yml │ ├── position_manager │ │ └── position_manager.cpp │ ├── robot_system │ │ ├── README.md │ │ ├── angle_distance.c │ │ ├── mixing.png │ │ └── robot_system.c │ ├── tests │ │ ├── obstacle_avoidance.cpp │ │ ├── test_blocking_detection_manager.cpp │ │ ├── test_geometry_discrete_circles.cpp │ │ └── test_geometry_polygon_intersection.cpp │ └── trajectory_manager │ │ ├── trajectory_manager.cpp │ │ ├── trajectory_manager_core.cpp │ │ └── trajectory_manager_utils.cpp ├── chibios-syscalls │ ├── .gitignore │ ├── CMakeLists.txt │ ├── LICENSE │ ├── README.md │ ├── cpp_stubs.cpp │ ├── dynamic_alloc_stubs.cpp │ ├── include │ │ └── chibios-syscalls │ │ │ └── stdio_lock.h │ ├── malloc_lock.c │ ├── newlib_syscalls.c │ ├── package.yml │ └── stdio_lock.c ├── cmp │ ├── .gitignore │ ├── CMakeLists.txt │ ├── LICENSE │ ├── README.md │ ├── TODO.md │ ├── VERSION.md │ ├── cmp.c │ ├── examples │ │ ├── build_examples.sh │ │ ├── cmp_data.dat │ │ ├── example1.c │ │ └── example2.c │ ├── include │ │ └── cmp │ │ │ └── cmp.h │ ├── package.yml │ └── test │ │ ├── buf.c │ │ ├── buf.h │ │ ├── cases.mpac │ │ ├── run_tests.sh │ │ ├── test.c │ │ ├── utils.c │ │ └── utils.h ├── cmp_mem_access │ ├── CMakeLists.txt │ ├── LICENSE │ ├── Readme.md │ ├── cmp_mem_access.c │ ├── cmp_mem_access_test.cpp │ ├── example.c │ ├── example_build.sh │ ├── include │ │ └── cmp_mem_access │ │ │ └── cmp_mem_access.h │ └── package.yml ├── crc │ ├── CMakeLists.txt │ ├── crc16.c │ ├── crc32.c │ ├── include │ │ └── crc │ │ │ ├── crc16.h │ │ │ └── crc32.h │ ├── package.yml │ └── test │ │ ├── crc16_test.cpp │ │ └── crc32_test.cpp ├── dijkstra │ ├── include │ │ └── dijkstra │ │ │ └── dijkstra.hpp │ ├── package.yml │ └── tests │ │ └── dijkstra.cpp ├── error │ ├── CMakeLists.txt │ ├── error.c │ ├── include │ │ └── error │ │ │ └── error.h │ ├── package.yml │ └── tests │ │ └── error.cpp ├── fatfs │ ├── CMakeLists.txt │ ├── ff.c │ ├── include │ │ └── fatfs │ │ │ ├── diskio.h │ │ │ ├── ff.h │ │ │ ├── ffconf.h │ │ │ └── integer.h │ ├── package.yml │ └── src │ │ ├── 00readme.txt │ │ └── option │ │ ├── cc932.c │ │ ├── cc936.c │ │ ├── cc949.c │ │ ├── cc950.c │ │ ├── ccsbcs.c │ │ └── unicode.c ├── filter │ ├── CMakeLists.txt │ ├── README.md │ ├── basic.c │ ├── iir.c │ ├── include │ │ └── filter │ │ │ ├── basic.h │ │ │ ├── iir.h │ │ │ └── mean.h │ ├── mean.c │ ├── package.yml │ └── tests │ │ ├── basic_test.cpp │ │ └── iir_test.cpp ├── goap │ ├── CMakeLists.demo.txt │ ├── CMakeLists.txt │ ├── README.md │ ├── copy.bara.sky │ ├── example.cpp │ ├── include │ │ └── goap │ │ │ ├── goap.hpp │ │ │ └── goap_internals.hpp │ ├── package.yml │ └── tests │ │ ├── goap_internals.cpp │ │ └── goap_test.cpp ├── list_uavcan_dsdl.py ├── msgbus │ ├── BUILD │ ├── CMakeLists.txt │ ├── README.md │ ├── WORKSPACE │ ├── demo.jinja │ ├── examples │ │ ├── chibios │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── STM32F302R8-Nucleo │ │ │ │ ├── .gitignore │ │ │ │ ├── Makefile │ │ │ │ ├── chconf.h │ │ │ │ ├── halconf.h │ │ │ │ ├── main.c │ │ │ │ ├── mcuconf.h │ │ │ │ └── openocd.cfg │ │ │ └── port.c │ │ └── posix │ │ │ ├── demo.c │ │ │ ├── demo_watchgroups.c │ │ │ ├── include │ │ │ └── msgbus │ │ │ │ └── posix │ │ │ │ └── port.h │ │ │ └── port.c │ ├── include │ │ └── msgbus │ │ │ ├── messagebus.h │ │ │ └── messagebus_cpp.hpp │ ├── messagebus.c │ ├── package.yml │ └── tests │ │ ├── atomicity.cpp │ │ ├── foreach.cpp │ │ ├── mocks │ │ ├── synchronization.cpp │ │ └── synchronization.hpp │ │ ├── msgbus.cpp │ │ ├── new_topic_callbacks.cpp │ │ ├── signaling.cpp │ │ ├── statistics.cpp │ │ ├── test_cpp_interface.cpp │ │ └── watchgroups.cpp ├── nanopb │ ├── CMakeLists.txt │ └── package.yml ├── parameter │ ├── CMakeLists.txt │ ├── Readme.md │ ├── include │ │ └── parameter │ │ │ ├── parameter.h │ │ │ ├── parameter_msgpack.h │ │ │ ├── parameter_port.h │ │ │ └── parameter_print.h │ ├── package.yml │ ├── parameter.c │ ├── parameter_msgpack.c │ ├── parameter_print.c │ └── tests │ │ ├── msgpack_test.cpp │ │ ├── parameter_port_dummy.cpp │ │ ├── parameter_print_test.cpp │ │ ├── parameter_test.cpp │ │ └── parameter_types_test.cpp ├── parameter_flash_storage │ ├── .gitignore │ ├── CMakeLists.txt │ ├── LICENSE │ ├── README.md │ ├── flash_f3.c │ ├── flash_f4.c │ ├── include │ │ └── parameter_flash_storage │ │ │ ├── flash.h │ │ │ ├── parameter_flash_storage.h │ │ │ └── parameter_flash_storage_private.h │ ├── package.yml │ ├── parameter_flash_storage.c │ └── tests │ │ ├── flash_mock.cpp │ │ └── parameter_flash_storage.cpp ├── pid │ ├── .gitignore │ ├── .travis.yml │ ├── CMakeLists.txt │ ├── README.markdown │ ├── include │ │ └── pid │ │ │ └── pid.h │ ├── package.yml │ ├── pid.c │ └── tests │ │ └── pid_test.cpp ├── quadramp │ ├── CMakeLists.txt │ ├── include │ │ └── quadramp │ │ │ └── quadramp.h │ ├── package.yml │ ├── quadramp.c │ └── tests │ │ └── quadramp.cpp ├── raft │ ├── CMakeLists.demo.jinja │ ├── demos │ │ ├── error_handlers.c │ │ ├── error_handlers.h │ │ ├── leader_election.cpp │ │ ├── log_replication.cpp │ │ ├── udp_transport.cpp │ │ └── udp_transport.hpp │ ├── doc │ │ └── raft.pdf │ ├── package.yml │ ├── raft.hpp │ └── tests │ │ ├── messages_comparator.cpp │ │ ├── messages_comparator.hpp │ │ ├── test_leader_election.cpp │ │ ├── test_log.cpp │ │ ├── test_log_replication.cpp │ │ ├── test_state_machine.hpp │ │ └── test_state_machine_commit.cpp ├── softspi │ ├── include │ │ └── softspi │ │ │ └── softspi.h │ ├── package.yml │ ├── softspi.c │ └── softspi_test.cpp ├── test-runner │ ├── .gitignore │ ├── CMakeLists.txt │ ├── README.md │ ├── main.cpp │ └── package.yml ├── timestamp │ ├── CMakeLists.txt │ ├── include │ │ └── timestamp │ │ │ ├── timestamp.h │ │ │ ├── timestamp_stm32.h │ │ │ └── timestamp_stm32_settings.h │ ├── package.yml │ ├── timestamp.c │ ├── timestamp_stm32.c │ └── timestamp_test.cpp ├── trace │ ├── CMakeLists.txt │ ├── include │ │ └── trace │ │ │ └── trace.h │ ├── package.yml │ ├── tests │ │ ├── trace_mocks.c │ │ ├── trace_points.c │ │ ├── trace_points.h │ │ └── trace_test.cpp │ └── trace.c ├── ugfx.cmake └── version │ ├── CMakeLists.txt │ ├── include │ └── version │ │ └── version.h │ ├── package.yml │ ├── tests │ └── test_version.cpp │ └── version.sh ├── master-firmware ├── .gdbinit ├── CMakeLists.txt ├── README.md ├── packaging │ ├── cvra-master.service │ ├── postinst │ └── prerm ├── protobuf │ ├── Timestamp.proto │ ├── actuators.proto │ ├── ally_position.proto │ ├── beacons.proto │ ├── encoders.proto │ ├── manipulator.proto │ ├── position.proto │ ├── protocol.proto │ ├── sensors.proto │ └── strategy.proto ├── src │ ├── .gitignore │ ├── base │ │ ├── base_controller.cpp │ │ ├── base_controller.h │ │ ├── cs_port.c │ │ ├── cs_port.h │ │ ├── map.c │ │ ├── map.h │ │ ├── map_server.cpp │ │ ├── map_server.h │ │ ├── rs_port.c │ │ └── rs_port.h │ ├── can │ │ ├── UavcanToMessagebusProxy.hpp │ │ ├── actuator_driver.c │ │ ├── actuator_driver.h │ │ ├── actuator_driver_uavcan.cpp │ │ ├── actuator_driver_uavcan.hpp │ │ ├── actuator_handler.cpp │ │ ├── actuator_handler.h │ │ ├── beacon_signal_handler.cpp │ │ ├── beacon_signal_handler.hpp │ │ ├── bus_enumerator.c │ │ ├── bus_enumerator.h │ │ ├── can_io_driver.cpp │ │ ├── can_io_driver.h │ │ ├── emergency_stop_handler.cpp │ │ ├── emergency_stop_handler.hpp │ │ ├── motor_driver.c │ │ ├── motor_driver.h │ │ ├── motor_driver_uavcan.cpp │ │ ├── motor_driver_uavcan.hpp │ │ ├── motor_feedback_streams_handler.cpp │ │ ├── motor_feedback_streams_handler.hpp │ │ ├── motor_manager.c │ │ ├── motor_manager.h │ │ ├── sensor_handler.cpp │ │ ├── sensor_handler.h │ │ ├── time_sync_server.cpp │ │ ├── time_sync_server.h │ │ ├── uavcan_node.cpp │ │ ├── uavcan_node.h │ │ ├── wheel_encoders_handler.cpp │ │ └── wheel_encoders_handler.hpp │ ├── commands.cpp │ ├── commands.h │ ├── config.c │ ├── config.h │ ├── control_panel.cpp │ ├── control_panel.h │ ├── debug │ │ ├── log.c │ │ └── log.h │ ├── gfxconf │ │ └── gfxconf.h │ ├── gpio_input.cpp │ ├── gpio_input.h │ ├── gui.cpp │ ├── gui.h │ ├── gui │ │ ├── ActuatorPage.h │ │ ├── AllyPage.h │ │ ├── GoapActionPage.h │ │ ├── Menu.cpp │ │ ├── Menu.h │ │ ├── MenuPage.cpp │ │ ├── MenuPage.h │ │ ├── MovePage.h │ │ ├── Page.h │ │ ├── PositionPage.h │ │ └── ScorePage.h │ ├── main.cpp │ ├── main.h │ ├── math │ │ ├── lie_groups.c │ │ └── lie_groups.h │ ├── msgbus_protobuf.c │ ├── msgbus_protobuf.h │ ├── parameter_port.cpp │ ├── robot_helpers │ │ ├── autoposition.cpp │ │ ├── autoposition.h │ │ ├── beacon_helpers.cpp │ │ ├── beacon_helpers.h │ │ ├── math_helpers.c │ │ ├── math_helpers.h │ │ ├── robot.h │ │ ├── trajectory_helpers.cpp │ │ └── trajectory_helpers.h │ ├── shell_commands.h │ ├── strategy.cpp │ ├── strategy.h │ ├── strategy │ │ ├── actions.h │ │ ├── actions_goap.cpp │ │ ├── actions_impl.cpp │ │ ├── color.h │ │ ├── goals.cpp │ │ ├── goals.h │ │ ├── score.cpp │ │ ├── score.h │ │ ├── state.cpp │ │ ├── state.h │ │ └── table.h │ ├── strategy_impl │ │ ├── base.cpp │ │ ├── base.h │ │ └── context.h │ ├── timestamp.cpp │ ├── timestamp.h │ ├── udp_topic_broadcaster.c │ └── udp_topic_broadcaster.h ├── test_build.sh └── tests │ ├── bus_enumerator.cpp │ ├── can │ └── actuator_driver.cpp │ ├── ch.cpp │ ├── ch.h │ ├── hal.h │ ├── lie_groups.cpp │ ├── msgbus_protobuf.cpp │ ├── strategy │ ├── test_actions.cpp │ ├── test_goals.cpp │ └── test_score.cpp │ ├── test_beacon_helpers.cpp │ ├── test_map.cpp │ ├── test_math_helpers.cpp │ ├── test_strategy.cpp │ ├── test_strategy_helpers.cpp │ ├── test_trajectory_helpers.cpp │ ├── trajectory_manager_test.cpp │ ├── uavcan_to_messagebus_test.cpp │ └── unix-timestamp.cpp ├── mkdocs.yml ├── motor-control-firmware ├── .gdbinit ├── .gitignore ├── Makefile ├── Makefile.include.jinja ├── README.md ├── board │ ├── board.c │ └── board.h ├── doc │ ├── motor_schema.png │ └── noname.markdown ├── linker │ ├── STM32F303xC.ld │ └── STM32F303xC_bootloader.ld ├── openocd.cfg ├── package.yml ├── src │ ├── analog.c │ ├── analog.h │ ├── blocking_uart_driver.c │ ├── blocking_uart_driver.h │ ├── bootloader_config.c │ ├── bootloader_config.h │ ├── chconf.h │ ├── control.c │ ├── control.h │ ├── encoder.c │ ├── encoder.h │ ├── feedback.c │ ├── feedback.h │ ├── halconf.h │ ├── index.c │ ├── index.h │ ├── libstubs.cpp │ ├── main.c │ ├── main.h │ ├── mcuconf.h │ ├── motor_protection.c │ ├── motor_protection.h │ ├── motor_pwm.c │ ├── motor_pwm.h │ ├── parameter_port.c │ ├── pid_cascade.c │ ├── pid_cascade.h │ ├── reboot.c │ ├── rpm.c │ ├── rpm.h │ ├── rpm_port.h │ ├── setpoint.c │ ├── setpoint.h │ ├── stream.c │ ├── stream.h │ ├── timestamp_stm32_settings.h │ └── uavcan │ │ ├── EmergencyStop_handler.cpp │ │ ├── EmergencyStop_handler.hpp │ │ ├── Position_handler.cpp │ │ ├── Position_handler.hpp │ │ ├── Reboot_handler.cpp │ │ ├── Reboot_handler.hpp │ │ ├── Torque_handler.cpp │ │ ├── Torque_handler.hpp │ │ ├── Trajectory_handler.cpp │ │ ├── Trajectory_handler.hpp │ │ ├── Velocity_handler.cpp │ │ ├── Velocity_handler.hpp │ │ ├── Voltage_handler.cpp │ │ ├── Voltage_handler.hpp │ │ ├── parameter_server.cpp │ │ ├── parameter_server.hpp │ │ ├── uavcan_node.cpp │ │ ├── uavcan_node.h │ │ ├── uavcan_streams.cpp │ │ └── uavcan_streams.hpp └── tests │ ├── feedback_test.cpp │ ├── pid_cascade_test.cpp │ ├── rpm_test.cpp │ └── setpoint_test.cpp ├── proximity-beacon-firmware ├── .gitignore ├── Makefile ├── Makefile.include.jinja ├── package.yml └── src │ ├── beacon_main.c │ ├── node.cpp │ ├── proximity_beacon.c │ ├── proximity_beacon.h │ ├── proximity_beacon_publisher.cpp │ └── proximity_beacon_publisher.hpp ├── run-clang-tidy.py ├── sensor-firmware ├── .gdbinit ├── .gitignore ├── CMakeLists.txt.jinja ├── Makefile ├── app_src.mk.jinja ├── linker │ ├── STM32F302x8.ld │ └── STM32F302x8_bootloader.ld ├── openocd.cfg ├── package.yml ├── read_color.py ├── read_distance.py ├── src │ ├── TCS3472.c │ ├── TCS3472.h │ ├── assert.h │ ├── board.c │ ├── board.h │ ├── bootloader_config.c │ ├── bootloader_config.h │ ├── chconf.h │ ├── debug.c │ ├── debug.h │ ├── halconf.h │ ├── main.c │ ├── main.h │ ├── mcuconf.h │ ├── uavcan │ │ ├── ColorRGBC_pub.cpp │ │ ├── ColorRGBC_pub.h │ │ ├── DistanceVL6180X_pub.cpp │ │ ├── DistanceVL6180X_pub.h │ │ ├── node.cpp │ │ └── node.h │ └── vl6180x │ │ ├── vl6180x.c │ │ ├── vl6180x.h │ │ ├── vl6180x_chibios.c │ │ └── vl6180x_registers.h └── tests │ └── test_range_sensor.cpp ├── tools ├── build_opkg_package.py ├── call_explorer.py ├── config │ ├── config_send.py │ ├── config_to_c.py │ ├── config_to_msgpack.py │ ├── parser │ │ ├── __init__.py │ │ └── parser.py │ └── tests │ │ ├── __init__.py │ │ ├── test_config_to_init.py │ │ ├── test_config_to_struct.py │ │ └── test_depth.py ├── gdbinit ├── generate_ctags.mk ├── heap_size.py ├── log_udp_protobuf │ ├── ally_position_inject.py │ ├── log_ally_position.py │ ├── log_udp_protobuf.py │ ├── messages.py │ ├── plot_arm.py │ ├── plot_demo.py │ └── plot_position.py ├── motor_config_calculator.py ├── motor_config_loader.py ├── raspi_debug_server │ ├── README.md │ ├── bootloader_change_id_remote.sh │ ├── bootloader_flash_remote.sh │ ├── bootloader_read_config_remote.sh │ ├── bootloader_run_app_remote.sh │ ├── bootloader_write_config_remote.sh │ ├── oocd_raspberry.cfg │ ├── openocd-remote.service │ └── shell-ssh.sh ├── read_beacon_signal.py ├── studio │ ├── cvra_studio │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── cli.py │ │ ├── commands │ │ │ ├── __init__.py │ │ │ ├── actuator.py │ │ │ ├── cmd_vel.py │ │ │ ├── node.py │ │ │ ├── node_discovery.py │ │ │ ├── param_tree.py │ │ │ ├── pid_plot.py │ │ │ ├── plot2d.py │ │ │ ├── plot_uwb.py │ │ │ └── publish.py │ │ ├── network │ │ │ ├── NodeStatusMonitor.py │ │ │ ├── ParameterTree.py │ │ │ ├── SetpointPublisher.py │ │ │ ├── UavcanNode.py │ │ │ └── __init__.py │ │ └── viewers │ │ │ ├── LivePlotter.py │ │ │ ├── LivePlotter2D.py │ │ │ ├── NestedDict.py │ │ │ ├── Selector.py │ │ │ ├── __init__.py │ │ │ ├── helpers.py │ │ │ └── wrappers.py │ ├── requirements.txt │ └── setup.py ├── uavcan_ip_interface.py └── uavcan_time_client.cpp ├── uavcan_data_types └── cvra │ ├── 20001.Reboot.uavcan │ ├── ServoTrajectory.uavcan │ ├── actuator │ ├── 20150.Feedback.uavcan │ └── 20151.Command.uavcan │ ├── drive │ └── 20200.VelocityCommand.uavcan │ ├── io │ ├── 20130.DigitalInput.uavcan │ └── 20131.ServoPWM.uavcan │ ├── metal_detector │ └── 20300.EMIRawSignal.uavcan │ ├── motor │ ├── 20000.EmergencyStop.uavcan │ ├── README.md │ ├── control │ │ ├── 20020.Trajectory.uavcan │ │ ├── 20021.Velocity.uavcan │ │ ├── 20022.Position.uavcan │ │ ├── 20023.Torque.uavcan │ │ └── 20024.Voltage.uavcan │ └── feedback │ │ ├── 20010.MotorEncoderPosition.uavcan │ │ ├── 20030.MotorPosition.uavcan │ │ ├── 20031.MotorTorque.uavcan │ │ ├── 20040.CurrentPID.uavcan │ │ ├── 20041.VelocityPID.uavcan │ │ ├── 20042.PositionPID.uavcan │ │ └── 20043.Index.uavcan │ ├── odometry │ └── 20160.WheelEncoder.uavcan │ ├── proximity_beacon │ ├── 20128.Signal.uavcan │ └── 20129.Settings.uavcan │ ├── sensor │ ├── 20140.DistanceVL6180X.uavcan │ └── 20141.ColorRGBC.uavcan │ └── uwb_beacon │ ├── 2100.RadioRange.uavcan │ ├── 2101.TagPosition.uavcan │ └── 2200.DataPacket.uavcan ├── uwb-beacon-firmware ├── .gdbinit ├── CMakeLists.txt ├── Makefile ├── README.md ├── STM32F405xG.ld ├── STM32F405xG_bootloader.ld ├── app_src.mk.jinja ├── doc │ ├── DW1000_Software_API_Guide_rev2p4.pdf │ ├── design_uwb_data_protocol.md │ ├── report.pdf │ └── report │ │ ├── .gitattributes │ │ ├── .gitignore │ │ ├── README.md │ │ ├── abstract.tex │ │ ├── code_source_org.md │ │ ├── code_source_org.tex │ │ ├── convert_ipython.sh │ │ ├── convert_readme.sh │ │ ├── experiments │ │ ├── Madgwick drift.ipynb │ │ ├── madgwick_bias.csv │ │ ├── range_noise.csv │ │ └── range_noise.ipynb │ │ ├── figures │ │ ├── antoine.jpg │ │ ├── architecture.graffle │ │ ├── architecture.pdf │ │ ├── board.jpg │ │ ├── board.xcf │ │ ├── board_schematic.pdf │ │ ├── radio enhancements.graffle │ │ ├── radio_broadcast.pdf │ │ ├── radio_unicast.pdf │ │ ├── ranging_protocol.png │ │ ├── ranging_protocol.xcf │ │ ├── system.graffle │ │ ├── system.pdf │ │ └── uavcan_gui.png │ │ ├── lsro_titlepage.sty │ │ ├── models │ │ ├── Bandwidth in half duplex nodes.ipynb │ │ ├── Differential 2 beacons.ipynb │ │ ├── EKF C++ validation.ipynb │ │ ├── Gyro integrating model.ipynb │ │ ├── Simple model.ipynb │ │ ├── UWB only.ipynb │ │ ├── ekf.py │ │ ├── simple_model.py │ │ ├── tests │ │ │ ├── __init__.py │ │ │ ├── test_kalman_filter.py │ │ │ ├── test_simple_model.py │ │ │ └── test_trajectory_generator.py │ │ └── trajectories.py │ │ ├── planning.gan │ │ ├── report.bib │ │ ├── report.tex │ │ ├── requirements.txt │ │ └── user_guide.tex ├── oocd.cfg ├── package.yml ├── src │ ├── MadgwickAHRS.c │ ├── MadgwickAHRS.h │ ├── ahrs_thread.c │ ├── ahrs_thread.h │ ├── anchor_position_cache.c │ ├── anchor_position_cache.h │ ├── board.c │ ├── board.h │ ├── bootloader_config.c │ ├── bootloader_config.h │ ├── chconf.h │ ├── cmd.c │ ├── cmd.h │ ├── decadriver │ │ ├── deca_device.c │ │ ├── deca_device_api.h │ │ ├── deca_param_types.h │ │ ├── deca_params_init.c │ │ ├── deca_regs.h │ │ ├── deca_types.h │ │ └── deca_version.h │ ├── decawave_interface.c │ ├── decawave_interface.h │ ├── ekf.hpp │ ├── exti.c │ ├── exti.h │ ├── halconf.h │ ├── imu_thread.c │ ├── imu_thread.h │ ├── log.c │ ├── log.h │ ├── lru_cache.c │ ├── lru_cache.h │ ├── main.c │ ├── main.h │ ├── mcuconf.h │ ├── mpu9250.c │ ├── mpu9250.h │ ├── mpu9250_registers.h │ ├── parameter_port.c │ ├── ranging_thread.c │ ├── ranging_thread.h │ ├── shellconf.h │ ├── state_estimation.cpp │ ├── state_estimation.hpp │ ├── state_estimation_thread.cpp │ ├── state_estimation_thread.h │ ├── timestamp_stm32_settings.h │ ├── trace_points.h │ ├── trace_port.c │ ├── uavcan │ │ ├── data_packet_handler.cpp │ │ ├── data_packet_handler.hpp │ │ ├── parameter_enumeration.cpp │ │ ├── parameter_enumeration.hpp │ │ ├── parameter_server.cpp │ │ ├── parameter_server.hpp │ │ ├── position_handler.cpp │ │ ├── position_handler.hpp │ │ ├── restart_server.cpp │ │ ├── restart_server.hpp │ │ ├── topics_publisher.cpp │ │ ├── topics_publisher.hpp │ │ ├── uavcan_node.cpp │ │ └── uavcan_node.h │ ├── usbconf.c │ ├── usbconf.h │ ├── uwb_protocol.c │ └── uwb_protocol.h ├── tests │ ├── decawave.cpp │ ├── ekf.cpp │ ├── hal.h │ ├── hal_mocks.cpp │ ├── lru_cache.cpp │ ├── madgwick.cpp │ ├── mpu9250.cpp │ ├── parameter_by_index.cpp │ ├── state_estimation.cpp │ └── uwb_protocol.cpp └── tools │ ├── antenna_delay_calibration.py │ ├── ekf_python_bindings.cpp │ ├── read_attitude.py │ └── read_range.py ├── webot_sim ├── Eurobot_2021 │ ├── protos │ │ ├── BaseTable.proto │ │ ├── Buoy.proto │ │ ├── CentralPlatform.proto │ │ ├── Cleats22x22.proto │ │ ├── GameArea.proto │ │ ├── GroundedZone.proto │ │ ├── LeftBeaconSupport.proto │ │ ├── RightBeaconSupport.proto │ │ ├── Robot2021.proto │ │ ├── RockyArea.proto │ │ ├── Table2021.proto │ │ ├── WeatherVane.proto │ │ ├── Windsock.proto │ │ └── textures │ │ │ ├── aruco.png │ │ │ ├── eurobot2020_girouette.png │ │ │ └── vinyl_texture.jpg │ └── worlds │ │ ├── BaseTable.wbt │ │ ├── Eurobot_2021.wbt │ │ ├── Robot_2021.wbt │ │ ├── Table_2021.wbt │ │ └── textures │ │ ├── aruco.png │ │ ├── brushed_aluminium │ │ ├── brushed_aluminium_base_color.jpg │ │ ├── brushed_aluminium_normal.jpg │ │ └── brushed_aluminium_roughness.jpg │ │ ├── eurobot2020_girouette.png │ │ ├── eurobot2021_vinyl_texture.png │ │ ├── parquetry │ │ ├── chequered_parquetry_base_color.jpg │ │ ├── chequered_parquetry_normal.jpg │ │ ├── chequered_parquetry_occlusion.jpg │ │ └── chequered_parquetry_roughness.jpg │ │ └── vinyl_texture.jpg ├── controllers │ └── uavcan_controller │ │ ├── .gitignore │ │ ├── CMakeLists.txt │ │ ├── Makefile │ │ └── uavcan_controller.cpp └── worlds │ ├── .cvra.wbproj │ └── cvra.wbt └── wheel-encoder-firmware ├── .gitignore ├── Makefile ├── Makefile.include.jinja ├── README.md ├── linker ├── STM32F303xC.ld └── STM32F303xC_bootloader.ld ├── openocd.cfg ├── package.yml └── src ├── board ├── board.c └── board.h ├── bootloader_config.c ├── bootloader_config.h ├── chconf.h ├── encoder.c ├── encoder.h ├── halconf.h ├── libstubs.cpp ├── main.c ├── main.h ├── mcuconf.h └── uavcan ├── WheelEncoder_pub.cpp ├── WheelEncoder_pub.hpp ├── uavcan_node.cpp └── uavcan_node.h /.clang-tidy: -------------------------------------------------------------------------------- 1 | --- 2 | Checks: '-*,readability-braces-around-statements,bugprone-macro-parentheses,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-override,modernize-use-nullptr,readability-simplify-boolean-expr,readability-named-parameter,readability-redundant-control-flow,readability-qualified-auto,abseil-*' 3 | WarningsAsErrors: '' 4 | HeaderFilterRegex: '' 5 | FormatStyle: 'file' 6 | CheckOptions: [] 7 | ... 8 | -------------------------------------------------------------------------------- /.github/workflows/build-raspi.yml: -------------------------------------------------------------------------------- 1 | name: Raspberry Pi build 2 | on: [push] 3 | jobs: 4 | build: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | with: 9 | submodules: 'recursive' 10 | - name: Prepare CMake project 11 | uses: docker://antoinealb/cvra-sdk:latest 12 | with: 13 | args: bash -c "cd /github/workspace && mkdir build && cd build && cmake .. -DCMAKE_TOOLCHAIN_FILE=/aarch64-buildroot-linux-gnu_sdk-buildroot/share/buildroot/toolchainfile.cmake" 14 | - name: Prepare Nanopb 15 | uses: docker://antoinealb/cvra-sdk:latest 16 | with: 17 | args: bash -c "cd /github/workspace/lib/nanopb/nanopb/generator/proto && make" 18 | - name: Build 19 | uses: docker://antoinealb/cvra-sdk:latest 20 | with: 21 | args: bash -c "cd /github/workspace/build && make master-firmware.ipk" 22 | -------------------------------------------------------------------------------- /.github/workflows/clang-format.yml: -------------------------------------------------------------------------------- 1 | on: push 2 | name: clang-format Code Formatter 3 | jobs: 4 | lint: 5 | name: clang-format Code Formatter 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Clang Code Formatter 9 | uses: cvra/clang-format-action@master 10 | env: 11 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 12 | -------------------------------------------------------------------------------- /.github/workflows/python-format.yml: -------------------------------------------------------------------------------- 1 | on: push 2 | name: Black Python Code Formatter 3 | jobs: 4 | lint: 5 | name: Black Python Code Formatter 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Black Python Code Formatter 9 | uses: cvra/python-format-action@master 10 | env: 11 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 12 | -------------------------------------------------------------------------------- /.github/workflows/ssh_key_copybara.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCvSLx8vHuSLf9j5dSSWut2YnX0p0rreN+q4vRZkAE9armYZ4HwYVCbBYeJfaqxNdWmBvJmkzh4UuH3r9KlaJL8gt/s32jLyBPciipS+QYho6Pa1hG7ALA2DfvavW6WarT1hVI3jY4bnn4RSxw5iz8472Hb56u/NZQqxZ0CQt2Sp+X1JIr73V8YVjfaE77CaGWw/nte25BjQMwKF+w5MNbv0eK+2EA5KBL8X85TtXjF54IMuFx1Jkz3peChPALst5e5GNC4rXASe4STTn5Rvrhb8pRkyxw/dnUKd3YP5oEDxdIdXL6BnfbtFqCWL715tMx5ODTKX0teWq/9q10wjyKc8nw3mJHgy9TdMBFh9+OBl9pEXRCBL5KsRJlCff19mnWaCgDCFiohGdUlrXc3A2pWsZTS2KBvnzJ+EUwD7X+zbmu68EaEYGIB5L+VlxdyRSo+xyPfPkH1lf7JklmsS3B+gPayLymNgxKeVpf55O4kBeLp7TEHtgSuY1nQA7E6C2Zwd/mDluLWwXvSmoNYWVfRheZKK8WCCsK47jKtjozQ9qXblSpMov+YnVbG+BK9mIrL2Wn+NESo1qs/VIiVp3YI2YWorGpbsFJqTgm6vuO3zDMwkI8dtfJQky1aO1KF/yAAtKoTUK9VVjD/eFGUwYJrSPb+/FUeNz1l2ESl5wvthw== antoinealb@prime-mover 2 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | # Just automatically builds the docker image used for CI purpose. 2 | # The actual build is done by Github actions 3 | image: gcr.io/kaniko-project/executor:debug 4 | 5 | stages: 6 | - package 7 | 8 | build-docker: 9 | stage: package 10 | only: 11 | refs: 12 | - master 13 | image: 14 | name: gcr.io/kaniko-project/executor:debug 15 | entrypoint: [""] 16 | script: 17 | - echo "{\"auths\":{\"https://index.docker.io/v1/\":{\"auth\":\"$CI_HUB_SECRET\"}}}" > /kaniko/.docker/config.json 18 | - /kaniko/executor --context $CI_PROJECT_DIR/output/images --dockerfile $CI_PROJECT_DIR/ci/Dockerfile --destination antoinealb/cvra-ci:latest 19 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ChibiOS"] 2 | path = lib/ChibiOS 3 | url = https://github.com/cvra/ChibiOS 4 | [submodule "uavcan"] 5 | path = lib/uavcan 6 | url = https://github.com/cvra/uavcan.git 7 | [submodule "lib/can-bootloader"] 8 | path = lib/can-bootloader 9 | url = https://github.com/cvra/can-bootloader.git 10 | [submodule "lib/eigen"] 11 | path = lib/eigen 12 | url = https://github.com/cvra/eigen 13 | [submodule "lib/ugfx"] 14 | path = lib/ugfx 15 | url = https://github.com/cvra/ugfx 16 | [submodule "lib/nanopb/nanopb"] 17 | path = lib/nanopb/nanopb 18 | url = https://github.com/nanopb/nanopb 19 | [submodule "lib/abseil"] 20 | path = lib/abseil 21 | url = https://github.com/abseil/abseil-cpp.git 22 | [submodule "lib/box2d"] 23 | path = lib/box2d 24 | url = https://github.com/erincatto/box2d.git 25 | -------------------------------------------------------------------------------- /actuator-firmware/.gdbinit: -------------------------------------------------------------------------------- 1 | file ./build/ch.elf 2 | target remote localhost:3333 3 | -------------------------------------------------------------------------------- /actuator-firmware/.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # ChibiOS build files 32 | .dep/* 33 | build/ 34 | 35 | # Packager build files 36 | app_src.mk 37 | 38 | # Vim swap 39 | *.swp 40 | 41 | CMakeLists.txt 42 | 43 | # uavcan dsdl compiler output 44 | dsdlc_generated/ 45 | tags 46 | .tags* 47 | 48 | # generated config 49 | master-firmware/src/config_msgpack.c 50 | -------------------------------------------------------------------------------- /actuator-firmware/README.md: -------------------------------------------------------------------------------- 1 | # Actuator board firmware 2 | 3 | https://github.com/cvra/actuator-board 4 | 5 | ## Loading via bootloader 6 | 7 | ```bash 8 | make USE_BOOTLOADER=yes 9 | bootloader_flash -b build/ch.bin -a 0x08003800 -c "actuator-board" 1 10 | ``` 11 | -------------------------------------------------------------------------------- /actuator-firmware/app_src.mk.jinja: -------------------------------------------------------------------------------- 1 | {% for dir in include_directories %} 2 | INCDIR += {{ dir }} 3 | {% endfor %} 4 | 5 | {% for file in target.arm + source -%} 6 | {% if file.endswith('.c') %}CSRC += {{ file }} 7 | {% elif file.endswith('.s') %}ASMSRC += {{ file }} 8 | {% elif file.endswith('.cpp') %}CPPSRC += {{ file }} 9 | {% endif %}{% endfor %} 10 | -------------------------------------------------------------------------------- /actuator-firmware/openocd.cfg: -------------------------------------------------------------------------------- 1 | telnet_port 4444 2 | gdb_port 3333 3 | 4 | # ST-Link-V2 5 | source [find interface/stlink-v2.cfg] 6 | 7 | transport select hla_swd 8 | source [find target/stm32f3x.cfg] 9 | -------------------------------------------------------------------------------- /actuator-firmware/package.yml: -------------------------------------------------------------------------------- 1 | dependency-dir: ../lib 2 | 3 | source: 4 | - src/pressure_sensor.c 5 | 6 | depends: 7 | - chibios-syscalls 8 | - cmp 9 | - cmp_mem_access 10 | - error 11 | - crc 12 | - version 13 | - quadramp 14 | - softspi 15 | 16 | target.arm: 17 | - ../lib/can-bootloader/config.c 18 | - src/analog_input.c 19 | - src/board.c 20 | - src/bootloader_config.c 21 | - src/debug.c 22 | - src/main.c 23 | - src/pressure_sensor_interface.c 24 | - src/pump.c 25 | - src/pwm.c 26 | - src/safety.c 27 | - src/servo.c 28 | - src/uavcan/Command_handler.cpp 29 | - src/uavcan/feedback_publisher.cpp 30 | - src/uavcan/node.cpp 31 | 32 | tests: 33 | - tests/pressure_sensor_driver_test.cpp 34 | 35 | templates: 36 | app_src.mk.jinja: app_src.mk 37 | -------------------------------------------------------------------------------- /actuator-firmware/src/analog_input.h: -------------------------------------------------------------------------------- 1 | #ifndef ANALOG_INPUT_H 2 | #define ANALOG_INPUT_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | /** Configures the ADC peripherals */ 9 | void analog_start(void); 10 | 11 | /* Reads the analog inputs, and fills the provided array with the voltage from 12 | * 0 to 6.6 [V]. */ 13 | void analog_input_read(float voltages[2]); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | #endif 19 | -------------------------------------------------------------------------------- /actuator-firmware/src/assert.h: -------------------------------------------------------------------------------- 1 | #ifndef ASSERT_H 2 | #define ASSERT_H 3 | 4 | #include 5 | 6 | #define assert(x) \ 7 | do { \ 8 | if (!(x)) { \ 9 | chSysHalt("assertion failed"); \ 10 | } \ 11 | } while (0) 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /actuator-firmware/src/bootloader_config.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOTLOADER_CONFIG_H 2 | #define BOOTLOADER_CONFIG_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // returns true if config read was successful 13 | bool config_get(bootloader_config_t* cfg); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif /* BOOTLOADER_CONFIG_H */ 20 | -------------------------------------------------------------------------------- /actuator-firmware/src/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUG_H 2 | #define DEBUG_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void debug_msg(const char* fmt, ...); 9 | void debug_init(void); 10 | void print_stack_info(void); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif /* DEBUG_H */ 17 | -------------------------------------------------------------------------------- /actuator-firmware/src/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | extern bootloader_config_t config; 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif /* MAIN_H */ 16 | -------------------------------------------------------------------------------- /actuator-firmware/src/pressure_sensor_interface.h: -------------------------------------------------------------------------------- 1 | #ifndef PRESSURE_SENSOR_INTERFACE_H 2 | #define PRESSURE_SENSOR_INTERFACE_H 3 | 4 | #include "pressure_sensor.h" 5 | 6 | void mpr_start(void); 7 | 8 | extern mpr_driver_t pressure_sensors[2]; 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /actuator-firmware/src/pump.h: -------------------------------------------------------------------------------- 1 | #ifndef PUMPS_H 2 | #define PUMPS_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void pump_init(void); 9 | 10 | void pump_set_pwm(int index, float duty_cycle); 11 | 12 | void pump_set_solenoid(int index, int on); 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | #endif 18 | -------------------------------------------------------------------------------- /actuator-firmware/src/safety.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* After how long without new orders on CAN we should start moving. */ 5 | #define SAFETY_TIMEOUT TIME_MS2I(500) 6 | 7 | static virtual_timer_t safety_timer_timer; 8 | static bool is_allowed_to_move = false; 9 | 10 | static void _safety_timer_cb(void* p) 11 | { 12 | (void)p; 13 | board_power_output_disable(); 14 | is_allowed_to_move = false; 15 | 16 | /* unfortunately we cannot WARNING() from here as this is called from an 17 | * interrupt context. */ 18 | } 19 | 20 | void safety_timer_restart(void) 21 | { 22 | board_power_output_enable(); 23 | is_allowed_to_move = true; 24 | chVTSet(&safety_timer_timer, SAFETY_TIMEOUT, _safety_timer_cb, NULL); 25 | } 26 | 27 | int safety_motion_is_allowed(void) 28 | { 29 | return is_allowed_to_move; 30 | } 31 | -------------------------------------------------------------------------------- /actuator-firmware/src/safety.h: -------------------------------------------------------------------------------- 1 | #ifndef SAFETY_H 2 | #define SAFETY_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | /** Checks if we are allowed to run any of the actuators. 9 | * 10 | * For safety reasons, the board is only allowed to have any actuators on if a 11 | * CAN command has been received recently (see safety.c for the precise timeout 12 | * duration). Otherwise we assume that we are disconnected from the master 13 | * board and refuse to move 14 | */ 15 | int safety_motion_is_allowed(void); 16 | 17 | /** Restarts the safety timer, typically called when receiving a CAN order. */ 18 | void safety_timer_restart(void); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /actuator-firmware/src/servo.h: -------------------------------------------------------------------------------- 1 | #ifndef SERVO_H 2 | #define SERVO_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #define SERVO_COUNT 2 9 | 10 | void servo_start(void); 11 | 12 | /** Sets the i-th servo motor setpoint, as well as its trajectory parameters. 13 | * 14 | * The position is unitless and varies between 0 and 1. The velocity have a 15 | * unit of per second, and acceleration per second squared. 16 | */ 17 | void servo_set(int index, float pos, float vel, float acc); 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif /* SERVO_H */ 24 | -------------------------------------------------------------------------------- /actuator-firmware/src/uavcan/Command_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef COMMAND_HANDLER_HPP 2 | #define COMMAND_HANDLER_HPP 3 | 4 | #include 5 | 6 | int Command_handler_start(uavcan::INode& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /actuator-firmware/src/uavcan/feedback_publisher.h: -------------------------------------------------------------------------------- 1 | #ifndef FEEDBACK_PUBLISHER_H 2 | #define FEEDBACK_PUBLISHER_H 3 | 4 | #include 5 | 6 | bool feedback_publish(uavcan::INode& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /actuator-firmware/src/uavcan/node.h: -------------------------------------------------------------------------------- 1 | #ifndef UAVCAN_NODE_H 2 | #define UAVCAN_NODE_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void uavcan_start(unsigned int node_id, const char* node_name); 9 | 10 | void uavcan_set_node_is_ok(int ok); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /can-io-firmware/.gdbinit: -------------------------------------------------------------------------------- 1 | file ./build/ch.elf 2 | target remote localhost:3333 3 | -------------------------------------------------------------------------------- /can-io-firmware/.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # ChibiOS build files 32 | .dep/* 33 | build/ 34 | 35 | # Packager build files 36 | app_src.mk 37 | 38 | # Vim swap 39 | *.swp 40 | 41 | CMakeLists.txt 42 | 43 | # uavcan dsdl compiler output 44 | dsdlc_generated/ 45 | tags 46 | .tags* 47 | 48 | # generated config 49 | master-firmware/src/config_msgpack.c 50 | -------------------------------------------------------------------------------- /can-io-firmware/README.md: -------------------------------------------------------------------------------- 1 | # CAN IO firmware 2 | 3 | ## Loading via bootloader 4 | 5 | ```bash 6 | make USE_BOOTLOADER=yes 7 | bootloader_flash -b build/ch.bin -a 0x08003800 -c "can-io-board" 1 8 | ``` 9 | -------------------------------------------------------------------------------- /can-io-firmware/app_src.mk.jinja: -------------------------------------------------------------------------------- 1 | {% for dir in include_directories %} 2 | INCDIR += {{ dir }} 3 | {% endfor %} 4 | 5 | {% for file in target.arm + source -%} 6 | {% if file.endswith('.c') %}CSRC += {{ file }} 7 | {% elif file.endswith('.s') %}ASMSRC += {{ file }} 8 | {% elif file.endswith('.cpp') %}CPPSRC += {{ file }} 9 | {% endif %}{% endfor %} 10 | -------------------------------------------------------------------------------- /can-io-firmware/openocd.cfg: -------------------------------------------------------------------------------- 1 | telnet_port 4444 2 | gdb_port 3333 3 | 4 | # ST-Link-V2 5 | source [find interface/stlink-v2.cfg] 6 | 7 | transport select hla_swd 8 | source [find target/stm32f3x.cfg] 9 | -------------------------------------------------------------------------------- /can-io-firmware/package.yml: -------------------------------------------------------------------------------- 1 | dependency-dir: ../lib 2 | 3 | depends: 4 | - chibios-syscalls 5 | - cmp 6 | - cmp_mem_access 7 | - error 8 | - crc 9 | - version 10 | - quadramp 11 | 12 | target.arm: 13 | - src/main.c 14 | - src/debug.c 15 | - src/board.c 16 | - src/uavcan/node.cpp 17 | - src/uavcan/ServoPWM_handler.cpp 18 | - src/uavcan/DigitalInput_pub.cpp 19 | - src/bootloader_config.c 20 | - src/pwm.c 21 | - src/servo.c 22 | - ../lib/can-bootloader/config.c 23 | 24 | templates: 25 | app_src.mk.jinja: app_src.mk 26 | -------------------------------------------------------------------------------- /can-io-firmware/src/assert.h: -------------------------------------------------------------------------------- 1 | #ifndef ASSERT_H 2 | #define ASSERT_H 3 | 4 | #include 5 | 6 | #define assert(x) \ 7 | do { \ 8 | if (!(x)) { \ 9 | chSysHalt("assertion failed"); \ 10 | } \ 11 | } while (0) 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /can-io-firmware/src/bootloader_config.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOTLOADER_CONFIG_H 2 | #define BOOTLOADER_CONFIG_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // returns true if config read was successful 13 | bool config_get(bootloader_config_t* cfg); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif /* BOOTLOADER_CONFIG_H */ 20 | -------------------------------------------------------------------------------- /can-io-firmware/src/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUG_H 2 | #define DEBUG_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void debug_msg(const char* fmt, ...); 9 | void debug_init(void); 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif /* DEBUG_H */ 16 | -------------------------------------------------------------------------------- /can-io-firmware/src/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | extern bootloader_config_t config; 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif /* MAIN_H */ 16 | -------------------------------------------------------------------------------- /can-io-firmware/src/pwm.h: -------------------------------------------------------------------------------- 1 | #ifndef PWM_H 2 | #define PWM_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | 11 | enum pwm_channel { 12 | PWM_CHANNEL_0, // Timer 16 channel 0 13 | PWM_CHANNEL_1, // Timer 17 channel 0 14 | PWM_CHANNEL_2, // Timer 1 channel 1 15 | PWM_CHANNEL_3, // Timer 1 channel 2 16 | }; 17 | 18 | void pwm_init(uint32_t frequency, uint32_t period); 19 | 20 | /* Set given pulse width in clock ticks to the corresponding PWM channel */ 21 | void pwm_set_pulsewidth(enum pwm_channel channel, uint32_t pulsewidth); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | 27 | #endif /* PWM_H */ 28 | -------------------------------------------------------------------------------- /can-io-firmware/src/servo.h: -------------------------------------------------------------------------------- 1 | #ifndef SERVO_H 2 | #define SERVO_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void servo_init(void); 9 | void servo_start(void); 10 | void servo_set(const float pos[4], const float vel[4], const float acc[4]); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif /* SERVO_H */ 17 | -------------------------------------------------------------------------------- /can-io-firmware/src/uavcan/DigitalInput_pub.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DIGITALINPUT_PUB_HPP 2 | #define DIGITALINPUT_PUB_HPP 3 | 4 | #include 5 | 6 | void digital_input_publish(uavcan::INode& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /can-io-firmware/src/uavcan/ServoPWM_handler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ServoPWM_handler.hpp" 3 | #include "servo.h" 4 | #include "main.h" 5 | 6 | void ServoPWM_handler(const uavcan::ReceivedDataStructure& msg) 7 | { 8 | float pos[4]; 9 | float vel[4]; 10 | float acc[4]; 11 | 12 | if (msg.node_id != config.ID) { 13 | DEBUG("PWM message not addressed to us, dropping it."); 14 | return; 15 | } 16 | 17 | for (int i = 0; i < 4; i++) { 18 | pos[i] = msg.servo_pos[i]; 19 | vel[i] = msg.servo_vel[i]; 20 | acc[i] = msg.servo_acc[i]; 21 | } 22 | 23 | NOTICE("Changing the PWM values: %.2f %.2f %.2f %.2f", pos[0], pos[1], pos[2], pos[3]); 24 | servo_set(pos, vel, acc); 25 | } 26 | -------------------------------------------------------------------------------- /can-io-firmware/src/uavcan/ServoPWM_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PWM_SERVER_H 2 | #define PWM_SERVER_H 3 | 4 | #include 5 | #include 6 | 7 | void ServoPWM_handler(const uavcan::ReceivedDataStructure&); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /can-io-firmware/src/uavcan/node.h: -------------------------------------------------------------------------------- 1 | #ifndef UAVCAN_NODE_H 2 | #define UAVCAN_NODE_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void uavcan_start(unsigned int node_id, const char* node_name); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /ci/Dockerfile: -------------------------------------------------------------------------------- 1 | # Intended to build the antoinealb/cvra-ci docker image used for CI purpose. 2 | # Automatically built from antoinealb's gitlab instance, see .gitlab-ci.yml 3 | FROM ubuntu:18.04 4 | 5 | RUN apt-get update && apt-get install -y \ 6 | git \ 7 | make \ 8 | python3 \ 9 | python3-pip \ 10 | python3-dev \ 11 | wget 12 | 13 | RUN wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/8-2018q4/gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2 -O arm-gcc-linux.tar.bz2 && \ 14 | tar -xf arm-gcc-linux.tar.bz2 15 | 16 | RUN pip3 install cvra-packager~=1.0.0 \ 17 | PyYAML==3.11 \ 18 | msgpack-python~=0.5.6 19 | 20 | ENV PATH="/gcc-arm-none-eabi-8-2018-q4-major/bin:${PATH}" 21 | -------------------------------------------------------------------------------- /cmake/FindChibiOS.cmake: -------------------------------------------------------------------------------- 1 | MESSAGE(STATUS "Chibios version:" ${ChibiOS_FIND_VERSION_MAJOR}) 2 | 3 | INCLUDE(ChibiOS/18.2/ChibiOS) 4 | 5 | LIST(REMOVE_DUPLICATES ChibiOS_INCLUDE_DIRS) 6 | LIST(REMOVE_DUPLICATES ChibiOS_SOURCES) 7 | 8 | INCLUDE(FindPackageHandleStandardArgs) 9 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(ChibiOS DEFAULT_MSG ChibiOS_SOURCES ChibiOS_INCLUDE_DIRS) 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/architecture/archi2020.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/docs/architecture/archi2020.graffle -------------------------------------------------------------------------------- /docs/architecture/hardware2020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/docs/architecture/hardware2020.png -------------------------------------------------------------------------------- /docs/architecture/life-of-a-motion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/docs/architecture/life-of-a-motion.png -------------------------------------------------------------------------------- /docs/can/images/beacon-board.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/docs/can/images/beacon-board.jpg -------------------------------------------------------------------------------- /docs/can/images/bootloader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/docs/can/images/bootloader.png -------------------------------------------------------------------------------- /docs/can/images/can-adapter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/docs/can/images/can-adapter.jpg -------------------------------------------------------------------------------- /docs/can/images/io-board.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/docs/can/images/io-board.jpg -------------------------------------------------------------------------------- /docs/can/images/motor-board.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/docs/can/images/motor-board.jpg -------------------------------------------------------------------------------- /docs/can/images/positioning_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/docs/can/images/positioning_diagram.png -------------------------------------------------------------------------------- /docs/can/images/sensor-board-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/docs/can/images/sensor-board-1.jpg -------------------------------------------------------------------------------- /docs/can/images/sensor-board.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/docs/can/images/sensor-board.jpg -------------------------------------------------------------------------------- /docs/howto/odometry-wheel-difference-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/docs/howto/odometry-wheel-difference-error.png -------------------------------------------------------------------------------- /docs/howto/odometry-wheel-difference-trajectory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/docs/howto/odometry-wheel-difference-trajectory.png -------------------------------------------------------------------------------- /docs/ytvideo.css: -------------------------------------------------------------------------------- 1 | /** Class to center youtube videos. */ 2 | .ytvideo { 3 | position: relative; 4 | padding-bottom: 56.25%; 5 | padding-top: 35px; 6 | height: 0; 7 | overflow: hidden; 8 | vertical-align: middle; 9 | text-align: center; 10 | margin-bottom: 3em; 11 | } 12 | 13 | /* http://www.smashingmagazine.com/2014/02/making-embedded-content-work-in-responsive-design/ */ 14 | .ytvideo iframe { 15 | position: absolute; 16 | top:0; 17 | left: 0; 18 | width: 100%; 19 | height: 100%; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /embedded-computer/README.md: -------------------------------------------------------------------------------- 1 | # Setup for the embedded Linux platforms 2 | 3 | ## nuc_setup 4 | 5 | This folder contains basic SaltStack code for running Ubuntu 18.04 on an intel NUC. 6 | Basic features: 7 | 8 | * Basic toolchains 9 | * ROS 10 | * Creates a Wifi hotspot for config / debug (not complete yet) 11 | * Basic fixes like grub not surviving a power reset 12 | 13 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.configure("2") do |config| 5 | config.vm.box = "ubuntu/bionic64" 6 | config.vm.synced_folder "salt/roots/", "/srv/salt/" 7 | 8 | config.vm.provider "virtualbox" do |v| 9 | v.memory = 4096 10 | v.cpus = 2 11 | end 12 | config.vm.provision :salt do |salt| 13 | salt.run_highstate = true 14 | salt.verbose = false 15 | salt.install_master = false 16 | salt.bootstrap_options = '-F -c /tmp/ -P' 17 | salt.colorize = true 18 | salt.minion_config = "salt/minion" 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/minion: -------------------------------------------------------------------------------- 1 | file_client: local 2 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/can/slcan.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=SLCAN interface on robot 3 | After=multi-user.target 4 | 5 | [Service] 6 | Type=forking 7 | ExecStart=/usr/local/bin/uavcan_add_slcan -r -s8 /dev/serial/by-id/usb-CVRA_CVRA_CAN2USB_303-if00 8 | 9 | [Install] 10 | WantedBy=multi-user.target 11 | 12 | # vim: set ft=systemd: 13 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/core/init.sls: -------------------------------------------------------------------------------- 1 | vim: 2 | pkgrepo.managed: 3 | - ppa: jonathonf/vim 4 | pkg.installed: [] 5 | 6 | git: 7 | pkgrepo.managed: 8 | - ppa: git-core/ppa 9 | pkg.latest: 10 | - refresh: True 11 | 12 | # Friendly Interactive SHell 13 | fish: 14 | pkgrepo.managed: 15 | - ppa: fish-shell/release-2 16 | pkg.latest: 17 | - refresh: True 18 | 19 | mosh: 20 | pkg.installed 21 | 22 | tmux: 23 | pkg.installed 24 | 25 | silversearcher-ag: 26 | pkg.installed 27 | 28 | build-essential: 29 | pkg.installed 30 | 31 | openssh-server: 32 | pkg.installed 33 | 34 | /etc/sudoers.d/passwordless_sudo: 35 | file.managed: 36 | - source: salt://core/passwordless_sudo 37 | - user: root 38 | - group: root 39 | - mode: 440 40 | 41 | /etc/update-manager/release-upgrades: 42 | file.managed: 43 | - source: salt://core/release-upgrades 44 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/core/passwordless_sudo: -------------------------------------------------------------------------------- 1 | # Allow members of group sudo to execute any command 2 | %sudo ALL=NOPASSWD:ALL 3 | 4 | # Allow gitlab shell runner to run salt highstate 5 | gitlab-runner ALL=(ALL) NOPASSWD: /usr/bin/salt-call 6 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/core/release-upgrades: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | Prompt=never 3 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/dev/python.sls: -------------------------------------------------------------------------------- 1 | python-pip: 2 | pkg.installed 3 | 4 | python3-pip: 5 | pkg.installed 6 | 7 | {% for pkg in [ 8 | "pyyaml", 9 | "jinja2", 10 | "progressbar2", 11 | "pyserial", 12 | "msgpack-python", 13 | "numpy", 14 | "scipy", 15 | "scikit-learn", 16 | ]%} 17 | {{ pkg }}-python3: 18 | pip.installed: 19 | - name: {{ pkg }} 20 | - bin_env: /usr/bin/pip3 21 | - require: 22 | - pkg: python3-pip 23 | {% endfor %} 24 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/dev/realsense.sls: -------------------------------------------------------------------------------- 1 | realsense-repo: 2 | pkgrepo.managed: 3 | - humanname: Intel Realsense repository 4 | - name: deb http://realsense-hw-public.s3.amazonaws.com/Debian/apt-repo bionic main 5 | - dist: bionic 6 | - keyid: C8B3A55A6F3EFCDE 7 | - keyserver: keyserver.ubuntu.com 8 | - require_in: 9 | - pkg: librealsense2-dkms 10 | - pkg: librealsense2-dev 11 | - pkg: librealsense2-udev-rules 12 | 13 | librealsense2-dkms: 14 | pkg.installed 15 | 16 | librealsense2-dev: 17 | pkg.installed 18 | 19 | librealsense2-udev-rules: 20 | pkg.installed 21 | 22 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/grub/default: -------------------------------------------------------------------------------- 1 | # For full documentation of the options in this file, see: 2 | # info -f grub -n 'Simple configuration' 3 | 4 | GRUB_DEFAULT=0 5 | GRUB_HIDDEN_TIMEOUT=0 6 | GRUB_HIDDEN_TIMEOUT_QUIET=true 7 | GRUB_TIMEOUT=1 8 | 9 | # Prevents GRUB from hanging after power loss 10 | GRUB_RECORDFAIL_TIMEOUT=1 11 | GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` 12 | GRUB_CMDLINE_LINUX_DEFAULT="" 13 | GRUB_CMDLINE_LINUX="" 14 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/grub/init.sls: -------------------------------------------------------------------------------- 1 | /etc/default/grub: 2 | file.managed: 3 | - mode: 644 4 | - source: salt://grub/default 5 | - user: root 6 | - group: root 7 | cmd.wait: 8 | - name: update-grub 9 | - watch: 10 | - file: /etc/default/grub 11 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/http/init.sls: -------------------------------------------------------------------------------- 1 | nginx: 2 | pkg.installed: [] 3 | service.running: 4 | - watch: 5 | - file: /etc/nginx/sites-available/default 6 | 7 | /etc/nginx/sites-available/default: 8 | file.managed: 9 | - source: salt://http/server.conf 10 | 11 | /var/www/html/index.html: 12 | file.symlink: 13 | - target: /home/cvra/robot-software/minesweepers/live_map.html 14 | 15 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/http/server.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80 default_server; 3 | listen [::]:80 default_server; 4 | 5 | root /var/www/html; 6 | 7 | index index.html index.htm index.nginx-debian.html; 8 | 9 | server_name _; 10 | 11 | location / { 12 | # First attempt to serve request as file, then 13 | # as directory, then fall back to displaying a 404. 14 | try_files $uri $uri/ =404; 15 | } 16 | } 17 | # vim: set ft=nginx: 18 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/sound.sls: -------------------------------------------------------------------------------- 1 | libasound2: 2 | pkg.installed 3 | 4 | libasound2-plugins: 5 | pkg.installed 6 | 7 | alsa-utils: 8 | pkg.installed 9 | 10 | alsa-oss: 11 | pkg.installed 12 | 13 | pulseaudio: 14 | pkg.installed 15 | 16 | mplayer: 17 | pkg.installed 18 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/top.sls: -------------------------------------------------------------------------------- 1 | base: 2 | '*': 3 | - core 4 | - users.cvra 5 | - dev.ros 6 | - dev.python 7 | - can 8 | - dev.realsense 9 | - sound 10 | - http 11 | 12 | 'virtual:physical': 13 | - match: grain 14 | - grub 15 | - wifi 16 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/users/cvra.sls: -------------------------------------------------------------------------------- 1 | cvra: 2 | user.present: 3 | - fullname: CVRA 4 | - shell: /bin/bash 5 | - home: /home/cvra 6 | - groups: 7 | - sudo 8 | - dialout 9 | - plugdev 10 | - audio 11 | 12 | ssh_auth.present: 13 | - name: github 14 | - user: cvra 15 | - source: salt://users/cvra.keys 16 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/wifi/hostapd.conf: -------------------------------------------------------------------------------- 1 | interface=wlp2s0 2 | driver=nl80211 3 | 4 | # Radio 5 | ssid=CVRA-Rover 6 | hw_mode=g 7 | channel=11 8 | 9 | # 802.11n 10 | wmm_enabled=1 11 | ieee80211n=1 12 | ht_capab=[HT40-][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40][DSSS_CCK-40][DSSS_CCK-40] 13 | 14 | # WPA 15 | auth_algs=1 16 | wpa=2 17 | wpa_passphrase=cvracvra 18 | wpa_key_mgmt=WPA-PSK 19 | wpa_pairwise=TKIP 20 | rsn_pairwise=CCMP 21 | -------------------------------------------------------------------------------- /embedded-computer/nuc_setup/salt/roots/wifi/wlan_config.yaml: -------------------------------------------------------------------------------- 1 | # This file describes the network interfaces available on your system 2 | # For more information, see netplan(5). 3 | network: 4 | version: 2 5 | renderer: networkd 6 | ethernets: 7 | wlp2s0: 8 | dhcp4: no 9 | dhcp6: no 10 | addresses: [10.0.0.1/24] 11 | -------------------------------------------------------------------------------- /hitl/.gitignore: -------------------------------------------------------------------------------- 1 | !CMakeLists.txt 2 | -------------------------------------------------------------------------------- /hitl/OpponentRobot.cpp: -------------------------------------------------------------------------------- 1 | #include "OpponentRobot.h" 2 | 3 | OpponentRobot::OpponentRobot(b2World& world, b2Vec2 initial_pos) 4 | { 5 | b2BodyDef robotDef; 6 | robotDef.type = b2_staticBody; 7 | 8 | robotDef.position = initial_pos; 9 | robotDef.angle = 0.f; 10 | 11 | robotBody = world.CreateBody(&robotDef); 12 | b2CircleShape shape; 13 | shape.m_radius = OpponentRobot::radius; 14 | 15 | robotBody->CreateFixture(&shape, 1.f); 16 | } 17 | -------------------------------------------------------------------------------- /hitl/OpponentRobot.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | class OpponentRobot { 7 | b2Body* robotBody; 8 | 9 | public: 10 | // The current rules allow a max perimeter of 1300 mm, use it to compute the 11 | // radius of the opponent. 12 | static constexpr float radius = 1.3f / (2.f * M_PI); 13 | 14 | OpponentRobot(b2World& world, b2Vec2 initial_pos); 15 | 16 | b2Vec2 GetPosition() const 17 | { 18 | return robotBody->GetPosition(); 19 | } 20 | 21 | void SetPosition(b2Vec2 pos) 22 | { 23 | robotBody->SetTransform(pos, 0.f); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /hitl/PhysicsCup.cpp: -------------------------------------------------------------------------------- 1 | #include "PhysicsCup.h" 2 | 3 | PhysicsCup::PhysicsCup(b2World& world, b2Vec2 pos) 4 | { 5 | b2BodyDef def; 6 | def.type = b2_dynamicBody; 7 | 8 | def.position = pos; 9 | 10 | body = world.CreateBody(&def); 11 | 12 | b2CircleShape shape; 13 | shape.m_radius = PhysicsCup::radius; 14 | 15 | const float mass = 0.1; 16 | const float density = mass / (3.14 * PhysicsCup::radius * PhysicsCup::radius); 17 | 18 | body->CreateFixture(&shape, density); 19 | body->SetLinearDamping(100); 20 | } 21 | -------------------------------------------------------------------------------- /hitl/PhysicsCup.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class PhysicsCup { 6 | protected: 7 | b2Body* body; 8 | 9 | public: 10 | static constexpr float radius = 0.036; 11 | PhysicsCup(b2World& world, b2Vec2 pos); 12 | b2Vec2 GetPosition() { return body->GetWorldCenter(); } 13 | }; 14 | -------------------------------------------------------------------------------- /hitl/PhysicsRobot.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class PhysicsRobot { 6 | protected: 7 | float size_y; 8 | float pulse_per_mm; 9 | float pos_left, pos_right; 10 | b2Body* robotBody; 11 | 12 | public: 13 | PhysicsRobot(b2World& world, float size_x, float size_y, float mass, float pulse_per_mm, b2Vec2 initial_pos, float heading); 14 | void ApplyWheelbaseForces(float left, float right); 15 | void AccumulateWheelEncoders(float dt); 16 | void GetWheelEncoders(int& left, int& right) const; 17 | 18 | b2Vec2 GetPosition() const 19 | { 20 | return robotBody->GetPosition(); 21 | } 22 | 23 | b2Vec2 GetLinearVelocity() const 24 | { 25 | return robotBody->GetLinearVelocity(); 26 | } 27 | 28 | float GetAngle() const 29 | { 30 | return robotBody->GetAngle(); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /hitl/README.md: -------------------------------------------------------------------------------- 1 | # Hardware in the loop 2 | 3 | # Requirements 4 | 5 | * SocketCAN for the parts that emulate a board. 6 | That means those binaries can only be used on Linux. 7 | * gRPC for inter process communication. 8 | This was testing with version 1.24.1. 9 | See [the quick start guide](https://grpc.io/docs/quickstart/cpp/) for explanations. 10 | * Protoc version 3 or more. 11 | 12 | ## Building 13 | 14 | From the root of the project (robot-software), **NOT** from this directory, run the following: 15 | 16 | ``` 17 | mkdir build 18 | cd build 19 | cmake .. 20 | make 21 | ``` 22 | 23 | ## Adding a virtual SocketCAN interface 24 | 25 | ```bash 26 | lib/uavcan/libuavcan_drivers/linux/scripts/uavcan_add_vcan vcan0 27 | 28 | # check its existence 29 | ip link show dev vcan0 30 | 31 | # to delete it 32 | ip link delete vcan0 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /hitl/logging.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void logging_init(); 4 | -------------------------------------------------------------------------------- /hitl/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | void opponent_set_position(float x, float y); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /hitl/png_loader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Loads an OpenGL texture from the given path, and returns its OpenGL texture ID 4 | int texture_load(const char* file, int* width, int* height); 5 | -------------------------------------------------------------------------------- /hitl/table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/hitl/table.png -------------------------------------------------------------------------------- /hitl/uavcan_node.h: -------------------------------------------------------------------------------- 1 | #ifndef UAVCAN_NODE_H 2 | #define UAVCAN_NODE_H 3 | 4 | #include 5 | 6 | constexpr unsigned NodeMemoryPoolSize = 16384; 7 | 8 | typedef uavcan::Node Node; 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /lib/.gitignore: -------------------------------------------------------------------------------- 1 | !CMakeLists.txt 2 | -------------------------------------------------------------------------------- /lib/arm-cortex-tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if (${CMAKE_CROSSCOMPILING}) 2 | add_library(arm_cortex_tools 3 | mpu.c 4 | fault.c 5 | fault_v7m.s 6 | ) 7 | 8 | target_include_directories(arm_cortex_tools 9 | PUBLIC include 10 | ) 11 | 12 | target_link_libraries(arm_cortex_tools chibios) 13 | endif() 14 | -------------------------------------------------------------------------------- /lib/arm-cortex-tools/fault_v6m.s: -------------------------------------------------------------------------------- 1 | .syntax unified 2 | .cpu cortex-m0 3 | .fpu softvfp 4 | .thumb 5 | .text 6 | 7 | .thumb_func 8 | .globl HardFault_Handler 9 | HardFault_Handler: 10 | mrs r1, msp 11 | mrs r2, psp 12 | 13 | // save registers on stack 14 | push {r4-r7, lr} 15 | mov r4, r8 16 | mov r5, r9 17 | mov r6, r10 18 | mov r7, r11 19 | push {r4-r7} 20 | 21 | mrs r0, msp 22 | bl fault_handler 23 | // never return 24 | -------------------------------------------------------------------------------- /lib/arm-cortex-tools/include/arm-cortex-tools/fault.h: -------------------------------------------------------------------------------- 1 | #ifndef FAULT_H 2 | #define FAULT_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void fault_init(void); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif /* FAULT_H */ 15 | -------------------------------------------------------------------------------- /lib/arm-cortex-tools/package.yml: -------------------------------------------------------------------------------- 1 | target.arm: 2 | - mpu.c 3 | - fault.c 4 | - fault_v7m.s 5 | -------------------------------------------------------------------------------- /lib/aversive/control_system_manager/general_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/lib/aversive/control_system_manager/general_architecture.png -------------------------------------------------------------------------------- /lib/aversive/control_system_manager/implementation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/lib/aversive/control_system_manager/implementation.png -------------------------------------------------------------------------------- /lib/aversive/math/geometry/discrete_circles.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | bool discretize_circle(poly_t* poly, circle_t circle, int samples, float angle_offset) 6 | { 7 | if (samples != poly->l) { 8 | return false; // Number of samples doesn't match size of polygon 9 | } 10 | 11 | float angle_increment = 2.f * M_PI / (float)samples; 12 | 13 | for (int i = 0; i < samples; i++) { 14 | float angle = i * angle_increment + angle_offset; 15 | poly->pts[i].x = circle.x + circle.r * cosf(angle); 16 | poly->pts[i].y = circle.y + circle.r * sinf(angle); 17 | } 18 | 19 | return true; 20 | } 21 | -------------------------------------------------------------------------------- /lib/aversive/obstacle_avoidance/benchmark/.gitignore: -------------------------------------------------------------------------------- 1 | benchmark 2 | -------------------------------------------------------------------------------- /lib/aversive/obstacle_avoidance/benchmark/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | CC=clang++ 3 | CFLAGS=-I../../../../lib 4 | 5 | cd $(dirname $0) 6 | 7 | $CC $CFLAGS -o benchmark -lbenchmark -O3 \ 8 | main.cpp \ 9 | ../../math/geometry/polygon.c \ 10 | ../../math/geometry/lines.c \ 11 | ../../math/geometry/vect_base.c \ 12 | ../obstacle_avoidance.c 13 | -------------------------------------------------------------------------------- /lib/aversive/robot_system/mixing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/lib/aversive/robot_system/mixing.png -------------------------------------------------------------------------------- /lib/chibios-syscalls/.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Debug files 32 | *.dSYM/ 33 | -------------------------------------------------------------------------------- /lib/chibios-syscalls/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if (CMAKE_CROSSCOMPILING) 2 | add_library(chibios-syscalls 3 | malloc_lock.c 4 | newlib_syscalls.c 5 | cpp_stubs.cpp 6 | dynamic_alloc_stubs.cpp 7 | stdio_lock.c 8 | ) 9 | 10 | target_include_directories(chibios-syscalls PUBLIC include) 11 | 12 | target_link_libraries(chibios-syscalls chibios) 13 | endif() 14 | -------------------------------------------------------------------------------- /lib/chibios-syscalls/README.md: -------------------------------------------------------------------------------- 1 | # chibios-syscalls 2 | Better syscalls implementations for ChibiOS 3 | 4 | ## Usage 5 | 6 | Nothing particular is needed: just add this package to your dependencies and it should automatically work. 7 | If you want to use stdout, for example for `printf (3)`, you should define `STDOUT_SD` to the stream you want to use. 8 | Same goes for stdin, using `STDIN_SD`. 9 | 10 | One way to do it is to put the following in your `board.h`: 11 | ```cpp 12 | #define STDOUT_SD SDU1 13 | #define STDIN_SD SDU1 14 | ``` 15 | 16 | You could also do it in your Makefile by adding the following line: 17 | 18 | ``` 19 | UDEFS = -DSTDOUT_SD=SDU1 -DSTDIN_SD=SDU1 20 | ``` 21 | -------------------------------------------------------------------------------- /lib/chibios-syscalls/dynamic_alloc_stubs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #ifndef CVRA_NO_DYNAMIC_ALLOCATION 8 | #define CVRA_NO_DYNAMIC_ALLOCATION 0 9 | #endif 10 | 11 | #if CVRA_NO_DYNAMIC_ALLOCATION 12 | void* operator new(size_t) 13 | { 14 | osalSysHalt("operator new"); 15 | return reinterpret_cast(0xFFFFFFFF); 16 | } 17 | 18 | void* operator new[](size_t) 19 | { 20 | osalSysHalt("operator new[]"); 21 | return reinterpret_cast(0xFFFFFFFF); 22 | } 23 | 24 | void operator delete(void*) 25 | { 26 | osalSysHalt("operator delete"); 27 | } 28 | 29 | void operator delete[](void*) 30 | { 31 | osalSysHalt("operator delete[]"); 32 | } 33 | #endif /* CVRA_NO_DYNAMIC_ALLOCATION */ 34 | -------------------------------------------------------------------------------- /lib/chibios-syscalls/include/chibios-syscalls/stdio_lock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | void stdio_lock(void); 8 | void stdio_unlock(void); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | -------------------------------------------------------------------------------- /lib/chibios-syscalls/malloc_lock.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | static MUTEX_DECL(lock); 7 | 8 | #if !CH_CFG_USE_MUTEXES_RECURSIVE 9 | #error "Malloc lock must be recursive, please enable CH_CFG_USE_MUTEXES_RECURSIVE" 10 | #endif 11 | 12 | void __malloc_lock(struct _reent* reent) 13 | { 14 | (void)reent; 15 | chMtxLock(&lock); 16 | } 17 | 18 | void __malloc_unlock(struct _reent* reent) 19 | { 20 | (void)reent; 21 | chMtxUnlock(&lock); 22 | } 23 | -------------------------------------------------------------------------------- /lib/chibios-syscalls/package.yml: -------------------------------------------------------------------------------- 1 | target.arm: 2 | - malloc_lock.c 3 | - newlib_syscalls.c 4 | - cpp_stubs.cpp 5 | - dynamic_alloc_stubs.cpp 6 | - stdio_lock.c 7 | 8 | include_directories: [include] 9 | -------------------------------------------------------------------------------- /lib/chibios-syscalls/stdio_lock.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | static MUTEX_DECL(lock); 7 | 8 | #if !CH_CFG_USE_MUTEXES_RECURSIVE 9 | #error "stdio lock must be recursive, please enable CH_CFG_USE_MUTEXES_RECURSIVE" 10 | #endif 11 | 12 | void stdio_lock(void) 13 | { 14 | chMtxLock(&lock); 15 | } 16 | 17 | void stdio_unlock(void) 18 | { 19 | chMtxUnlock(&lock); 20 | } 21 | -------------------------------------------------------------------------------- /lib/cmp/.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Libraries 8 | *.lib 9 | *.a 10 | 11 | # Shared objects (inc. Windows DLLs) 12 | *.dll 13 | *.so 14 | *.so.* 15 | *.dylib 16 | 17 | # Executables 18 | *.exe 19 | *.out 20 | *.app 21 | *.i*86 22 | *.x86_64 23 | *.hex 24 | 25 | # Vim swap files 26 | *.swp 27 | *.swo 28 | 29 | # Testing executable 30 | test/test-cmp 31 | 32 | -------------------------------------------------------------------------------- /lib/cmp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(cmp 2 | cmp.c 3 | 4 | ) 5 | 6 | target_include_directories(cmp PUBLIC include) 7 | 8 | cvra_add_test(TARGET cmp_test SOURCES 9 | test/buf.c 10 | test/utils.c 11 | test/test.c 12 | DEPENDENCIES 13 | cmp 14 | ) 15 | -------------------------------------------------------------------------------- /lib/cmp/TODO.md: -------------------------------------------------------------------------------- 1 | - Prevent users from using extended types < 0 (reserved by MessagePack) 2 | -------------------------------------------------------------------------------- /lib/cmp/VERSION.md: -------------------------------------------------------------------------------- 1 | Why CMP uses a single-number versioning system 2 | ============================================== 3 | 4 | There are lots of versioning systems, one example uses the three-number system 5 | -- like Python -- to give users some information just by looking at the 6 | version, X.X.X. Changing the 3rd number means something was fixed, changing 7 | the 2nd number means something was added, changing the 1st number means 8 | something was broken. 9 | 10 | I'm not confident in saying that version X.N.N is compatible in every way with 11 | version X.M.M. Every release of CMP is a major-version release and should be 12 | treated as such. On the bright side, at least you'll never see something like 13 | CMP v2.576.30 (what?) 14 | 15 | -------------------------------------------------------------------------------- /lib/cmp/examples/build_examples.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | CC=clang 4 | CFLAGS="--std=c89 -Werror -Wall -Wextra" 5 | CFLAGS="$CFLAGS -funsigned-char" 6 | CFLAGS="$CFLAGS -fwrapv" 7 | CFLAGS="$CFLAGS -Wmissing-format-attribute" 8 | CFLAGS="$CFLAGS -Wpointer-arith" 9 | CFLAGS="$CFLAGS -Wformat-nonliteral" 10 | CFLAGS="$CFLAGS -Winit-self" 11 | CFLAGS="$CFLAGS -Wwrite-strings" 12 | CFLAGS="$CFLAGS -Wshadow" 13 | CFLAGS="$CFLAGS -Wenum-compare" 14 | CFLAGS="$CFLAGS -Wempty-body" 15 | CFLAGS="$CFLAGS -Wsizeof-array-argument" 16 | CFLAGS="$CFLAGS -Wstring-conversion" 17 | CFLAGS="$CFLAGS -Wparentheses" 18 | CFLAGS="$CFLAGS -Wcast-align" 19 | CFLAGS="$CFLAGS -Wstrict-aliasing" 20 | CFLAGS="$CFLAGS --pedantic-errors" 21 | CFLAGS="$CFLAGS -g" 22 | 23 | $CC $CFLAGS -I../ -o example1 ../cmp.c example1.c 24 | $CC $CFLAGS -I../ -o example2 ../cmp.c example2.c 25 | 26 | -------------------------------------------------------------------------------- /lib/cmp/examples/cmp_data.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/lib/cmp/examples/cmp_data.dat -------------------------------------------------------------------------------- /lib/cmp/package.yml: -------------------------------------------------------------------------------- 1 | source: 2 | - cmp.c 3 | 4 | include_directories: [include] 5 | -------------------------------------------------------------------------------- /lib/cmp/test/cases.mpac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/lib/cmp/test/cases.mpac -------------------------------------------------------------------------------- /lib/cmp/test/utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "utils.h" 10 | 11 | void error_and_exit(const char* msg) 12 | { 13 | fprintf(stderr, "%s\n", msg); 14 | exit(EXIT_FAILURE); 15 | } 16 | 17 | void errorf_and_exit(const char* msg, ...) 18 | { 19 | va_list args; 20 | 21 | va_start(args, msg); 22 | vfprintf(stderr, msg, args); 23 | va_end(args); 24 | 25 | exit(EXIT_FAILURE); 26 | } 27 | 28 | char* _strdup(const char* s) 29 | { 30 | char* out = calloc(strlen(s) + 1, sizeof(char)); 31 | 32 | strcpy(out, s); 33 | 34 | return out; 35 | } 36 | 37 | /* vi: set et ts=2 sw=2: */ 38 | -------------------------------------------------------------------------------- /lib/cmp/test/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_H__ 2 | #define UTILS_H__ 3 | 4 | void error_and_exit(const char* msg); 5 | 6 | #ifdef __GNUC__ 7 | void errorf_and_exit(const char* msg, ...) 8 | __attribute__((format(printf, 1, 2))); 9 | #else 10 | void errorf_and_exit(const char* msg, ...); 11 | #endif 12 | 13 | char* _strdup(const char* s); 14 | 15 | #ifndef strdup 16 | #define strdup _strdup 17 | #endif 18 | 19 | #ifndef MAX 20 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) 21 | #endif 22 | 23 | #ifndef MIN 24 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) 25 | #endif 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /lib/cmp_mem_access/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(cmp_mem_access 2 | cmp_mem_access.c 3 | ) 4 | 5 | target_include_directories(cmp_mem_access PUBLIC include) 6 | 7 | target_link_libraries(cmp_mem_access 8 | cmp 9 | ) 10 | 11 | cvra_add_test(TARGET cmp_mem_access_test SOURCES 12 | cmp_mem_access_test.cpp 13 | DEPENDENCIES 14 | cmp_mem_access 15 | ) 16 | -------------------------------------------------------------------------------- /lib/cmp_mem_access/example_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | git clone https://github.com/camgunz/cmp.git 4 | clang cmp_mem_access.c cmp/cmp.c example.c -I . -o example 5 | ./example 6 | -------------------------------------------------------------------------------- /lib/cmp_mem_access/package.yml: -------------------------------------------------------------------------------- 1 | source: 2 | - cmp_mem_access.c 3 | 4 | tests: 5 | - cmp_mem_access_test.cpp 6 | 7 | include_directories: 8 | - include 9 | 10 | depends: 11 | - cmp 12 | - test-runner 13 | -------------------------------------------------------------------------------- /lib/crc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(crc 2 | crc32.c 3 | crc16.c 4 | ) 5 | 6 | target_include_directories(crc PUBLIC include) 7 | 8 | cvra_add_test(TARGET crc_test SOURCES 9 | test/crc32_test.cpp 10 | test/crc16_test.cpp 11 | DEPENDENCIES 12 | crc 13 | ) 14 | -------------------------------------------------------------------------------- /lib/crc/crc16.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define CRC16_POLYNOMIAL 0xA001 // bit reversed 0x8005 6 | 7 | uint16_t crc16(uint16_t init, const void* data, size_t length) 8 | { 9 | uint8_t* p = (uint8_t*)data; 10 | uint16_t crc = init; 11 | while (length--) { 12 | int i; 13 | crc ^= *p++; 14 | for (i = 0; i < 8; i++) { 15 | if (crc & 1) { 16 | crc = (crc >> 1) ^ CRC16_POLYNOMIAL; 17 | } else { 18 | crc = crc >> 1; 19 | } 20 | } 21 | } 22 | return crc; 23 | } 24 | -------------------------------------------------------------------------------- /lib/crc/crc32.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define CRC32_POLYNOMIAL 0xEDB88320 // bit reversed 0x04C11DB7 6 | 7 | uint32_t crc32(uint32_t init, const void* data, size_t length) 8 | { 9 | uint8_t* p = (uint8_t*)data; 10 | uint32_t crc = ~init; 11 | size_t i; 12 | for (i = 0; i < length; i++) { 13 | int bit; 14 | for (bit = 0; bit < 8; bit++) { 15 | if ((crc & 1) != ((p[i] >> bit) & 1)) { 16 | crc = (crc >> 1) ^ CRC32_POLYNOMIAL; 17 | } else { 18 | crc = crc >> 1; 19 | } 20 | } 21 | } 22 | return ~crc; 23 | } 24 | -------------------------------------------------------------------------------- /lib/crc/include/crc/crc16.h: -------------------------------------------------------------------------------- 1 | #ifndef CRC16_H 2 | #define CRC16_H 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | // CRC-16-ANSI/IBM algorithm 12 | uint16_t crc16(uint16_t init, const void* data, size_t length); 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | 18 | #endif /* CRC16_H */ 19 | -------------------------------------------------------------------------------- /lib/crc/include/crc/crc32.h: -------------------------------------------------------------------------------- 1 | #ifndef CRC32_H 2 | #define CRC32_H 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | // Standard Ethernet CRC-32 algoritm using polynomial 0x04C11DB7 12 | uint32_t crc32(uint32_t init, const void* data, size_t length); 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /lib/crc/package.yml: -------------------------------------------------------------------------------- 1 | depends: 2 | - test-runner 3 | 4 | source: 5 | - crc32.c 6 | - crc16.c 7 | 8 | tests: 9 | - test/crc32_test.cpp 10 | - test/crc16_test.cpp 11 | 12 | include_directories: [include] 13 | -------------------------------------------------------------------------------- /lib/crc/test/crc16_test.cpp: -------------------------------------------------------------------------------- 1 | #include "CppUTest/TestHarness.h" 2 | #include 3 | 4 | TEST_GROUP (CRC16TestGroup) { 5 | }; 6 | 7 | TEST(CRC16TestGroup, CorrectCRC) 8 | { 9 | const char* data = "123456789"; 10 | CHECK_EQUAL(0xBB3D, crc16(0, data, 9)); 11 | } 12 | 13 | TEST(CRC16TestGroup, NonConstantOutput) 14 | { 15 | CHECK(crc16(0, "foo", 3) != crc16(0, "bar", 3)); 16 | } 17 | 18 | TEST(CRC16TestGroup, TestChaining) 19 | { 20 | uint16_t crc = crc16(0, "1234", 4); 21 | crc = crc16(crc, "56789", 5); 22 | CHECK_EQUAL(0xBB3D, crc); 23 | } 24 | 25 | TEST(CRC16TestGroup, TestZero) 26 | { 27 | uint16_t crc = crc16(0, "cvra", 4); 28 | uint8_t crc_buf[] = {(uint8_t)crc, (uint8_t)(crc >> 8)}; 29 | crc = crc16(crc, crc_buf, sizeof(crc_buf)); 30 | CHECK_EQUAL(0, crc); 31 | } 32 | -------------------------------------------------------------------------------- /lib/dijkstra/package.yml: -------------------------------------------------------------------------------- 1 | include_directories: 2 | - include 3 | 4 | depends: 5 | - test-runner 6 | 7 | tests: 8 | - tests/dijkstra.cpp 9 | -------------------------------------------------------------------------------- /lib/error/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(error 2 | error.c 3 | ) 4 | 5 | target_include_directories(error PUBLIC include) 6 | 7 | cvra_add_test(TARGET error_test SOURCES 8 | tests/error.cpp 9 | DEPENDENCIES 10 | error 11 | ) 12 | -------------------------------------------------------------------------------- /lib/error/package.yml: -------------------------------------------------------------------------------- 1 | depends: 2 | - test-runner 3 | 4 | source: 5 | - error.c 6 | 7 | tests: 8 | - tests/error.cpp 9 | 10 | include_directories: [include] 11 | -------------------------------------------------------------------------------- /lib/fatfs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if (${CMAKE_CROSSCOMPILING}) 2 | add_library(fatfs 3 | ff.c 4 | ) 5 | 6 | target_include_directories(fatfs PUBLIC include) 7 | target_link_libraries(fatfs chibios) 8 | 9 | # This library contains only ffconf.h, which is required by ChibiOS 10 | add_library(fatfs_conf INTERFACE) 11 | target_include_directories(fatfs_conf INTERFACE include/fatfs) 12 | endif() 13 | -------------------------------------------------------------------------------- /lib/fatfs/include/fatfs/integer.h: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------*/ 2 | /* Integer type definitions for FatFs module */ 3 | /*-------------------------------------------*/ 4 | 5 | #ifndef _FF_INTEGER 6 | #define _FF_INTEGER 7 | 8 | #ifdef _WIN32 /* FatFs development platform */ 9 | 10 | #include 11 | #include 12 | 13 | #else /* Embedded platform */ 14 | 15 | /* This type MUST be 8 bit */ 16 | typedef unsigned char BYTE; 17 | 18 | /* These types MUST be 16 bit */ 19 | typedef short SHORT; 20 | typedef unsigned short WORD; 21 | typedef unsigned short WCHAR; 22 | 23 | /* These types MUST be 16 bit or 32 bit */ 24 | typedef int INT; 25 | typedef unsigned int UINT; 26 | 27 | /* These types MUST be 32 bit */ 28 | typedef long LONG; 29 | typedef unsigned long DWORD; 30 | 31 | #endif 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /lib/fatfs/package.yml: -------------------------------------------------------------------------------- 1 | target.arm: 2 | - src/ff.c 3 | 4 | include_directories: 5 | - src 6 | 7 | source: [] 8 | -------------------------------------------------------------------------------- /lib/fatfs/src/option/unicode.c: -------------------------------------------------------------------------------- 1 | #include "../ff.h" 2 | 3 | #if _USE_LFN != 0 4 | 5 | #if _CODE_PAGE == 932 /* Japanese Shift_JIS */ 6 | #include "cc932.c" 7 | #elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ 8 | #include "cc936.c" 9 | #elif _CODE_PAGE == 949 /* Korean */ 10 | #include "cc949.c" 11 | #elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ 12 | #include "cc950.c" 13 | #else /* Small character-set */ 14 | #include "ccsbcs.c" 15 | #endif 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /lib/filter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(filter 2 | iir.c 3 | basic.c 4 | 5 | ) 6 | 7 | target_include_directories(filter PUBLIC include) 8 | 9 | cvra_add_test(TARGET filter_test SOURCES 10 | tests/iir_test.cpp 11 | tests/basic_test.cpp 12 | DEPENDENCIES 13 | filter 14 | ) -------------------------------------------------------------------------------- /lib/filter/README.md: -------------------------------------------------------------------------------- 1 | filter 2 | ====== 3 | 4 | A collection of signal processing filters. 5 | -------------------------------------------------------------------------------- /lib/filter/basic.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | float filter_limit(float value, float min, float max) 4 | { 5 | if (value > max) { 6 | return max; 7 | } else if (value < min) { 8 | return min; 9 | } else { 10 | return value; 11 | } 12 | } 13 | 14 | float filter_limit_sym(float value, float limit) 15 | { 16 | return filter_limit(value, -limit, limit); 17 | } 18 | -------------------------------------------------------------------------------- /lib/filter/include/filter/basic.h: -------------------------------------------------------------------------------- 1 | #ifndef FILTER_BASIC_H 2 | #define FILTER_BASIC_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | float filter_limit(float value, float min, float max); 9 | float filter_limit_sym(float value, float limit); 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /lib/filter/include/filter/iir.h: -------------------------------------------------------------------------------- 1 | #ifndef FILTER_IIR_H 2 | #define FILTER_IIR_H 3 | 4 | typedef struct { 5 | const float* b; // coefficients b0 to bn, size n+1 6 | const float* a; // coefficients a1 to an, size n 7 | int n; 8 | float* d; // delays (buffer), size n 9 | } filter_iir_t; 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | void filter_iir_init(filter_iir_t* f, 16 | const float* b, 17 | const float* a, 18 | int n, 19 | float* d); 20 | 21 | float filter_iir_apply(filter_iir_t* f, float in); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /lib/filter/include/filter/mean.h: -------------------------------------------------------------------------------- 1 | #ifndef FILTER_MEAN_H 2 | #define FILTER_MEAN_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | float mean(float* set, size_t n); 9 | int mean_int16(int16_t* set, size_t n); 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /lib/filter/mean.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "mean.h" 3 | 4 | float mean(float* set, size_t n) 5 | { 6 | float ret = 0.0f; 7 | int i; 8 | 9 | for (i = 0; i < n; i++) { 10 | ret += set[i]; 11 | } 12 | 13 | return ret / n; 14 | } 15 | 16 | int mean_int16(int16_t* set, size_t n) 17 | { 18 | int ret = 0; 19 | int i; 20 | 21 | for (i = 0; i < n; i++) { 22 | ret += set[i]; 23 | } 24 | 25 | return ret / n; 26 | } 27 | -------------------------------------------------------------------------------- /lib/filter/package.yml: -------------------------------------------------------------------------------- 1 | depends: 2 | - test-runner 3 | 4 | source: 5 | - iir.c 6 | - basic.c 7 | 8 | tests: 9 | - tests/iir_test.cpp 10 | - tests/basic_test.cpp 11 | 12 | include_directories: [include] 13 | -------------------------------------------------------------------------------- /lib/filter/tests/basic_test.cpp: -------------------------------------------------------------------------------- 1 | #include "CppUTest/TestHarness.h" 2 | #include 3 | 4 | TEST_GROUP (Limit) { 5 | const float min = -5; 6 | const float max = 99; 7 | }; 8 | 9 | TEST(Limit, InsideMinMaxRange) 10 | { 11 | float value = 42; 12 | 13 | DOUBLES_EQUAL(value, filter_limit(value, min, max), 1.0e-7); 14 | } 15 | 16 | TEST(Limit, OutsideMinMaxRange) 17 | { 18 | float value = 1337; 19 | 20 | DOUBLES_EQUAL(max, filter_limit(value, min, max), 1.0e-7); 21 | } 22 | 23 | TEST(Limit, InsideSymmetricRange) 24 | { 25 | float value = 42; 26 | 27 | DOUBLES_EQUAL(value, filter_limit_sym(value, max), 1.0e-7); 28 | } 29 | 30 | TEST(Limit, OutsideSymmetricRange) 31 | { 32 | float value = -128; 33 | 34 | DOUBLES_EQUAL(-max, filter_limit_sym(value, max), 1.0e-7); 35 | } 36 | -------------------------------------------------------------------------------- /lib/goap/CMakeLists.demo.txt: -------------------------------------------------------------------------------- 1 | project(goap) 2 | cmake_minimum_required(VERSION 3.10) 3 | 4 | add_executable(example 5 | example.cpp 6 | ) 7 | 8 | target_include_directories(example PUBLIC include) 9 | 10 | add_executable(tests 11 | tests/goap_internals.cpp 12 | tests/goap_test.cpp 13 | tests/main.cpp 14 | ) 15 | target_include_directories(tests PUBLIC include) 16 | target_link_libraries(tests CppUTest CppUTestExt) 17 | -------------------------------------------------------------------------------- /lib/goap/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(goap INTERFACE) 2 | target_include_directories(goap INTERFACE include) 3 | 4 | cvra_add_test(TARGET goap_test SOURCES 5 | tests/goap_internals.cpp 6 | tests/goap_test.cpp 7 | DEPENDENCIES 8 | goap 9 | ) 10 | 11 | add_executable(goap_example 12 | example.cpp 13 | ) 14 | 15 | target_link_libraries(goap_example goap) 16 | -------------------------------------------------------------------------------- /lib/goap/package.yml: -------------------------------------------------------------------------------- 1 | depends: 2 | - test-runner 3 | 4 | tests: 5 | - tests/goap_test.cpp 6 | - tests/goap_internals.cpp 7 | -------------------------------------------------------------------------------- /lib/msgbus/README.md: -------------------------------------------------------------------------------- 1 | # Microcontroller message bus 2 | 3 | ## Features 4 | 5 | * Runtime declaration of topics 6 | * Many publishers, many subscribers (N to M). 7 | * Subscribers and publishers can be removed without impacting bus. 8 | * Can block waiting for a message. 9 | * Can poll to see if there was an update to the message. 10 | * Topics are atomic. 11 | * Different serialization methods are possible. 12 | * Each topic can have a metadata block. 13 | It can be used to contain function pointers to serialization / deserialization methods for example. 14 | Metadata do not offer the same atomicity guarantees as the topic data themselves. 15 | * Possibility to register callbacks that are triggered on topic creation. 16 | 17 | ## Features that won't be supported 18 | 19 | The following features won't be supported, to keep the codebase simple. 20 | 21 | * Runtime deletion of topics 22 | 23 | -------------------------------------------------------------------------------- /lib/msgbus/WORKSPACE: -------------------------------------------------------------------------------- 1 | workspace(name = "ch_cvra_msgbus") 2 | -------------------------------------------------------------------------------- /lib/msgbus/demo.jinja: -------------------------------------------------------------------------------- 1 | {% extends "CMakeLists.txt.jinja" %} 2 | 3 | {% block additional_targets %} 4 | add_executable( 5 | demo 6 | {% for s in source + target.demo -%} 7 | {{ s }} 8 | {% endfor %} 9 | ) 10 | 11 | target_link_libraries( 12 | demo 13 | pthread 14 | ) 15 | 16 | add_executable( 17 | demo_watchgroups 18 | {% for s in source + target.demo_watchgroups -%} 19 | {{ s }} 20 | {% endfor %} 21 | ) 22 | 23 | target_link_libraries( 24 | demo 25 | pthread 26 | ) 27 | 28 | 29 | 30 | {% endblock %} 31 | -------------------------------------------------------------------------------- /lib/msgbus/examples/chibios/.gitignore: -------------------------------------------------------------------------------- 1 | ChibiOS 2 | -------------------------------------------------------------------------------- /lib/msgbus/examples/chibios/README.md: -------------------------------------------------------------------------------- 1 | # ChibiOS examples 2 | 3 | This directory contains examples to use with ChibiOS. 4 | You should first clone it in this repository: 5 | 6 | ```bash 7 | git clone https://github.com/cvra/ChibiOS.git 8 | git checkout 3.0.1-cvra 9 | ``` 10 | -------------------------------------------------------------------------------- /lib/msgbus/examples/chibios/STM32F302R8-Nucleo/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .dep 3 | -------------------------------------------------------------------------------- /lib/msgbus/examples/chibios/STM32F302R8-Nucleo/openocd.cfg: -------------------------------------------------------------------------------- 1 | telnet_port 4444 2 | gdb_port 3333 3 | 4 | source [find board/st_nucleo_f3.cfg] 5 | -------------------------------------------------------------------------------- /lib/msgbus/examples/chibios/port.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void messagebus_lock_acquire(void* p) 5 | { 6 | mutex_t* lock = (mutex_t*)p; 7 | chMtxLock(lock); 8 | } 9 | 10 | void messagebus_lock_release(void* p) 11 | { 12 | mutex_t* lock = (mutex_t*)p; 13 | chMtxUnlock(lock); 14 | } 15 | 16 | void messagebus_condvar_broadcast(void* p) 17 | { 18 | condition_variable_t* cond = (condition_variable_t*)p; 19 | chCondBroadcast(cond); 20 | } 21 | 22 | void messagebus_condvar_wait(void* p) 23 | { 24 | condition_variable_t* cond = (condition_variable_t*)p; 25 | chCondWait(cond); 26 | } 27 | -------------------------------------------------------------------------------- /lib/msgbus/examples/posix/include/msgbus/posix/port.h: -------------------------------------------------------------------------------- 1 | #ifndef PORT_H 2 | #define PORT_H 3 | #include 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | typedef struct { 10 | pthread_mutex_t mutex; 11 | pthread_cond_t cond; 12 | } condvar_wrapper_t; 13 | 14 | #define MESSAGEBUS_POSIX_SYNC_DECL(name) \ 15 | condvar_wrapper_t name = {PTHREAD_MUTEX_INITIALIZER, \ 16 | PTHREAD_COND_INITIALIZER} 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | #endif 22 | -------------------------------------------------------------------------------- /lib/msgbus/examples/posix/port.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void messagebus_lock_acquire(void* p) 5 | { 6 | condvar_wrapper_t* wrapper = (condvar_wrapper_t*)p; 7 | pthread_mutex_lock(&wrapper->mutex); 8 | } 9 | 10 | void messagebus_lock_release(void* p) 11 | { 12 | condvar_wrapper_t* wrapper = (condvar_wrapper_t*)p; 13 | pthread_mutex_unlock(&wrapper->mutex); 14 | } 15 | 16 | void messagebus_condvar_broadcast(void* p) 17 | { 18 | condvar_wrapper_t* wrapper = (condvar_wrapper_t*)p; 19 | pthread_cond_broadcast(&wrapper->cond); 20 | } 21 | 22 | void messagebus_condvar_wait(void* p) 23 | { 24 | condvar_wrapper_t* wrapper = (condvar_wrapper_t*)p; 25 | pthread_cond_wait(&wrapper->cond, &wrapper->mutex); 26 | } 27 | -------------------------------------------------------------------------------- /lib/msgbus/package.yml: -------------------------------------------------------------------------------- 1 | depends: 2 | - test-runner 3 | 4 | source: 5 | - messagebus.c 6 | 7 | tests: 8 | - tests/mocks/synchronization.cpp 9 | - tests/atomicity.cpp 10 | - tests/msgbus.cpp 11 | - tests/signaling.cpp 12 | - tests/foreach.cpp 13 | - tests/watchgroups.cpp 14 | - tests/new_topic_callbacks.cpp 15 | - tests/test_cpp_interface.cpp 16 | - tests/statistics.cpp 17 | 18 | target.demo: 19 | - examples/posix/demo.c 20 | - examples/posix/port.c 21 | 22 | target.demo_watchgroups: 23 | - examples/posix/demo_watchgroups.c 24 | - examples/posix/port.c 25 | 26 | target.arm: 27 | - examples/chibios/port.c 28 | 29 | templates: 30 | demo.jinja: CMakeLists.txt 31 | 32 | include_directories: [include] 33 | -------------------------------------------------------------------------------- /lib/msgbus/tests/mocks/synchronization.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SYNCHRONIZATION_HPP 2 | #define SYNCHRONIZATION_HPP 3 | 4 | void lock_mocks_enable(bool enabled); 5 | void condvar_mocks_enable(bool enabled); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /lib/msgbus/tests/statistics.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../messagebus.h" 4 | 5 | TEST_GROUP (MessagebusStats) { 6 | messagebus_topic_t topic; 7 | 8 | void setup() 9 | { 10 | messagebus_topic_init(&topic, nullptr, nullptr, nullptr, 0); 11 | } 12 | }; 13 | 14 | TEST(MessagebusStats, StatsAreZeroedOnInit) 15 | { 16 | messagebus_topic_stats_t stats; 17 | messagebus_topic_stats_get(&topic, &stats); 18 | CHECK_EQUAL(0, stats.messages); 19 | } 20 | 21 | TEST(MessagebusStats, MessagesAreIncrementedOnPublish) 22 | { 23 | messagebus_topic_stats_t stats; 24 | 25 | messagebus_topic_publish(&topic, nullptr, 0); 26 | messagebus_topic_stats_get(&topic, &stats); 27 | CHECK_EQUAL(1, stats.messages); 28 | } 29 | -------------------------------------------------------------------------------- /lib/nanopb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(nanopb 2 | nanopb/pb_common.c 3 | nanopb/pb_decode.c 4 | nanopb/pb_encode.c 5 | ) 6 | 7 | target_include_directories(nanopb PUBLIC nanopb) 8 | -------------------------------------------------------------------------------- /lib/nanopb/package.yml: -------------------------------------------------------------------------------- 1 | include_directories: 2 | - nanopb 3 | source: 4 | - nanopb/pb_common.c 5 | - nanopb/pb_decode.c 6 | - nanopb/pb_encode.c 7 | -------------------------------------------------------------------------------- /lib/parameter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(parameter 2 | parameter.c 3 | parameter_msgpack.c 4 | parameter_print.c 5 | ) 6 | 7 | target_include_directories(parameter PUBLIC include) 8 | 9 | 10 | target_link_libraries(parameter 11 | cmp_mem_access 12 | cmp 13 | cmp_mem_access 14 | ) 15 | 16 | 17 | if(NOT ${CMAKE_CROSSCOMPILING}) 18 | add_library(parameter_port_dummy 19 | tests/parameter_port_dummy.cpp 20 | ) 21 | 22 | target_link_libraries(parameter_port_dummy parameter) 23 | endif() 24 | 25 | 26 | cvra_add_test(TARGET parameter_test SOURCES 27 | tests/parameter_test.cpp 28 | tests/parameter_types_test.cpp 29 | tests/parameter_print_test.cpp 30 | tests/msgpack_test.cpp 31 | DEPENDENCIES 32 | parameter 33 | parameter_port_dummy 34 | ) 35 | -------------------------------------------------------------------------------- /lib/parameter/include/parameter/parameter_print.h: -------------------------------------------------------------------------------- 1 | #ifndef PARAMETER_PRINT_H 2 | #define PARAMETER_PRINT_H 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | typedef int (*parameter_printfn_t)(void*, const char*, ...); 11 | 12 | // print the parameter tree of the given namespace as yaml 13 | void parameter_print(parameter_namespace_t* ns, 14 | parameter_printfn_t printfn, 15 | void* printfn_arg); 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #endif /* PARAMETER_PRINT_H */ 22 | -------------------------------------------------------------------------------- /lib/parameter/package.yml: -------------------------------------------------------------------------------- 1 | source: 2 | - parameter.c 3 | - parameter_msgpack.c 4 | - parameter_print.c 5 | 6 | depends: 7 | - cmp_mem_access 8 | - test-runner 9 | - cmp 10 | - cmp_mem_access 11 | 12 | tests: 13 | - tests/parameter_test.cpp 14 | - tests/parameter_types_test.cpp 15 | - tests/parameter_print_test.cpp 16 | - tests/msgpack_test.cpp 17 | 18 | include_directories: [include] 19 | -------------------------------------------------------------------------------- /lib/parameter/tests/parameter_port_dummy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | extern "C" { 8 | 9 | void parameter_port_lock(void) 10 | { 11 | } 12 | 13 | void parameter_port_unlock(void) 14 | { 15 | } 16 | 17 | void parameter_port_assert(int condition) 18 | { 19 | CHECK_TRUE(condition); 20 | } 21 | 22 | void* parameter_port_buffer_alloc(size_t size) 23 | { 24 | return malloc(size); 25 | } 26 | 27 | void parameter_port_buffer_free(void* buffer) 28 | { 29 | free(buffer); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/parameter_flash_storage/.gitignore: -------------------------------------------------------------------------------- 1 | # ChibiOS build files 2 | .dep/* 3 | build/ 4 | debug/ 5 | *.elf 6 | *.a 7 | 8 | 9 | # Vim swap 10 | *.swp 11 | 12 | # Packager files 13 | CMakeLists.txt 14 | src/src.mk 15 | 16 | .tags* 17 | 18 | env 19 | -------------------------------------------------------------------------------- /lib/parameter_flash_storage/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(parameter_flash_storage 2 | parameter_flash_storage.c 3 | ) 4 | 5 | target_include_directories(parameter_flash_storage PUBLIC include) 6 | 7 | target_link_libraries(parameter_flash_storage 8 | parameter 9 | crc 10 | ) 11 | 12 | cvra_add_test(TARGET parameter_flash_storage_test SOURCES 13 | tests/flash_mock.cpp 14 | tests/parameter_flash_storage.cpp 15 | DEPENDENCIES 16 | parameter 17 | parameter_flash_storage 18 | parameter_port_dummy 19 | ) 20 | 21 | add_library(parameter_flash_f4 22 | flash_f4.c 23 | ) 24 | 25 | target_include_directories(parameter_flash_f4 PUBLIC include) 26 | 27 | add_library(parameter_flash_f3 28 | flash_f3.c 29 | ) 30 | 31 | target_include_directories(parameter_flash_f3 PUBLIC include) 32 | -------------------------------------------------------------------------------- /lib/parameter_flash_storage/include/parameter_flash_storage/flash.h: -------------------------------------------------------------------------------- 1 | #ifndef FLASH_H 2 | #define FLASH_H 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | void flash_lock(void); 11 | void flash_unlock(void); 12 | 13 | /* Write data of size len at addr. 14 | * Note: flash must be unlocked for this operation. */ 15 | void flash_write(void* addr, const void* data, size_t len); 16 | 17 | /** Erase sector given by its base address. 18 | * 19 | * @note flash must be unlocked for this operation. 20 | */ 21 | void flash_sector_erase(void* addr); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | 27 | #endif /* FLASH_H */ 28 | -------------------------------------------------------------------------------- /lib/parameter_flash_storage/package.yml: -------------------------------------------------------------------------------- 1 | depends: 2 | - parameter 3 | - crc 4 | - test-runner 5 | 6 | source: 7 | - parameter_flash_storage.c 8 | 9 | target.stm32f4: 10 | - flash_f4.c 11 | 12 | target.stm32f3: 13 | - flash_f3.c 14 | 15 | tests: 16 | - tests/flash_mock.cpp 17 | - tests/parameter_flash_storage.cpp 18 | 19 | include_directories: [include] 20 | -------------------------------------------------------------------------------- /lib/pid/.gitignore: -------------------------------------------------------------------------------- 1 | # # Editor swap files 2 | *.swp 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Libraries 11 | *.lib 12 | *.a 13 | 14 | # Shared objects (inc. Windows DLLs) 15 | *.dll 16 | *.so 17 | *.so.* 18 | *.dylib 19 | 20 | # Executables 21 | *.exe 22 | *.out 23 | *.app 24 | *.i*86 25 | *.x86_64 26 | *.hex 27 | 28 | # Build scripts and directories 29 | CMakeLists.txt 30 | build/* 31 | dependencies/* 32 | -------------------------------------------------------------------------------- /lib/pid/.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | compiler: 3 | - gcc 4 | - clang 5 | 6 | before_install: 7 | - sudo pip install pyaml jinja2 8 | - pushd .. 9 | - wget "https://github.com/cpputest/cpputest.github.io/blob/master/releases/cpputest-3.6.tar.gz?raw=true" -O cpputest.tar.gz 10 | - tar -xzf cpputest.tar.gz 11 | - cd cpputest-3.6/ 12 | - ./configure 13 | - make 14 | - sudo make install 15 | - popd 16 | 17 | - git clone https://github.com/cvra/packager ../packager 18 | 19 | before_script: 20 | - ../packager/packager.py 21 | - mkdir build/ 22 | - cd build/ 23 | - cmake .. 24 | 25 | script: 26 | - make 27 | - ./tests 28 | -------------------------------------------------------------------------------- /lib/pid/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(pid 2 | pid.c 3 | ) 4 | 5 | target_include_directories(pid PUBLIC include) 6 | 7 | cvra_add_test(TARGET pid_test SOURCES 8 | tests/pid_test.cpp 9 | DEPENDENCIES 10 | pid 11 | ) 12 | -------------------------------------------------------------------------------- /lib/pid/package.yml: -------------------------------------------------------------------------------- 1 | depends: 2 | - test-runner 3 | 4 | source: 5 | - pid.c 6 | 7 | tests: 8 | - tests/pid_test.cpp 9 | 10 | include_directories: [include] 11 | -------------------------------------------------------------------------------- /lib/quadramp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(quadramp 2 | quadramp.c 3 | ) 4 | 5 | target_include_directories(quadramp PUBLIC include) 6 | 7 | cvra_add_test(TARGET quadramp_test SOURCES 8 | tests/quadramp.cpp 9 | DEPENDENCIES 10 | quadramp 11 | ) 12 | -------------------------------------------------------------------------------- /lib/quadramp/package.yml: -------------------------------------------------------------------------------- 1 | depends: 2 | - test-runner 3 | 4 | source: 5 | - quadramp.c 6 | 7 | tests: 8 | - tests/quadramp.cpp 9 | 10 | include_directories: [include] 11 | -------------------------------------------------------------------------------- /lib/raft/CMakeLists.demo.jinja: -------------------------------------------------------------------------------- 1 | {% extends 'CMakeLists.txt.jinja' %} 2 | 3 | 4 | {% block additional_targets %} 5 | 6 | {% for demo_name in target.keys() %} 7 | add_executable( 8 | {{ demo_name }} 9 | {% for file in source -%} 10 | {{ file }} 11 | {% endfor -%} 12 | 13 | {% for file in target[demo_name] -%} 14 | {{ file }} 15 | {% endfor -%} 16 | ) 17 | {% endfor %} 18 | 19 | 20 | {% endblock %} 21 | -------------------------------------------------------------------------------- /lib/raft/demos/error_handlers.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | static void mylog(struct error* e, ...) 8 | { 9 | va_list va; 10 | va_start(va, e); 11 | 12 | const char* filename_start = strrchr(e->file, '/') + 1; 13 | 14 | printf("%s:%d: %s: ", filename_start, e->line, error_severity_get_name(e->severity)); 15 | vprintf(e->text, va); 16 | printf("\n"); 17 | 18 | va_end(va); 19 | } 20 | 21 | void register_error_handlers(void) 22 | { 23 | error_register_error(mylog); 24 | error_register_warning(mylog); 25 | error_register_notice(mylog); 26 | //error_register_debug(mylog); 27 | } 28 | -------------------------------------------------------------------------------- /lib/raft/demos/error_handlers.h: -------------------------------------------------------------------------------- 1 | #ifndef ERROR_HANDLERS_H 2 | #define ERROR_HANDLERS_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void register_error_handlers(void); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /lib/raft/demos/udp_transport.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "udp_transport.hpp" 3 | 4 | int make_receive_socket(int port) 5 | { 6 | auto recv_socket = socket(AF_INET, SOCK_DGRAM, 0); 7 | 8 | struct sockaddr_in addr; 9 | addr.sin_family = AF_INET; 10 | addr.sin_port = htons(port); 11 | addr.sin_addr.s_addr = htonl(INADDR_ANY); 12 | 13 | if (::bind(recv_socket, (struct sockaddr*)&addr, sizeof(addr)) < 0) { 14 | ERROR("Could not bind socket"); 15 | } 16 | 17 | struct timeval read_timeout; 18 | read_timeout.tv_sec = 0; 19 | read_timeout.tv_usec = 10; 20 | setsockopt(recv_socket, SOL_SOCKET, SO_RCVTIMEO, &read_timeout, sizeof(read_timeout)); 21 | 22 | return recv_socket; 23 | } 24 | -------------------------------------------------------------------------------- /lib/raft/doc/raft.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/lib/raft/doc/raft.pdf -------------------------------------------------------------------------------- /lib/raft/package.yml: -------------------------------------------------------------------------------- 1 | templates: 2 | CMakeLists.demo.jinja: CMakeLists.txt 3 | 4 | depends: 5 | - test-runner 6 | - error 7 | 8 | tests: 9 | - tests/test_leader_election.cpp 10 | - tests/messages_comparator.cpp 11 | - tests/test_log_replication.cpp 12 | - tests/test_log.cpp 13 | - tests/test_state_machine_commit.cpp 14 | 15 | target.demo_leader_election: 16 | - demos/leader_election.cpp 17 | - demos/error_handlers.c 18 | - demos/udp_transport.cpp 19 | 20 | target.demo_log_replication: 21 | - demos/log_replication.cpp 22 | - demos/error_handlers.c 23 | - demos/udp_transport.cpp 24 | -------------------------------------------------------------------------------- /lib/raft/tests/messages_comparator.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../raft.hpp" 4 | #include "test_state_machine.hpp" 5 | 6 | class RaftMessageComparator : public MockNamedValueComparator { 7 | public: 8 | virtual bool isEqual(const void* object1, const void* object2); 9 | virtual SimpleString valueToString(const void* object); 10 | }; 11 | 12 | // Helper functions to allow use of CHECK_EQUAL with enum classes 13 | SimpleString StringFrom(TestMessage::Type type); 14 | SimpleString StringFrom(raft::NodeState state); 15 | -------------------------------------------------------------------------------- /lib/raft/tests/test_state_machine.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../raft.hpp" 4 | 5 | class TestStateMachine { 6 | public: 7 | enum class Operation { 8 | FOO = 0xca, 9 | BAR = 0xfe, 10 | }; 11 | 12 | void apply(Operation op) 13 | { 14 | (void)op; 15 | } 16 | }; 17 | 18 | using TestRaftState = raft::State; 19 | using TestPeer = raft::Peer; 20 | using TestMessage = raft::Message; 21 | -------------------------------------------------------------------------------- /lib/softspi/package.yml: -------------------------------------------------------------------------------- 1 | depends: 2 | - test-runner 3 | 4 | source: 5 | - softspi.c 6 | 7 | tests: 8 | - softspi_test.cpp 9 | 10 | include_directories: [include] 11 | -------------------------------------------------------------------------------- /lib/test-runner/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Compiled Dynamic libraries 8 | *.so 9 | *.dylib 10 | *.dll 11 | 12 | # Compiled Static libraries 13 | *.lai 14 | *.la 15 | *.a 16 | *.lib 17 | 18 | # Executables 19 | *.exe 20 | *.out 21 | *.app 22 | -------------------------------------------------------------------------------- /lib/test-runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if (NOT ${CMAKE_CROSSCOMPILING}) 2 | add_library(test-runner 3 | main.cpp 4 | ) 5 | 6 | target_link_libraries(test-runner 7 | CppUTest 8 | CppUTestExt 9 | ) 10 | endif() 11 | -------------------------------------------------------------------------------- /lib/test-runner/README.md: -------------------------------------------------------------------------------- 1 | test-runner 2 | =========== 3 | 4 | A simple CppUTest runner for the CVRA packager. 5 | -------------------------------------------------------------------------------- /lib/test-runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include "CppUTest/CommandLineTestRunner.h" 2 | #include "CppUTest/TestRegistry.h" 3 | #include "CppUTestExt/MockSupportPlugin.h" 4 | 5 | int main(int ac, char** av) 6 | { 7 | MockSupportPlugin mockPlugin; 8 | TestRegistry::getCurrentRegistry()->installPlugin(&mockPlugin); 9 | return CommandLineTestRunner::RunAllTests(ac, av); 10 | } 11 | -------------------------------------------------------------------------------- /lib/test-runner/package.yml: -------------------------------------------------------------------------------- 1 | tests: 2 | - main.cpp 3 | -------------------------------------------------------------------------------- /lib/timestamp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(timestamp 2 | timestamp.c 3 | ) 4 | 5 | target_include_directories(timestamp PUBLIC include) 6 | 7 | cvra_add_test(TARGET timestamp_test SOURCES 8 | timestamp_test.cpp 9 | DEPENDENCIES 10 | timestamp 11 | ) 12 | 13 | if (CMAKE_CROSSCOMPILING) 14 | add_library(timestamp_stm32 15 | timestamp_stm32.c 16 | ) 17 | 18 | target_link_libraries(timestamp_stm32 timestamp chibios) 19 | endif() 20 | -------------------------------------------------------------------------------- /lib/timestamp/include/timestamp/timestamp_stm32.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMESTAMP_STM32_H 2 | #define TIMESTAMP_STM32_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void timestamp_stm32_init(void); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif /* TIMESTAMP_STM32_H */ -------------------------------------------------------------------------------- /lib/timestamp/include/timestamp/timestamp_stm32_settings.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMESTAMP_STM32_SETTINGS_H 2 | #define TIMESTAMP_STM32_SETTINGS_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | // settings 11 | #define TIMESTAMP_TIMER TIM7 12 | #define TIMER_REG STM32_TIM7 13 | #define TIMER_IRQ_NAME STM32_TIM7_HANDLER 14 | #define RCC_EN() rccEnableTIM7(FALSE) 15 | #define RCC_RESET() rccResetTIM7() 16 | #define NVIC_NB STM32_TIM7_NUMBER 17 | 18 | #define COUNTER_MAX 0xffff 19 | 20 | // CK_CNT = CK_INT / (PSC[15:0] + 1) 21 | #if STM32_PPRE1 == STM32_PPRE1_DIV1 22 | #define PRESCALER (STM32_PCLK1 / 1000000 - 1) 23 | #else 24 | #define PRESCALER (2 * STM32_PCLK1 / 1000000 - 1) 25 | #endif 26 | #define INTERRUPT_PRIO 5 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | 32 | #endif /* TIMESTAMP_STM32_SETTINGS_H */ 33 | -------------------------------------------------------------------------------- /lib/timestamp/package.yml: -------------------------------------------------------------------------------- 1 | depends: 2 | - test-runner 3 | 4 | source: 5 | - timestamp.c 6 | 7 | target.arm: 8 | - timestamp_stm32.c 9 | 10 | tests: 11 | - timestamp_test.cpp 12 | 13 | include_directories: [include] 14 | -------------------------------------------------------------------------------- /lib/timestamp/timestamp.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int32_t timestamp_duration_us(timestamp_t t1, timestamp_t t2) 4 | { 5 | return (t2 - t1); 6 | } 7 | 8 | float timestamp_duration_s(timestamp_t t1, timestamp_t t2) 9 | { 10 | return (float)timestamp_duration_us(t1, t2) / 1000000.f; 11 | } 12 | 13 | int64_t ltimestamp_duration_us(ltimestamp_t t1, ltimestamp_t t2) 14 | { 15 | return (t2 - t1); 16 | } 17 | 18 | float ltimestamp_duration_s(ltimestamp_t t1, ltimestamp_t t2) 19 | { 20 | return (float)ltimestamp_duration_us(t1, t2) / 1000000.f; 21 | } 22 | -------------------------------------------------------------------------------- /lib/trace/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(trace 2 | trace.c 3 | ) 4 | 5 | target_include_directories(trace PUBLIC include) 6 | 7 | add_library(trace_platform_mocks 8 | tests/trace_mocks.c 9 | tests/trace_points.c 10 | ) 11 | target_link_libraries(trace_platform_mocks trace) 12 | 13 | cvra_add_test(TARGET trace_test SOURCES 14 | tests/trace_test.cpp 15 | DEPENDENCIES 16 | trace 17 | trace_platform_mocks 18 | ) 19 | 20 | -------------------------------------------------------------------------------- /lib/trace/package.yml: -------------------------------------------------------------------------------- 1 | depends: 2 | - test-runner 3 | tests: 4 | - tests/trace_test.cpp 5 | - tests/trace_points.c 6 | source: 7 | - trace.c 8 | 9 | include_directories: [include] 10 | -------------------------------------------------------------------------------- /lib/trace/tests/trace_mocks.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "trace/trace.h" 4 | 5 | int32_t trace_timestamp_ms_get(void) 6 | { 7 | return 1234; 8 | } 9 | 10 | int32_t trace_lock(void) 11 | { 12 | return 0; 13 | } 14 | 15 | void trace_unlock(int32_t status) 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /lib/trace/tests/trace_points.c: -------------------------------------------------------------------------------- 1 | #include "trace_points.h" 2 | 3 | #undef C 4 | #define C(x) #x, 5 | 6 | const char* trace_point_names[] = { 7 | TRACE_POINTS}; 8 | -------------------------------------------------------------------------------- /lib/trace/tests/trace_points.h: -------------------------------------------------------------------------------- 1 | #ifndef TRACE_POINTS_H 2 | #define TRACE_POINTS_H 3 | 4 | #define TRACE_POINTS \ 5 | C(TRACE_POINT_0) \ 6 | C(TRACE_POINT_1) \ 7 | C(TRACE_POINT_2) 8 | 9 | /* List of all trace points in numerical format. */ 10 | #undef C 11 | #define C(x) x, 12 | enum { 13 | TRACE_POINTS 14 | }; 15 | 16 | #endif /* TRACE_POINTS_H */ 17 | -------------------------------------------------------------------------------- /lib/version/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cvra_add_test(TARGET version_test 2 | SOURCES tests/test_version.cpp 3 | DEPENDENCIES version 4 | ) 5 | 6 | add_custom_command(COMMAND ./version.sh \"${CVRA_BOARD_NAME}\" ${CMAKE_BINARY_DIR}/version.c 7 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 8 | OUTPUT ${CMAKE_BINARY_DIR}/version.c 9 | COMMENT "Generating git version" 10 | ) 11 | 12 | add_library(version ${CMAKE_BINARY_DIR}/version.c) 13 | target_include_directories(version INTERFACE include) 14 | -------------------------------------------------------------------------------- /lib/version/include/version/version.h: -------------------------------------------------------------------------------- 1 | #ifndef VERSION_H 2 | #define VERSION_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | extern const char* software_version_str; 11 | extern const char* hardware_version_str; 12 | extern const uint32_t software_version_short; 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | 18 | #endif /* VERSION_H */ 19 | -------------------------------------------------------------------------------- /lib/version/package.yml: -------------------------------------------------------------------------------- 1 | include_directories: [include] 2 | -------------------------------------------------------------------------------- /lib/version/tests/test_version.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | TEST_GROUP (VersionTestGroup) { 6 | }; 7 | 8 | TEST(VersionTestGroup, GitCommitIsCorrectLength) 9 | { 10 | std::string software_version{software_version_str}; 11 | CHECK_TRUE(0 < software_version.length()); 12 | } 13 | -------------------------------------------------------------------------------- /master-firmware/.gdbinit: -------------------------------------------------------------------------------- 1 | ../tools/gdbinit -------------------------------------------------------------------------------- /master-firmware/packaging/cvra-master.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Eurobot master control firmware 3 | 4 | [Service] 5 | Type=simple 6 | User=root 7 | # TODO(antoinealb): What do we want to do with the onboard LED? 8 | ExecStart=/bin/xinit /bin/cvra-master --enable_gui --can_iface="can0" \ 9 | --lock_memory \ 10 | --led_comm_path=/sys/class/leds/onboard \ 11 | --led_ready_path=/sys/class/leds/ready \ 12 | --led_debug_path=/sys/class/leds/debug \ 13 | --led_bus_path=/sys/class/leds/bus \ 14 | --led_error_path=/sys/class/leds/error \ 15 | --led_power_path=/sys/class/leds/power \ 16 | --strat_autoposition --strat_wait_for_starter 17 | Restart=on-failure 18 | LimitMEMLOCK=infinity 19 | 20 | 21 | [Install] 22 | WantedBy=multi-user.target 23 | -------------------------------------------------------------------------------- /master-firmware/packaging/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | systemctl daemon-reload 4 | systemctl enable cvra-master 5 | systemctl start cvra-master 6 | -------------------------------------------------------------------------------- /master-firmware/packaging/prerm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | systemctl stop cvra-master 4 | systemctl disable cvra-master 5 | -------------------------------------------------------------------------------- /master-firmware/protobuf/Timestamp.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "nanopb.proto"; 4 | 5 | /* Timestamp is used to represent instants in time, such as when a sensor 6 | * reading was received. Usually code should be handling absl::Time, but 7 | * passing data around on either the message bus or in the logs is easier with 8 | * this message. */ 9 | message Timestamp { 10 | /* Timestamps don't require a msgid themselves, but given that they are 11 | * used a lot as a simple message in unit tests, it is useful to give them 12 | * an id. */ 13 | option (nanopb_msgopt).msgid = 1; 14 | 15 | required uint64 us = 1; // Timestamp in microseconds since UNIX epoch 16 | } 17 | -------------------------------------------------------------------------------- /master-firmware/protobuf/actuators.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "nanopb.proto"; 4 | 5 | message ActuatorFeedback { 6 | option (nanopb_msgopt).msgid = 16; 7 | repeated float pressure = 1 8 | [ (nanopb).fixed_count = true, (nanopb).max_count = 2 ]; 9 | required bool digital_input = 2; 10 | }; 11 | -------------------------------------------------------------------------------- /master-firmware/protobuf/ally_position.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "nanopb.proto"; 4 | 5 | message AllyPosition { 6 | option (nanopb_msgopt).msgid = 15; 7 | required float x = 1; 8 | required float y = 2; 9 | required float a = 3; 10 | }; 11 | -------------------------------------------------------------------------------- /master-firmware/protobuf/beacons.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "nanopb.proto"; 4 | import "Timestamp.proto"; 5 | import "sensors.proto"; 6 | 7 | // Deprecated message, please use AllyPosition 8 | message AlliedPosition { 9 | option (nanopb_msgopt).msgid = 2; 10 | required Timestamp timestamp = 1; 11 | required float x = 2; 12 | required float y = 3; 13 | } 14 | 15 | message BeaconSignal { 16 | option (nanopb_msgopt).msgid = 4; 17 | // Raw readings containing a bearing and range 18 | required Timestamp timestamp = 1; 19 | required RangeBearing range = 2; 20 | 21 | // Converted to be an absolute position in the odometry coordinate space 22 | required float x = 3; 23 | required float y = 4; 24 | } 25 | -------------------------------------------------------------------------------- /master-firmware/protobuf/encoders.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "nanopb.proto"; 4 | 5 | message WheelEncodersPulse { 6 | option (nanopb_msgopt).msgid = 6; 7 | required int32 left = 1; 8 | required int32 right = 2; 9 | } 10 | -------------------------------------------------------------------------------- /master-firmware/protobuf/manipulator.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "nanopb.proto"; 4 | 5 | message Joints { 6 | option (nanopb_msgopt).msgid = 10; 7 | required float q1 = 1; 8 | required float q2 = 2; 9 | required float q3 = 3; 10 | } 11 | 12 | message Pose { 13 | option (nanopb_msgopt).msgid = 11; 14 | required float x = 1; 15 | required float y = 2; 16 | required float heading = 3; 17 | } 18 | 19 | message Manipulator { 20 | option (nanopb_msgopt).msgid = 12; 21 | required Pose pose = 1; 22 | required Joints measured = 2; 23 | required Joints input = 3; 24 | } 25 | -------------------------------------------------------------------------------- /master-firmware/protobuf/position.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "nanopb.proto"; 4 | 5 | message RobotPosition { 6 | option (nanopb_msgopt).msgid = 13; 7 | required float x = 1; 8 | required float y = 2; 9 | required float a = 3; 10 | } 11 | -------------------------------------------------------------------------------- /master-firmware/protobuf/protocol.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "nanopb.proto"; 4 | 5 | // Header used to indicate the size of the following protobuf message. 6 | // As we cannot give information about the size of this message, only constant 7 | // size types should be used here. 8 | message MessageSize { 9 | required fixed32 bytes = 1; // Message size in bytes 10 | } 11 | 12 | message TopicHeader { 13 | required uint32 msgid = 1; // Type information, expressed as a nanopb msgid 14 | required string name = 2 [ (nanopb).max_size = 65 ]; 15 | } 16 | -------------------------------------------------------------------------------- /master-firmware/protobuf/sensors.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "nanopb.proto"; 4 | 5 | message Range { 6 | option (nanopb_msgopt).msgid = 3; 7 | enum RangeType { 8 | ULTRASOUND = 1; 9 | LASER = 2; 10 | OTHER = 3; 11 | }; 12 | 13 | required RangeType type = 1; 14 | required float distance = 2; 15 | } 16 | 17 | message SwitchStatus { 18 | option (nanopb_msgopt).msgid = 5; 19 | required bool switched = 1; 20 | } 21 | 22 | message RangeBearing { 23 | option (nanopb_msgopt).msgid = 9; 24 | required Range range = 1; 25 | required float angle = 2; 26 | } 27 | -------------------------------------------------------------------------------- /master-firmware/src/.gitignore: -------------------------------------------------------------------------------- 1 | config_order.c 2 | config_chaos.c 3 | -------------------------------------------------------------------------------- /master-firmware/src/base/cs_port.c: -------------------------------------------------------------------------------- 1 | #include "cs_port.h" 2 | 3 | void cs_pid_set_out_divider(void* _pid, float divider) 4 | { 5 | cs_pid_t* pid = (cs_pid_t*)_pid; 6 | pid->divider = divider; 7 | } 8 | 9 | int32_t cs_pid_process(void* _pid, int32_t error) 10 | { 11 | cs_pid_t* pid = (cs_pid_t*)_pid; 12 | float cmd = pid_process(&(pid->pid), (float)error / pid->divider); 13 | return cmd * pid->divider; 14 | } 15 | -------------------------------------------------------------------------------- /master-firmware/src/base/cs_port.h: -------------------------------------------------------------------------------- 1 | #ifndef AVERSIVE_CS_PORT_H 2 | #define AVERSIVE_CS_PORT_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | #include 11 | 12 | typedef struct { 13 | pid_ctrl_t pid; 14 | float divider; 15 | } cs_pid_t; 16 | 17 | void cs_pid_set_out_divider(void* pid, float divider); 18 | int32_t cs_pid_process(void* pid, int32_t error); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif /* AVERSIVE_CS_PORT_H */ 25 | -------------------------------------------------------------------------------- /master-firmware/src/base/map_server.h: -------------------------------------------------------------------------------- 1 | #ifndef MAP_SERVER_H 2 | #define MAP_SERVER_H 3 | 4 | #include "robot_helpers/autoposition.h" 5 | #include "base/map.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | void map_server_start(enum strat_color_t color); 12 | struct _map* map_server_map_lock_and_get(void); 13 | void map_server_map_release(struct _map* map); 14 | 15 | void map_server_enable_opponent(struct _map* map_ptr, bool enable); 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #endif /* MAP_SERVER_H */ 22 | -------------------------------------------------------------------------------- /master-firmware/src/base/rs_port.h: -------------------------------------------------------------------------------- 1 | #ifndef AVERSIVE_RS_PORT_H 2 | #define AVERSIVE_RS_PORT_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "can/motor_manager.h" 9 | 10 | typedef struct { 11 | motor_manager_t* m; 12 | float direction; 13 | } rs_motor_t; 14 | 15 | void rs_left_wheel_set_voltage(void* motor, int32_t voltage); 16 | void rs_right_wheel_set_voltage(void* motor, int32_t voltage); 17 | 18 | void rs_encoder_init(void); 19 | int32_t rs_encoder_get_left_ext(void* nothing); 20 | int32_t rs_encoder_get_right_ext(void* nothing); 21 | 22 | #ifdef __cplusplus 23 | } 24 | #endif 25 | 26 | #endif /* AVERSIVE_RS_PORT_H */ 27 | -------------------------------------------------------------------------------- /master-firmware/src/can/actuator_driver_uavcan.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ACTUATOR_DRIVER_UAVCAN_HPP 2 | #define ACTUATOR_DRIVER_UAVCAN_HPP 3 | 4 | #include 5 | 6 | int actuator_driver_uavcan_init(uavcan::INode& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /master-firmware/src/can/actuator_handler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "bus_enumerator.h" 5 | 6 | int actuator_handler_init(uavcan::INode& node, bus_enumerator_t* enumerator); 7 | -------------------------------------------------------------------------------- /master-firmware/src/can/beacon_signal_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BEACON_SIGNAL_HANDLER_HPP 2 | #define BEACON_SIGNAL_HANDLER_HPP 3 | 4 | #include 5 | 6 | int beacon_signal_handler_init(uavcan::INode& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /master-firmware/src/can/can_io_driver.h: -------------------------------------------------------------------------------- 1 | #ifndef CAN_IO_H 2 | #define CAN_IO_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void can_io_set_pwm(const char* can_io_name, int channel, float pwm); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #ifdef __cplusplus 15 | #include 16 | int can_io_init(uavcan::INode& node); 17 | #endif 18 | 19 | #endif /* CAN_IO_H */ 20 | -------------------------------------------------------------------------------- /master-firmware/src/can/emergency_stop_handler.cpp: -------------------------------------------------------------------------------- 1 | #include "emergency_stop_handler.hpp" 2 | #include 3 | #include 4 | 5 | static void emergency_stop_cb(const uavcan::ReceivedDataStructure& msg) 6 | { 7 | (void)msg; 8 | WARNING("received emergency stop, exiting..."); 9 | exit(1); 10 | } 11 | 12 | int emergency_stop_init(uavcan::INode& node) 13 | { 14 | uavcan::Subscriber emergency_stop_sub(node); 15 | return emergency_stop_sub.start(emergency_stop_cb); 16 | } 17 | -------------------------------------------------------------------------------- /master-firmware/src/can/emergency_stop_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EMERGENCY_STOP_HANDLER_HPP 2 | #define EMERGENCY_STOP_HANDLER_HPP 3 | 4 | #include 5 | 6 | int emergency_stop_init(uavcan::INode& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /master-firmware/src/can/motor_driver_uavcan.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MOTOR_DRIVER_UAVCAN_HPP 2 | #define MOTOR_DRIVER_UAVCAN_HPP 3 | 4 | #include 5 | 6 | int motor_driver_uavcan_init(uavcan::INode& node); 7 | 8 | #endif /* MOTOR_DRIVER_UAVCAN_HPP */ 9 | -------------------------------------------------------------------------------- /master-firmware/src/can/motor_feedback_streams_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MOTOR_FEEDBACK_STREAMS_HANDLER_HPP 2 | #define MOTOR_FEEDBACK_STREAMS_HANDLER_HPP 3 | 4 | #include 5 | #include "bus_enumerator.h" 6 | 7 | int motor_feedback_stream_handler_init(uavcan::INode& node, bus_enumerator_t* enumerator); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /master-firmware/src/can/sensor_handler.h: -------------------------------------------------------------------------------- 1 | #ifndef SENSOR_HANDLER_H 2 | #define SENSOR_HANDLER_H 3 | 4 | #include 5 | #include "bus_enumerator.h" 6 | 7 | int sensor_handler_init(uavcan::INode& node, bus_enumerator_t* enumerator); 8 | 9 | #endif /* SENSOR_HANDLER_H */ 10 | -------------------------------------------------------------------------------- /master-firmware/src/can/time_sync_server.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | int time_sync_server_start(uavcan::INode& node); 6 | -------------------------------------------------------------------------------- /master-firmware/src/can/uavcan_node.h: -------------------------------------------------------------------------------- 1 | #ifndef UAVCAN_NODE_H 2 | #define UAVCAN_NODE_H 3 | 4 | #ifdef __cplusplus 5 | #include 6 | 7 | void uavcan_node_start(std::string can_iface, uint8_t id); 8 | 9 | extern "C" { 10 | #endif 11 | 12 | #include 13 | #include "bus_enumerator.h" 14 | 15 | extern bus_enumerator_t bus_enumerator; 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #endif /* UAVCAN_NODE_H */ 22 | -------------------------------------------------------------------------------- /master-firmware/src/can/wheel_encoders_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WHEEL_ENCODERS_HANDLER_HPP 2 | #define WHEEL_ENCODERS_HANDLER_HPP 3 | 4 | #include 5 | 6 | int wheel_encoder_handler_init(uavcan::INode& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /master-firmware/src/commands.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMANDS_H_ 2 | #define COMMANDS_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | void shell_spawn(BaseSequentialStream* stream); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif /* COMMANDS_H_ */ 17 | -------------------------------------------------------------------------------- /master-firmware/src/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | extern parameter_namespace_t global_config; 11 | extern parameter_namespace_t actuator_config; 12 | extern parameter_namespace_t master_config; 13 | 14 | /* Inits all the globally available objects. */ 15 | void config_init(void); 16 | 17 | /** Shorthand to get a parameter via its name. 18 | * 19 | * @note Panics if the ID is unknown. 20 | */ 21 | float config_get_scalar(const char* id); 22 | int config_get_integer(const char* id); 23 | bool config_get_boolean(const char* id); 24 | 25 | /* Macro to easily find a parameter from path */ 26 | #define PARAMETER(s) parameter_find(&global_config, (s)) 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | 32 | #endif /* CONFIG_H */ 33 | -------------------------------------------------------------------------------- /master-firmware/src/debug/log.h: -------------------------------------------------------------------------------- 1 | #ifndef LOG_H 2 | #define LOG_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void log_init(int enable_verbose); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif /* LOG_H */ 15 | -------------------------------------------------------------------------------- /master-firmware/src/gui.h: -------------------------------------------------------------------------------- 1 | #ifndef GUI_H 2 | #define GUI_H 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | void gui_start(void); 12 | 13 | #ifdef __cplusplus 14 | } 15 | #endif 16 | 17 | #endif /* GUI_H */ 18 | -------------------------------------------------------------------------------- /master-firmware/src/gui/MenuPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "Menu.h" 5 | #include "Page.h" 6 | #include 7 | 8 | class MenuPage : public Page { 9 | GHandle buttons[6]; 10 | Page* next_page[6]; 11 | Menu& menu_; 12 | const char* name_; 13 | 14 | public: 15 | /// Creates a page linking to up to 6 subpages 16 | MenuPage(Menu& menu, 17 | const char* name, 18 | Page* p1, 19 | Page* p2 = nullptr, 20 | Page* p3 = nullptr, 21 | Page* p4 = nullptr, 22 | Page* p5 = nullptr, 23 | Page* p6 = nullptr); 24 | 25 | virtual void on_enter(GHandle parent); 26 | 27 | virtual void on_event(GEvent* event); 28 | 29 | virtual const char* get_name() 30 | { 31 | return name_; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /master-firmware/src/gui/Page.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class Page { 6 | Page* history_previous; 7 | 8 | public: 9 | /** Event called when we enter this page. */ 10 | virtual void on_enter(GHandle parent) = 0; 11 | 12 | /** Event called when we exit this page. */ 13 | virtual void on_exit() 14 | { 15 | } 16 | 17 | /** Event called periodically */ 18 | virtual void on_timer() 19 | { 20 | } 21 | 22 | /** Called when an event occured. */ 23 | virtual void on_event(GEvent* event) = 0; 24 | 25 | virtual const char* get_name() = 0; 26 | 27 | void set_previous_page(Page* p) 28 | { 29 | history_previous = p; 30 | } 31 | 32 | Page* get_previous_page() const 33 | { 34 | return history_previous; 35 | } 36 | 37 | virtual ~Page() 38 | { 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /master-firmware/src/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #include "can/motor_manager.h" 5 | #include "can/actuator_driver.h" 6 | #include 7 | #include "msgbus_protobuf.h" 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #define MAX_NB_MOTOR_DRIVERS 20 14 | #define MAX_NB_BUS_ENUMERATOR_ENTRIES 21 15 | 16 | /** Robot wide interthread bus. */ 17 | extern messagebus_t bus; 18 | 19 | extern motor_manager_t motor_manager; 20 | extern parameter_namespace_t global_config; 21 | 22 | extern actuator_driver_t actuator_front_left, actuator_front_center, actuator_front_right; 23 | extern actuator_driver_t actuator_back_left, actuator_back_center, actuator_back_right; 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif /* MAIN_H */ 30 | -------------------------------------------------------------------------------- /master-firmware/src/parameter_port.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static std::mutex parameter_lock; 6 | 7 | extern "C" void parameter_port_lock(void) 8 | { 9 | parameter_lock.lock(); 10 | } 11 | 12 | extern "C" void parameter_port_unlock(void) 13 | { 14 | parameter_lock.unlock(); 15 | } 16 | 17 | extern "C" void parameter_port_assert(int condition) 18 | { 19 | if (!condition) { 20 | ERROR("parameter_assert()"); 21 | } 22 | } 23 | 24 | extern "C" void* parameter_port_buffer_alloc(size_t size) 25 | { 26 | return new uint8_t[size]; 27 | } 28 | 29 | extern "C" void parameter_port_buffer_free(void* buffer) 30 | { 31 | uint8_t* ptr = (uint8_t*)buffer; 32 | delete[] ptr; 33 | } 34 | -------------------------------------------------------------------------------- /master-firmware/src/robot_helpers/autoposition.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "strategy/color.h" 5 | 6 | /** Auto position robot at requested location, and ensure the correct 7 | * position is reached by aligning against walls. 8 | */ 9 | void strategy_auto_position(int32_t x, int32_t y, int32_t heading, enum strat_color_t robot_color); 10 | 11 | /** Align on y axis */ 12 | void strategy_align_y(int32_t y); 13 | -------------------------------------------------------------------------------- /master-firmware/src/robot_helpers/beacon_helpers.h: -------------------------------------------------------------------------------- 1 | #ifndef BEACON_HELPERS_H 2 | #define BEACON_HELPERS_H 3 | 4 | #include 5 | #include 6 | 7 | /** Compute beacon angle from beacon signal values 8 | */ 9 | float beacon_get_angle(float start_angle, float signal_length); 10 | 11 | /** Convert from 2D polar coordinates to 2D cartesian coordinates 12 | */ 13 | void beacon_cartesian_convert(struct robot_position* robot_pos, 14 | float distance, 15 | float angle, 16 | float* x, 17 | float* y); 18 | 19 | #endif /* BEACON_HELPERS_H */ 20 | -------------------------------------------------------------------------------- /master-firmware/src/robot_helpers/robot.h: -------------------------------------------------------------------------------- 1 | #ifndef ROBOT_HELPERS_ROBOT_H 2 | #define ROBOT_HELPERS_ROBOT_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | typedef enum { 9 | RIGHT = (0b01), 10 | LEFT = (0b10), 11 | BOTH = (0b11), 12 | } manipulator_side_t; 13 | #define USE_RIGHT(side) ((side & RIGHT) > 0) 14 | #define USE_LEFT(side) ((side & LEFT) > 0) 15 | 16 | #define MIRROR_ARM(side, x) ((side == RIGHT) ? (+x) : (-x)) 17 | 18 | typedef enum { 19 | GRIPPER_OFF, 20 | GRIPPER_ACQUIRE, 21 | GRIPPER_RELEASE, 22 | } gripper_state_t; 23 | 24 | #ifdef __cplusplus 25 | } 26 | #endif 27 | 28 | #endif /* ROBOT_HELPERS_ROBOT_H */ 29 | -------------------------------------------------------------------------------- /master-firmware/src/strategy.h: -------------------------------------------------------------------------------- 1 | #ifndef STRATEGY_H 2 | #define STRATEGY_H 3 | 4 | #include 5 | #include "strategy/actions.h" 6 | 7 | void strategy_play_game(); 8 | 9 | std::vector*> strategy_get_actions(); 10 | 11 | #endif /* STRATEGY_H */ 12 | -------------------------------------------------------------------------------- /master-firmware/src/strategy/color.h: -------------------------------------------------------------------------------- 1 | #ifndef STRATEGY_COLOR_H 2 | #define STRATEGY_COLOR_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | /** Team color 9 | */ 10 | enum strat_color_t { 11 | BLUE = 0, 12 | YELLOW 13 | }; 14 | 15 | /** Compute the symmetrical position depending on color 16 | */ 17 | #define MIRROR_X(color, x) (color == YELLOW ? (x) : 3000.f - (x)) 18 | #define MIRROR_A(color, a_deg) (color == YELLOW ? (a_deg) : 180.f - (a_deg)) 19 | #define MIRROR(color, value) (color == YELLOW ? (value) : -(value)) 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif /* STRATEGY_COLOR_H */ 26 | -------------------------------------------------------------------------------- /master-firmware/src/strategy/goals.cpp: -------------------------------------------------------------------------------- 1 | #include "goals.h" 2 | 3 | namespace goals { 4 | int LighthouseEnabled::distance_to(const StrategyState& state) const 5 | { 6 | return goap::Distance().shouldBeTrue(state.lighthouse_is_on); 7 | } 8 | 9 | int WindsocksUp::distance_to(const StrategyState& state) const 10 | { 11 | return goap::Distance() 12 | .shouldBeTrue(state.windsocks_are_up[0]) 13 | .shouldBeTrue(state.windsocks_are_up[1]); 14 | } 15 | } // namespace goals 16 | -------------------------------------------------------------------------------- /master-firmware/src/strategy/goals.h: -------------------------------------------------------------------------------- 1 | #ifndef STRATEGY_GOALS_H 2 | #define STRATEGY_GOALS_H 3 | 4 | #include 5 | #include "state.h" 6 | 7 | namespace goals { 8 | class LighthouseEnabled : public goap::Goal { 9 | public: 10 | int distance_to(const StrategyState& state) const override; 11 | }; 12 | 13 | class WindsocksUp : public goap::Goal { 14 | public: 15 | int distance_to(const StrategyState& state) const override; 16 | }; 17 | 18 | } // namespace goals 19 | 20 | // TODO(all): Write goals 21 | 22 | #endif /* STRATEGY_GOALS_H */ 23 | -------------------------------------------------------------------------------- /master-firmware/src/strategy/score.h: -------------------------------------------------------------------------------- 1 | #ifndef SCORE_H 2 | #define SCORE_H 3 | 4 | #include "strategy/state.h" 5 | 6 | int compute_score(const StrategyState& state, bool is_main_robot); 7 | 8 | #endif /* SCORE_H */ 9 | -------------------------------------------------------------------------------- /master-firmware/src/strategy/state.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "state.h" 4 | 5 | StrategyState initial_state() 6 | { 7 | StrategyState state = StrategyState_init_default; 8 | 9 | return state; 10 | } 11 | 12 | bool operator==(const StrategyState& lhs, const StrategyState& rhs) 13 | { 14 | return !memcmp(&lhs, &rhs, sizeof(StrategyState)); 15 | } 16 | -------------------------------------------------------------------------------- /master-firmware/src/strategy/state.h: -------------------------------------------------------------------------------- 1 | #ifndef STRATEGY_STATE_H 2 | #define STRATEGY_STATE_H 3 | 4 | #include 5 | 6 | #include "table.h" 7 | 8 | #include "protobuf/strategy.pb.h" 9 | 10 | #define PUCK_IS_GREEN_OR_BLUE(puck) (((puck) == PuckColor_BLUE) || ((puck) == PuckColor_GREEN)) 11 | 12 | StrategyState initial_state(void); 13 | bool operator==(const StrategyState& lhs, const StrategyState& rhs); 14 | 15 | #endif /* STRATEGY_STATE_H */ 16 | -------------------------------------------------------------------------------- /master-firmware/src/strategy/table.h: -------------------------------------------------------------------------------- 1 | #ifndef STRATEGY_TABLE_H 2 | #define STRATEGY_TABLE_H 3 | 4 | #include "protobuf/strategy.pb.h" 5 | 6 | // TODO(all): Write the table content here 7 | 8 | #endif /* STRATEGY_TABLE_H */ 9 | -------------------------------------------------------------------------------- /master-firmware/src/timestamp.cpp: -------------------------------------------------------------------------------- 1 | #include "timestamp.h" 2 | #include 3 | 4 | int64_t timestamp_get_us() 5 | { 6 | auto now = std::chrono::steady_clock::now(); 7 | return std::chrono::time_point_cast(now) 8 | .time_since_epoch() 9 | .count(); 10 | } 11 | 12 | absl::Time timestamp_get() 13 | { 14 | return absl::FromUnixMicros(timestamp_get_us()); 15 | } 16 | -------------------------------------------------------------------------------- /master-firmware/src/timestamp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | /** Returns the number of microseconds since UNIX epoch. Guaranteed to be 6 | * monotoonic (never goes back in time), means that it can be different from 7 | * the computer's local time. */ 8 | int64_t timestamp_get_us(); 9 | 10 | /** Returns an absl::Time representation of the time represented in 11 | * timestamp_get_us(). This is different from absl::Now(), which returns a 12 | * non-monotonic clock. */ 13 | absl::Time timestamp_get(); 14 | -------------------------------------------------------------------------------- /master-firmware/test_build.sh: -------------------------------------------------------------------------------- 1 | git submodule update --init --recursive 2 | docker run -it -v $(pwd):/src -w /src/lib/nanopb/nanopb/generator/proto cvra-buildroot make 3 | mkdir build-docker 4 | docker run -it -v $(pwd):/src -w /src/build-docker cvra-buildroot cmake .. -DCMAKE_TOOLCHAIN_FILE=/aarch64-buildroot-linux-gnu_sdk-buildroot/share/buildroot/toolchainfile.cmake 5 | docker run -it -v $(pwd):/src -w /src/build-docker cvra-buildroot make master-firmware.ipk 6 | -------------------------------------------------------------------------------- /master-firmware/tests/ch.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static bool lock_enabled = false; 6 | 7 | void chMtxObjectInit(mutex_t* mp) 8 | { 9 | (void)mp; 10 | } 11 | 12 | void chMtxLock(mutex_t* lock) 13 | { 14 | if (lock_enabled) { 15 | mock().actualCall("chMtxLock").withPointerParameter("lock", lock); 16 | } 17 | } 18 | 19 | void chMtxUnlock(mutex_t* lock) 20 | { 21 | if (lock_enabled) { 22 | mock().actualCall("chMtxUnlock").withPointerParameter("lock", lock); 23 | } 24 | } 25 | 26 | void lock_mocks_enable(bool enabled) 27 | { 28 | lock_enabled = enabled; 29 | } 30 | 31 | void chThdSleepMilliseconds(int milliseconds) 32 | { 33 | (void)milliseconds; 34 | } 35 | -------------------------------------------------------------------------------- /master-firmware/tests/ch.h: -------------------------------------------------------------------------------- 1 | #ifndef CH_H 2 | #define CH_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "stdbool.h" 9 | 10 | typedef int mutex_t; 11 | typedef int semaphore_t; 12 | 13 | void lock_mocks_enable(bool enabled); 14 | 15 | void chMtxObjectInit(mutex_t* mp); 16 | void chMtxLock(mutex_t* lock); 17 | void chMtxUnlock(mutex_t* lock); 18 | void chThdSleepMilliseconds(int milliseconds); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif /* CH_H */ 25 | -------------------------------------------------------------------------------- /master-firmware/tests/hal.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/master-firmware/tests/hal.h -------------------------------------------------------------------------------- /motor-control-firmware/.gdbinit: -------------------------------------------------------------------------------- 1 | ../tools/gdbinit -------------------------------------------------------------------------------- /motor-control-firmware/.gitignore: -------------------------------------------------------------------------------- 1 | src/src.mk 2 | CMakeLists.txt 3 | -------------------------------------------------------------------------------- /motor-control-firmware/Makefile.include.jinja: -------------------------------------------------------------------------------- 1 | {% for dir in include_directories %} 2 | PROJINC += {{ dir }} 3 | {% endfor %} 4 | 5 | {% for file in target.arm + target.stm32f3 + source %} 6 | {%- if file.endswith('.c') %}PROJCSRC += {{ file }} 7 | {% elif file.endswith('.s') %}PROJASMSRC += {{ file }} 8 | {% elif file.endswith('.cpp') %}PROJCPPSRC += {{ file }} 9 | {% endif -%}{% endfor %} 10 | -------------------------------------------------------------------------------- /motor-control-firmware/doc/motor_schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/motor-control-firmware/doc/motor_schema.png -------------------------------------------------------------------------------- /motor-control-firmware/doc/noname.markdown: -------------------------------------------------------------------------------- 1 | CVRA Motor Board User Manual 2 | ============================ 3 | 4 | # Definitions 5 | 6 | ![Schema](motor_schema.png) 7 | 8 | * θ: angular position at the output in __rad__ 9 | * ω: angular velocity at the output in __rad/s__ 10 | * α: angular acceleration at the output in __rad/s²__ 11 | * τ: torque at the output in __Nm__ 12 | * K: transmission ratio from motor to output 13 | * θ₂: angular position at supplementary encoder in __rad__ 14 | * ω₂: angular velocity at supplementary encoder __rad/s__ 15 | * Kτ: torque constant in __Nm/A__ 16 | 17 | # Use Cases 18 | 19 | # Pinout 20 | 21 | # Features 22 | 23 | 24 | -------------------------------------------------------------------------------- /motor-control-firmware/openocd.cfg: -------------------------------------------------------------------------------- 1 | telnet_port 4444 2 | gdb_port 3333 3 | 4 | source [find interface/stlink-v2.cfg] 5 | transport select hla_swd 6 | 7 | source [find target/stm32f3x.cfg] 8 | #reset_config srst_only srst_nogate 9 | -------------------------------------------------------------------------------- /motor-control-firmware/src/analog.h: -------------------------------------------------------------------------------- 1 | #ifndef ANALOG_H 2 | #define ANALOG_H 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #define ANALOG_EVENT_CONVERSION_DONE 1 11 | extern event_source_t analog_event; 12 | 13 | #define ANALOG_CONVERSION_FREQUENCY 2002 // frequency of the conversion event 14 | 15 | float analog_get_motor_current(void); 16 | float analog_get_battery_voltage(void); 17 | float analog_get_auxiliary(void); 18 | void analog_init(void); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif /* ANALOG_H */ 25 | -------------------------------------------------------------------------------- /motor-control-firmware/src/blocking_uart_driver.h: -------------------------------------------------------------------------------- 1 | #ifndef BLOCKING_UART_DRIVER_H 2 | #define BLOCKING_UART_DRIVER_H 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | extern const struct BaseSequentialStreamVMT blocking_uart_put_vmt; 12 | 13 | typedef struct { 14 | const struct BaseSequentialStreamVMT* vmt; 15 | USART_TypeDef* dev; 16 | } BlockingUARTDriver; 17 | 18 | msg_t blocking_uart_put(void* instance, uint8_t b); 19 | msg_t blocking_uart_get(void* instance); 20 | size_t blocking_uart_write(void* instance, const uint8_t* bp, size_t n); 21 | size_t blocking_uart_read(void* instance, uint8_t* bp, size_t n); 22 | 23 | void blocking_uart_init(BlockingUARTDriver* driver, USART_TypeDef* uart, uint32_t baud); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif /* BLOCKING_UART_DRIVER_H */ -------------------------------------------------------------------------------- /motor-control-firmware/src/bootloader_config.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOTLOADER_CONFIG_H 2 | #define BOOTLOADER_CONFIG_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // returns true if config read was successful 13 | bool config_get(bootloader_config_t* cfg); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif /* BOOTLOADER_CONFIG_H */ -------------------------------------------------------------------------------- /motor-control-firmware/src/encoder.h: -------------------------------------------------------------------------------- 1 | #ifndef ENCODER_H 2 | #define ENCODER_H 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | uint32_t encoder_get_primary(void); 11 | uint32_t encoder_get_secondary(void); 12 | void encoder_init_primary(void); 13 | void encoder_init_secondary(void); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif /* ENCODER_H */ 20 | -------------------------------------------------------------------------------- /motor-control-firmware/src/index.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "index.h" 3 | #include "control.h" 4 | 5 | static float position; 6 | static uint32_t update_count; 7 | 8 | static void index_cb(void* arg) 9 | { 10 | (void)arg; 11 | 12 | chSysLockFromISR(); 13 | 14 | position = control_get_position(); 15 | update_count++; 16 | 17 | chSysUnlockFromISR(); 18 | } 19 | 20 | void index_init(void) 21 | { 22 | position = 0; 23 | 24 | // Enable event on index pin, active low, PA12 25 | palEnableLineEvent(PAL_LINE(GPIOA, 12U), PAL_EVENT_MODE_FALLING_EDGE); 26 | palSetLineCallback(PAL_LINE(GPIOA, 12U), index_cb, NULL); 27 | } 28 | 29 | void index_get_position(float* out_position, uint32_t* out_update_count) 30 | { 31 | *out_position = position; 32 | *out_update_count = update_count; 33 | } 34 | -------------------------------------------------------------------------------- /motor-control-firmware/src/index.h: -------------------------------------------------------------------------------- 1 | #ifndef INDEX_H 2 | #define INDEX_H 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | void index_init(void); 11 | void index_get_position(float* out_position, uint32_t* out_update_count); 12 | 13 | #ifdef __cplusplus 14 | } 15 | #endif 16 | 17 | #endif /* INDEX_H */ 18 | -------------------------------------------------------------------------------- /motor-control-firmware/src/libstubs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace __gnu_cxx { 4 | 5 | void __verbose_terminate_handler() 6 | { 7 | std::abort(); 8 | } 9 | 10 | } // namespace __gnu_cxx 11 | -------------------------------------------------------------------------------- /motor-control-firmware/src/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | 11 | extern BaseSequentialStream* ch_stdout; 12 | extern parameter_namespace_t parameter_root_ns; 13 | 14 | /* Addresses provided by the linker script. */ 15 | extern int _config_start, _config_end; 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #endif /* MAIN_H */ 22 | -------------------------------------------------------------------------------- /motor-control-firmware/src/motor_protection.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "motor_protection.h" 3 | 4 | #define T_AMBIENT 25 5 | 6 | void motor_protection_init(motor_protection_t* p, float t_max, float r_th, float c_th, float current_gain) 7 | { 8 | p->t = T_AMBIENT; 9 | p->t_ambient = T_AMBIENT; 10 | p->t_max = t_max; 11 | p->r_th = r_th; 12 | p->c_th = c_th; 13 | p->current_gain = current_gain; 14 | } 15 | 16 | float motor_protection_update(motor_protection_t* p, float current, float delta_t) 17 | { 18 | float P_in = current * p->current_gain; 19 | float P_out = (p->t - p->t_ambient) / p->r_th; 20 | p->t += (P_in - P_out) * delta_t / p->c_th; 21 | 22 | float equilibrium_current = P_out / p->current_gain; // P_in = P_out 23 | if (p->t >= p->t_max) { 24 | return equilibrium_current; 25 | } 26 | return INFINITY; 27 | } 28 | -------------------------------------------------------------------------------- /motor-control-firmware/src/motor_protection.h: -------------------------------------------------------------------------------- 1 | #ifndef MOTOR_PROTECTION_H 2 | #define MOTOR_PROTECTION_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | typedef struct { 9 | float t; 10 | float t_max; 11 | float t_ambient; 12 | float r_th; 13 | float c_th; 14 | float current_gain; 15 | } motor_protection_t; 16 | 17 | void motor_protection_init(motor_protection_t* p, float t_max, float r_th, float c_th, float current_gain); 18 | float motor_protection_update(motor_protection_t* p, float current, float delta_t); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif /* MOTOR_PROTECTION_H */ 25 | -------------------------------------------------------------------------------- /motor-control-firmware/src/motor_pwm.h: -------------------------------------------------------------------------------- 1 | #ifndef MOTOR_PWM_H 2 | #define MOTOR_PWM_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void motor_pwm_setup(void); 9 | 10 | /* 11 | * dc : duty cycle between -1 and +1, negative for reverse direction 12 | */ 13 | void motor_pwm_set(float dc); 14 | 15 | /* 16 | * drive the motor voltage 17 | */ 18 | void motor_pwm_enable(void); 19 | 20 | /* 21 | * don't drive the motor (floating) 22 | */ 23 | void motor_pwm_disable(void); 24 | 25 | /* 26 | * trigger charge pump recharge cycle (must be called every 2ms) 27 | */ 28 | void motor_pwm_trigger_update_from_isr(bool recharge); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif /* MOTOR_PWM_H */ -------------------------------------------------------------------------------- /motor-control-firmware/src/reboot.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #define BOOT_ARG_MAGIC_VALUE_LO 0x01234567 6 | #define BOOT_ARG_MAGIC_VALUE_HI 0x0089abcd 7 | 8 | void reboot_system(uint8_t arg) 9 | { 10 | uint32_t* ram_start = (uint32_t*)0x20000000; 11 | 12 | ram_start[0] = BOOT_ARG_MAGIC_VALUE_LO; 13 | ram_start[1] = BOOT_ARG_MAGIC_VALUE_HI | (arg << 24); 14 | 15 | NVIC_SystemReset(); 16 | } 17 | -------------------------------------------------------------------------------- /motor-control-firmware/src/rpm.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef RPM_H 3 | #define RPM_H 4 | 5 | #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | void rpm_barrier_crossing(timestamp_t time); // called by interrupt 12 | float rpm_get_position(void); 13 | float rpm_get_velocity(void); 14 | void rpm_get_velocity_and_position(float* velocity, float* position); 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | 20 | #endif /* RPM_H */ 21 | -------------------------------------------------------------------------------- /motor-control-firmware/src/rpm_port.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef RPM_PORT_H 3 | #define RPM_PORT_H 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) 10 | 11 | #define RPM_LOCK() \ 12 | { \ 13 | } 14 | 15 | #define RPM_UNLOCK() \ 16 | { \ 17 | } 18 | 19 | #else 20 | 21 | #include 22 | 23 | #define RPM_LOCK() \ 24 | { \ 25 | chSysLock(); \ 26 | } 27 | 28 | #define RPM_UNLOCK() \ 29 | { \ 30 | chSysUnlock(); \ 31 | } 32 | 33 | #endif 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif /* RPM_PORT_H */ 40 | -------------------------------------------------------------------------------- /motor-control-firmware/src/stream.c: -------------------------------------------------------------------------------- 1 | #include "stream.h" 2 | #include 3 | 4 | void stream_set_prescaler(stream_config_t* stream_config, float frequency, float spin_frequency) 5 | { 6 | stream_config->prescaler = nearbyint(spin_frequency / frequency); 7 | stream_config->counter = stream_config->prescaler; 8 | } 9 | 10 | void stream_enable(stream_config_t* stream_config, bool enabled) 11 | { 12 | stream_config->enabled = enabled; 13 | } 14 | 15 | bool stream_should_send(stream_config_t* stream_config) 16 | { 17 | if (stream_config->enabled) { 18 | stream_config->counter--; 19 | if (stream_config->counter == 0) { 20 | stream_config->counter = stream_config->prescaler; 21 | return true; 22 | } else { 23 | return false; 24 | } 25 | } 26 | 27 | return false; 28 | } 29 | -------------------------------------------------------------------------------- /motor-control-firmware/src/stream.h: -------------------------------------------------------------------------------- 1 | #ifndef STREAM_H 2 | #define STREAM_H 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef struct { 12 | bool enabled; 13 | uint16_t prescaler; 14 | uint16_t counter; 15 | } stream_config_t; 16 | 17 | void stream_set_prescaler(stream_config_t* stream_config, float frequency, float spin_frequency); 18 | void stream_enable(stream_config_t* stream_config, bool enabled); 19 | bool stream_should_send(stream_config_t* stream_config); 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif /* STREAM_H */ 26 | -------------------------------------------------------------------------------- /motor-control-firmware/src/timestamp_stm32_settings.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMESTAMP_STM32_SETTINGS_H 2 | #define TIMESTAMP_STM32_SETTINGS_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | // settings 11 | #define TIMESTAMP_TIMER TIM7 12 | #define TIMER_REG STM32_TIM7 13 | #define TIMER_IRQ_NAME STM32_TIM7_HANDLER 14 | #define RCC_EN() rccEnableTIM7(FALSE) 15 | #define RCC_RESET() rccResetTIM7() 16 | #define NVIC_NB STM32_TIM7_NUMBER 17 | 18 | #define COUNTER_MAX 0xffff 19 | 20 | // CK_CNT = CK_INT / (PSC[15:0] + 1) 21 | #if STM32_PPRE1 == STM32_PPRE1_DIV1 22 | #define PRESCALER (STM32_PCLK1 / 1000000 - 1) 23 | #else 24 | #define PRESCALER (2 * STM32_PCLK1 / 1000000 - 1) 25 | #endif 26 | #define INTERRUPT_PRIO 5 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | 32 | #endif /* TIMESTAMP_STM32_SETTINGS_H */ 33 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/EmergencyStop_handler.cpp: -------------------------------------------------------------------------------- 1 | #include "EmergencyStop_handler.hpp" 2 | #include 3 | #include 4 | 5 | int EmergencyStop_handler_start(Node& node) 6 | { 7 | int ret; 8 | static uavcan::Subscriber sub(node); 9 | 10 | ret = sub.start( 11 | [&](const uavcan::ReceivedDataStructure& msg) { 12 | (void)msg; 13 | reboot_system(BOOT_ARG_START_BOOTLOADER_NO_TIMEOUT); 14 | }); 15 | return ret; 16 | } 17 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/EmergencyStop_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EMERGENCYSTOP_HANDLER_HPP 2 | #define EMERGENCYSTOP_HANDLER_HPP 3 | 4 | #include "uavcan_node.h" 5 | 6 | int EmergencyStop_handler_start(Node& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/Position_handler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Position_handler.hpp" 3 | #include "uavcan_node.h" 4 | #include 5 | #include "control.h" 6 | 7 | int Position_handler_start(Node& node) 8 | { 9 | int ret; 10 | static uavcan::Subscriber sub(node); 11 | 12 | ret = sub.start( 13 | [&](const uavcan::ReceivedDataStructure& msg) { 14 | if (uavcan::NodeID(msg.node_id) == node.getNodeID()) { 15 | control_update_position_setpoint(msg.position); 16 | } 17 | }); 18 | 19 | return ret; 20 | } 21 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/Position_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef POSITION_HANDLER_HPP 2 | #define POSITION_HANDLER_HPP 3 | 4 | #include "uavcan_node.h" 5 | int Position_handler_start(Node& node); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/Reboot_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOOT_HANDLER_HPP 2 | #define REBOOT_HANDLER_HPP 3 | 4 | #include "uavcan_node.h" 5 | 6 | int Reboot_handler_start(Node& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/Torque_handler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Torque_handler.hpp" 3 | #include "uavcan_node.h" 4 | #include 5 | #include "control.h" 6 | 7 | int Torque_handler_start(Node& node) 8 | { 9 | int ret; 10 | static uavcan::Subscriber sub(node); 11 | 12 | ret = sub.start( 13 | [&](const uavcan::ReceivedDataStructure& msg) { 14 | if (uavcan::NodeID(msg.node_id) == node.getNodeID()) { 15 | control_update_torque_setpoint(msg.torque); 16 | } 17 | }); 18 | 19 | return ret; 20 | } 21 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/Torque_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TORQUE_HANDLER_HPP 2 | #define TORQUE_HANDLER_HPP 3 | 4 | #include "uavcan_node.h" 5 | int Torque_handler_start(Node& node); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/Trajectory_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TRAJECTORY_HANDLER_HPP 2 | #define TRAJECTORY_HANDLER_HPP 3 | 4 | #include "uavcan_node.h" 5 | 6 | int Trajectory_handler_start(Node& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/Velocity_handler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Velocity_handler.hpp" 3 | #include "uavcan_node.h" 4 | #include 5 | #include "control.h" 6 | 7 | int Velocity_handler_start(Node& node) 8 | { 9 | int ret; 10 | static uavcan::Subscriber sub(node); 11 | 12 | ret = sub.start( 13 | [&](const uavcan::ReceivedDataStructure& msg) { 14 | if (uavcan::NodeID(msg.node_id) == node.getNodeID()) { 15 | control_update_velocity_setpoint(msg.velocity); 16 | } 17 | }); 18 | 19 | return ret; 20 | } 21 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/Velocity_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef VELOCITY_HANDLER_HPP 2 | #define VELOCITY_HANDLER_HPP 3 | 4 | #include "uavcan_node.h" 5 | int Velocity_handler_start(Node& node); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/Voltage_handler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Voltage_handler.hpp" 3 | #include "uavcan_node.h" 4 | #include 5 | #include "control.h" 6 | 7 | int Voltage_handler_start(Node& node) 8 | { 9 | int ret; 10 | static uavcan::Subscriber sub(node); 11 | 12 | ret = sub.start( 13 | [&](const uavcan::ReceivedDataStructure& msg) { 14 | if (uavcan::NodeID(msg.node_id) == node.getNodeID()) { 15 | control_update_voltage_setpoint(msg.voltage); 16 | } 17 | }); 18 | 19 | return ret; 20 | } 21 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/Voltage_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef VOLTAGE_HANDLER_HPP 2 | #define VOLTAGE_HANDLER_HPP 3 | 4 | #include "uavcan_node.h" 5 | int Voltage_handler_start(Node& node); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/parameter_server.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PARAMETER_SERVER_HPP 2 | #define PARAMETER_SERVER_HPP 3 | 4 | #include "uavcan_node.h" 5 | 6 | int parameter_server_start(Node& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/uavcan_node.h: -------------------------------------------------------------------------------- 1 | #ifndef UAVCAN_NODE_H 2 | #define UAVCAN_NODE_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | #define UAVCAN_SPIN_FREQUENCY 100 11 | 12 | struct uavcan_node_arg { 13 | const char* node_name; 14 | uint8_t node_id : 7; 15 | }; 16 | 17 | void uavcan_node_start(void* arg); 18 | void uavcan_init_complete(void); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #ifdef __cplusplus 25 | #include 26 | 27 | /** Returns the UAVCAN node. */ 28 | typedef uavcan::Node<4096> Node; 29 | 30 | #endif 31 | 32 | #endif /* UAVCAN_NODE_H */ 33 | -------------------------------------------------------------------------------- /motor-control-firmware/src/uavcan/uavcan_streams.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UAVCAN_STREAMS_HPP 2 | #define UAVCAN_STREAMS_HPP 3 | 4 | #include "uavcan_node.h" 5 | 6 | /** Starts the various state publishers. */ 7 | int uavcan_streams_start(Node& node); 8 | 9 | /** Must be called in the UAVCAN loop. */ 10 | void uavcan_streams_spin(Node& node); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /proximity-beacon-firmware/.gitignore: -------------------------------------------------------------------------------- 1 | CMakeLists.txt 2 | -------------------------------------------------------------------------------- /proximity-beacon-firmware/Makefile.include.jinja: -------------------------------------------------------------------------------- 1 | {% for dir in include_directories %} 2 | PROJINC += {{ dir }} 3 | {% endfor %} 4 | 5 | {% for file in target.stm32f3 + target.arm + source %} 6 | {%- if file.endswith('.c') %}PROJCSRC += {{ file }} 7 | {% elif file.endswith('.s') %}PROJASMSRC += {{ file }} 8 | {% elif file.endswith('.cpp') %}PROJCPPSRC += {{ file }} 9 | {% endif -%}{% endfor %} 10 | -------------------------------------------------------------------------------- /proximity-beacon-firmware/src/proximity_beacon.h: -------------------------------------------------------------------------------- 1 | #ifndef PROXIMITY_BEACON_H 2 | #define PROXIMITY_BEACON_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | struct proximity_beacon_signal { 9 | float start_angle; // [rad] 10 | float length; // [rad] 11 | }; 12 | 13 | void proximity_beacon_init(void); 14 | struct proximity_beacon_signal* proximity_beacon_signal_get(void); 15 | void proximity_beacon_signal_delete(struct proximity_beacon_signal* sp); 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #endif /* PROXIMITY_BEACON_H */ 22 | -------------------------------------------------------------------------------- /proximity-beacon-firmware/src/proximity_beacon_publisher.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PROXIMITY_BEACON_PUBLISHER_HPP 2 | #define PROXIMITY_BEACON_PUBLISHER_HPP 3 | 4 | #include "uavcan_node.h" 5 | 6 | int proximity_beacon_start(Node& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /sensor-firmware/.gdbinit: -------------------------------------------------------------------------------- 1 | file ./build/ch.elf 2 | target remote localhost:3333 3 | -------------------------------------------------------------------------------- /sensor-firmware/.gitignore: -------------------------------------------------------------------------------- 1 | CMakeLists.txt 2 | -------------------------------------------------------------------------------- /sensor-firmware/app_src.mk.jinja: -------------------------------------------------------------------------------- 1 | {% for dir in include_directories %} 2 | INCDIR += {{ dir }} 3 | {% endfor %} 4 | 5 | {% for file in target.arm + source -%} 6 | {% if file.endswith('.c') %}CSRC += {{ file }} 7 | {% elif file.endswith('.s') %}ASMSRC += {{ file }} 8 | {% elif file.endswith('.cpp') %}CPPSRC += {{ file }} 9 | {% endif %}{% endfor %} 10 | -------------------------------------------------------------------------------- /sensor-firmware/openocd.cfg: -------------------------------------------------------------------------------- 1 | telnet_port 4444 2 | gdb_port 3333 3 | 4 | # ST-Link-V2 5 | source [find interface/stlink-v2.cfg] 6 | 7 | transport select hla_swd 8 | source [find target/stm32f3x.cfg] 9 | -------------------------------------------------------------------------------- /sensor-firmware/package.yml: -------------------------------------------------------------------------------- 1 | dependency-dir: ../lib 2 | 3 | include_directories: 4 | - src/ 5 | 6 | depends: 7 | - chibios-syscalls 8 | - cmp 9 | - cmp_mem_access 10 | - error 11 | - crc 12 | - version 13 | 14 | source: 15 | - src/vl6180x/vl6180x.c 16 | 17 | target.arm: 18 | - src/main.c 19 | - src/debug.c 20 | - src/board.c 21 | - src/vl6180x/vl6180x_chibios.c 22 | - src/TCS3472.c 23 | - src/uavcan/node.cpp 24 | - src/uavcan/DistanceVL6180X_pub.cpp 25 | - src/uavcan/ColorRGBC_pub.cpp 26 | - src/bootloader_config.c 27 | - ../lib/can-bootloader/config.c 28 | 29 | tests: 30 | - tests/test_range_sensor.cpp 31 | 32 | templates: 33 | app_src.mk.jinja: app_src.mk 34 | CMakeLists.txt.jinja: CMakeLists.txt 35 | -------------------------------------------------------------------------------- /sensor-firmware/src/assert.h: -------------------------------------------------------------------------------- 1 | #ifndef ASSERT_H 2 | #define ASSERT_H 3 | 4 | #include 5 | 6 | #define assert(x) \ 7 | do { \ 8 | if (!(x)) { \ 9 | chSysHalt("assertion failed"); \ 10 | } \ 11 | } while (0) 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /sensor-firmware/src/bootloader_config.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOTLOADER_CONFIG_H 2 | #define BOOTLOADER_CONFIG_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // returns true if config read was successful 13 | bool config_get(bootloader_config_t* cfg); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif /* BOOTLOADER_CONFIG_H */ 20 | -------------------------------------------------------------------------------- /sensor-firmware/src/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUG_H 2 | #define DEBUG_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void debug_init(void); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif /* DEBUG_H */ 15 | -------------------------------------------------------------------------------- /sensor-firmware/src/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | extern bootloader_config_t config; 10 | 11 | #include 12 | extern vl6180x_t vl6180x_dev; 13 | 14 | #include 15 | extern TCS3472_t color_sensor; 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #endif /* MAIN_H */ 22 | -------------------------------------------------------------------------------- /sensor-firmware/src/uavcan/ColorRGBC_pub.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "ColorRGBC_pub.h" 4 | #include 5 | #include "main.h" 6 | 7 | void color_publish(uavcan::INode& node) 8 | { 9 | static uavcan::Publisher pub(node); 10 | 11 | uint16_t rgbc[4]; 12 | TCS3472_read_color(&color_sensor, rgbc); 13 | 14 | cvra::sensor::ColorRGBC msg = cvra::sensor::ColorRGBC(); 15 | 16 | msg.red = rgbc[0]; 17 | msg.green = rgbc[1]; 18 | msg.blue = rgbc[2]; 19 | msg.clear = rgbc[3]; 20 | 21 | pub.broadcast(msg); 22 | } 23 | -------------------------------------------------------------------------------- /sensor-firmware/src/uavcan/ColorRGBC_pub.h: -------------------------------------------------------------------------------- 1 | #ifndef COLOR_RGBC_PUB_H 2 | #define COLOR_RGBC_PUB_H 3 | 4 | #include 5 | 6 | void color_publish(uavcan::INode& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /sensor-firmware/src/uavcan/DistanceVL6180X_pub.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "DistanceVL6180X_pub.h" 4 | #include 5 | #include "main.h" 6 | 7 | void distance_publish(uavcan::INode& node) 8 | { 9 | static uavcan::Publisher pub(node); 10 | 11 | uint8_t distance_mm, status; 12 | status = vl6180x_measure_distance(&vl6180x_dev, &distance_mm); 13 | 14 | cvra::sensor::DistanceVL6180X msg = cvra::sensor::DistanceVL6180X(); 15 | 16 | msg.distance_mm = distance_mm; 17 | msg.status = status; 18 | 19 | pub.broadcast(msg); 20 | } 21 | -------------------------------------------------------------------------------- /sensor-firmware/src/uavcan/DistanceVL6180X_pub.h: -------------------------------------------------------------------------------- 1 | #ifndef DISTANCE_VL6180X_PUB_H 2 | #define DISTANCE_VL6180X_PUB_H 3 | 4 | #include 5 | 6 | void distance_publish(uavcan::INode& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /sensor-firmware/src/uavcan/node.h: -------------------------------------------------------------------------------- 1 | #ifndef UAVCAN_NODE_H 2 | #define UAVCAN_NODE_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void uavcan_start(unsigned int node_id, const char* node_name); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /sensor-firmware/src/vl6180x/vl6180x_chibios.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "vl6180x.h" 4 | 5 | #ifdef HAL_USE_I2C 6 | void vl6180x_write_register(vl6180x_t* dev, uint16_t reg, uint8_t val) 7 | { 8 | uint8_t buf[] = {(reg >> 8), reg & 0xff, val}; 9 | i2cMasterTransmit(dev->i2c, dev->address, buf, 3, NULL, 0); 10 | } 11 | 12 | uint8_t vl6180x_read_register(vl6180x_t* dev, uint16_t reg) 13 | { 14 | uint8_t ret; 15 | uint8_t buf[] = {(reg >> 8), reg & 0xff}; 16 | i2cMasterTransmit(dev->i2c, dev->address, buf, 2, &ret, 1); 17 | return ret; 18 | } 19 | #else 20 | #error "VL6180X driver requires I2C. Please enable HAL_USE_I2C." 21 | #endif 22 | -------------------------------------------------------------------------------- /tools/config/parser/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/tools/config/parser/__init__.py -------------------------------------------------------------------------------- /tools/config/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/tools/config/tests/__init__.py -------------------------------------------------------------------------------- /tools/gdbinit: -------------------------------------------------------------------------------- 1 | target remote localhost:3333 2 | file build/ch.elf 3 | -------------------------------------------------------------------------------- /tools/generate_ctags.mk: -------------------------------------------------------------------------------- 1 | # Generates a ctags file containing the correct definition for the build 2 | .PHONY: ctags 3 | ctags: 4 | @echo "Generating ctags file..." 5 | @cat .dep/*.d | grep ":$$" | sed "s/://" | sort | uniq | xargs ctags --file-scope=no --extra=+q $(CSRC) $(CPPSRC) 6 | -------------------------------------------------------------------------------- /tools/heap_size.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Shows how much heap memory is left in a ChibiOS project. 4 | """ 5 | import subprocess 6 | import argparse 7 | 8 | parser = argparse.ArgumentParser(description=__doc__) 9 | parser.add_argument("binary", help="Compiled program (ELF format)") 10 | 11 | args = parser.parse_args() 12 | 13 | command = "arm-none-eabi-nm --numeric-sort --print-size {}".format(args.binary).split() 14 | result = subprocess.check_output(command).decode().splitlines() 15 | 16 | heap_base = [s for s in result if "__heap_base__" in s][-1] 17 | heap_end = [s for s in result if "__heap_end__" in s][-1] 18 | 19 | heap_base = int(heap_base.split()[0], 16) 20 | heap_end = int(heap_end.split()[0], 16) 21 | 22 | print("Heap space left: {} bytes".format(heap_end - heap_base)) 23 | -------------------------------------------------------------------------------- /tools/raspi_debug_server/bootloader_change_id_remote.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu -o pipefail 3 | ssh pi@192.168.1.201 -t /home/pi/.local/bin/bootloader_change_id $@ -------------------------------------------------------------------------------- /tools/raspi_debug_server/bootloader_flash_remote.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu -o pipefail 3 | ssh pi@192.168.1.201 -t /home/pi/.local/bin/bootloader_flash $@ -------------------------------------------------------------------------------- /tools/raspi_debug_server/bootloader_read_config_remote.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu -o pipefail 3 | ssh pi@192.168.1.201 -t /home/pi/.local/bin/bootloader_read_config $@ -------------------------------------------------------------------------------- /tools/raspi_debug_server/bootloader_run_app_remote.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu -o pipefail 3 | ssh pi@192.168.1.201 -t /home/pi/.local/bin/bootloader_run_app $@ -------------------------------------------------------------------------------- /tools/raspi_debug_server/bootloader_write_config_remote.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu -o pipefail 3 | ssh pi@192.168.1.201 -t /home/pi/.local/bin/bootloader_write_config $@ -------------------------------------------------------------------------------- /tools/raspi_debug_server/oocd_raspberry.cfg: -------------------------------------------------------------------------------- 1 | telnet_port 4444 2 | gdb_port 3333 3 | bindto 0.0.0.0 4 | # raspberrypi 5 | interface sysfsgpio 6 | 7 | sysfsgpio_swd_nums 25 24 8 | 9 | transport select swd 10 | source [find target/stm32f4x.cfg] 11 | -------------------------------------------------------------------------------- /tools/raspi_debug_server/openocd-remote.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Launch openocd script(cvra) 3 | After=network.target 4 | 5 | [Service] 6 | Type=idle 7 | ExecStart=+/usr/local/bin/openocd -f /home/pi/src/oocd_raspberry.cfg 8 | Restart=always 9 | User=pi 10 | RemainAfterExit=no 11 | Restart=on-failure 12 | RestartSec=5s 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /tools/raspi_debug_server/shell-ssh.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ssh-copy-id pi@192.168.1.202 && ssh pi@192.168.1.202 -t "python3 -m serial.tools.miniterm /dev/serial/by-id/usb-CVRA_ChibiOS_RT_Virtual_COM_Port_master-if00" -------------------------------------------------------------------------------- /tools/studio/cvra_studio/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = "0.1.1" 2 | -------------------------------------------------------------------------------- /tools/studio/cvra_studio/__main__.py: -------------------------------------------------------------------------------- 1 | from .cli import main 2 | 3 | main() 4 | -------------------------------------------------------------------------------- /tools/studio/cvra_studio/cli.py: -------------------------------------------------------------------------------- 1 | """ 2 | CVRA Studio 3 | """ 4 | 5 | import argparse 6 | from inspect import getmembers, isclass 7 | import sys 8 | 9 | from cvra_studio import __version__ 10 | from cvra_studio import commands 11 | from cvra_studio.commands import * 12 | 13 | 14 | def main(): 15 | parser = argparse.ArgumentParser(__doc__) 16 | parser.add_argument("--version", "-v", action="version", version=__version__) 17 | 18 | subparsers = parser.add_subparsers() 19 | parsers = {} 20 | for command in commands.__all__: 21 | command_main = getattr(commands, command) 22 | parsers[command] = command_main.argparser(subparsers.add_parser(command)) 23 | parsers[command].set_defaults(func=command_main.main) 24 | 25 | args = parser.parse_args() 26 | if hasattr(args, "func"): 27 | args.func(args) 28 | else: 29 | parser.print_help() 30 | -------------------------------------------------------------------------------- /tools/studio/cvra_studio/commands/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 2 | "actuator", 3 | "cmd_vel", 4 | "node", 5 | "node_discovery", 6 | "param_tree", 7 | "pid_plot", 8 | "plot2d", 9 | "plot_uwb", 10 | "publish", 11 | ] 12 | -------------------------------------------------------------------------------- /tools/studio/cvra_studio/network/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 2 | "NodeStatusMonitor", 3 | "ParameterTree", 4 | "UavcanNode", 5 | ] 6 | -------------------------------------------------------------------------------- /tools/studio/cvra_studio/viewers/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 2 | "LivePlotter", 3 | "NestedDict", 4 | "Selector", 5 | "helpers", 6 | ] 7 | -------------------------------------------------------------------------------- /tools/studio/cvra_studio/viewers/helpers.py: -------------------------------------------------------------------------------- 1 | from functools import singledispatch 2 | from PyQt5.QtWidgets import QBoxLayout, QVBoxLayout, QHBoxLayout, QWidget 3 | 4 | 5 | def vstack(items): 6 | layout = QVBoxLayout() 7 | for item in items: 8 | stack(item, layout) 9 | return layout 10 | 11 | 12 | def hstack(items): 13 | layout = QHBoxLayout() 14 | for item in items: 15 | stack(item, layout) 16 | return layout 17 | 18 | 19 | @singledispatch 20 | def stack(item, layout): 21 | raise Exception("Non valid item of type", type(item)) 22 | 23 | 24 | @stack.register(QBoxLayout) 25 | def _(item, layout): 26 | layout.addLayout(item) 27 | 28 | 29 | @stack.register(QWidget) 30 | def _(item, layout): 31 | layout.addWidget(item) 32 | -------------------------------------------------------------------------------- /tools/studio/requirements.txt: -------------------------------------------------------------------------------- 1 | monotonic==1.4 2 | numpy==1.13.3 3 | PyQt5==5.10 4 | pyqtgraph==0.10.0 5 | sip==4.19.7 6 | uavcan==1.0.0.dev29 7 | scipy==1.1.0 8 | -------------------------------------------------------------------------------- /tools/studio/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | from cvra_studio import __version__ 4 | 5 | setup( 6 | name="cvra_studio", 7 | version=__version__, 8 | description="Introspection tool used for debugging our robot at CVRA", 9 | author="Club Vaudois de Robotique Autonome", 10 | author_email="info@cvra.ch", 11 | url="http://cvra.ch", 12 | license="BSD", 13 | packages=find_packages(exclude=["contrib", "docs", "tests*"]), 14 | install_requires=[ 15 | "docopt", 16 | "PyQt5", 17 | "pyserial", 18 | "pyqtgraph", 19 | "numpy", 20 | "uavcan", 21 | ], 22 | entry_points={ 23 | "console_scripts": [ 24 | "cvra=cvra_studio.cli:main", 25 | ], 26 | }, 27 | ) 28 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/20001.Reboot.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Reboot the device. 3 | # 4 | 5 | uint8 REBOOT = 0 6 | uint8 BOOTLOADER_TIMEOUT = 1 7 | uint8 BOOTLOADER_NO_TIMEOUT = 2 8 | 9 | uint8 bootmode 10 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/ServoTrajectory.uavcan: -------------------------------------------------------------------------------- 1 | # Type representing a setpoint for a single RC servomotor control 2 | # The positions, velocity and acceleration are all between 0 and 1, 3 | # corresponding to 0-100% PWM. 4 | # 5 | # The period is fixed to 20 ms. 6 | # 7 | # Note that a typical range for a servo motor would be between 1 and 2 ms on 8 | # time, therefore having a duty cycle of between 5 to 10% 9 | 10 | 11 | float16 position # dimensionless, between 0 and 1 12 | float16 velocity # dimensionless, unit is s^-1 13 | float16 acceleration # dimensionless, unit is s^-2 14 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/actuator/20150.Feedback.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Feedback coming from actuator-firmware nodes 3 | # 4 | 5 | uint32[2] pressure # [Pascal] 6 | float16[2] analog_input # [V] 7 | bool digital_input 8 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/actuator/20151.Command.uavcan: -------------------------------------------------------------------------------- 1 | # Command for an actuator board 2 | # 3 | # This message instructs a single actuator board of what it should do. Note 4 | # that the actuator board have a timeout mechanism: If they do not receive a 5 | # Command in some amount of time (see actuator-firmware/src/safety.c for the 6 | # value), then the outputs are disabled. To avoid this, send the message at 7 | # least 5 times as often as the timeout. 8 | 9 | uint7 node_id # UAVCAN node ID for unicast addressing 10 | 11 | float16[2] pump # PWM in range 0-1 12 | bool[2] solenoid # Power output for solenoids 13 | 14 | cvra.ServoTrajectory[2] servo_trajectories 15 | 16 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/drive/20200.VelocityCommand.uavcan: -------------------------------------------------------------------------------- 1 | # Linear velocity in [m/s] 2 | float32 linear_x 3 | float32 linear_y 4 | float32 linear_z 5 | 6 | # Angular velocity in [rad/s] 7 | float32 angular_x 8 | float32 angular_y 9 | float32 angular_z 10 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/io/20130.DigitalInput.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # GPIO input values 3 | # 4 | 5 | bool[8] pin 6 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/io/20131.ServoPWM.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Servo output position 3 | # 4 | 5 | # UAVCAN node ID for unicast addressing 6 | uint7 node_id 7 | 8 | float16[4] servo_pos 9 | float16[4] servo_vel # Negative coefficients are "do not change" 10 | float16[4] servo_acc # Negative coefficients are "do not change" 11 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/metal_detector/20300.EMIRawSignal.uavcan: -------------------------------------------------------------------------------- 1 | uint16 nb_samples 2 | uint16[<500] samples 3 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/motor/20000.EmergencyStop.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Emergency Stop 3 | # 4 | 5 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/motor/README.md: -------------------------------------------------------------------------------- 1 | # motor-control-uavcan-dsdl 2 | Data Structure Description for CVRA's DC Motor Controller. 3 | 4 | ## Data Structure Description Language specifications 5 | http://uavcan.org/Data_Structure_Description_Language_specification 6 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/motor/control/20020.Trajectory.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Switch to dynamic control to follow trajectory with given current position & 3 | # speed. Position interpolation between updates is done assuming constant speed. 4 | # A feed-forward torque can be applied if given. 5 | # 6 | 7 | # UAVCAN node ID for unicast addressing 8 | uint7 node_id 9 | 10 | float16 position # [rad] 11 | float16 velocity # [rad/s] 12 | float16 acceleration # [rad/s^2] 13 | float16 torque # [Nm] 14 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/motor/control/20021.Velocity.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Switch to velocity control and hold given velocity. 3 | # 4 | 5 | # UAVCAN node ID for unicast addressing 6 | uint7 node_id 7 | 8 | float32 velocity # [rad/s] 9 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/motor/control/20022.Position.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Switch to position control and hold given position. 3 | # A trapezoidal velocity profile is automatically generated. 4 | # 5 | 6 | # UAVCAN node ID for unicast addressing 7 | uint7 node_id 8 | 9 | float32 position # [rad] 10 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/motor/control/20023.Torque.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Switch to torque control and hold given torque. 3 | # 4 | 5 | # UAVCAN node ID for unicast addressing 6 | uint7 node_id 7 | 8 | float32 torque # [Nm] 9 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/motor/control/20024.Voltage.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Switch to voltage control. 3 | # 4 | 5 | # UAVCAN node ID for unicast addressing 6 | uint7 node_id 7 | 8 | float32 voltage # [V] 9 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/motor/feedback/20010.MotorEncoderPosition.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Motor Encoder Position 3 | # 4 | 5 | uint16 raw_encoder_position 6 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/motor/feedback/20030.MotorPosition.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Motor Position & Velocity 3 | # 4 | 5 | float32 position # [rad] 6 | float16 velocity # [rad/s] 7 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/motor/feedback/20031.MotorTorque.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Torque Feedback 3 | # 4 | 5 | float16 torque # [Nm] 6 | float16 position # [rad] 7 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/motor/feedback/20040.CurrentPID.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Stream to tune the current PID 3 | # 4 | 5 | float16 current_setpoint 6 | float16 current 7 | float16 motor_voltage 8 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/motor/feedback/20041.VelocityPID.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Stream to tune the velocity PID 3 | # 4 | 5 | float16 velocity_setpoint 6 | float16 velocity 7 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/motor/feedback/20042.PositionPID.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Stream to tune the position PID 3 | # 4 | 5 | float16 position_setpoint 6 | float16 position 7 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/motor/feedback/20043.Index.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Stream the position of the last index passage 3 | # 4 | 5 | float16 position 6 | uint32 update_count 7 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/odometry/20160.WheelEncoder.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Differential base Encoder Position 3 | # 4 | 5 | int32 left_encoder_raw 6 | int32 right_encoder_raw 7 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/proximity_beacon/20128.Signal.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Light pulse signal from Proximity beacon. 3 | # 4 | 5 | float32 start_angle # [rad] 6 | float32 length # [rad] 7 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/proximity_beacon/20129.Settings.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # Proximity beacon Settings. 3 | # 4 | 5 | float32 speed # [rad/s] 6 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/sensor/20140.DistanceVL6180X.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # ST VL8160X ToF distance sensor measurement 3 | # 4 | 5 | uint8 distance_mm # mm 6 | uint4 status 7 | 8 | uint4 STATUS_OK = 0 9 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/sensor/20141.ColorRGBC.uavcan: -------------------------------------------------------------------------------- 1 | # 2 | # 16bit RGBC color reading 3 | # 4 | 5 | uint16 red 6 | uint16 green 7 | uint16 blue 8 | uint16 clear 9 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/uwb_beacon/2100.RadioRange.uavcan: -------------------------------------------------------------------------------- 1 | # UWB ranging solution 2 | # 3 | uavcan.Timestamp timestamp 4 | uint16 anchor_addr # anchor UWB address 5 | float16 range # meters 6 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/uwb_beacon/2101.TagPosition.uavcan: -------------------------------------------------------------------------------- 1 | # Position that a tag has broadcast 2 | uavcan.Timestamp timestamp 3 | uint16 tag_addr # tag MAC address 4 | float16 x 5 | float16 y 6 | -------------------------------------------------------------------------------- /uavcan_data_types/cvra/uwb_beacon/2200.DataPacket.uavcan: -------------------------------------------------------------------------------- 1 | uint16 MAC_BROADCAST = 0xFFFF 2 | 3 | uint16 src_addr 4 | uint16 dst_addr 5 | uint8[<1024] data 6 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/.gdbinit: -------------------------------------------------------------------------------- 1 | target remote localhost:3333 2 | file build/uwb-beacon.elf 3 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/app_src.mk.jinja: -------------------------------------------------------------------------------- 1 | {% for dir in include_directories %} 2 | APPINC += -I {{ dir }} 3 | {% endfor %} 4 | 5 | {% for file in target.arm + target.stm32f4 + source -%} 6 | {% if file.endswith('.c') %}APPCSRC += {{ file }} 7 | {% elif file.endswith('.s') %}APPASMSRC += {{ file }} 8 | {% elif file.endswith('.cpp') %}APPCPPSRC += {{ file }} 9 | {% endif %}{% endfor %} 10 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/DW1000_Software_API_Guide_rev2p4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/DW1000_Software_API_Guide_rev2p4.pdf -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report.pdf -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/.gitattributes: -------------------------------------------------------------------------------- 1 | *.gan binary 2 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/README.md: -------------------------------------------------------------------------------- 1 | This folder contains the TeX source file for my report on the UWB project. 2 | 3 | To build it you will need the following tools: 4 | 5 | * Python (tested with 3.5) 6 | * Latex 7 | * A set of python packages, run `pip install -r requirements.txt` 8 | 9 | To build it, run the following commands: 10 | 11 | 1. `./convert_ipython.sh` to generate the figures 12 | 2. `latexmk -pdf report.tex` 13 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/convert_ipython.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd $(dirname $0) 3 | 4 | jupyter nbconvert --to notebook --execute "models/Simple model.ipynb" 5 | jupyter nbconvert --to notebook --execute "models/UWB only.ipynb" 6 | jupyter nbconvert --to notebook --execute "models/Differential 2 beacons.ipynb" 7 | jupyter nbconvert --to notebook --execute "models/Bandwidth in half duplex nodes.ipynb" 8 | jupyter nbconvert --to notebook --execute "experiments/range_noise.ipynb" 9 | jupyter nbconvert --to notebook --execute "experiments/Madgwick drift.ipynb" 10 | 11 | find . -name "*.nbconvert.ipynb" -delete 12 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/convert_readme.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd $(dirname $0) 4 | 5 | 6 | pandoc --from markdown --to latex --output user_guide.tex ../../README.md 7 | 8 | # Removes "doc/report" path from figures 9 | sed -i s/doc\\/report\\///g user_guide.tex 10 | 11 | # Convert links to footnotes 12 | sed -i "s/\\\\href{\\([^}]*\\)}{\\([^}]*\\)}/\2\\\\footnote{\\\\url{\1}}/" user_guide.tex 13 | 14 | pandoc --from markdown --to latex --output code_source_org.tex code_source_org.md 15 | 16 | # Use non numbered section for code source organization 17 | sed -i "s/section/section*/" code_source_org.tex 18 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/figures/antoine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/figures/antoine.jpg -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/figures/architecture.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/figures/architecture.graffle -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/figures/architecture.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/figures/architecture.pdf -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/figures/board.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/figures/board.jpg -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/figures/board.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/figures/board.xcf -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/figures/board_schematic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/figures/board_schematic.pdf -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/figures/radio enhancements.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/figures/radio enhancements.graffle -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/figures/radio_broadcast.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/figures/radio_broadcast.pdf -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/figures/radio_unicast.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/figures/radio_unicast.pdf -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/figures/ranging_protocol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/figures/ranging_protocol.png -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/figures/ranging_protocol.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/figures/ranging_protocol.xcf -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/figures/system.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/figures/system.graffle -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/figures/system.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/figures/system.pdf -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/figures/uavcan_gui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/figures/uavcan_gui.png -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/models/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/uwb-beacon-firmware/doc/report/models/tests/__init__.py -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/models/trajectories.py: -------------------------------------------------------------------------------- 1 | from math import cos, sin 2 | from collections import namedtuple 3 | 4 | TrajectoryPoint = namedtuple( 5 | "TrajectoryPoint", ("timestamp", "pos", "theta", "omega", "acc") 6 | ) 7 | 8 | 9 | def generate_circular_traj(r, omega, dt): 10 | """ 11 | Generates a series of point on a circle of given radius. The speed and time 12 | interval between two points must also be given. 13 | """ 14 | theta = 0.0 15 | ts = 0.0 16 | while True: 17 | pos = (r * cos(theta), r * sin(theta)) 18 | acc = (0, omega ** 2 * r) 19 | yield TrajectoryPoint(ts, pos, theta, omega, acc) 20 | ts += dt 21 | theta += omega * dt 22 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/doc/report/requirements.txt: -------------------------------------------------------------------------------- 1 | sympy==1.1.1 2 | numpy==1.13.1 3 | jupyter==1.0.0 4 | matplotlib==2.0.2 5 | pandas==0.20.3 6 | 7 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/oocd.cfg: -------------------------------------------------------------------------------- 1 | telnet_port 4444 2 | gdb_port 3333 3 | 4 | # STLink-V2 SWD debugger 5 | source [find interface/stlink-v2.cfg] 6 | transport select hla_swd 7 | 8 | source [find target/stm32f4x.cfg] 9 | 10 | #reset_config srst_only srst_nogate 11 | adapter_khz 950 12 | 13 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/ahrs_thread.h: -------------------------------------------------------------------------------- 1 | #ifndef AHRS_THREAD_H 2 | #define AHRS_THREAD_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | typedef struct { 9 | uint32_t timestamp; /**< Timestamp in us since boot. */ 10 | struct { 11 | float w; 12 | float x; 13 | float y; 14 | float z; 15 | } q; /**< orientation quaternion */ 16 | } attitude_msg_t; 17 | 18 | void ahrs_start(void); 19 | 20 | void ahrs_calibrate_gyro(void); 21 | 22 | #ifdef __cplusplus 23 | } 24 | #endif 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/anchor_position_cache.h: -------------------------------------------------------------------------------- 1 | #ifndef ANCHOR_POSITION_CACHE_H 2 | #define ANCHOR_POSITION_CACHE_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "lru_cache.h" 9 | #include "ranging_thread.h" 10 | 11 | void anchor_position_cache_start(void); 12 | 13 | anchor_position_msg_t* anchor_position_cache_get(uint16_t anchor_addr); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/bootloader_config.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOTLOADER_CONFIG_H 2 | #define BOOTLOADER_CONFIG_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // returns true if config read was successful 13 | bool config_get(bootloader_config_t* cfg); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif /* BOOTLOADER_CONFIG_H */ 20 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/cmd.h: -------------------------------------------------------------------------------- 1 | #ifndef _CMD_H_ 2 | #define _CMD_H_ 3 | 4 | #include 5 | extern const ShellCommand shell_commands[]; 6 | 7 | void shell_start(BaseSequentialStream* io); 8 | 9 | #endif /* _CMD_H_ */ 10 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/decawave_interface.h: -------------------------------------------------------------------------------- 1 | #ifndef DECAWAVE_INTERFACE_H 2 | #define DECAWAVE_INTERFACE_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | /** Starts the communication interface to the chip. */ 11 | void decawave_start(void); 12 | uint64_t decawave_get_rx_timestamp_u64(void); 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/exti.h: -------------------------------------------------------------------------------- 1 | #ifndef EXTI_H 2 | #define EXTI_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | extern event_source_t imu_event; 9 | extern event_source_t uwb_event; 10 | 11 | /** Starts the external interrupt processing service. */ 12 | void exti_start(void); 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | 18 | #endif /* EXTI_H */ 19 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/log.h: -------------------------------------------------------------------------------- 1 | #ifndef LOG_H 2 | #define LOG_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void log_init(void); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif /* LOG_H */ 15 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | extern messagebus_t bus; 12 | extern parameter_namespace_t parameter_root; 13 | 14 | /* Addresses provided by the linker script. */ 15 | extern int _config_start, _config_end; 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #endif /* MAIN_H */ 22 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/shellconf.h: -------------------------------------------------------------------------------- 1 | #ifndef SHELLCONF_H 2 | #define SHELLCONF_H 3 | 4 | /* Shell related config */ 5 | #define SHELL_MAX_ARGUMENTS 5 6 | #define SHELL_MAX_LINE_LENGTH 100 7 | #define SHELL_USE_HISTORY TRUE 8 | #define SHELL_USE_ESC_SEQ TRUE 9 | #define SHELL_MAX_HIST_BUFF 4 * SHELL_MAX_LINE_LENGTH 10 | #define SHELL_PROMPT_STR "uwb-beacon> " 11 | 12 | #define SHELL_CMD_THREADS_ENABLED TRUE 13 | #define SHELL_CMD_TEST_ENABLED FALSE 14 | 15 | #endif /* SHELLCONF_H */ 16 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/state_estimation.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ekf.hpp" 3 | 4 | class RadioPositionEstimator { 5 | public: 6 | typedef Eigen::Matrix State; 7 | State state; 8 | Eigen::Matrix3f covariance; 9 | float measurementVariance; 10 | float processVariance; 11 | 12 | RadioPositionEstimator(); 13 | void setPosition(float x, float y, float z); 14 | std::tuple getPosition(); 15 | 16 | void processDistanceMeasurement(const float anchor_position[2], float distance); 17 | void predict(void); 18 | }; 19 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/state_estimation_thread.h: -------------------------------------------------------------------------------- 1 | #ifndef STATE_ESTIMATION_THREAD_H 2 | #define STATE_ESTIMATION_THREAD_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include "lru_cache.h" 10 | 11 | typedef struct { 12 | uint32_t timestamp; 13 | float x; 14 | float y; 15 | float z; 16 | float variance_x; 17 | float variance_y; 18 | float variance_z; 19 | } position_estimation_msg_t; 20 | 21 | void state_estimation_start(void); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/timestamp_stm32_settings.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMESTAMP_STM32_SETTINGS_H 2 | #define TIMESTAMP_STM32_SETTINGS_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | // settings 11 | #define TIMESTAMP_TIMER TIM7 12 | #define TIMER_REG STM32_TIM7 13 | #define TIMER_IRQ_NAME STM32_TIM7_HANDLER 14 | #define RCC_EN() rccEnableTIM7(FALSE) 15 | #define RCC_RESET() rccResetTIM7() 16 | #define NVIC_NB STM32_TIM7_NUMBER 17 | 18 | #define COUNTER_MAX 0xffff 19 | 20 | // CK_CNT = CK_INT / (PSC[15:0] + 1) 21 | #if STM32_PPRE1 == STM32_PPRE1_DIV1 22 | #define PRESCALER (STM32_PCLK1 / 1000000 - 1) 23 | #else 24 | #define PRESCALER (2 * STM32_PCLK1 / 1000000 - 1) 25 | #endif 26 | #define INTERRUPT_PRIO 5 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | 32 | #endif /* TIMESTAMP_STM32_SETTINGS_H */ 33 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/trace_points.h: -------------------------------------------------------------------------------- 1 | #ifndef TRACE_POINTS_H 2 | #define TRACE_POINTS_H 3 | #include 4 | 5 | #define TRACE_POINTS \ 6 | C(TRACE_POINT_UWB_IRQ) \ 7 | C(TRACE_POINT_UWB_SEND_ADVERTISEMENT) \ 8 | C(TRACE_POINT_UWB_TX_DONE) \ 9 | C(TRACE_POINT_UWB_RX) \ 10 | C(TRACE_POINT_UWB_PROCESS_FRAME) 11 | 12 | /* List of all trace points in numerical format. */ 13 | #undef C 14 | #define C(x) x, 15 | enum { 16 | TRACE_POINTS 17 | }; 18 | 19 | #endif /* TRACE_POINTS_H */ 20 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/trace_port.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "trace_points.h" 5 | 6 | extern int32_t trace_lock(void) 7 | { 8 | return chSysGetStatusAndLockX(); 9 | } 10 | 11 | extern void trace_unlock(int32_t status) 12 | { 13 | chSysRestoreStatusX(status); 14 | } 15 | 16 | extern int32_t trace_timestamp_ms_get(void) 17 | { 18 | return TIME_I2MS(chVTGetSystemTimeX()); 19 | } 20 | 21 | #undef C 22 | #define C(x) #x, 23 | 24 | const char* trace_point_names[] = { 25 | TRACE_POINTS}; 26 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/uavcan/data_packet_handler.cpp: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "data_packet_handler.hpp" 3 | #include "ranging_thread.h" 4 | #include 5 | #include 6 | 7 | using DataPacket = cvra::uwb_beacon::DataPacket; 8 | 9 | static void data_packet_cb(const uavcan::ReceivedDataStructure& msg) 10 | { 11 | static uint8_t data[1024]; 12 | 13 | for (auto i = 0u; i < msg.data.size(); i++) { 14 | data[i] = msg.data[i]; 15 | } 16 | 17 | ranging_send_data_packet(data, msg.data.size(), msg.dst_addr); 18 | } 19 | 20 | int data_packet_handler_init(Node& node) 21 | { 22 | static uavcan::Subscriber subscriber(node); 23 | 24 | return subscriber.start(data_packet_cb); 25 | } 26 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/uavcan/data_packet_handler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "./uavcan_node.h" 4 | 5 | int data_packet_handler_init(Node& node); 6 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/uavcan/parameter_enumeration.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PARAMETER_ENUMERATION_HPP 2 | #define PARAMETER_ENUMERATION_HPP 3 | 4 | #include 5 | 6 | parameter_t* parameter_find_by_index(parameter_namespace_t* root, int index); 7 | int parameter_tree_height(parameter_t* leaf); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/uavcan/parameter_server.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PARAMETER_SERVER_HPP 2 | #define PARAMETER_SERVER_HPP 3 | 4 | #include "./uavcan_node.h" 5 | 6 | int parameter_server_start(Node& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/uavcan/position_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef POSITION_HANDLER_H 2 | #define POSITION_HANDLER_H 3 | 4 | #include "./uavcan_node.h" 5 | 6 | int position_handler_init(Node& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/uavcan/restart_server.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RESTART_SERVER_HPP 2 | #define RESTART_SERVER_HPP 3 | 4 | #include "./uavcan_node.h" 5 | 6 | int restart_server_start(Node& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/uavcan/topics_publisher.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TOPICS_PUBLISHER_HPP 2 | #define TOPICS_PUBLISHER_HPP 3 | 4 | #include "./uavcan/uavcan_node.h" 5 | 6 | /** This module streams topics from the internal messagebus to the UAVCAN bus. */ 7 | void topics_publisher_start(Node& node); 8 | void topics_publisher_spin(Node& node); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/uavcan/uavcan_node.h: -------------------------------------------------------------------------------- 1 | #ifndef UAVCAN_NODE_H 2 | #define UAVCAN_NODE_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | #define UAVCAN_SPIN_FREQUENCY 200 11 | 12 | void uavcan_node_start(uint8_t id, const char* name); 13 | int64_t uavcan_get_utc_time_us(void); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #ifdef __cplusplus 20 | #include 21 | 22 | /** Returns the UAVCAN node. */ 23 | typedef uavcan::Node<4096> Node; 24 | 25 | #endif 26 | 27 | #endif /* UAVCAN_NODE_H */ 28 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/src/usbconf.h: -------------------------------------------------------------------------------- 1 | #ifndef USBCONF_H 2 | #define USBCONF_H 3 | 4 | #include 5 | 6 | extern SerialUSBDriver SDU1; 7 | 8 | /** Starts the UART over USB service. 9 | * 10 | * @parameter serial [in] serial number to use for the port. */ 11 | void usb_start(unsigned int serial); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/tests/hal.h: -------------------------------------------------------------------------------- 1 | #ifndef HAL_H 2 | #define HAL_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | /* Dummy functions implementing ChibiOS's HAL */ 11 | 12 | /* Generic */ 13 | void chThdSleepMilliseconds(int amount); 14 | 15 | /* SPI */ 16 | typedef int SPIDriver; 17 | void spiSelect(SPIDriver* p); 18 | void spiSend(SPIDriver* p, size_t n, const void* buf); 19 | void spiReceive(SPIDriver* spip, size_t n, void* rxbuf); 20 | void spiUnselect(SPIDriver* spip); 21 | 22 | #ifdef __cplusplus 23 | } 24 | #endif 25 | #endif 26 | -------------------------------------------------------------------------------- /uwb-beacon-firmware/tools/ekf_python_bindings.cpp: -------------------------------------------------------------------------------- 1 | #include "state_estimation.hpp" 2 | 3 | static RadioPositionEstimator estimator; 4 | 5 | extern "C" void estimator_predict(void) 6 | { 7 | estimator.predict(); 8 | } 9 | 10 | extern "C" void estimator_process_distance_measurement(float pos[2], float distance) 11 | { 12 | estimator.processDistanceMeasurement(pos, distance); 13 | } 14 | 15 | extern "C" float estimator_get_x(void) 16 | { 17 | return estimator.state(0); 18 | } 19 | 20 | extern "C" float estimator_get_y(void) 21 | { 22 | return estimator.state(1); 23 | } 24 | -------------------------------------------------------------------------------- /webot_sim/Eurobot_2021/protos/textures/aruco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/webot_sim/Eurobot_2021/protos/textures/aruco.png -------------------------------------------------------------------------------- /webot_sim/Eurobot_2021/protos/textures/eurobot2020_girouette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/webot_sim/Eurobot_2021/protos/textures/eurobot2020_girouette.png -------------------------------------------------------------------------------- /webot_sim/Eurobot_2021/protos/textures/vinyl_texture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/webot_sim/Eurobot_2021/protos/textures/vinyl_texture.jpg -------------------------------------------------------------------------------- /webot_sim/Eurobot_2021/worlds/textures/aruco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/webot_sim/Eurobot_2021/worlds/textures/aruco.png -------------------------------------------------------------------------------- /webot_sim/Eurobot_2021/worlds/textures/brushed_aluminium/brushed_aluminium_base_color.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/webot_sim/Eurobot_2021/worlds/textures/brushed_aluminium/brushed_aluminium_base_color.jpg -------------------------------------------------------------------------------- /webot_sim/Eurobot_2021/worlds/textures/brushed_aluminium/brushed_aluminium_normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/webot_sim/Eurobot_2021/worlds/textures/brushed_aluminium/brushed_aluminium_normal.jpg -------------------------------------------------------------------------------- /webot_sim/Eurobot_2021/worlds/textures/brushed_aluminium/brushed_aluminium_roughness.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/webot_sim/Eurobot_2021/worlds/textures/brushed_aluminium/brushed_aluminium_roughness.jpg -------------------------------------------------------------------------------- /webot_sim/Eurobot_2021/worlds/textures/eurobot2020_girouette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/webot_sim/Eurobot_2021/worlds/textures/eurobot2020_girouette.png -------------------------------------------------------------------------------- /webot_sim/Eurobot_2021/worlds/textures/eurobot2021_vinyl_texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/webot_sim/Eurobot_2021/worlds/textures/eurobot2021_vinyl_texture.png -------------------------------------------------------------------------------- /webot_sim/Eurobot_2021/worlds/textures/parquetry/chequered_parquetry_base_color.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/webot_sim/Eurobot_2021/worlds/textures/parquetry/chequered_parquetry_base_color.jpg -------------------------------------------------------------------------------- /webot_sim/Eurobot_2021/worlds/textures/parquetry/chequered_parquetry_normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/webot_sim/Eurobot_2021/worlds/textures/parquetry/chequered_parquetry_normal.jpg -------------------------------------------------------------------------------- /webot_sim/Eurobot_2021/worlds/textures/parquetry/chequered_parquetry_occlusion.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/webot_sim/Eurobot_2021/worlds/textures/parquetry/chequered_parquetry_occlusion.jpg -------------------------------------------------------------------------------- /webot_sim/Eurobot_2021/worlds/textures/parquetry/chequered_parquetry_roughness.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/webot_sim/Eurobot_2021/worlds/textures/parquetry/chequered_parquetry_roughness.jpg -------------------------------------------------------------------------------- /webot_sim/Eurobot_2021/worlds/textures/vinyl_texture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvra/robot-software/35378a824f33f3e6599c0e34893cb193d4085af8/webot_sim/Eurobot_2021/worlds/textures/vinyl_texture.jpg -------------------------------------------------------------------------------- /webot_sim/controllers/uavcan_controller/.gitignore: -------------------------------------------------------------------------------- 1 | uavcan_controller 2 | build 3 | -------------------------------------------------------------------------------- /webot_sim/controllers/uavcan_controller/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(uavcan_controller 2 | EXCLUDE_FROM_ALL 3 | uavcan_controller.cpp 4 | ) 5 | 6 | 7 | target_link_libraries(uavcan_controller PUBLIC uavcan uavcan_linux hitl_lib) 8 | 9 | # Integrate with Webots libs 10 | target_include_directories(uavcan_controller PUBLIC /usr/local/webots/include/controller/cpp) 11 | link_directories(/usr/local/webots/lib/controller) 12 | target_link_libraries(uavcan_controller PUBLIC Controller CppController) 13 | -------------------------------------------------------------------------------- /wheel-encoder-firmware/.gitignore: -------------------------------------------------------------------------------- 1 | src/src.mk 2 | CMakeLists.txt 3 | -------------------------------------------------------------------------------- /wheel-encoder-firmware/Makefile.include.jinja: -------------------------------------------------------------------------------- 1 | {% for dir in include_directories %} 2 | PROJINC += {{ dir }} 3 | {% endfor %} 4 | 5 | {% for file in target.arm + target.stm32f3 + source %} 6 | {%- if file.endswith('.c') %}PROJCSRC += {{ file }} 7 | {% elif file.endswith('.s') %}PROJASMSRC += {{ file }} 8 | {% elif file.endswith('.cpp') %}PROJCPPSRC += {{ file }} 9 | {% endif -%}{% endfor %} 10 | -------------------------------------------------------------------------------- /wheel-encoder-firmware/README.md: -------------------------------------------------------------------------------- 1 | # Wheel Encoder Firmware 2 | 3 | The wheel encoder board counts rotary encoder pulses of right and left wheels of the robot and sends the counts with a fixed frequency over UAVCAN. 4 | 5 | ## Hardware 6 | 7 | For a first prototype a CVRA motor board (STM32F303CCT6) is repurposed. 8 | The timer TIM3 and TIM4 are connected right and left wheel encoders and used in counter mode. 9 | The Encoder A/B input signals connected to PB4 and PB5 for TIM3 and PB6 and PB7 for TIM4. 10 | 11 | 12 | -------------------------------------------------------------------------------- /wheel-encoder-firmware/openocd.cfg: -------------------------------------------------------------------------------- 1 | telnet_port 4444 2 | gdb_port 3333 3 | 4 | source [find interface/stlink-v2.cfg] 5 | transport select hla_swd 6 | 7 | source [find target/stm32f3x.cfg] 8 | #reset_config srst_only srst_nogate 9 | -------------------------------------------------------------------------------- /wheel-encoder-firmware/package.yml: -------------------------------------------------------------------------------- 1 | dependency-dir: ../lib 2 | 3 | include_directories: 4 | - src/ 5 | - src/board 6 | 7 | target.stm32f3: [] 8 | target.arm: 9 | - src/board/board.c 10 | - src/main.c 11 | - src/encoder.c 12 | - src/bootloader_config.c 13 | - src/uavcan/uavcan_node.cpp 14 | - src/uavcan/WheelEncoder_pub.cpp 15 | - src/libstubs.cpp 16 | - ../lib/can-bootloader/config.c 17 | 18 | depends: 19 | - chibios-syscalls 20 | - cmp_mem_access 21 | - crc 22 | - cmp 23 | - version 24 | - parameter 25 | - parameter_flash_storage 26 | 27 | 28 | tests: [] 29 | 30 | templates: 31 | Makefile.include.jinja: src/src.mk 32 | -------------------------------------------------------------------------------- /wheel-encoder-firmware/src/bootloader_config.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOTLOADER_CONFIG_H 2 | #define BOOTLOADER_CONFIG_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // returns true if config read was successful 13 | bool config_get(bootloader_config_t* cfg); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif /* BOOTLOADER_CONFIG_H */ -------------------------------------------------------------------------------- /wheel-encoder-firmware/src/encoder.h: -------------------------------------------------------------------------------- 1 | #ifndef ENCODER_H 2 | #define ENCODER_H 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | int32_t encoder_get_right(void); 11 | int32_t encoder_get_left(void); 12 | int32_t encoder_tick_diff(uint32_t enc_old, uint32_t enc_new); 13 | void encoder_init(void); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif /* ENCODER_H */ 20 | -------------------------------------------------------------------------------- /wheel-encoder-firmware/src/libstubs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace __gnu_cxx { 4 | 5 | void __verbose_terminate_handler() 6 | { 7 | std::abort(); 8 | } 9 | 10 | } // namespace __gnu_cxx 11 | -------------------------------------------------------------------------------- /wheel-encoder-firmware/src/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | 11 | extern BaseSequentialStream* ch_stdout; 12 | extern parameter_namespace_t parameter_root_ns; 13 | 14 | /* Addresses provided by the linker script. */ 15 | extern int _config_start, _config_end; 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #endif /* MAIN_H */ 22 | -------------------------------------------------------------------------------- /wheel-encoder-firmware/src/uavcan/WheelEncoder_pub.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "WheelEncoder_pub.hpp" 7 | 8 | int wheel_encoder_init(uavcan::INode& node) 9 | { 10 | static uavcan::Publisher pub(node); 11 | static uavcan::Timer periodic_timer(node); 12 | periodic_timer.setCallback( 13 | [&](const uavcan::TimerEvent& event) { 14 | (void)event; 15 | auto msg = cvra::odometry::WheelEncoder(); 16 | 17 | msg.right_encoder_raw = encoder_get_right(); 18 | msg.left_encoder_raw = encoder_get_left(); 19 | 20 | pub.broadcast(msg); 21 | }); 22 | periodic_timer.startPeriodic(uavcan::MonotonicDuration::fromMSec(10)); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /wheel-encoder-firmware/src/uavcan/WheelEncoder_pub.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WHEELENCODER_PUB_HPP 2 | #define WHEELENCODER_PUB_HPP 3 | 4 | #include 5 | 6 | int wheel_encoder_init(uavcan::INode& node); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /wheel-encoder-firmware/src/uavcan/uavcan_node.h: -------------------------------------------------------------------------------- 1 | #ifndef UAVCAN_NODE_H 2 | #define UAVCAN_NODE_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | #define UAVCAN_SPIN_FREQUENCY 100 11 | 12 | struct uavcan_node_arg { 13 | const char* node_name; 14 | uint8_t node_id : 7; 15 | }; 16 | 17 | void uavcan_node_start(void* arg); 18 | void uavcan_init_complete(void); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #ifdef __cplusplus 25 | #include 26 | 27 | /** Returns the UAVCAN node. */ 28 | typedef uavcan::Node<4096> Node; 29 | 30 | #endif 31 | 32 | #endif /* UAVCAN_NODE_H */ 33 | --------------------------------------------------------------------------------