Aditi Kulkarni's Notebook - cps-vip/cps-cosimulation-env GitHub Wiki

Fall 2026

Week 1

Entry 1

  • First week, went over the different teams and the responsibilities that they entail:
  • Current focus of the team is simulation/analysis of substation equipment, robot coordination with substation equipment, and securing the data that controls the substations.
  • Key components to get familiar with are sensors, actuators, and Control systems.
  • Did background research on the fundamentals of ROS and HELICS:
    • ROS:
      • Not actually an operating system.
      • It's a middleware framework for robotics.
      • Nodes are independent processes.
      • Nodes talk to each other over topics.
      • Communication follows a publish/subscribe pattern.
      • Comes with pre-built packages for common robotics problems.
      • Most relevant one for us: Nav2, for path planning/navigation.
      • We use ROS2, not ROS1.
      • ROS2 swapped ROS1's custom transport for DDS.
      • DDS gives better real-time behavior.
      • DDS also gives better multi-robot support.
    • HELICS:
      • Stands for Hierarchical Engine for Large-scale Interoperable Co-Simulation.
      • Lets separate simulators run together.
      • Each simulator can model a different physical domain.
      • Simulators trade data with each other as they run.
      • Core vocab:
        • Federate: a simulator instance connected to HELICS.
        • Federation: the group of federates running together.
        • Broker: coordinates timing and message passing between federates.
        • Publications/Subscriptions: how federates actually exchange values.
      • For our project specifically:
        • GridLAB-D federate models the substation/grid physics.
        • ROS federate handles the robot.
        • They trade fault/command data through a broker.
        • They are not directly coupled to each other.

Entry 2

  • Covered CPS fundamentals and course logistics.
  • CPS definition:
    • A physical system controlled by networked computers.
    • Sensors observe system state.
    • Actuators modify system state.
    • Together this forms a feedback control loop.
  • Controller types used across CPS platforms:
    • CPUs: full OS, any programming language.
    • MCUs: RTOS or bare metal, programmed in C/C++/Rust.
    • PLCs: ruggedized MCUs for industrial settings.
    • FPGAs: reconfigurable hardware, programmed in VHDL/Verilog, used for precise timing.
  • Class is split into three teams:
    • Device Modeling: builds the HELICS device/network models.
    • ROS/HELICS (ours): robot + cosim integration.
    • Device Security: protects the devices/data.
  • Instructors:
    • Hayden Cook, research engineer at GTRI's CIPHER Lab.
    • Samuel Litchfield, research engineer at GTRI's CIPHER Lab.
  • Grading logistics:
    • Notebook checks: 5% of grade.
    • Attendance: 5% of grade.
    • AI policy: allowed for code review/learning verification only.
    • AI policy: not allowed for writing notebook entries or presentations.

Week 2

