Skip to content

Commit

Permalink
Merge pull request #1 from USF-IEEE/add_protobuf
Browse files Browse the repository at this point in the history
Fixing linker errors
  • Loading branch information
Johnnykoch02 committed Feb 16, 2024
2 parents 98de134 + 1914b5c commit ed6ccba
Show file tree
Hide file tree
Showing 12 changed files with 214 additions and 120 deletions.
44 changes: 33 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# TerriBull Device Manager

## Overview
The TerriBull Device Manager is a comprehensive system designed for managing various types of robotic devices. It provides a framework for initializing and controlling devices such as motors, IMUs, and other peripherals using a unified interface. This system is built on top of the PROS library for VEX Robotics, leveraging its functionalities for device communication and control.
The TerriBull Device Manager is a comprehensive system designed for managing various types of VEX devices. It provides a framework for initializing and controlling devices such as motors, IMUs, and other peripherals using a unified interface. This system is built on top of the PROS library for VEX Robotics, leveraging its functionalities for device communication and control. More specific documentation related to using the library will be coming soon.

## Features
- **Device Support**: Supports a wide range of devices including motors, IMUs, distance sensors, vision sensors, and more.
Expand All @@ -12,38 +12,60 @@ The TerriBull Device Manager is a comprehensive system designed for managing var
## Requirements
- PROS library for VEX Robotics
- nanopb
- arm-none-eabi compiler Toolset for Linux or WSL

## Installation
## Installation/Compilation
1. Ensure the PROS library is installed and properly configured in your development environment.
2. Clone this repository into your project's directory.
3. Include the `TerriBull.hpp` and the `Devices` directory in your project's include paths.

### Creating protobuf Definitions:
1. Ensure `nanopb` is installed, let `$nanopb_path` be the path to the nanopb/generator file.
1. Ensure `nanopb` is installed in the project.
2. cd into project
3.

```bash
python $nanopb_path/nanopb_generator.py --out=. ./include/protos/vex.proto
python python nanopb/generator/nanopb_generator.py --out=. ./include/protos/vex.proto
```

You should now have generated the `.pb.h` and `.pb.c` files.
- You should now have generated the `.pb.h` and `.pb.c` files.

- To finish this process, find the `vex.pb.h` file and modify the top of the file to look like this:
```c
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.9-dev */

#ifndef PB_TERRIBULLDEVICES_INCLUDE_PROTOS_VEX_PB_H_INCLUDED
#define PB_TERRIBULLDEVICES_INCLUDE_PROTOS_VEX_PB_H_INCLUDED
#include <pb.h>
#include <pb_encode.h>
#include <pb_decode.h>
#include <pb_common.h>
```
### Creating the obj Files
- Ensure you have `arm-none-eabi` compiler for Cortex
```bash
mkdir ./obj/
arm-none-eabi-gcc -c -o ./obj/vex.pb.o ./include/protos/vex.pb.c -I./nanopb/ -I.
arm-none-eabi-gcc -c -o ./obj/pb_encode.o ./nanopb/pb_encode.c -I./nanopb/ -I.
arm-none-eabi-gcc -c -o ./obj/pb_decode.o ./nanopb/pb_decode.c -I./nanopb/ -I.
arm-none-eabi-gcc -c -o ./obj/pb_common.o ./nanopb/pb_common.c -I./nanopb/ -I.
arm-none-eabi-g++ -c -o ./obj/vex.pb.o ./include/protos/vex.pb.c -I./nanopb/ -I.
arm-none-eabi-g++ -c -o ./obj/pb_encode.o ./nanopb/pb_encode.c -I./nanopb/ -I.
arm-none-eabi-g++ -c -o ./obj/pb_decode.o ./nanopb/pb_decode.c -I./nanopb/ -I.
arm-none-eabi-g++ -c -o ./obj/pb_common.o ./nanopb/pb_common.c -I./nanopb/ -I.
```
- You should now have the obj files linked in the obj/ directory.

Run:

