Rick Berglund's Notebook - cps-vip/cps-cosimulation-env GitHub Wiki

Week 1 (1/09 - 1/16)

  • Introduction to the VIP, deciding which subteam to join.

Week 2 (1/16 - 1/23)

  • Joined ROS/Helics subteam, assigned to work on Navigation/Nodes and Sensors subteam. Was sick for whole week, couldn't do much :(.
  • Made sure to look over weekly notes and the kick-off presentation.

Week 3 (1/23 - 1/30)

image

Week 4 (1/30 - 2/6)

Week 5 (2/6 - 2/13)

  • Not much progress was made (Exams were rough this week) besides more background research into sensors that we will use in the bot. Specifically on LIDAR, optical sensors, and heat sensors.
  • Reviewed the paper midterm draft, looking for improvements to the NAV/Sensors section.

Week 6 (2/13 - 2/20)

  • Shifting focus from research into testing sensors in ROS/Gazebo. Will have to follow ROS tutorials to understand it better.
  • Decided to focus on heat and infrared sensors for robot and figuring how to configure in ROS.

Week 8 (2/20 - 2/27)

  • Was really busy this week with outside work so not much progress on the side of the heat/infrared sensors.
  • Worked on updating the midterm presentation slides with progress from this semester and future plans. image

Week 9 (2/27 - 3/6)

Week 10 (3/6 - 3/13)

  • Ensuring that NAV2 works on local device. Everything seemed to work and got NAV2 from Natalie's notebook working. Screenshot 2025-04-03 162059 Screenshot 2025-04-03 162126
  • Need to make sure to put the proper version (in this case jazzy).

TODO:

  • continue heat sensor implementation search

Week 11 (3/13 - 3/20)

  • Spring break not much progress.

Week 12 (3/20 - 3/27)

  • Playing more with the heat sensor. Make sure to use proper commands to run it (see below): Screenshot 2025-04-03 162506 Instead, use this command: Screenshot 2025-04-03 162514
  • The UI for the heat sensor looks like Screenshot 2025-04-03 162708

TODO:

  • begin to look into how to put into physical environment of substation

Week 13 (3/27 - 4/3)

  • I began to look into how to actually put the heat sensor into what we already have in the GitHub. image

TODO:

  • work on attaching heat sensor to robot
  • figure out how to gather inputs and read them

Week 14 (4/3 - 4/10)

  • Try using example thermal camera sdf into the physical environment sdf in the github. image
  • Having some problems getting the actual environment and everything set up and working well with the camera, the environment looks strange... image
  • Final presentation is due next week, so I have to start thinking about edits to make
  • Sam was also able to get a heat sensor and listener working, so hopefully I can be able to add that heat sensor onto what we already have and then take in data

TODO:

  • final presentation
  • fixing environment
  • finding best heat sensor model

Week 15 (4/10-4/17)

  • Was very busy with 3 exams, so I wasn't able to make much progress with the enviro/heat sensor
  • Added information to our final presentation on the heat sensor progress and possible future steps

TODO:

  • work on final paper

Semester 2 Fall 2025

Week 1 (8/21-8/28)

  • Get reacquainted with VIP, try and make sense of next steps
  • Figured out who is in my subteam, and what our goals may be (mission nav?, building the robot?, fault??)

TODO:

  • review past semester's work
  • Kickoff Presen!

Week 2 (8/28-9/4)

  • Got on VC and chat with members of subteam (Natalie, Nguyen, Sam, Calvin, ...)
  • Worked on cutting down on the kickoff presentation, including deciding future goals
  • narrowed down that I will be working not as much on sensors but just a MVP of a complete mission

TODO:

Week 3 (9/4-9/11)

TODO:

  • make sense of Safiy's work
  • learn more about gridlab-d

Week 4 (9/11-9/18)

  • docker run -p 6080:80 --security-opt seccomp=unconfined --shm-size=512m helics-image-ros used this command to try and build docker image, it seems to have problems with ROS version, ROS2 solution?
  • Got acclimated with ROS again after long break, looked over video series for ROS2: https://www.youtube.com/watch?v=HJAE5Pk8Nyw&t=4664s