Entry 3

  • Got placed on the ROS/HELICS team.
  • Teammates: Favour Adekola, Txaber Doria, Rishika Vunnama.
  • Rest of the week: dug into the cosimulation stack in more depth.
  • Power system simulator breakdown:
    • PyPower: handles power flow equations.
    • GridLAB-D: handles physics modeling of the distribution network.
    • Custom device models + ROS: our side of the simulation.
    • HELICS: ties all of the above together.
  • Federate config:
    • Lives in a JSON file.
    • Sets coreName/coreType.
    • Sets timing: offset, period, timedelta.
    • Establishes pub/sub keys and their types.
  • GridLAB-D's .glm file:
    • Sets up the whole distribution network.
    • The piece that matters for integration is helics_msg.
    • helics_msg points to that federate's own JSON config.
  • Two ways to launch a HELICS run:
    • A shell script that starts each program separately, each program has to know how to talk to HELICS itself.
    • A single cosim_runner.json that lists all federates and their exec commands (we don't use this one).

Entry 4

  • ROS deep dive.
  • Not actually an OS.
  • It's a framework where nodes talk via publishers/subscribers.
  • Comes with pre-packaged algorithms, e.g. Nav2 for navigation.
  • Robot architecture:
    • RPi talks to an STM32.
    • STM32 reads LIDAR, IMU, and odometer data.
    • An EKF handles localization.
    • Nav2 handles navigation.
    • STM32 drives the motors.
  • Semester task list:
    • Finish the custom PCB (maybe add an FPGA).
    • Get Pi/STM32 comms working.
    • Get the Pi talking to sensors.
    • Implement a Kalman filter for state estimation.
  • Also sat through device security basics, as background for securing the robot's comms:
    • Side channel attacks:
      • Unintentionally leaked info, correlated to data.
      • Can come from timing, voltage, EM, even fan noise.
      • Can be used to steal the underlying data.
      • Example: a timing attack against a naive string comparison in a password check.
    • PUFs (Physical Unclonable Functions):
      • Use transistor variation to generate a random number.
      • That number is reproducible for a given chip.
      • That number is unique to that chip.
      • Used for key generation/storage.
      • Used for device authentication.

Week 3

Entry 5

  • Background research for the kickoff presentation.
  • Pulled from last semester's (Spring 26) final presentation.
  • Last semester's project: SUPERGHECTTI, a substation patrol robot.
  • Motivation:
    • The grid is vulnerable to weather, cyber threats, and physical attacks.
    • Human maintenance labor risks injury/electrocution.
  • Last semester's architecture:
    • ROS2 robot in Gazebo simulation with NAV2.
    • Synced to HELICS + GridLAB-D through a broker.
    • A Control Center Python federate reads relay/transmission/distribution faults.
  • Mission 1 (done):
    • GridLAB-D generates a fault.
    • Control Center detects it, messages ROS via HELICS.
    • Robot navigates to the fault location in Gazebo.
  • Mission 1.5 (done):
    • Extended Mission 1 to overheating transformers.
    • Thermal Monitor federate estimates temperature from current draw.
    • Robot does a 360° thermal scan once it reaches the fault.
  • Mission 2 (in progress last semester):
    • Moving from simulation to a physical robot.
    • Chassis revamp.
    • Custom STM32H723 PCB.
    • Pi/STM32 serial comms over cmd/vel.
    • LIDAR + IMU added for SLAM.
    • Kalman filtering via ROS2's robot_localization package.
    • EKF combines IMU + quadrature encoder data.

Entry 6

  • Presentation prep with the team.
  • Divided up sections with Favour, Txaber, and Rishika.
  • Agreed to carry forward Mission 2's unfinished pieces:
    • Finishing the PCB.
    • Pi/STM32 comms.
    • Sensor fusion.
  • Built the "where we left off" slides using the Entry 5 research.
  • Reviewed the grading rubric on Canvas ahead of next class.

Entry 7

  • Spent some time on the device modeling team's repo (cps-cosimulation-env).
  • This is outside our team's scope, but wanted to see the build through.
  • Setup steps followed:
sh <(curl -s -L https://nixos.org/nix/install) --daemon
sudo nano /etc/nix/nix.conf   # add: experimental-features = nix-command flakes
git submodule update --init --recursive
nix develop
make all-install
  • Build results:
    • HELICS built clean.
    • GridLAB-D compiled, only legacy-code warnings.
    • gridlabd crashed at runtime: dyld: missing LC_UUID load command.
  • Debugging steps:
    • Ran otool -l gridlabd | grep LC_UUID, confirmed the UUID was genuinely missing.
    • Tried codesign -f -s -, didn't fix it, that regenerates a signature, not linker metadata.
    • Forced the link through Apple's native linker (-fuse-ld=/usr/bin/ld) instead of nix's bundled one.
    • Confirmed via verbose build output that the flag was actually applied.
    • Still no UUID.
    • Traced it to a stray beta SDK: MacOSX26.5.sdk.
    • nix's clang was resolving to that instead of the real MacOSX.sdk.
    • Likely caused by being on the macOS 26 beta.
    • Manually relinked against the correct SDK path.
    • Got further, but UUID still isn't showing up.
  • Status: unresolved for now, parking it since it's not our team's branch.

Week 4

Entry 8

  • Gave our ROS/HELICS kickoff presentation and finalized the direction for the semester.
  • Main semester goal: move the existing work from simulation onto a physical inspection robot that can navigate around the classroom.
  • Split the team into two main subtasks:
    • Robot Design: Txaber, Rishika, and me.
    • Navigation and Fault Detection Integration: Favour and Ryo.
  • Our Robot Design group is responsible for designing, building, and testing the physical substation inspection robot.
  • Main parts of our work:
    • Robot chassis and electronics.
    • Custom PCB.
    • Raspberry Pi and STM32 communication.
    • Integrating the hardware needed for physical navigation.
  • The current robot design is a ground traversal robot:
    • Wheeled platform that can move around a substation environment.
    • Intended to allow remote inspection of faults.
    • Eventually should be automatically deployed after a fault is detected.

Entry 9

  • Went through the current PCB design and what still needs to be completed.
  • Progress from the previous semester:
    • First design review was completed.
    • Encoders were added for measuring wheel motion.
    • Motor drivers were added to control the motors.
    • Buck converters were added for power regulation.
    • Switches and LEDs were added for basic control/status indication.
  • Remaining PCB work:
    • Finish assigning footprints.
    • Start the PCB layout.
    • Add expansion headers for additional hardware.
  • One important goal is making the board flexible enough to connect the sensors and other components that will be needed later in the semester.

Entry 10

  • Looked more closely at how the Raspberry Pi and STM32 will communicate.
  • Planned control flow:
    • NAV2 outputs the robot's desired forward and rotational velocity.
    • The Raspberry Pi receives those velocity commands.
    • The commands have to be converted into individual wheel velocities.
    • Those wheel commands are then sent to the STM32 through serial communication.
    • The STM32 handles the lower-level motor control.
  • This creates a bridge between ROS2/NAV2 on the Raspberry Pi and the physical motors controlled by the STM32.
  • Also reviewed the localization side of the system:
    • Kalman filtering combines noisy sensor measurements with a model/prediction of the robot's state.
    • ROS2's robot_localization package will handle the filtering.
    • Sensor data has to be provided in the correct ROS2 message format.
    • The filter updates TF transforms that NAV2 uses for localization and navigation.
  • Remaining localization/control work:
    • Tune the Extended Kalman Filter measurement and process covariances.
    • Fuse wheel odometry with IMU data.
    • Tune SLAM to generate a more stable classroom map.
    • Tune the PID control loop used for wheel velocity.
  • Main challenge for this semester is translating everything that already works in simulation into reliable behavior on the physical robot.

Week 5

Entry 11

  • Continued work on the Robot Design side with Txaber and Rishika.
  • Focus this week: working out how NAV2's velocity commands actually turn into motor commands on the STM32.
  • Differential drive kinematics:
    • NAV2 publishes on /cmd_vel as a geometry_msgs/Twist message.
    • Only two fields matter for a ground robot: linear.x (forward velocity, m/s) and angular.z (rotation rate, rad/s).
    • Need to convert these into individual left/right wheel velocities.
    • Equations:
      • v_left = v - (ω · L / 2)
      • v_right = v + (ω · L / 2)
      • L = track width (distance between the two wheels).
    • To get wheel angular velocity (what the motors care about): divide by wheel radius r.
    • Robot parameters we still need to measure on the physical chassis: track width and wheel radius.
  • Serial protocol planning (Pi → STM32):
    • Pi runs a ROS2 node that subscribes to /cmd_vel, does the conversion, and sends wheel speeds over UART.
    • Need to define a packet format both sides agree on.
    • Ideas discussed:
      • Start byte so the STM32 can find the beginning of a packet.
      • Left and right wheel speeds as fixed-size values.
      • Checksum at the end to catch corrupted packets.
    • Also need a timeout on the STM32 side: if no command arrives within a set window, stop the motors.
      • Safety measure so the robot doesn't keep driving if the Pi crashes or the cable disconnects.
  • Feedback path (STM32 → Pi):
    • STM32 reads the quadrature encoders and sends wheel ticks/velocities back to the Pi.
    • Pi converts these into a nav_msgs/Odometry message.
    • This odometry is what feeds into robot_localization's EKF along with the IMU.
  • PCB progress:
    • Working on getting a ready made PCB.
    • Hardware side of things going to add header and see if any new parts need to be printed to accommodate for out new PCB.

Entry 11

  • Working on drafting a PCB design based on last year's PCB and current specifications.
  • Do research on making an STM32 blank and keeping it inactive until the module is further developed.
  • Use Sabina's notebook for PCB reference. See reference images below.
image image
⚠️ **GitHub.com Fallback** ⚠️