```bash
ar rcs firmware/libvex.a obj/vex.pb.o obj/pb_encode.o obj/pb_decode.o obj/pb_common.o
arm-none-eabi-ar rcs firmware/libvex.a obj/vex.pb.o obj/pb_encode.o obj/pb_decode.o obj/pb_common.o
```

### Building with Pros
- Ensure you have Pros CLI installed on your computer.
- An error will occur if
Run:
```bash
pros build --verbose
```

## Usage
Expand Down
8 changes: 4 additions & 4 deletions common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ wlprefix=-Wl,$(subst $(SPACE),$(COMMA),$1)
LNK_FLAGS=--gc-sections --start-group $(strip $(LIBRARIES)) -lgcc -lstdc++ --end-group -T$(FWDIR)/v5-common.ld

ASMFLAGS=$(MFLAGS) $(WARNFLAGS)
NANOPB_DIR := $(realpath ./nanopb)
CFLAGS=$(MFLAGS) $(CPPFLAGS) $(WARNFLAGS) $(GCCFLAGS) --std=gnu11
CFLAGS+= -I$(NANOPB_DIR)
CXXFLAGS=$(MFLAGS) $(CPPFLAGS) $(WARNFLAGS) $(GCCFLAGS) --std=gnu++17
NANOPB_DIR := $(realpath ./nanopb)
CXXFLAGS += -I$(NANOPB_DIR)


Expand Down Expand Up @@ -228,7 +228,7 @@ $(MONOLITH_BIN): $(MONOLITH_ELF) $(BINDIR)

$(MONOLITH_ELF): $(ELF_DEPS) $(LIBRARIES)
$(call _pros_ld_timestamp)
$(call test_output_2,Linking project with $(ARCHIVE_TEXT_LIST) ,$(LD) $(LDFLAGS) $(ELF_DEPS) $(LDTIMEOBJ) $(call wlprefix,-T$(FWDIR)/v5.ld $(LNK_FLAGS)) L./firmware -lvex -o $@,$(OK_STRING))
$(call test_output_2,Linking project with $(ARCHIVE_TEXT_LIST) ,$(LD) $(LDFLAGS) $(ELF_DEPS) $(LDTIMEOBJ) $(call wlprefix,-T$(FWDIR)/v5.ld $(LNK_FLAGS)) -lvex -o $@,$(OK_STRING))
@echo Section sizes:
-$(VV)$(SIZETOOL) $(SIZEFLAGS) $@ $(SIZES_SED) $(SIZES_NUMFMT)

Expand All @@ -237,7 +237,7 @@ $(COLD_BIN): $(COLD_ELF)

$(COLD_ELF): $(COLD_LIBRARIES)
$(VV)mkdir -p $(dir $@)
$(call test_output_2,Creating cold package with $(ARCHIVE_TEXT_LIST) ,$(LD) $(LDFLAGS) $(call wlprefix,--gc-keep-exported --whole-archive $^ -lstdc++ --no-whole-archive) $(call wlprefix,-T$(FWDIR)/v5.ld $(LNK_FLAGS) L./firmware -lvex -o $@),$(OK_STRING))
$(call test_output_2,Creating cold package with $(ARCHIVE_TEXT_LIST) ,$(LD) $(LDFLAGS) $(call wlprefix,--gc-keep-exported --whole-archive $^ -lstdc++ --no-whole-archive) $(call wlprefix,-T$(FWDIR)/v5.ld $(LNK_FLAGS) -o $@),$(OK_STRING))
$(call test_output_2,Stripping cold package ,$(OBJCOPY) --strip-symbol=install_hot_table --strip-symbol=__libc_init_array --strip-symbol=_PROS_COMPILE_DIRECTORY --strip-symbol=_PROS_COMPILE_TIMESTAMP --strip-symbol=_PROS_COMPILE_TIMESTAMP_INT $@ $@, $(DONE_STRING))
@echo Section sizes:
-$(VV)$(SIZETOOL) $(SIZEFLAGS) $@ $(SIZES_SED) $(SIZES_NUMFMT)
Expand All @@ -247,7 +247,7 @@ $(HOT_BIN): $(HOT_ELF) $(COLD_BIN)

