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.
- Device Management: from external computers, you can easily control and manage your VEX specific devices on a V5 brain. This can be used to offload compute power to
- Device Support: The framework supports a comprehensive range of VEX devices, including motors, IMUs, rotation sensors, distance sensors, vision sensors, and ADI (Analog/Digital Inputs).
- Dynamic Initialization and Configuration: Devices can be dynamically initialized and configured with specific parameters such as gear sets for motors, enabling flexible and adaptive use cases.
- Velocity and Position Control: Provides API for setting motor velocities and sensor positions, offering precise control over the hardware.
- Serialization and Deserialization: Integrated with nanopb for efficient communication, allowing devices to send and receive structured data via serial communication.
- Extensible Architecture: Designed with extensibility in mind, making it easy to add support for new devices or functionalities as needed.
- Unified Device Management: Centralizes the management of different types of devices, facilitating easier tracking and control of hardware components.
- Real-Time Updates: Supports real-time updates of device states, ensuring responsive and synchronous operation of robotics components.
- Error Handling: Implements comprehensive error handling mechanisms, providing robustness and reliability in device operations.
- PROS library/CLI for VEX Robotics
- nanopb (included as submodule)
- arm-none-eabi compiler Toolset for Linux
- Ensure the PROS library is installed and properly configured in your development environment.
- Clone this repository into your project's directory.
- Include the
TerriBull.hpp
and theDevices
directory in your project's include paths.
- Ensure
nanopb
is installed in the project. - cd into project
python nanopb/generator/nanopb_generator.py --out=. ./include/protos/vex.proto
-
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:
/* 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>
Use the following command to automatically do this:
sed -i '/#include <pb.h>/a #include <pb_encode.h>\n#include <pb_decode.h>\n#include <pb_common.h>' include/protos/vex.pb.h
- Ensure you have
arm-none-eabi
compiler for Cortex
mkdir ./obj/ 2>/dev/null || echo "Creating obj/ Directory..."
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:
arm-none-eabi-ar rcs firmware/libvex.a obj/vex.pb.o obj/pb_encode.o obj/pb_decode.o obj/pb_common.o
- Ensure you have Pros CLI installed on your computer.
- An error will occur if Run:
pros build --verbose
The DeviceManager class provides a high-level interface to manage and interact with various devices, such as motors and sensors, on a robotics platform. Below are examples of how to initialize a motor, set its velocity, and manage devices with the DeviceManager.
- Note: the following examples use placeholders to demonstrate actual values. Remember to replace placeholder values like port, GEAR_SET, BREAK_MODE, and velocity with actual values according to your application needs.
To initialize a motor with specific parameters, use the motor_device_initialize
method from the DeviceManager
class. Provide a motor_initialize_callback_data
struct with the necessary configuration.
#include "DeviceManager.hpp"
#include "TerriBullDevices.hpp"
DeviceManager deviceManager;
TerriBull::motor_initialize_callback_data motorData = {port, GEAR_SET, BREAK_MODE};
deviceManager.motor_device_initialize(&motorData);
To set the velocity of a motor, use the motor_device_set_velocity
method with a motor_set_velocity_callback_data
struct containing the desired velocity and port.
TerriBull::motor_set_velocity_callback_data velocityData = {port, velocity};
deviceManager.motor_device_set_velocity(&velocityData);
Devices are managed through the DeviceManager
, which allows adding, retrieving, and updating devices through a unified interface.
Devices, once initialized, can be added to the DeviceManager
for easy access and management.
MotorDevice motor;
motor.header.port = port;
// Set other motor attributes...
deviceManager.add_device(&motor.header);
Retrieve a device by its port to update or read its properties.
DeviceHeader* device = deviceManager.get_device(port);
if (device != nullptr) {
// Cast to specific device type as needed and interact with it
}
The DeviceManager
can iterate over all managed devices to perform updates, such as reading sensor values or updating motor velocities.
deviceManager.update_devices(deltaTime);
This method should be called periodically, where deltaTime
is the time elapsed since the last update, to ensure device states are current.
The DeviceManager
class is defined in DeviceManager.hpp
and implemented in DeviceManager.cpp
. It encapsulates the logic for device management, including adding devices, retrieving them by port, and processing messages for device configuration.
- DeviceManager.hpp: Declares the
DeviceManager
class, including its methods and internal data structures. - DeviceManager.cpp: Implements the
DeviceManager
class methods, such as device initialization, serialization of messages, and device updates.
- For
device.hpp
anddevice.cpp
:
- Define the Device Struct
- Define the Device Message in proto (Device Struct, the callback data structs, the return value structs)
- Define the Device functions (Update, Initialize, Set)
- Define the Callbacks for the functions (port, additional parameters)
- Recompile using the README instructions
-
Note: this should be all you need for
device.hpp
anddevice.cpp
. Also, some steps are dependent on prior steps, such as defining the callbacks, and defining the probuf Messages. -
For
DeviceManager.cpp
;
- Add case handling for when new device functions are called in processMessage
- Add case handling for when a instance of the device is update in update_devices
- Jonathan Koch:
jonathan.koch@caemilusa.com
- Fagan ...:
something@usf.edu
TODO