Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions firmware/OBC/teensy/enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,55 @@

#include <cstdint>

// ==========================================
// 1. DEFINE THE ENUM TYPES (The Blueprints)
// ==========================================

enum UROS_states {
UROS_INIT,
UROS_FOUND,
UROS_OK,
UROS_ERROR
} state_UROS;
};

enum fan_states{
FANS_INIT,
FANS_OK,
FANS_ERROR
} state_fans;
};

enum TSB_STATES{
TSB_INIT,
TSB_OK,
TSB_ERROR
} state_TSB;
};

enum HYDROGEN_STATES{
HYDROGEN_INIT,
HYDROGEN_OK,
HYDROGEN_ERROR
} state_hydrogen;
};

enum OZONE_STATES{
OZONE_INIT,
OZONE_OK,
OZONE_ERROR
} state_ozone;
};

enum LORA_STATES {
LORA_INIT,
LORA_TRANSMIT,
LORA_FLAG,
LORA_FINISH,
LORA_DELAY
} state_lora;
};

enum LED_States {
LED_STATE_OFF,
LED_STATE_AUTO,
LED_STATE_TELEOP,
LED_STATE_ARRIVED
};

enum EMC2305_Reg : uint8_t
{
Expand All @@ -66,4 +77,14 @@ enum MIC184_Zone : uint8_t
MIC184_INTERNAL = 0x00
};



extern UROS_states state_UROS;
extern fan_states state_fans;
extern TSB_STATES state_TSB;
extern HYDROGEN_STATES state_hydrogen;
extern OZONE_STATES state_ozone;
extern LORA_STATES state_lora;
// Note: current_led_state is already extern'd inside led.h

#endif
77 changes: 77 additions & 0 deletions firmware/OBC/teensy/led.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include "led.h"

// Initialize the variables here
rcl_subscription_t led_sub;
std_msgs__msg__Int32 led_msg;
rclc_executor_t led_executor;

volatile LED_States current_led_state = LED_STATE_OFF;
unsigned long last_flash_time = 0;
bool flash_state = false;

void LED_setup() {
pinMode(PIN_LED_RED, OUTPUT);
pinMode(PIN_LED_GREEN, OUTPUT);
pinMode(PIN_LED_BLUE, OUTPUT);
Comment on lines +13 to +15

@chosterto chosterto Jun 22, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is just for testing, but eventually we will need to change how we control the LEDs (may require a more precise method for controlling PWM, like DMA?)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah the basic pin setup is just to verify the micro-Ros state machine is working. I agree, we are going to require a DMA driver for the LEDs. I think I should finish testing this state machine first and then move on to creating that.

LED_SM();
Comment thread
Gobind-Kailey marked this conversation as resolved.
}

bool led_setup_subscription(rcl_node_t *node, rclc_support_t *support, rcl_allocator_t *allocator) {
rcl_ret_t rc = rclc_subscription_init_default(
&led_sub,
node,
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
"rover_led_state"
);
if (rc != RCL_RET_OK) { return false; }

rc = rclc_executor_init(&led_executor, &support->context, 1, allocator);
if (rc != RCL_RET_OK) { return false; }

rc = rclc_executor_add_subscription(
&led_executor,
&led_sub,
&led_msg,
&led_subscription_callback,
ON_NEW_DATA
);
return rc == RCL_RET_OK;
}
// Subscriber Callback
void led_subscription_callback(const void * msgin) {
const std_msgs__msg__Int32 * msg = (const std_msgs__msg__Int32 *)msgin;
current_led_state = static_cast<LED_States>(msg->data);
}