$(HOT_ELF): $(COLD_ELF) $(ELF_DEPS)
$(call _pros_ld_timestamp)
$(call test_output_2,Linking hot project with $(COLD_ELF) and $(ARCHIVE_TEXT_LIST) ,$(LD) -nostartfiles $(LDFLAGS) $(call wlprefix,-R $<) $(filter-out $<,$^) $(LDTIMEOBJ) $(LIBRARIES) $(call wlprefix,-T$(FWDIR)/v5-hot.ld $(LNK_FLAGS) L./firmware -lvex -o $@),$(OK_STRING))
$(call test_output_2,Linking hot project with $(COLD_ELF) and $(ARCHIVE_TEXT_LIST) ,$(LD) -nostartfiles $(LDFLAGS) $(call wlprefix,-R $<) $(filter-out $<,$^) $(LDTIMEOBJ) $(LIBRARIES) $(call wlprefix,-T$(FWDIR)/v5-hot.ld $(LNK_FLAGS) -o $@),$(OK_STRING))
@printf "%s\n" "Section sizes:"
-$(VV)$(SIZETOOL) $(SIZEFLAGS) $@ $(SIZES_SED) $(SIZES_NUMFMT)

Expand Down
Binary file modified firmware/libvex.a
Binary file not shown.
24 changes: 10 additions & 14 deletions include/TerriBull/DeviceManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,34 @@
#define __DEVICEMANAGER__

#include "TerriBull.hpp"
#include "./Devices/device.hpp"
#include <map>

#ifdef __cplusplus

extern "C" {
#include "../protos/vex.pb.h" // Adjust the path as necessary
#include "../protos/vex.pb.h" // Adjust the path as necessary
}

#include "Devices/device.hpp"

#endif

#include <iostream>
#include <memory>
#include <string>

class DeviceManager {
private:
std::map<uint8_t, DeviceHeader*> devices;
public:
DeviceManager() = default;
~DeviceManager(); // Implement cleanup in the CPP file

DeviceManager() {}
~DeviceManager(); // TODO: delete all devices
/**
* @brief Adds a device to the manager
*
* @param device DeviceHeader* to keep track of on a port
*/
void add_device(DeviceHeader* device); // get port from device (device->port)
DeviceHeader* get_device(uint8_t port);
bool serializeMessage(const TerriBullDevices_FunctionCall* message, uint8_t* buffer, size_t buffer_size, size_t* message_length);
void add_device(DeviceHeader* device);
DeviceHeader* get_device(uint32_t port);
bool processMessage(const uint8_t* buffer, size_t size);
bool serializeMessage(const FunctionCall* message, uint8_t* buffer, size_t buffer_size, size_t* message_length);

private:
std::map<uint32_t, DeviceHeader*> devices;

};

Expand Down
69 changes: 33 additions & 36 deletions include/TerriBull/Devices/device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
#define __TERRIBULL_DEVICES__

#include "../TerriBull.hpp"
// namespace TerriBull {

class DeviceManager;