TODO:

  • try and inject some faults and see fault detection in action
  • learn more gridlab-d and about mission

Week 5 (9/18-9/25) Team meeting:

  • Not much, just discussed progress and what we want to do moving forward.

Individual Time:

  • Had to go into VM for the fault detection and mission testing, ran commands again from the past semester to set up.
  • Able to load up VSCodium and repo, make sure to select weaker encryption: image
  • Interested in AI/ML concepts for searching to map out the best path for the robot.

TODO:

  • Talk with other team members about mission

Week 6 (9/25-10/2) Team meeting:

  • Discussed more updates about progress.
  • Discussed issues with Docker and using images from the past semester made by Joseph (same one I'm using).

Individual Time:

  • Was able to figure out that A* search is probably the best for finding the shortest path for the robot. I read some textbook/paper on A* and learned about how it uses heuristic and total cost to reach the current position to estimate the best way to reach the target. This can be adapted to include things that can increase cost during certain conditions.
  • (some info on A* https://en.wikipedia.org/wiki/A*_search_algorithm) image
  • I have to figure out a heuristic to use, though, and also how to map out the substation to learn about where the possible paths are.

TODO:

  • Want to get an actual mission running with a set input and directions, figure out from other members.

Week 7 (10/2-10/9) Team meeting:

  • Discussed midterm presentation expectations.

Individual Time:

  • Had fall break and an exam the same week, so I wasn't able to make much progress.
  • Did talk with Sam (on my subteam) about Rviz2 progress and the heat sensor I touched a bit last semester (hopes still alive to use that for nav)

TODO:

  • still have to get mission...

Week 8 (10/9-10/16) Team meeting:

  • Was not able to attend due to interview overlap

Individual Time:

  • I spent all my time this week prepping for interview (I'm sorry Sam and Will I've been so busy recently 😭)
  • Side note: use ![image]{attatchment} instead of the html tag to attach images looks much better.

TODO:

  • interested in some Bayesian statistics to figure out if a fault is actually what is causing a problem in the substation. (Will have to look into this more)

Week 9 (10/17-10/23) Team meeting:

  • started to discuss possible things to put on final presentation
  • learned more about built in search functions in ROS2

Individual Time:

  • looked at Nguyen's notebook for some info on mission, especially on trying to automize the movement of robot to fault
  • switching focus from figuring out if something is a fault to just assuming that a fault will occur at a certain voltage

TODO:

  • start to prep for final presentation

Week 10 (10/24-10/30) Team Meeting:

  • was not able to attend

Individual Time:

  • Started to figure out how to get fault injected in HELICS and get a ROS2 bridge to automatically move
  • previously this was done manually image
  • this image shows how a fault is injected into HELICS, and with the help of a ROS2 bridge moves the bot

TODO:

  • finalize the code and publish to github
  • look into gazebo to model the robot

Week 11 (10/31 - 11/6) Halloween!

  • had two midterms and was sick so not much progress was done
  • looked a little into gazebo from Nguyen/Natalie notebook

Week 12/14 (11/7 - 11/20) Team Meeting: Final Presentation

Individual Time:

  • published github branch with my code in python with the ROS2 HELICS bridge that successfully moves the robot
  • use a coordinate mapper to map location of substation component to location for the robot, which autmotically uses algos like A* to find a path
  • https://github.com/cps-vip/NAV2/tree/feature/helics-bridge image
  • the image here shows this coordinate map, but need to figure out a better way for this, having to manually put loc in is not good
  • for future semester, have to figure out how to get the gazebo sim to work, right now shows the robot not moving at all...
  • also have to figure out when exactly to trigger a fault detection, is just set to a set voltage
  • made some slides on the final presen on work
  • it's also very complicated to run all of this, with multiple terminals having to be open to start the publisher, fault injection, etc. have to figure out how to simplify this

Steps to run fault and movement:

  1. Once in right branch, run Helics broker with: python3 -c "import helics; import time; b=helics.helicsCreateBroker('zmq','', '-f 2'); print('Broker started. Waiting...'); time.sleep(3600)"
  2. Run Gazebo (which is not connecting properly right now): source /opt/ros/jazzy/setup.bash cd ~/Desktop/nav2/NAV2 source install/setup.bash ros2 launch vipnav launch_sim.launch.py
  3. Run the navigation: source /opt/ros/jazzy/setup.bash cd ~/Desktop/nav2/NAV2 source install/setup.bash ros2 launch nav2_bringup bringup_launch.py use_sim_time:=True map:=./mapSave.yaml
  4. Run the robot script: source /opt/ros/jazzy/setup.bash cd ~/Desktop/nav2/NAV2 source install/setup.bash python3 src/vipnav/node/waypoint_publisher.py
  5. Give a fault: cd ~ python3 test_trigger.py It should say Injecting Fault and Dispatching to.

Semester 3 Spring 2026

Week 1-3 (1/12 - 1/29)

  • It's the third semester! First three weeks spent mostly looking over my past semesters' work and looking at what to do next
  • next steps are to get connection to gazebo working with the fault injection and detection logic to model movement of robot
  • creating connection with gazebo and the NAV2 hardware interfaces will allow for physical robot to have full mission
  • worked on the Spring kickoff slides, hiding some of the slides that are no longer relevant/have people to work on

TODO:

  • look into gazebo and ROS2/Helics connection

Week 4-5 (2/5 - 2/12)

  • With others working on mission 1, decided to go back to thermal camera from previous semesters to try and implement different faults
  • https://gazebosim.org/api/sensors/6/thermalcameraigngazebo.html Built in gazebo thermal camera can be used to scan for high heat signatures.
  • I^2*R is equal to heat produced by current I and resistance R, which can be used to calculate a simulated temperature.

TODO:

  • have a HELICS federate monitor Gridlab-D for a simulated temp

Week 6-7 (2/12 - 2/26)

  • Not as much progress due to midterm and recovering from surgery

  • looked into completed mission 1 and was able to replicate on my end

  • I was running into the yaml problem as listed so used pip install pyyaml readme

  • started to try and implement the heat sensor into the mission 1.

  • Refined slides on the midterm presentation and deleted old things.

  • This xacro file adds the thermal sensor to the robot `

<joint name="thermal_camera_joint" type="fixed">
    <parent link="chassis"/> <child link="thermal_camera_link"/>
    <origin xyz="0.15 0 0.2" rpy="0 0 0"/> 
</joint>

<link name="thermal_camera_link">
    <visual>
        <geometry>
            <box size="0.02 0.05 0.03"/>
        </geometry>
        <material name="black"/>
    </visual>
    <collision>
        <geometry>
            <box size="0.02 0.05 0.03"/>
        </geometry>
    </collision>
    <inertial>
        <mass value="0.1"/>
        <origin xyz="0 0 0" rpy="0 0 0"/>
        <inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001"/>
    </inertial>
</link>

<gazebo reference="thermal_camera_link">
    <sensor name="thermal_camera" type="thermal">
        <camera>
            <horizontal_fov>1.047</horizontal_fov>
            <image>
                <width>320</width>
                <height>240</height>
                <format>L8</format> </image>
            <clip>
                <near>0.1</near>
                <far>100.0</far>
            </clip>
        </camera>
        <always_on>1</always_on>
        <update_rate>10.0</update_rate>
        <visualize>true</visualize>
        <topic>/thermal_camera/image_raw</topic>
    </sensor>
</gazebo>
`
  • note: the thermal camera is very small, so it's hard to see

###TODO:

  • add a transformer that will heat up into the world
  • write the HELICS federate to subscribe to GridLab-D

Week 8 (2/26 - 3/5)

Screenshot 2026-04-20 190246 - created HELICS federate to monitor for thermal faults: image

###TODO:

  • edit the waypoint publisher for mission one to accept thermal fault

Week 9 (3/5 - 3/12)

Screenshot 2026-04-20 231005 - currently running into errors with getting everything connected as seen below: Screenshot 2026-04-20 224328 Screenshot 2026-04-20 224400

TODO:

  • create broker to successfully connect and run everything

Week 10 (3/12 - 3/19)

  • Created run_thermal.sh file to use instead of cc_run_example.sh as outlined for Mission 1. To run use:
cd ~/software/cosim-fault-injection/simple_gridlabd_example
bash ./run_thermal.sh
Screenshot 2026-04-21 005256

TODO:

  • try and make a manual fault injector to see if problem persists
  • figure out RVIZ displays

Week 11 (3/18 - 3/26)

  • spring break :)

Week 12-13 (4/2 - 4/16)

  • Referencing the mission 1 flow, adapted the cc_run_example.sh with a simplified version:
#!/bin/bash

mkdir -p results/
TIMESTAMP=$(date +%s)

BROKER_LOG="./results/broker_$TIMESTAMP.log"
TRANSMISSION_LOG="./results/TransmissionSim_$TIMESTAMP.log"
CC_LOG="./results/CCSim_$TIMESTAMP.log"
DISTRIBUTION_LOG="./results/DistributionSim_$TIMESTAMP.log"
RELAY_LOG="./results/RelaySim_$TIMESTAMP.log"
THERMAL_LOG="./results/ThermalSim_$TIMESTAMP.log" 

touch $BROKER_LOG $TRANSMISSION_LOG $DISTRIBUTION_LOG $CC_LOG $RELAY_LOG $THERMAL_LOG

HELICS_BROKER=`which helics_broker`
# Start broker expecting 6 federates (5 grid + 1 robot)
($HELICS_BROKER -t="zmq" --federates=6 --name=mainbroker > $BROKER_LOG)&

echo "Starting Power Grid Simulators..."
cd Transmission
uv run Transmission_simulator.py > ../$TRANSMISSION_LOG 2>&1 &
cd ..

cd CC
uv run CC_simulator.py > ../$CC_LOG 2>&1 &
cd ..

cd Distribution
gridlabd IEEE_123_feeder_0.glm > ../$DISTRIBUTION_LOG 2>&1 &
cd ..

cd Relay 
uv run Relay_simulator.py > ../$RELAY_LOG 2>&1 &
cd ..

echo "Starting Thermal Fault Monitor..."
cd ThermalMonitor
uv run thermal_fault_monitor.py > ../$THERMAL_LOG 2>&1 &
cd ..

echo "Grid simulation started! The broker is now paused and waiting for your Waypoint Publisher to join."
  • Adding this along with thermal_fault_monitor.py (below) in a subfolder in Elliot's branch outlined in README for mission 1 in the simple gridlabd example and https://github.com/cps-vip/NAV2/tree/feature/helics-bridge-heat was able to replicate architecture for mission 1 but with thermal camera and overheating transformer
#!/usr/bin/env python3
import helics as h
import time

# Simulated thermal properties
AMBIENT_TEMP = 25.0 # Celsius
CRITICAL_TEMP = 35.0 # Celsius (Threshold for fault dispatch)
HEATING_COEFFICIENT = 0.05 # Rate of heating per Ampere above rating

# Substation coordinate map
SUBSTATION_MAP = {
    "Feeder_Node": (2.0, -2.0)
}

def main():
    fedinfo = h.helicsCreateFederateInfo()
    h.helicsFederateInfoSetCoreTypeFromString(fedinfo, "zmq")
    h.helicsFederateInfoSetCoreInitString(fedinfo, "--federates=1")
    fed = h.helicsCreateValueFederate("Thermal_Monitor_Fed", fedinfo)

    sub_current = h.helicsFederateRegisterSubscription(fed, "IEEE_123_feeder_0/currentA", "A")
    pub_fault = h.helicsFederateRegisterPublication(fed, "cc/thermal_fault", h.HELICS_DATA_TYPE_STRING, "")
    
    h.helicsFederateEnterExecutingMode(fed)
    
    current_time = 0.0
    sim_temperature = AMBIENT_TEMP
    fault_dispatched = False

    print("Starting Thermal Monitor...")

    while h.helicsFederateGetState(fed) == h.HELICS_STATE_EXECUTION:
        current_time = h.helicsFederateRequestTime(fed, current_time + 1)
        
        if h.helicsInputIsUpdated(sub_current):
            current_str = h.helicsInputGetString(sub_current)
            try:
                magnitude = abs(complex(current_str.replace('i', 'j'))) 
                
                if magnitude > 50.0:
                    sim_temperature += (magnitude - 50.0) * HEATING_COEFFICIENT
                else:
                    sim_temperature = max(AMBIENT_TEMP, sim_temperature - 1.0)
                    
                print(f"[Time {current_time}] Transformer_A Temp: {sim_temperature:.1f} °C")

                if sim_temperature >= CRITICAL_TEMP and not fault_dispatched:
                    x, y = SUBSTATION_MAP["Feeder_Node"]
                    h.helicsPublicationPublishString(pub_fault, f"{x},{y}")
                    print(f"CRITICAL HEAT DETECTED! Dispatching robot to {x},{y}")
                    fault_dispatched = True

            except ValueError:
                pass
                
    h.helicsFederateDisconnect(fed)

if __name__ == '__main__':
    main()
  • one thing to note is that the calculation for simulated heat in the file above is if magnitude > 50.0: sim_temperature += (magnitude - 50.0) * HEATING_COEFFICIENT, which is a linear approximation; a realistic ohmic heating calculation could be more accurate: sim_temperature += (magnitude**2 * R_VALUE) * HEATING_COEFFICIENT
  • also ensured that the RVIZ displays are properly setup like for mission 1, but adding Marker as well as the thermal camera image which can be found in the by topic tab:
Screenshot 2026-04-20 183958
  • there are also instances where errors can occur due to zombie programs such as in the screenshot below:
Screenshot 2026-04-21 011519
  • make sure to run pkill for any scripts run and helics/gridlabd; making a clean rebuild may also help if there are any faulty cached scripts:
cd ~/ros2_ws
rm -rf build/vipnav install/vipnav
source /opt/ros/jazzy/setup.bash
colcon build --symlink-install --packages-select vipnav

TODO:

  • work on updating presentation/notebook
  • create manual trigger to test thermal faults due to some lags in faults

Week 14 (4/16 - 4/23)

Screenshot 2026-04-21 004833
  • this works, allowing for a fault to be detected and a route to be planned for the robot:
Screenshot 2026-04-21 001944
  • steps to run manual trigger after following mission 1 setup: Terminal 1: Core Sim
cd ~/ros2_ws
source install/setup.bash
ros2 launch vipnav launch_sim.launch.py

Terminal 2: NAV2 Stack

cd ~/ros2_ws
source install/setup.bash
ros2 launch vipnav navigation_launch.py use_sim_time:=True

Terminal 3: Mini broker to just test robot and trigger

helics_broker -t zmq -f 2 --name=mainbroker

Terminal 4: Waypoint Publisher

cd ~/ros2_ws
source install/setup.bash
ros2 run vipnav waypoint_publisher.py

Terminal 5: manual trigger

cd ~/ros2_ws/src/NAV2/src/vipnav/node
python3 test_trigger.py
Screenshot 2026-04-20 191237
  • This graph shows the change in voltage and load, which gives the value needed to calculate the simulated temperature
  • Added a slide on the final presentation about the thermal camera and adaptation to mission 1
  • for RVIZ can be helpful to increase size of lasers to see pathing and obstacles easier
  • be careful using pkill to kill faulty programs; pkill python closed my VM...

TODO:

  • final presentation
  • peer reviews
  • final notebook snapshot
⚠️ **GitHub.com Fallback** ⚠️