// State Machine
void LED_SM() {
switch (current_led_state) {
case LED_STATE_AUTO: // Solid Red
analogWrite(PIN_LED_RED, 255);
analogWrite(PIN_LED_GREEN, 0);
analogWrite(PIN_LED_BLUE, 0);
break;

case LED_STATE_TELEOP: // Solid Blue
analogWrite(PIN_LED_RED, 0);
analogWrite(PIN_LED_GREEN, 0);
analogWrite(PIN_LED_BLUE, 255);
break;

case LED_STATE_ARRIVED: // Flashing Green
analogWrite(PIN_LED_RED, 0);
analogWrite(PIN_LED_BLUE, 0);
if (millis() - last_flash_time > 500) {
last_flash_time = millis();
flash_state = !flash_state;
analogWrite(PIN_LED_GREEN, flash_state ? 255 : 0);
}
break;

default: // Off / Idle
analogWrite(PIN_LED_RED, 0);
analogWrite(PIN_LED_GREEN, 0);
analogWrite(PIN_LED_BLUE, 0);
break;
}
}
29 changes: 29 additions & 0 deletions firmware/OBC/teensy/led.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef LED_H
#define LED_H

#include <Arduino.h>
#include <micro_ros_arduino.h>
#include <rcl/rcl.h>
#include <rclc/rclc.h>
#include <rclc/executor.h> // <--- This explicitly fixes the 'does not name a type' error!
#include <std_msgs/msg/int32.h>
#include "enums.h" // <--- Kept your awesome enum update

// --- LED INDICATOR PINS ---
#define PIN_LED_RED 2
#define PIN_LED_GREEN 3
#define PIN_LED_BLUE 4

// --- GLOBAL VARIABLES ---
extern rcl_subscription_t led_sub;
extern std_msgs__msg__Int32 led_msg;
extern rclc_executor_t led_executor;
extern volatile LED_States current_led_state; // Kept your enum type

// --- FUNCTION PROTOTYPES ---
void LED_setup();
bool led_setup_subscription(rcl_node_t *node, rclc_support_t *support, rcl_allocator_t *allocator);
void led_subscription_callback(const void * msgin);
void LED_SM();

#endif
2 changes: 1 addition & 1 deletion firmware/OBC/teensy/science.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define _SCIENCE_H

#include "DFRobot_MultiGasSensor.h" //Have to download from https://github.com/DFRobot/DFRobot_MultiGasSensor/releases/tag/V3.0.0
// #include "DFRobot_OzoneSensor.h" // https://github.com/DFRobot/DFRobot_OzoneSensor/releases/tag/V1.0.1
//#include "DFRobot_OzoneSensor.h" // https://github.com/DFRobot/DFRobot_OzoneSensor/releases/tag/V1.0.1

#include "enums.h"
#include "i2c.h"
Expand Down
79 changes: 56 additions & 23 deletions firmware/OBC/teensy/teensy.ino
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,27 @@
#include "servo.h"
#include "science.h"
#include "viper_topics.h"
#define ON_ROVER
#include "led.h"
#include "enums.h"
// #define ON_ROVER
#define USING_ROS
#define USING_LED
#define USING_IMU_ONBOARD
// #define USING_IMU_OTHER
#define USING_GPS
// #define USING_GPS
//#define USING_TSB
#define USING_FANS
#define USING_SERVO
#define USING_SCIENCE_SENSORS
#define USING_LORA
// #define USING_FANS
// #define USING_SERVO
// #define USING_SCIENCE_SENSORS
// #define USING_LORA

// --- STATE VARIABLES ---
UROS_states state_UROS;
fan_states state_fans;
TSB_STATES state_TSB;
HYDROGEN_STATES state_hydrogen;
OZONE_STATES state_ozone;
LORA_STATES state_lora;


#define DOMAIN_ID 5
Expand All @@ -39,7 +50,7 @@
#define AD0_VAL 1
#define IMU_INT1 23
#define MG_TO_MS2 0.0098066
#define DEG_TO_RAD 0.01745329
#define DEG_TO_RAD 0.01745329
#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){return false;}}
#define ROS_EXECUTE_INTERVAL(MS, X) do { \
static volatile int64_t init = -1; \
Expand All @@ -48,7 +59,6 @@
} while (0)\



rcl_allocator_t allocator;
rclc_support_t support;

Expand Down Expand Up @@ -203,6 +213,12 @@ void obc_destory_uros_entities()
rcl_publisher_fini(&health_pub, &teensy_node);
rcl_subscription_fini(&servo1_sub, &teensy_node);
rcl_subscription_fini(&servo2_sub, &teensy_node);