/**
* E_DEVICE_NONE = 0,
Expand All @@ -17,7 +18,7 @@
* E_DEVICE_GPS = 20,
* E_DEVICE_SERIAL = 129,
*/
typedef struct {
typedef struct {
pros::c::v5_device_e_t pros_device_type;
uint8_t port;
} DeviceHeader;
Expand All @@ -36,9 +37,10 @@ typedef struct {
*/

typedef enum device_callback_return_code {
SUCCESS = 0,
DEVICE_TYPE_MISMATCH = 1,
DEVICE_NOT_EXIST = 2,
FUNC_NOT_FOUND = 0,
SUCCESS = 1,
DEVICE_TYPE_MISMATCH = 2,
DEVICE_NOT_EXIST = 3
};

typedef struct {
Expand All @@ -50,30 +52,11 @@ typedef struct {
// Other motor-specific members
} MotorDevice;

/**
* @brief Should Initialize device with Port and proto data
*
* @param port
* @param data contains {uint8_t port, int GEAR_SET, int BREAK_MODE}
* @return device_callback_return_code
*/

typedef struct {
uint8_t port; int GEAR_SET; int BREAK_MODE;
} motor_initialize_callback_data;

device_callback_return_code motor_device_initalize(DeviceManager* _motherSys, motor_initialize_callback_data data) {
MotorDevice* device = (MotorDevice*) malloc(sizeof(MotorDevice));
device->header.pros_device_type = pros::c::v5_device_e_t::E_DEVICE_MOTOR;
device->header.port = data.port;
device->gear_set = (pros::motor_gearset_e_t) data.GEAR_SET;
device->break_mode = (pros::motor_brake_mode_e_t) data.BREAK_MODE;
pros::c::motor_tare_position(device->header.port);
pros::c::motor_set_brake_mode(device->header.port, device->break_mode);
pros::c::motor_set_gearing(device->header.port, device->gear_set);
device->velocity = pros::c::motor_get_actual_velocity(device->header.port);
_motherSys->add_device(device); // pointer to device
return device_callback_return_code::SUCCESS;
}

/**
* @brief Should set motors velocity to the proto data
Expand All @@ -88,28 +71,42 @@ typedef struct {
int16_t velocity;
} motor_set_velocity_callback_data;

device_callback_return_code motor_device_set_velocity(DeviceManager* _motherSys, motor_set_velocity_callback_data data) {
DeviceHeader* device = _motherSys->get_device(data.port);
if (device != nullptr) return device_callback_return_code::DEVICE_NOT_EXIST;
if( ! device->pros_device_type == pros::c::v5_device_e_t::E_DEVICE_MOTOR) return device_callback_return_code::DEVICE_TYPE_MISMATCH;

MotorDevice* motor = static_cast<MotorDevice*>((void*)device);
pros::c::motor_move_velocity(motor->header.port, data.velocity);
return device_callback_return_code::SUCCESS;
}


typedef struct {
DeviceHeader header; // First member is the DeviceHeader
DeviceHeader header;
float roll;
float yaw;
float pitch;
pros::c::imu_accel_s_t accel;
} IMUDevice;

typedef struct {
DeviceHeader header; // First member is the DeviceHeader
DeviceHeader header;
float value;
} AnalogDevice;


#include "../DeviceManager.hpp"

// Callbacks and Function Definitions

/**
* @brief Should Initialize motor device with Port and proto data
*
* @param data contains {uint8_t port, int GEAR_SET, int BREAK_MODE}
* @return device_callback_return_code
*/
device_callback_return_code motor_device_initalize(DeviceManager* _motherSys, motor_initialize_callback_data data);
/**
* @brief Should set motors velocity to the proto data
*
* @param port
* @param data contains {uint8_t port, int GEAR_SET, int BREAK_MODE}
* @return device_callback_return_code
* This velocity corresponds to different actual speeds depending on the gearset used for the motor. This results in a range of +-100 for E_MOTOR_GEARSET_36, +-200 for E_MOTOR_GEARSET_18, and +-600 for blue. The velocity is held with PID to ensure consistent speed, as opposed to setting the motor’s voltage.
*/
device_callback_return_code motor_device_set_velocity(DeviceManager* _motherSys, motor_set_velocity_callback_data data);


#endif
2 changes: 0 additions & 2 deletions include/TerriBull/SerialController.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ class SerialController {
private:

static constexpr char __end_of_transmission[4] = { (char)0, (char)0, (char)10, (char)10 };
map<int, CallbackItem*> Callbacks;
map<int, CallbackItem*> tmpCallbacks;
vector<ScheduledUpdate*> ScheduledUpdates;
DeviceManager* motherSys;

Expand Down
3 changes: 3 additions & 0 deletions include/protos/vex.pb.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ PB_BIND(TerriBullDevices_DeviceValue, TerriBullDevices_DeviceValue, AUTO)
PB_BIND(TerriBullDevices_FunctionCall, TerriBullDevices_FunctionCall, AUTO)


PB_BIND(TerriBullDevices_ReturnData, TerriBullDevices_ReturnData, AUTO)





Expand Down
Loading

0 comments on commit ed6ccba

Please sign in to comment.