#ifdef USING_LED
rcl_subscription_fini(&led_sub, &teensy_node);
rclc_executor_fini(&led_executor);
#endif

destroy_viper_topics(&teensy_node);
rcl_node_fini(&teensy_node);
rclc_support_fini(&support);
Expand All @@ -212,20 +228,20 @@ bool obc_setup_uros()
{
#ifdef USING_ROS
if (Ethernet.linkStatus() == LinkOFF) {
return false;
}

locator.address = agent_ip;
locator.port = 9999;

RCCHECK(rmw_uros_set_custom_transport(
false,
(void *) &locator,
arduino_native_ethernet_udp_transport_open,
arduino_native_ethernet_udp_transport_close,
arduino_native_ethernet_udp_transport_write,
arduino_native_ethernet_udp_transport_read
));
return false;
}

locator.address = agent_ip;
locator.port = 9999;

RCCHECK(rmw_uros_set_custom_transport(
false,
(void *) &locator,
arduino_native_ethernet_udp_transport_open,
arduino_native_ethernet_udp_transport_close,
arduino_native_ethernet_udp_transport_write,
arduino_native_ethernet_udp_transport_read
));
allocator = rcl_get_default_allocator();

if (!options_initialized) {
Expand All @@ -236,8 +252,14 @@ bool obc_setup_uros()
options_initialized = true;
}

// 1. Core structures must be initialized FIRST
RCCHECK(rclc_support_init_with_options(&support, 0, NULL, &init_options, &allocator));
RCCHECK(rclc_node_init_default(&teensy_node, "obc_node", "obc", &support));

#ifdef USING_LED
if(!led_setup_subscription(&teensy_node, &support, &allocator)){return false;}
#endif

#ifdef USING_SERVO
if(!servo_setup_subscription(&teensy_node, &support, &allocator)){return false;}
#endif
Expand All @@ -246,7 +268,6 @@ bool obc_setup_uros()
if(!viper_setup_subscription(&teensy_node, &support, &allocator)){return false;}
#endif


RCCHECK(rclc_publisher_init_default(
&imu_pub,
&teensy_node,
Expand Down Expand Up @@ -390,6 +411,10 @@ void setup()
state_hydrogen = HYDROGEN_INIT;
state_ozone = OZONE_INIT;

#ifdef USING_LED
LED_setup();
#endif

pwm.begin();
pwm.setPWMFreq(50);
}
Expand All @@ -413,6 +438,7 @@ void Uros_SM(){
break;
}
case UROS_OK:{

ROS_EXECUTE_INTERVAL(200, state_UROS = (RMW_RET_OK == rmw_uros_ping_agent(100, 1)) ? UROS_OK : UROS_ERROR;);

if (state_UROS == UROS_OK) {
Expand All @@ -434,6 +460,10 @@ void Uros_SM(){
#ifdef USING_LORA
rclc_executor_spin_some(&viper_executor, RCL_MS_TO_NS(10));
#endif

Comment thread
Gobind-Kailey marked this conversation as resolved.
#ifdef USING_LED
rclc_executor_spin_some(&led_executor, RCL_MS_TO_NS(10));
#endif
}


Expand Down Expand Up @@ -683,6 +713,9 @@ void loop()
HYDROGEN_SM();
OZONE_SM();
#endif
#ifdef USING_LED
LED_SM();
#endif

health_msg.data.data[0] = state_UROS;
health_msg.data.data[1] = state_fans;
Expand Down
3 changes: 1 addition & 2 deletions firmware/OBC/teensy/viper_topics.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <rclc/executor.h>

#include <custom_interfaces/msg/viper_card_status.h>
#include <custom_interfaces/msg/viper_status.h>
#include <custom_interfaces/msg/viper_status.h>
#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){return false;}}


Expand Down Expand Up @@ -201,4 +201,3 @@ void destroy_viper_topics(rcl_node_t *node){
}

#endif

12 changes: 0 additions & 12 deletions ros_ws/src/robot_description/CMakeLists.txt

This file was deleted.

9 changes: 0 additions & 9 deletions ros_ws/src/robot_description/README.md

This file was deleted.

This file was deleted.

Loading