<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Takeo</title>
    <description>The latest articles on DEV Community by Takeo (@takeofuture).</description>
    <link>https://dev.to/takeofuture</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4049905%2Fd2644aef-bfe1-4d63-b446-ed732da60feb.png</url>
      <title>DEV Community: Takeo</title>
      <link>https://dev.to/takeofuture</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/takeofuture"/>
    <language>en</language>
    <item>
      <title>Trying VLA (Part 4): Testing Teleoperation from the Command Line</title>
      <dc:creator>Takeo</dc:creator>
      <pubDate>Thu, 03 Sep 2026 03:03:05 +0000</pubDate>
      <link>https://dev.to/takeofuture/trying-vla-part-4-testing-teleoperation-from-the-command-line-1721</link>
      <guid>https://dev.to/takeofuture/trying-vla-part-4-testing-teleoperation-from-the-command-line-1721</guid>
      <description>&lt;h1&gt;
  
  
  Trying VLA (Part 4): Testing Teleoperation from the Command Line
&lt;/h1&gt;

&lt;p&gt;In the previous article, I completed the assembly and calibration of the LeRobot SO-101.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/takeofuture/trying-vla-part-3-finally-assembling-lerobot-from-joint-2-to-calibration-3g79"&gt;https://dev.to/takeofuture/trying-vla-part-3-finally-assembling-lerobot-from-joint-2-to-calibration-3g79&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This time, I will send commands to each joint individually and check whether the robot moves correctly.&lt;/p&gt;

&lt;p&gt;First, let's check the current state of the robot.&lt;/p&gt;

&lt;p&gt;Before doing that, connect the control PC to the Waveshare board on the LeRobot arm, and connect the 12V power supply as well.&lt;/p&gt;

&lt;p&gt;For safety, I also keep the robot arm folded before starting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhpqi5ex7z5x05m1aq6fp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhpqi5ex7z5x05m1aq6fp.png" alt=" " width="680" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, activate the Python virtual environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ source ~/pyenv/lerobot/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's check the current position of each joint.&lt;/p&gt;

&lt;p&gt;This time, I will run the Python code directly from the command line. Of course, you could also save the same code in a Python file and execute it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(lerobot)$ python - &amp;lt;&amp;lt;'PY'
from lerobot.robots.so_follower import SOFollower, SOFollowerRobotConfig

robot = SOFollower(
    SOFollowerRobotConfig(
        port="/dev/ttyACM0",
        id="takeo_so101",
        use_degrees=True,
    )
)

robot.connect()

try:
    obs = robot.get_observation()

    for name, value in obs.items():
        if name.endswith(".pos"):
            print(f"{name:22s} = {value:.2f}")

finally:
    robot.disconnect()

PY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything is working correctly, you should see values similar to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;shoulder_pan.pos       = 5.67
shoulder_lift.pos      = -102.59
elbow_flex.pos         = 97.63
wrist_flex.pos         = 22.77
wrist_roll.pos         = 2.07
gripper.pos            = 20.16
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One thing worth mentioning here is what happens after calibration or after running a Python script that only reads the joint positions.&lt;/p&gt;

&lt;p&gt;At that point, you can still move the arm manually.&lt;/p&gt;

&lt;p&gt;However, if the arm is extended forward, it may suddenly drop downward under its own weight.&lt;/p&gt;

&lt;p&gt;This happens because the default setting is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;disable_torque_on_disconnect=True&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When the robot disconnects, the servo torque is turned off.&lt;/p&gt;

&lt;p&gt;As a result, joints such as &lt;code&gt;shoulder_lift&lt;/code&gt;, &lt;code&gt;elbow_flex&lt;/code&gt;, and &lt;code&gt;wrist_flex&lt;/code&gt; can no longer hold the weight of the arm against gravity.&lt;/p&gt;

&lt;p&gt;The SOFollower follows this setting and disables torque when it disconnects.&lt;/p&gt;

&lt;p&gt;Now let's create a small script that moves each motor only a little so that we can verify that every joint works correctly.&lt;/p&gt;

&lt;h4&gt;
  
  
  Testing Each Motor
&lt;/h4&gt;

&lt;p&gt;Create the following file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;test_motor.py&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/usr/bin/env python3

import sys
import time

from lerobot.robots.so_follower import SOFollower, SOFollowerRobotConfig


JOINTS = {
    1: "shoulder_pan.pos",
    2: "shoulder_lift.pos",
    3: "elbow_flex.pos",
    4: "wrist_flex.pos",
    5: "wrist_roll.pos",
    6: "gripper.pos",
}


def print_positions(title, obs):
    print()
    print("=" * 55)
    print(title)
    print("=" * 55)

    for motor_id, joint in JOINTS.items():
        value = obs[joint]

        if motor_id == 6:
            print(f"ID{motor_id}  {joint:20s} = {value:8.2f}")
        else:
            print(f"ID{motor_id}  {joint:20s} = {value:8.2f} deg")

    print("=" * 55)


def main():
    if len(sys.argv) != 3:
        print("Usage:")
        print("  python test_motor.py MOTOR_ID DELTA")
        print()
        print("Examples:")
        print("  python test_motor.py 1 5")
        print("  python test_motor.py 2 -2")
        print("  python test_motor.py 6 5")
        sys.exit(1)

    motor_id = int(sys.argv[1])
    delta = float(sys.argv[2])

    if motor_id not in JOINTS:
        print("ERROR: MOTOR_ID must be 1 - 6")
        sys.exit(1)

    # Do not move the joint too far during the initial motion test.
    if abs(delta) &amp;gt; 10:
        print("ERROR: For safety, DELTA must be between -10 and +10.")
        sys.exit(1)

    joint = JOINTS[motor_id]

    robot = SOFollower(
        SOFollowerRobotConfig(
            port="/dev/ttyACM0",
            id="takeo_so101",
            use_degrees=True,
        )
    )

    robot.connect()

    try:

        # -------------------------------------------------
        # 1. Read the current positions.
        # -------------------------------------------------

        robot.bus.disable_torque()

        before = robot.get_observation()
        print_positions("BEFORE", before)

        current = before[joint]
        target_value = current + delta

        print()
        print(f"Selected motor : ID{motor_id}")
        print(f"Joint          : {joint}")
        print(f"Current        : {current:.2f}")
        print(f"Delta          : {delta:+.2f}")
        print(f"Target         : {target_value:.2f}")
        print()

        # -------------------------------------------------
        # 2. Set the current position as the goal position
        #    for every motor.
        #    This prevents sudden jumps when torque is enabled.
        # -------------------------------------------------

        hold_action = {
            name: before[name]
            for name in JOINTS.values()
        }

        robot.send_action(hold_action)

        input(
            "Support the arm and make sure it is safe.\n"
            "Press ENTER to enable torque and move the motor..."
        )

        # -------------------------------------------------
        # 3. Torque ON
        # -------------------------------------------------

        robot.bus.enable_torque()

        time.sleep(0.5)

        # -------------------------------------------------
        # 4. Change the target only for the selected motor.
        # -------------------------------------------------

        action = hold_action.copy()
        action[joint] = target_value

        print()

        print(
            f"&amp;gt;&amp;gt;&amp;gt; Moving ID{motor_id} "
            f"{joint}: {current:.2f} -&amp;gt; {target_value:.2f}"
        )

        robot.send_action(action)

        # Wait briefly for the motor to move.
        time.sleep(2.0)

        # -------------------------------------------------
        # 5. Display the position after the movement.
        # -------------------------------------------------

        after = robot.get_observation()
        print_positions("AFTER", after)

        print()
        print(f"Requested target : {target_value:.2f}")
        print(f"Actual position  : {after[joint]:.2f}")
        print()

        input("Press ENTER to disable torque and exit...")

    finally:
        robot.disconnect()

    print()
    print("Torque OFF / disconnected.")


if __name__ == "__main__":
    main()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's actually run it.&lt;/p&gt;

&lt;p&gt;I tested each motor using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ID1: Shoulder pan, +5°
python test_motor.py 1 5

# ID2: Shoulder lift, +2°
python test_motor.py 2 2

# ID3: Elbow, -5°
python test_motor.py 3 -5

# ID4: Wrist flex, +2°
python test_motor.py 4 2

# ID5: Wrist roll, +5°
python test_motor.py 5 5

# ID6: Gripper open/close, +5
python test_motor.py 6 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run these commands, each motor moves only a small amount.&lt;/p&gt;

&lt;p&gt;For Motor 3, I used a negative value to move it in the desired direction.&lt;/p&gt;

&lt;p&gt;Also, once torque is turned off, the arm drops again under gravity.&lt;/p&gt;

&lt;p&gt;During actual teleoperation, we normally keep the torque enabled so that the robot can maintain its posture instead of collapsing under its own weight.&lt;/p&gt;

&lt;p&gt;Here are the actual results from my tests.&lt;/p&gt;

&lt;h4&gt;
  
  
  Motor 1: Shoulder Pan
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(lerobot)$ python test_motor.py 1 5

=======================================================
BEFORE
=======================================================
ID1  shoulder_pan.pos     =    10.33 deg
ID2  shoulder_lift.pos    =   -91.60 deg
ID3  elbow_flex.pos       =    98.15 deg
ID4  wrist_flex.pos       =    24.88 deg
ID5  wrist_roll.pos       =     6.99 deg
ID6  gripper.pos          =    24.70
=======================================================

Selected motor : ID1
Joint          : shoulder_pan.pos
Current        : 10.33
Delta          : +5.00
Target         : 15.33

Support the arm and make sure it is safe.
Press ENTER to enable torque and move the motor...

&amp;gt;&amp;gt;&amp;gt; Moving ID1 shoulder_pan.pos: 10.33 -&amp;gt; 15.33

=======================================================
AFTER
=======================================================
ID1  shoulder_pan.pos     =    15.08 deg
ID2  shoulder_lift.pos    =   -91.60 deg
ID3  elbow_flex.pos       =    97.89 deg
ID4  wrist_flex.pos       =    24.88 deg
ID5  wrist_roll.pos       =     6.99 deg
ID6  gripper.pos          =    24.70
=======================================================

Requested target : 15.33
Actual position  : 15.08

Press ENTER to disable torque and exit...

Torque OFF / disconnected.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Motor 1 moved from &lt;code&gt;10.33°&lt;/code&gt; to &lt;code&gt;15.08°&lt;/code&gt;, very close to the requested target of &lt;code&gt;15.33°&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Motor 2: Shoulder Lift
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(lerobot)$ python test_motor.py 2 2

=======================================================
BEFORE
=======================================================
ID1  shoulder_pan.pos     =    15.08 deg
ID2  shoulder_lift.pos    =   -91.60 deg
ID3  elbow_flex.pos       =    97.89 deg
ID4  wrist_flex.pos       =    24.88 deg
ID5  wrist_roll.pos       =     6.99 deg
ID6  gripper.pos          =    24.70
=======================================================

Selected motor : ID2
Joint          : shoulder_lift.pos
Current        : -91.60
Delta          : +2.00
Target         : -89.60

Support the arm and make sure it is safe.
Press ENTER to enable torque and move the motor...

&amp;gt;&amp;gt;&amp;gt; Moving ID2 shoulder_lift.pos: -91.60 -&amp;gt; -89.60

=======================================================
AFTER
=======================================================
ID1  shoulder_pan.pos     =    15.08 deg
ID2  shoulder_lift.pos    =   -89.67 deg
ID3  elbow_flex.pos       =    97.89 deg
ID4  wrist_flex.pos       =    24.88 deg
ID5  wrist_roll.pos       =     6.99 deg
ID6  gripper.pos          =    24.70
=======================================================

Requested target : -89.60
Actual position  : -89.67

Press ENTER to disable torque and exit...

Torque OFF / disconnected.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Motor 2 also reached almost exactly the requested position.&lt;/p&gt;

&lt;h4&gt;
  
  
  Motor 3: Elbow Flex
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(lerobot)$ python test_motor.py 3 -5

=======================================================
BEFORE
=======================================================
ID1  shoulder_pan.pos     =    15.08 deg
ID2  shoulder_lift.pos    =   -89.67 deg
ID3  elbow_flex.pos       =    97.89 deg
ID4  wrist_flex.pos       =    24.88 deg
ID5  wrist_roll.pos       =     6.99 deg
ID6  gripper.pos          =    24.70
=======================================================

Selected motor : ID3
Joint          : elbow_flex.pos
Current        : 97.89
Delta          : -5.00
Target         : 92.89

Support the arm and make sure it is safe.
Press ENTER to enable torque and move the motor...

&amp;gt;&amp;gt;&amp;gt; Moving ID3 elbow_flex.pos: 97.89 -&amp;gt; 92.89

=======================================================
AFTER
=======================================================
ID1  shoulder_pan.pos     =    14.99 deg
ID2  shoulder_lift.pos    =   -89.76 deg
ID3  elbow_flex.pos       =    95.08 deg
ID4  wrist_flex.pos       =    24.88 deg
ID5  wrist_roll.pos       =     6.99 deg
ID6  gripper.pos          =    24.70
=======================================================

Requested target : 92.89
Actual position  : 95.08

Press ENTER to disable torque and exit...

Torque OFF / disconnected.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Motor 3 also moved in the expected direction, although the actual position did not reach the requested target as closely as some of the other joints.&lt;/p&gt;

&lt;h4&gt;
  
  
  Motor 4: Wrist Flex
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(lerobot)$ python test_motor.py 4 2

=======================================================
BEFORE
=======================================================
ID1  shoulder_pan.pos     =    15.08 deg
ID2  shoulder_lift.pos    =   -89.76 deg
ID3  elbow_flex.pos       =    98.07 deg
ID4  wrist_flex.pos       =    25.05 deg
ID5  wrist_roll.pos       =     6.99 deg
ID6  gripper.pos          =    24.70
=======================================================

Selected motor : ID4
Joint          : wrist_flex.pos
Current        : 25.05
Delta          : +2.00
Target         : 27.05

Support the arm and make sure it is safe.
Press ENTER to enable torque and move the motor...

&amp;gt;&amp;gt;&amp;gt; Moving ID4 wrist_flex.pos: 25.05 -&amp;gt; 27.05

=======================================================
AFTER
=======================================================
ID1  shoulder_pan.pos     =    15.08 deg
ID2  shoulder_lift.pos    =   -89.76 deg
ID3  elbow_flex.pos       =    97.89 deg
ID4  wrist_flex.pos       =    26.73 deg
ID5  wrist_roll.pos       =     6.99 deg
ID6  gripper.pos          =    24.70
=======================================================

Requested target : 27.05
Actual position  : 26.73

Press ENTER to disable torque and exit...

Torque OFF / disconnected.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Motor 4 moved from &lt;code&gt;25.05°&lt;/code&gt; to &lt;code&gt;26.73°&lt;/code&gt;, close to the requested target of &lt;code&gt;27.05°&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Motor 5: Wrist Roll
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(lerobot)$ python test_motor.py 5 5

=======================================================
BEFORE
=======================================================
ID1  shoulder_pan.pos     =    15.08 deg
ID2  shoulder_lift.pos    =   -89.76 deg
ID3  elbow_flex.pos       =    97.89 deg
ID4  wrist_flex.pos       =    26.73 deg
ID5  wrist_roll.pos       =     6.99 deg
ID6  gripper.pos          =    24.70
=======================================================

Selected motor : ID5
Joint          : wrist_roll.pos
Current        : 6.99
Delta          : +5.00
Target         : 11.99

Support the arm and make sure it is safe.
Press ENTER to enable torque and move the motor...

&amp;gt;&amp;gt;&amp;gt; Moving ID5 wrist_roll.pos: 6.99 -&amp;gt; 11.99

=======================================================
AFTER
=======================================================
ID1  shoulder_pan.pos     =    15.08 deg
ID2  shoulder_lift.pos    =   -89.76 deg
ID3  elbow_flex.pos       =    97.89 deg
ID4  wrist_flex.pos       =    26.73 deg
ID5  wrist_roll.pos       =    11.56 deg
ID6  gripper.pos          =    24.70
=======================================================

Requested target : 11.99
Actual position  : 11.56

Press ENTER to disable torque and exit...

Torque OFF / disconnected.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Motor 5 also moved correctly.&lt;/p&gt;

&lt;h4&gt;
  
  
  Motor 6: Gripper
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(lerobot)$ python test_motor.py 6 5

=======================================================
BEFORE
=======================================================
ID1  shoulder_pan.pos     =    15.08 deg
ID2  shoulder_lift.pos    =   -89.76 deg
ID3  elbow_flex.pos       =    97.89 deg
ID4  wrist_flex.pos       =    26.73 deg
ID5  wrist_roll.pos       =    11.56 deg
ID6  gripper.pos          =    24.70
=======================================================

Selected motor : ID6
Joint          : gripper.pos
Current        : 24.70
Delta          : +5.00
Target         : 29.70

Support the arm and make sure it is safe.
Press ENTER to enable torque and move the motor...

&amp;gt;&amp;gt;&amp;gt; Moving ID6 gripper.pos: 24.70 -&amp;gt; 29.70

=======================================================
AFTER
=======================================================
ID1  shoulder_pan.pos     =    15.08 deg
ID2  shoulder_lift.pos    =   -89.76 deg
ID3  elbow_flex.pos       =    97.89 deg
ID4  wrist_flex.pos       =    26.73 deg
ID5  wrist_roll.pos       =    11.56 deg
ID6  gripper.pos          =    29.31
=======================================================

Requested target : 29.70
Actual position  : 29.31

Press ENTER to disable torque and exit...

Torque OFF / disconnected.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The gripper also responded correctly.&lt;/p&gt;

&lt;p&gt;With this test, I was able to confirm that the assembly, wiring, motor ID assignment, and calibration were basically working correctly.&lt;/p&gt;

&lt;p&gt;All six motors responded to commands and moved in the expected way.&lt;/p&gt;

&lt;p&gt;So now the SO-101 is finally ready for actual operation.&lt;/p&gt;

&lt;p&gt;For my setup, however, I am not planning to use a leader arm.&lt;/p&gt;

&lt;p&gt;Instead, I want to try controlling the SO-101 using a &lt;strong&gt;3D mouse (SpaceMouse)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That will be the next step.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Trying VLA (Part 3): Finally Assembling LeRobot — From Joint 2 to Calibration</title>
      <dc:creator>Takeo</dc:creator>
      <pubDate>Thu, 03 Sep 2026 02:51:15 +0000</pubDate>
      <link>https://dev.to/takeofuture/trying-vla-part-3-finally-assembling-lerobot-from-joint-2-to-calibration-3g79</link>
      <guid>https://dev.to/takeofuture/trying-vla-part-3-finally-assembling-lerobot-from-joint-2-to-calibration-3g79</guid>
      <description>&lt;p&gt;In the previous article, I explained how to assemble the first joint, Joint 1.&lt;/p&gt;

&lt;p&gt;I covered Joint 1 separately because there were several things worth paying attention to, such as the different types of screws, tips for fitting the parts together, and a few points that could easily cause trouble — at least, they did for me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/takeofuture/trying-vla-part-1-preparing-lerobot-and-assigning-ids-to-the-motors-538g"&gt;https://dev.to/takeofuture/trying-vla-part-1-preparing-lerobot-and-assigning-ids-to-the-motors-538g&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, I will continue the assembly process and go all the way through calibration.&lt;/p&gt;

&lt;p&gt;Based on the difficulties I encountered during the assembly, I want to mention one important point right at the beginning:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Joint 5, I recommend slightly changing the order of the assembly steps.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Joint 2
&lt;/h4&gt;

&lt;p&gt;(As long as you connect the wiring first, I think you can basically follow the video as-is.)&lt;/p&gt;

&lt;p&gt;Slide the second motor into place from above.&lt;/p&gt;

&lt;p&gt;Use four M2×6mm screws to secure Motor 2.&lt;/p&gt;

&lt;p&gt;Attach motor horns to both sides of Motor 2. As before, use M3×6mm motor-horn screws to secure them.&lt;/p&gt;

&lt;p&gt;Attach the Upper Arm and secure it with four M3×6mm screws on each side.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/Joint2_v2.mp4" rel="noopener noreferrer"&gt;https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/Joint2_v2.mp4&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It may be easier to connect the motors to each other before assembling them. Also, when fitting the motor into place, the motor horn can easily shift, so it may be better to push it into position in one motion. If it shifts out of alignment, the screw holes can become hidden, making it impossible to insert the screws.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0grn5cuj6w8inaau8urd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0grn5cuj6w8inaau8urd.png" alt=" " width="672" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Joint 3
&lt;/h4&gt;

&lt;p&gt;(Again, as long as you connect the wiring first, I think you can basically follow the video as-is.)&lt;/p&gt;

&lt;p&gt;Insert the third motor and secure it using four M2×6mm screws.&lt;/p&gt;

&lt;p&gt;Attach motor horns to both sides of Motor 3. As before, secure one side using an M3×6mm motor-horn screw.&lt;/p&gt;

&lt;p&gt;Attach the Forearm to Motor 3 and secure it with four M3×6mm screws on each side.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/Joint3_v2.mp4" rel="noopener noreferrer"&gt;https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/Joint3_v2.mp4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1hzd3yd93nh13vvifghd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1hzd3yd93nh13vvifghd.png" alt=" " width="698" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Joint 4
&lt;/h4&gt;

&lt;p&gt;(As long as you connect the wiring first, I think you can follow the video as-is.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/Joint4_v2.mp4" rel="noopener noreferrer"&gt;https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/Joint4_v2.mp4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fujksyhv84eoi5i4cqt55.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fujksyhv84eoi5i4cqt55.png" alt=" " width="690" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Joint 5
&lt;/h4&gt;

&lt;p&gt;(&lt;strong&gt;For this joint, I strongly recommend connecting the wiring before tightening the screws!&lt;/strong&gt;)&lt;/p&gt;

&lt;p&gt;First, assemble only the section shown in the video.&lt;/p&gt;

&lt;p&gt;Insert the motor and attach the motor horn on only one side.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft4rm1ws2cge5m615jg4f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft4rm1ws2cge5m615jg4f.png" alt=" " width="388" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  👆 It is very important to connect the power cables before tightening the screws as shown above!
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Do not install the screws immediately. At this stage, connect Motor 4 to Motor 5, and also connect the cable from Motor 5 that will later go to Motor 6.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In other words, once Motor 5 has been inserted into the frame, complete the wiring from Motor 4 to Motor 5 and from Motor 5 to Motor 6.&lt;/p&gt;

&lt;p&gt;If you tighten the screws before doing this, inserting the power connectors afterward becomes extremely difficult.&lt;/p&gt;

&lt;p&gt;I originally followed the video exactly and ended up struggling quite a lot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/Joint5_v2.mp4" rel="noopener noreferrer"&gt;https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/Joint5_v2.mp4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because I installed Motor 5 and tightened the screws first, connecting Motor 4 to Motor 5 and connecting the power cable from Motor 5 to Motor 6 became extremely difficult.&lt;/p&gt;

&lt;p&gt;To make things worse, once I had installed the screws, I was unable to remove one of them, so I could not simply take everything apart and redo the assembly.&lt;/p&gt;

&lt;p&gt;I suspect this may have been related to the quality of the frame parts I purchased. The screw hole appeared to become damaged or stripped, and I could no longer remove the screw that was holding the frame together.&lt;/p&gt;

&lt;p&gt;Eventually, I managed to insert the power connectors using tweezers and carefully pushing them into place with my little finger.&lt;/p&gt;

&lt;p&gt;However, I probably spent around &lt;strong&gt;two hours&lt;/strong&gt; on this step alone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6fr4dx9bgzj99edbmm8o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6fr4dx9bgzj99edbmm8o.png" alt=" " width="509" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  👆 If you assemble and tighten everything before wiring, accessing the power connectors becomes extremely difficult!
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Gripper / Handle / Waveshare Board Installation
&lt;/h4&gt;

&lt;p&gt;Attach the gripper to Motor 5.&lt;/p&gt;

&lt;p&gt;Secure it to the wrist-side motor horn using four M3×6mm screws.&lt;/p&gt;

&lt;p&gt;Insert the gripper motor and secure it using two M2×6mm screws on each side.&lt;/p&gt;

&lt;p&gt;Attach the motor horn and secure it using the M3×6mm motor-horn screw.&lt;/p&gt;

&lt;p&gt;Attach the Gripper Claw and secure it with four M3×6mm screws on each side.&lt;/p&gt;

&lt;p&gt;For this part, I think you can simply follow the video without any major problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/Gripper_v2.mp4" rel="noopener noreferrer"&gt;https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/Gripper_v2.mp4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the assembly is complete, attach the board and connect it to Motor 1.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl95csczvfl9w0pvz1qnp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl95csczvfl9w0pvz1qnp.png" alt=" " width="704" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depending on the quality of the frame parts, some components may not fit properly.&lt;/p&gt;

&lt;p&gt;If necessary, you may need to carefully widen or clean up a distorted opening using a file or utility knife.&lt;/p&gt;

&lt;p&gt;Since I had already connected the motors to each other while assembling the arm, at this stage I only needed to connect the Waveshare board to Motor 1, as shown at the beginning of the video.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/Wiring_v2.mp4" rel="noopener noreferrer"&gt;https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/Wiring_v2.mp4&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Securing the Robot Arm to the Desk
&lt;/h4&gt;

&lt;p&gt;If you leave the robot arm as-is, it can tip over when the arm is extended because of the shift in its center of gravity.&lt;/p&gt;

&lt;p&gt;For that reason, I secured the base to my desk.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5x2tmo4489v1mrfm1i0s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5x2tmo4489v1mrfm1i0s.png" alt=" " width="697" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For some reason, I still had one frame part left over, and I was not completely sure what it was supposed to be used for.&lt;br&gt;
I decided not to worry about it and continued.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg3m1yj09y95jmcimatri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg3m1yj09y95jmcimatri.png" alt=" " width="688" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, connect the PC to the Waveshare board using USB-C and connect power to the Waveshare board as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F50rgo8zxyo5jf18avnkb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F50rgo8zxyo5jf18avnkb.png" alt=" " width="425" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point, check that power is reaching Motor 6, which is the last motor in the daisy-chain connection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqt7xi3a44eycjgixnh3j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqt7xi3a44eycjgixnh3j.png" alt=" " width="691" height="388"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Calibration
&lt;/h4&gt;

&lt;p&gt;At this point, each motor can still be rotated manually by hand.&lt;/p&gt;

&lt;p&gt;You will feel some resistance and hear a slight mechanical sound while turning them, but they should still rotate manually.&lt;/p&gt;

&lt;p&gt;Before starting calibration, move each joint to approximately the middle of its range of motion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/pyenv/lerobot/bin/activate
&lt;span class="o"&gt;(&lt;/span&gt;lerobot&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;lerobot-calibrate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--robot&lt;/span&gt;.type&lt;span class="o"&gt;=&lt;/span&gt;so101_follower &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--robot&lt;/span&gt;.port&lt;span class="o"&gt;=&lt;/span&gt;/dev/ttyACM0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--robot&lt;/span&gt;.id&lt;span class="o"&gt;=&lt;/span&gt;takeo_so101
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INFO 2026-09-02 10:30:46 calibrate.py:89 {'robot': {'calibration_dir': None,
           'cameras': {},
           'disable_torque_on_disconnect': True,
           'id': 'takeo_so101',
           'max_relative_target': None,
           'num_read_retries': 2,
           'port': '/dev/ttyACM0',
           'position_d_coefficient': 32,
           'position_i_coefficient': 0,
           'position_p_coefficient': 16,
           'use_degrees': True},
 'teleop': None}
INFO 2026-09-02 10:30:46 follower.py:109 takeo_so101 SOFollower connected.
Press ENTER to use provided calibration file associated with the id takeo_so101, or type 'c' and press ENTER to run calibration:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I had already calibrated this robot once before.&lt;/p&gt;

&lt;p&gt;If I want to reuse the previous calibration file, I can simply press ENTER.&lt;/p&gt;

&lt;p&gt;If I want to perform calibration again, I can type &lt;code&gt;c&lt;/code&gt; and press ENTER.&lt;/p&gt;

&lt;p&gt;If this is your first time calibrating the robot, I believe you can proceed by pressing ENTER.&lt;/p&gt;

&lt;p&gt;For this article, however, I wanted to show the calibration process again, so I entered &lt;code&gt;c&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Press ENTER to use provided calibration file associated with the id takeo_so101, or type 'c' and press ENTER to run calibration: c
INFO 2026-09-02 10:35:41 follower.py:126
Running calibration of takeo_so101 SOFollower
Move takeo_so101 SOFollower to the middle of its range of motion and press ENTER....
Move all joints except 'wrist_roll' sequentially through their entire ranges of motion.
Recording positions. Press ENTER to stop...

-------------------------------------------
-------------------------------------------
NAME            |    MIN |    POS |    MAX
shoulder_pan    |   1171 |   2131 |   2968
shoulder_lift   |    325 |   2690 |   2697
elbow_flex      |    818 |    866 |   3021
wrist_flex      |   1100 |   2514 |   3418
gripper         |   1311 |   2719 |   2720
Calibration saved to /home/takeo/.cache/huggingface/lerobot/calibration/robots/so_follower/takeo_so101.json
INFO 2026-09-02 10:37:13 follower.py:238 takeo_so101 SOFollower disconnected.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you manually rotate each joint, the values in the table above continuously change.&lt;/p&gt;

&lt;p&gt;The following motors and joints are involved in the calibration process:&lt;/p&gt;

&lt;p&gt;ID1  shoulder_pan    → Left/right rotation&lt;br&gt;
ID2  shoulder_lift   → Shoulder up/down&lt;br&gt;
ID3  elbow_flex      → Elbow&lt;br&gt;
ID4  wrist_flex      → Wrist up/down&lt;br&gt;
ID5  wrist_roll      → Not included in this calibration process&lt;br&gt;
ID6  gripper         → Gripper open/close&lt;/p&gt;

&lt;p&gt;The calibration parameters are then stored in the following JSON file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;(lerobot)$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;cat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/home/takeo/.cache/huggingface/lerobot/calibration/robots/so_follower/takeo_so&lt;/span&gt;&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="err"&gt;.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"shoulder_pan"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"drive_mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"homing_offset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-1979&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1171&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2968&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"shoulder_lift"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"drive_mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"homing_offset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-422&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;325&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2697&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"elbow_flex"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"drive_mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"homing_offset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1146&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;818&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3021&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"wrist_flex"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"drive_mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"homing_offset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;795&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3418&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"wrist_roll"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"drive_mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"homing_offset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2006&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4095&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"gripper"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"drive_mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"homing_offset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1764&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1311&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2720&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, the assembly and calibration of the SO-101 follower arm are complete.&lt;/p&gt;

&lt;p&gt;In the next article, I plan to run teleoperation from the command line and check whether the robot moves correctly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/takeofuture/trying-vla-part-4-testing-teleoperation-from-the-command-line-1721"&gt;https://dev.to/takeofuture/trying-vla-part-4-testing-teleoperation-from-the-command-line-1721&lt;/a&gt;&lt;/p&gt;

</description>
      <category>hardware</category>
      <category>robotics</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Trying VLA (Part 2): Assembling LeRobot — Joint 1</title>
      <dc:creator>Takeo</dc:creator>
      <pubDate>Tue, 01 Sep 2026 07:09:28 +0000</pubDate>
      <link>https://dev.to/takeofuture/trying-vla-part-2-assembling-lerobot-joint-1-2npj</link>
      <guid>https://dev.to/takeofuture/trying-vla-part-2-assembling-lerobot-joint-1-2npj</guid>
      <description>&lt;p&gt;In the previous article, I assigned IDs to each motor and determined where each motor should be installed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/takeofuture/trying-vla-part-1-preparing-lerobot-and-assigning-ids-to-the-motors-538g"&gt;https://dev.to/takeofuture/trying-vla-part-1-preparing-lerobot-and-assigning-ids-to-the-motors-538g&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now it is finally time to start assembling the robot.&lt;br&gt;
👉 All the parts required for assembly should already be included, so the only tool you really need is a screwdriver.&lt;br&gt;
However, I strongly recommend using a &lt;strong&gt;magnetic screwdriver that can hold the screws in place against gravity&lt;/strong&gt;.&lt;br&gt;
Without one, installing some of the screws can be surprisingly difficult!&lt;/p&gt;

&lt;p&gt;For the assembly process, I mainly referred to the following official documentation and videos.&lt;br&gt;
&lt;a href="https://huggingface.co/docs/lerobot/main/assemble_so101" rel="noopener noreferrer"&gt;https://huggingface.co/docs/lerobot/main/assemble_so101&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/Joint1_v2.mp4" rel="noopener noreferrer"&gt;https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/Joint1_v2.mp4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One thing that may not be very obvious from the video is that I strongly recommend connecting the cable to the next motor &lt;strong&gt;before assembling the frame&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once the motor is installed inside those small frame parts, connecting the cable becomes much more difficult. Looking at the structure, it makes sense — there is simply not much space left to work with afterward 💦.&lt;/p&gt;

&lt;p&gt;In this article, I will not cover the entire assembly process. Instead, I will focus on &lt;strong&gt;Joint 1&lt;/strong&gt; and explain how I assembled it, including several places where I personally got stuck or had to redo the work.&lt;/p&gt;

&lt;p&gt;First, each motor comes with a motor horn and screws like these.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6tf6qrevohajc2pvq9ll.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6tf6qrevohajc2pvq9ll.png" alt=" " width="318" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;M3 screw&lt;/strong&gt; has a diameter of 3 mm and, in this case, a length of 6 mm.&lt;br&gt;
An &lt;strong&gt;M2 screw&lt;/strong&gt; has a diameter of 2 mm — measured around the shaft directly below the screw head — and in this case also has a length of 6 mm. The M2 screws used here have a countersunk-style head.&lt;/p&gt;

&lt;p&gt;Understanding screw specifications is actually quite useful when building robots like this.&lt;br&gt;
It becomes especially important when planning a project or sourcing replacement parts. At the very least, it is worth asking your LLM assistant about screw standards and making sure you understand them before starting.&lt;/p&gt;

&lt;p&gt;This kind of basic mechanical knowledge will become useful again if you build other robots, drones, or similar hardware projects in the future.&lt;br&gt;
If possible, I also recommend learning some basic soldering and how to repair power cables. If you accidentally pull a wire too hard and disconnect or damage it, knowing how to solder can allow you to repair at least some of those problems yourself.&lt;/p&gt;

&lt;h4&gt;
  
  
  Installing the Motor Horn — Pay Attention to the Orientation!!!
&lt;/h4&gt;

&lt;p&gt;Now let's install the motor horn.&lt;/p&gt;

&lt;p&gt;There is one important thing to be careful about at this stage.&lt;/p&gt;

&lt;p&gt;When I first installed the horn, I pushed it onto the motor and secured it with an &lt;strong&gt;M3x6mm screw&lt;/strong&gt; like this.&lt;/p&gt;

&lt;p&gt;However, the orientation of the horn must match the screw positions of the frame part. Otherwise, you may have to remove it and reinstall it later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm0s6xyxgy1ffev2823vc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm0s6xyxgy1ffev2823vc.png" alt=" " width="510" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first, I followed the orientation shown in the video, where the screw holes looked like a &lt;strong&gt;diamond shape&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, I eventually had to redo it because the screw positions on my frame part did not match that orientation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F74d9pvdmn71wzz7euw18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F74d9pvdmn71wzz7euw18.png" alt=" " width="413" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Push the horn slightly onto the motor shaft, and then secure it using the M3 screw.&lt;/p&gt;

&lt;p&gt;The important point is the orientation.&lt;/p&gt;

&lt;p&gt;When looking at the four outer screw holes, I initially positioned them so that connecting the holes would form a diamond shape, similar to what appeared in the video.&lt;/p&gt;

&lt;p&gt;For my frame, however, the holes needed to form a &lt;strong&gt;square&lt;/strong&gt; instead.&lt;/p&gt;

&lt;p&gt;This was my first mistake.&lt;/p&gt;

&lt;p&gt;Install the horn at an angle where the four screw holes look like the red circles shown below — forming a square rather than a diamond.&lt;/p&gt;

&lt;p&gt;More precisely, you should check the screw positions on your actual frame part at this stage and align the horn orientation accordingly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2adkkgfgw90zlzne2h9p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2adkkgfgw90zlzne2h9p.png" alt=" " width="211" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The horn on the opposite side does not need to be secured with a screw.&lt;/p&gt;

&lt;p&gt;You also do not necessarily need to install it at this stage. It may be easier to place it later while assembling the frame parts so that you can align the orientation correctly.&lt;/p&gt;

&lt;p&gt;I will explain this part later, so you do not need to install it yet.&lt;/p&gt;

&lt;p&gt;However, just like the other side, its orientation also needs to match the frame. In my case, it needed to be positioned as a square rather than a diamond.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqypiemch1p0f0bow16l9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqypiemch1p0f0bow16l9.png" alt=" " width="399" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgyeiw064zdnqg1tq3hvs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgyeiw064zdnqg1tq3hvs.png" alt=" " width="706" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I believe this depends on the frame parts you ordered or printed with a 3D printer.&lt;/p&gt;

&lt;p&gt;The screw-hole positions may differ slightly depending on the specific parts you have.&lt;/p&gt;

&lt;p&gt;Therefore, before tightening everything, check the screw-hole layout of your own frame and adjust the motor horn orientation accordingly.&lt;/p&gt;

&lt;h4&gt;
  
  
  Installing the Motor
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;TIP 1: First, test-fit the parts before tightening any screws.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TIP 2: Connect Motor 1 and Motor 2 before installing Motor 1 into the frame.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I personally struggled because I did not follow TIP 2.&lt;/p&gt;

&lt;p&gt;Before installing the first motor into the frame, I strongly recommend connecting the first motor to the second motor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj496lg5avnu72w1452p9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj496lg5avnu72w1452p9.png" alt=" " width="480" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this stage, before installing any screws, check that the motor can be pushed properly into the frame part, as shown in the assembly video.&lt;/p&gt;

&lt;p&gt;I think it is safer to verify the fit first and only then install the screws.&lt;/p&gt;

&lt;p&gt;Do not force the parts too hard.&lt;/p&gt;

&lt;p&gt;If you apply too much pressure, you may damage the threaded parts of the frame, strip the screw head, or make the screw difficult or impossible to remove later.&lt;/p&gt;

&lt;p&gt;Before installing screws into the motor, first check whether the following frame part fits properly.&lt;/p&gt;

&lt;p&gt;The official video installs the screws first, but based on my experience, I recommend checking the fit of the frame part beforehand.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1bucerazaxjyfxsa2xgs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1bucerazaxjyfxsa2xgs.png" alt=" " width="540" height="652"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Without tightening the screws, first check that the frame part fits correctly.&lt;/p&gt;

&lt;p&gt;Then check whether the motor screw holes align with the screw positions of the frame.&lt;/p&gt;

&lt;p&gt;The following image shows one of my mistakes, where the screw-hole orientation was offset by about 45 degrees.&lt;/p&gt;

&lt;p&gt;This happened because I followed the orientation shown in the video without first checking the actual frame part.&lt;/p&gt;

&lt;p&gt;So before tightening the horn, look carefully at your frame and determine how the screw holes need to be aligned.&lt;/p&gt;

&lt;p&gt;I followed the screw-hole orientation in the video and ended up with the wrong position.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F51me3pokz9mhoox8117q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F51me3pokz9mhoox8117q.png" alt=" " width="457" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdtnewrifvupqxnfdfg08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdtnewrifvupqxnfdfg08.png" alt=" " width="516" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I corrected the orientation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjf1xo1dnz7fmqg2drxf5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjf1xo1dnz7fmqg2drxf5.png" alt=" " width="497" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, &lt;strong&gt;this may vary depending on the frame parts you are using!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once you confirm that everything fits correctly, you can tighten the screws.&lt;/p&gt;

&lt;p&gt;To be honest, considering that this robot is mainly intended for education and experimentation, if the frame itself holds the motor firmly enough, it may not always be necessary to tighten every screw extremely firmly.&lt;/p&gt;

&lt;p&gt;Because of the quality of some screws and 3D-printed frame parts, applying too much force can potentially strip the screw head or damage the threaded hole.&lt;/p&gt;

&lt;p&gt;If that happens, removing the screw later can become very difficult.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5744lsed7r859jew0s9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5744lsed7r859jew0s9v.png" alt=" " width="518" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So first confirm that everything fits properly, and only then secure it with screws.&lt;/p&gt;

&lt;p&gt;If you discover, as I did, that the screw holes do not align correctly, one option is to redo the motor horn orientation.&lt;/p&gt;

&lt;p&gt;Another possibility, depending on how securely the motor is already held by the frame, may be to leave one side without screws rather than forcing a badly aligned screw into place.&lt;/p&gt;

&lt;p&gt;Next, after securing the motor with the &lt;strong&gt;M3x6mm screws&lt;/strong&gt;, install the next frame part.&lt;/p&gt;

&lt;p&gt;This is the part with a small protruding section on the upper-right side.&lt;/p&gt;

&lt;p&gt;There is another part with a very similar shape, so be careful not to confuse them.&lt;/p&gt;

&lt;p&gt;As mentioned earlier, I recommend connecting the cable to the next motor &lt;strong&gt;before installing the motor into the frame&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjo4imqnl6v9pibapjyv8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjo4imqnl6v9pibapjyv8.png" alt=" " width="523" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my case, I assembled the frame first without connecting the cable.&lt;/p&gt;

&lt;p&gt;As a result, I had to do the wiring afterward in a very narrow space, which made the work slightly more difficult.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fexvyq2zd8mzoo42j3ksr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fexvyq2zd8mzoo42j3ksr.png" alt=" " width="464" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I had connected the cable beforehand, the assembly would have been much easier.&lt;/p&gt;

&lt;p&gt;Rather than simply following the assembly video step by step, I recommend checking the following three points first. Doing this can significantly reduce the amount of rework.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check the orientation of the motor horn screw holes against the screw positions on the actual frame parts.&lt;/li&gt;
&lt;li&gt;Push the motor into the frame and test-fit the next part &lt;strong&gt;before tightening the screws&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Before installing Motor 1 into the frame, connect the power/data cable between Motor 1 and Motor 2.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it!&lt;/p&gt;

&lt;p&gt;In the next article, I’ll finish assembling the robot arm, secure it to the desk, and complete the calibration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/takeofuture/trying-vla-part-3-finally-assembling-lerobot-from-joint-2-to-calibration-3g79"&gt;https://dev.to/takeofuture/trying-vla-part-3-finally-assembling-lerobot-from-joint-2-to-calibration-3g79&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Trying VLA (Part 1): Preparing LeRobot and Assigning IDs to the Motors</title>
      <dc:creator>Takeo</dc:creator>
      <pubDate>Sun, 30 Aug 2026 23:16:21 +0000</pubDate>
      <link>https://dev.to/takeofuture/trying-vla-part-1-preparing-lerobot-and-assigning-ids-to-the-motors-538g</link>
      <guid>https://dev.to/takeofuture/trying-vla-part-1-preparing-lerobot-and-assigning-ids-to-the-motors-538g</guid>
      <description>&lt;p&gt;In the previous article, I briefly explained what VLA is, what LeRobot is, and what makes it useful, and then introduced the products I purchased.&lt;br&gt;
&lt;a href="https://dev.to/takeofuture/getting-started-with-lerobot-and-so-101-building-a-low-cost-physical-ai-robot-arm-part-0-6j1"&gt;https://dev.to/takeofuture/getting-started-with-lerobot-and-so-101-building-a-low-cost-physical-ai-robot-arm-part-0-6j1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that all the parts have arrived, it is finally time to start assembling the robot.&lt;/p&gt;

&lt;p&gt;However, before jumping straight into the assembly, there is one important step we need to complete first. You should have received six motors, and each of them needs to be assigned its own ID. In this article, I will first explain how to do that.&lt;/p&gt;

&lt;p&gt;We will connect the controller board to a PC and assign the IDs from there. You can also install Ubuntu on Windows using WSL (Windows Subsystem for Linux), but if possible, I recommend using a native Ubuntu installation. As of August 30, 2026, the latest stable LTS version is Ubuntu 24.04.&lt;/p&gt;
&lt;h2&gt;
  
  
  Installing the setup tools
&lt;/h2&gt;

&lt;p&gt;I will assume that Python 3 is already installed. If it is not, install it with the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;python3 python3-venv python3-pip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's create a Python virtual environment. Here, I will name it &lt;code&gt;lerobot&lt;/code&gt;, and then activate it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv lerobot
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source &lt;/span&gt;lerobot/bin/activate
&lt;span class="o"&gt;(&lt;/span&gt;lerobot&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pip 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, install LeRobot.&lt;/p&gt;

&lt;p&gt;Because the SO-101 uses STS3215 motors, the &lt;code&gt;feetech&lt;/code&gt; option is important.&lt;/p&gt;

&lt;p&gt;If this PC is only being used for configuration or teleoperation and does not have an NVIDIA GPU, it is better to install the CPU-only version of PyTorch first so that unnecessary NVIDIA GPU-related PyTorch packages are not downloaded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;lerobot&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;2.11.0+cpu &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--index-url&lt;/span&gt; https://download.pytorch.org/whl/cpu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;lerobot&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;span class="o"&gt;(&lt;/span&gt;lerobot&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git clone https://github.com/huggingface/lerobot.git
&lt;span class="o"&gt;(&lt;/span&gt;lerobot&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;lerobot
&lt;span class="o"&gt;(&lt;/span&gt;lerobot&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;".[feetech]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the installation is complete, you should be able to use commands such as the following!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;lerobot&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;lerobot-find-port &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;lerobot&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;lerobot-setup-motors &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting the Waveshare board to USB mode
&lt;/h2&gt;

&lt;p&gt;To communicate with the PC via USB-C, insert six jumpers arranged in two columns and three rows vertically into the appropriate pins.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd2f9zsvvunhp9l1epiw5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd2f9zsvvunhp9l1epiw5.png" alt=" " width="477" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7g5y4yg9ua9arbq39kba.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7g5y4yg9ua9arbq39kba.png" alt=" " width="470" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Connect the Waveshare board to the PC via USB, and also connect the power cable.&lt;/p&gt;

&lt;p&gt;The USB connection itself supplies power to the board, but it does not provide enough power to operate the motors, so you also need to connect the 12V power supply.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fry6b5ei1olggujsnxqi3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fry6b5ei1olggujsnxqi3.png" alt=" " width="484" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvsh0jn455ewf209ic9v6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvsh0jn455ewf209ic9v6.png" width="554" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the following command from the terminal to identify the port.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;lerobot&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;lerobot-find-port
Finding all available ports &lt;span class="k"&gt;for &lt;/span&gt;the MotorsBus.
Ports before disconnecting: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'/dev/ttyACM0'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyprintk'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS31'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS30'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS29'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS28'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS27'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/S20'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS19'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS18'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS17'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS16'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS15'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS14'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS13'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS12'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS11'&lt;/span&gt;, &lt;span class="s1"&gt;'/d'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS3'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS2'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS1'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/ttyS0'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty63'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty62'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty61'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty60'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty59'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty58'&lt;/span&gt;, &lt;span class="s1"&gt;'1'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty50'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty49'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty48'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty47'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty46'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty45'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty44'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty43'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty42'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty41'&lt;/span&gt;, 34&lt;span class="s1"&gt;', '&lt;/span&gt;/dev/tty33&lt;span class="s1"&gt;', '&lt;/span&gt;/dev/tty32&lt;span class="s1"&gt;', '&lt;/span&gt;/dev/tty31&lt;span class="s1"&gt;', '&lt;/span&gt;/dev/tty30&lt;span class="s1"&gt;', '&lt;/span&gt;/dev/tty29&lt;span class="s1"&gt;', '&lt;/span&gt;/dev/tty28&lt;span class="s1"&gt;', '&lt;/span&gt;/dev/tty27&lt;span class="s1"&gt;', '&lt;/span&gt;/dev/tty26&lt;span class="s1"&gt;', '&lt;/span&gt;/dev/tty25&lt;span class="s1"&gt;', '&lt;/span&gt;/dev/tty24&lt;span class="s1"&gt;',y17'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty16'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty15'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty14'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty13'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty12'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty11'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty10'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty9'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty8'&lt;/span&gt;, &lt;span class="s1"&gt;'/dev/tty7'&lt;/span&gt;, &lt;span class="s1"&gt;'ev/tty'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
Remove the USB cable from your MotorsBus and press Enter when &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As instructed by the command, disconnect the USB cable connecting the Waveshare device to the PC, and then press Enter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The port of this MotorsBus is '/dev/ttyACM0'
Reconnect the USB cable.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Success! We can now confirm that this Waveshare device is associated with&lt;br&gt;
/dev/ttyACM0&lt;/p&gt;

&lt;p&gt;If you are not running these commands as root, give your user account permission to access serial devices with the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;lerobot&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; dialout yourusername
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reconnect the USB cable to the PC. Then disconnect the power supply temporarily and connect a motor.&lt;/p&gt;

&lt;p&gt;Both the motors and the Waveshare board have two connectors, and either connector can be used. However, it is better to keep the connection pattern consistent. I will proceed using the following connection scheme.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Board left connector
   ↓
Motor 1 left connector

Motor 1 right connector
   ↓
Motor 2 left connector

Motor 2 right connector
   ↓
Motor 3 left connector
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the motor is connected, run the following command.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feorf9fiqzsh9f5xuqbon.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feorf9fiqzsh9f5xuqbon.png" alt=" " width="569" height="687"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;lerobot&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;lerobot-setup-motors &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--robot&lt;/span&gt;.type&lt;span class="o"&gt;=&lt;/span&gt;so101_follower &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--robot&lt;/span&gt;.port&lt;span class="o"&gt;=&lt;/span&gt;/dev/ttyACM0
Connect the controller board to the &lt;span class="s1"&gt;'gripper'&lt;/span&gt; motor only and press enter.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After pressing Enter, you should see the following output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'gripper' motor id set to 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The motor ID is important because it determines which motor will be installed at which joint of the robot. In this case, the motor was assigned ID 6, so it is a good idea to physically label the motor.&lt;/p&gt;

&lt;p&gt;Then repeat the same process for the remaining five motors.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disconnect the 12V power supply&lt;/li&gt;
&lt;li&gt;Disconnect the current motor&lt;/li&gt;
&lt;li&gt;Connect only one new motor to the board&lt;/li&gt;
&lt;li&gt;Reconnect the 12V power supply&lt;/li&gt;
&lt;li&gt;Press Enter&lt;/li&gt;
&lt;li&gt;Attach a label to the configured motor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Repeat this process until IDs have been assigned to all six motors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;lerobot&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;lerobot-setup-motors &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--robot&lt;/span&gt;.type&lt;span class="o"&gt;=&lt;/span&gt;so101_follower &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--robot&lt;/span&gt;.port&lt;span class="o"&gt;=&lt;/span&gt;/dev/ttyACM0
Connect the controller board to the &lt;span class="s1"&gt;'gripper'&lt;/span&gt; motor only and press enter.
&lt;span class="s1"&gt;'gripper'&lt;/span&gt; motor &lt;span class="nb"&gt;id set &lt;/span&gt;to 6
Connect the controller board to the &lt;span class="s1"&gt;'wrist_roll'&lt;/span&gt; motor only and press enter.
&lt;span class="s1"&gt;'wrist_roll'&lt;/span&gt; motor &lt;span class="nb"&gt;id set &lt;/span&gt;to 5
Connect the controller board to the &lt;span class="s1"&gt;'wrist_flex'&lt;/span&gt; motor only and press enter.
&lt;span class="s1"&gt;'wrist_flex'&lt;/span&gt; motor &lt;span class="nb"&gt;id set &lt;/span&gt;to 4
Connect the controller board to the &lt;span class="s1"&gt;'elbow_flex'&lt;/span&gt; motor only and press enter.
&lt;span class="s1"&gt;'elbow_flex'&lt;/span&gt; motor &lt;span class="nb"&gt;id set &lt;/span&gt;to 3
Connect the controller board to the &lt;span class="s1"&gt;'shoulder_lift'&lt;/span&gt; motor only and press enter.
&lt;span class="s1"&gt;'shoulder_lift'&lt;/span&gt; motor &lt;span class="nb"&gt;id set &lt;/span&gt;to 2
Connect the controller board to the &lt;span class="s1"&gt;'shoulder_pan'&lt;/span&gt; motor only and press enter.
&lt;span class="s1"&gt;'shoulder_pan'&lt;/span&gt; motor &lt;span class="nb"&gt;id set &lt;/span&gt;to 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fey0r5fsw20fk5l76731z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fey0r5fsw20fk5l76731z.png" alt=" " width="473" height="689"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To summarize, the motor IDs are assigned as follows. This mapping is very important, so make sure to record it carefully.&lt;br&gt;
ID 1 = shoulder_pan&lt;br&gt;
ID 2 = shoulder_lift&lt;br&gt;
ID 3 = elbow_flex&lt;br&gt;
ID 4 = wrist_flex&lt;br&gt;
ID 5 = wrist_roll&lt;br&gt;
ID 6 = gripper&lt;/p&gt;

&lt;p&gt;Next, we’re finally ready to start assembling the robot arm.&lt;br&gt;
&lt;a href="https://dev.to/takeofuture/trying-vla-part-2-assembling-lerobot-joint-1-2npj"&gt;https://dev.to/takeofuture/trying-vla-part-2-assembling-lerobot-joint-1-2npj&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Trying VLA (Part 0): Getting Started with LeRobot and SO-101: Building a Low-Cost Physical AI Robot Arm</title>
      <dc:creator>Takeo</dc:creator>
      <pubDate>Sun, 30 Aug 2026 22:44:36 +0000</pubDate>
      <link>https://dev.to/takeofuture/getting-started-with-lerobot-and-so-101-building-a-low-cost-physical-ai-robot-arm-part-0-6j1</link>
      <guid>https://dev.to/takeofuture/getting-started-with-lerobot-and-so-101-building-a-low-cost-physical-ai-robot-arm-part-0-6j1</guid>
      <description>&lt;p&gt;With the rapid development of LLMs (Large Language Models) and VLMs (Vision-Language Models), a new type of model called VLA (Vision-Language-Action) has been attracting increasing attention in robotics.&lt;/p&gt;

&lt;p&gt;In this series, I will use Hugging Face LeRobot and the relatively low-cost SO-101 robot arm to experiment with imitation learning, robot learning, and eventually VLA models on real hardware.&lt;/p&gt;

&lt;p&gt;In this Part 0, I will first cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What VLA is&lt;/li&gt;
&lt;li&gt;What LeRobot is&lt;/li&gt;
&lt;li&gt;Why I chose LeRobot instead of starting with ROS + Raspberry Pi&lt;/li&gt;
&lt;li&gt;What hardware I purchased to build the SO-101&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the following articles, I plan to move from assembling the robot to calibration, teleoperation, dataset collection, imitation learning, and eventually VLA experiments.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Is VLA?
&lt;/h4&gt;

&lt;p&gt;VLA stands for Vision-Language-Action.&lt;br&gt;
In a very simplified form, it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vision
"What can the robot see?"
        +
Language
"What does the human want?"
        ↓
       VLA
        ↓
Action
"How should the robot move?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LLMs have already become widely known through systems such as ChatGPT.&lt;br&gt;
An LLM primarily works with language.&lt;br&gt;
From there, VLMs (Vision-Language Models) expanded AI systems so that they could process both language and visual information such as images.&lt;br&gt;
A simplified progression looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LLM
Understand and generate language
        ↓
VLM
Understand language + images
        ↓
VLA
Understand language + images
and generate physical actions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Up to the VLM stage, AI primarily observes information in a digital environment and responds to it.&lt;/p&gt;

&lt;p&gt;VLA goes one step further.&lt;/p&gt;

&lt;p&gt;The goal is for an AI model to:&lt;/p&gt;

&lt;p&gt;observe the physical world, understand a human instruction, and actually control a robot to perform the task.&lt;/p&gt;

&lt;p&gt;For example, suppose a camera sees:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a red block&lt;/li&gt;
&lt;li&gt;a blue box&lt;/li&gt;
&lt;li&gt;a robot arm&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and the user says:&lt;br&gt;
"Put the red block into the blue box."&lt;/p&gt;

&lt;p&gt;A VLA system could generate a sequence of robot actions such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Move the arm toward the red block
↓
Open the gripper
↓
Grasp the block
↓
Lift the block
↓
Move toward the blue box
↓
Open the gripper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important difference is that the AI does not simply respond:&lt;br&gt;
"There is a red block in the image."&lt;/p&gt;

&lt;p&gt;Instead, it takes action in the physical world.&lt;/p&gt;

&lt;p&gt;Physical AI&lt;br&gt;
Combining AI with robots, cameras, sensors, motors, and other physical systems so that the AI can&lt;/p&gt;

&lt;p&gt;perceive → reason → act&lt;/p&gt;

&lt;p&gt;in the real world is increasingly described as Physical AI.&lt;/p&gt;

&lt;p&gt;VLA is one important approach toward building Physical AI systems.&lt;/p&gt;

&lt;p&gt;For my experiments, I will use:&lt;/p&gt;

&lt;p&gt;Hugging Face LeRobot&lt;br&gt;
SO-101 robot arm&lt;/p&gt;

&lt;p&gt;to explore this area using relatively inexpensive hardware.&lt;/p&gt;

&lt;p&gt;Physical AI Is Becoming Accessible to Individuals&lt;/p&gt;

&lt;p&gt;Traditionally, buying a robot for serious robotics research could be extremely expensive.&lt;/p&gt;

&lt;p&gt;Even relatively small research or industrial robot systems could easily cost tens of thousands of dollars.&lt;/p&gt;

&lt;p&gt;In that environment, a robot costing approximately as much as a passenger car could almost be considered "inexpensive" for research use.&lt;/p&gt;

&lt;p&gt;However, the situation has been changing rapidly.&lt;/p&gt;

&lt;p&gt;Today we have access to increasingly affordable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;servo motors&lt;/li&gt;
&lt;li&gt;cameras&lt;/li&gt;
&lt;li&gt;Raspberry Pi computers&lt;/li&gt;
&lt;li&gt;NVIDIA Jetson devices&lt;/li&gt;
&lt;li&gt;small robots&lt;/li&gt;
&lt;li&gt;drones&lt;/li&gt;
&lt;li&gt;3D printers&lt;/li&gt;
&lt;li&gt;open-source robotics software&lt;/li&gt;
&lt;li&gt;open AI models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because of this, robotics is gradually moving away from a world where meaningful experiments require expensive proprietary hardware.&lt;br&gt;
Instead, individuals can now assemble relatively inexpensive components and experiment with robotics and AI themselves.&lt;/p&gt;

&lt;p&gt;The SO-101 is a good example of this trend.&lt;br&gt;
Instead of purchasing an expensive research-grade robot arm, it is possible to build a small robot arm for only a few hundred dollars and use it to experiment with technologies such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;imitation learning&lt;/li&gt;
&lt;li&gt;robot learning&lt;/li&gt;
&lt;li&gt;VLA&lt;/li&gt;
&lt;li&gt;Physical AI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For me, this is one of the most exciting aspects of the SO-101.&lt;/p&gt;
&lt;h4&gt;
  
  
  Why LeRobot Instead of ROS + Raspberry Pi?
&lt;/h4&gt;

&lt;p&gt;Of course, SO-101 + LeRobot is not the only way to combine inexpensive hardware with AI.&lt;br&gt;
For example, it is possible to connect motors, sensors, and cameras to a Raspberry Pi and build a small robot car or robot arm.&lt;br&gt;
I previously experimented with this approach by modifying a very inexpensive toy robot car and combining it with an LLM.&lt;br&gt;
You can find that experiment here(Sorry Japanese only now but you can translate by LLM/VLM, I will translate and publish here soon):&lt;br&gt;
&lt;a href="https://zenn.dev/takeofuture/articles/458c1a3abcce04" rel="noopener noreferrer"&gt;https://zenn.dev/takeofuture/articles/458c1a3abcce04&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Experimenting with an LLM and a Low-Cost Robot Car&lt;br&gt;
For more advanced robotics projects, another very common option is ROS (Robot Operating System).&lt;br&gt;
A typical architecture might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Camera / LiDAR / Sensors
          ↓
      Raspberry Pi
       / Jetson
          ↓
          ROS
          ↓
 Motor Controller
          ↓
        Robot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ROS provides a common framework for many important robotics functions, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;acquiring images from cameras&lt;/li&gt;
&lt;li&gt;reading LiDAR and other sensors&lt;/li&gt;
&lt;li&gt;controlling motors&lt;/li&gt;
&lt;li&gt;estimating robot position&lt;/li&gt;
&lt;li&gt;planning paths&lt;/li&gt;
&lt;li&gt;exchanging data between different programs and devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this reason, ROS is one of the most important platforms in modern robotics.&lt;br&gt;
So why am I using LeRobot instead of starting with Raspberry Pi + ROS?&lt;br&gt;
The Goal Is Not Just to Program the Robot&lt;br&gt;
The goal of this project is not simply:&lt;br&gt;
"Write a program that moves a robot."&lt;/p&gt;

&lt;p&gt;Instead, I want to explore the following process:&lt;br&gt;
Have a human demonstrate a task, collect the robot data, train an AI model using that data, and finally let the AI control the robot by itself.&lt;br&gt;
This is where LeRobot becomes especially interesting.&lt;br&gt;
LeRobot is an open-source framework from Hugging Face designed for robot learning.&lt;/p&gt;

&lt;p&gt;At a high level, the workflow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Human operates the robot
        ↓
Teleoperation
        ↓
Record camera images,
joint states, and actions
        ↓
Dataset
        ↓
Train an AI model
        ↓
ACT / SmolVLA / π0 / etc.
        ↓
The trained AI controls the robot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, imagine that a human demonstrates the following task dozens of times:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pick up the red block and put it into the box.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During each demonstration, LeRobot can record data such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Camera images
+
Robot joint states
+
Actions performed by the human
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This becomes a training dataset.&lt;br&gt;
The dataset can then be used to train an imitation-learning policy or a VLA model.&lt;/p&gt;

&lt;p&gt;After training, the goal is for the robot to observe the camera image and perform the same task without continuous human control.&lt;/p&gt;

&lt;p&gt;In a very simplified comparison:&lt;br&gt;
ROS&lt;br&gt;
Focus:&lt;br&gt;
"How do I build and control the robot system?"&lt;/p&gt;

&lt;p&gt;LeRobot&lt;br&gt;
Focus:&lt;br&gt;
"How do I collect robot data, train a model,and let AI control the robot?"&lt;/p&gt;

&lt;p&gt;This is obviously an oversimplification, but I think it is a useful way to understand the difference.&lt;br&gt;
ROS and LeRobot are also not competing technologies.&lt;br&gt;
They can be used together.&lt;br&gt;
For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sensors / Camera
       ↓
      ROS
       ↓
Hardware Control
       ↓
    LeRobot
       ↓
Dataset / Training
       ↓
    Robot AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ROS could handle hardware interfaces and sensors while LeRobot manages robot-learning datasets and AI policies.&lt;/p&gt;

&lt;h4&gt;
  
  
  A Simple SO-101 Setup
&lt;/h4&gt;

&lt;p&gt;The SO-101 is a relatively simple robot arm.&lt;br&gt;
Because of that, I do not necessarily need to place Raspberry Pi or ROS between the computer and the robot.&lt;br&gt;
I can start with a much simpler architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Camera
   ↓
PC running Ubuntu
   ↓
LeRobot
   ↓ USB
Servo Controller
   ↓
SO-101
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this project, my main goal is not to build every part of the robot infrastructure from scratch.&lt;br&gt;
Instead, I want to reach the robot AI experiments as quickly as possible.&lt;br&gt;
In particular, I want to experiment with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;teleoperation&lt;/li&gt;
&lt;li&gt;dataset collection&lt;/li&gt;
&lt;li&gt;imitation learning&lt;/li&gt;
&lt;li&gt;learned robot policies&lt;/li&gt;
&lt;li&gt;VLA models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why I chose LeRobot + SO-101 for this project.&lt;/p&gt;
&lt;h4&gt;
  
  
  SO-101 Hardware
&lt;/h4&gt;

&lt;p&gt;So what do we actually need to build an SO-101?&lt;br&gt;
It is possible to purchase a completely assembled SO-101, but the mechanical structure itself is relatively simple.&lt;br&gt;
The frame can also be produced using a 3D printer.&lt;br&gt;
In other words, you do not necessarily need to purchase a pre-made frame kit.&lt;br&gt;
A basic system could be assembled from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3D-printed frame
       +
Servo motors
       +
Servo controller
       +
PC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can reduce the cost even further.&lt;br&gt;
I think this is another very interesting part of modern low-cost robotics.&lt;br&gt;
Instead of purchasing an entire robot from a manufacturer, we can download designs, print the mechanical parts ourselves, purchase inexpensive motors and controllers, and assemble the system.&lt;br&gt;
I would eventually like to try this approach with other robots or drones and build the mechanical structure myself using a 3D printer.&lt;br&gt;
However, that is not the main goal of this particular project.&lt;/p&gt;

&lt;p&gt;My priority this time is:&lt;br&gt;
Build the SO-101 as quickly as possible and move on to LeRobot, imitation learning, and VLA experiments.&lt;br&gt;
Therefore, I decided to purchase a pre-made SO-101 Follower Arm Frame Kit instead of printing every frame component myself.&lt;br&gt;
I also purchased an Electronics Kit rather than sourcing every servo motor, cable, controller, and power supply individually.&lt;br&gt;
In other words, my goal is not:&lt;br&gt;
Build every component of the robot completely from scratch.&lt;/p&gt;

&lt;p&gt;My goal is:&lt;br&gt;
Reach the robot-learning and Physical AI experiments as quickly as possible.&lt;/p&gt;
&lt;h4&gt;
  
  
  What I Purchased
&lt;/h4&gt;

&lt;p&gt;I purchased two main kits.&lt;br&gt;
I currently live in the United States, so I purchased them through Amazon.com.&lt;br&gt;
Similar SO-101 kits and components are also available from various sellers in other countries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SO-101 Follower Arm Frame Kit
The frame kit contains the mechanical components required to assemble the robot arm.
The kit includes items such as:&lt;/li&gt;
&lt;li&gt;3D-printed frame parts&lt;/li&gt;
&lt;li&gt;gripper components&lt;/li&gt;
&lt;li&gt;camera mount&lt;/li&gt;
&lt;li&gt;&lt;p&gt;screws and assembly hardware&lt;br&gt;
Amazon.com Product:&lt;br&gt;
SO-101 Follower Arm Frame Kit&lt;br&gt;
ASIN:B0GH429G4X&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fowxozg3umo4e18arwvqq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fowxozg3umo4e18arwvqq.png" alt=" " width="676" height="373"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SO-101 Follower Arm Electronics Kit&lt;br&gt;
The Electronics Kit contains most of the electronic components required to operate the SO-101.&lt;br&gt;
The kit includes:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;6 × Feetech STS3215 servo motors&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Waveshare Serial Bus Servo Controller&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;12V 5A power supply&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;connection cables&lt;br&gt;
Amazon.com&lt;br&gt;
Product:&lt;br&gt;
SO-101 Follower Arm Electronics Kit&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7tyjp8o6tj9no59zak9r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7tyjp8o6tj9no59zak9r.png" alt=" " width="674" height="525"&gt;&lt;/a&gt;&lt;br&gt;
ASIN:B0GH35175P&lt;br&gt;
Hardware Architecture&lt;br&gt;
With these components, the basic architecture looks like this:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PC running Ubuntu
       ↓ USB
Waveshare
Serial Bus Servo Controller
       ↓
Feetech STS3215 × 6
       ↓
SO-101 Frame
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After adding a camera, the system becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Camera
   ↓
PC
   ↓
LeRobot
   ↓
Servo Controller
   ↓
SO-101
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will allow me to start experimenting with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Teleoperation
      ↓
Dataset Collection
      ↓
Model Training
      ↓
AI-controlled Robot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What's Next?&lt;br&gt;
The next step is to assemble the SO-101.&lt;br&gt;
However, before physically assembling the robot arm, there is one important task:&lt;br&gt;
assigning an ID to each servo motor.&lt;br&gt;
The SO-101 uses multiple servo motors connected through the same serial bus.&lt;br&gt;
Because of this, each servo must have its own unique ID so that the controller can identify and control it independently.&lt;br&gt;
The next article covers this servo ID configuration process in detail:&lt;br&gt;
SO-101 Servo Motor ID Configuration&lt;br&gt;
After that, I plan to proceed roughly in the following order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Servo ID Configuration
        ↓
SO-101 Assembly
        ↓
Calibration
        ↓
Teleoperation
        ↓
Dataset Collection
        ↓
Imitation Learning
        ↓
VLA / Physical AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My final goal is not simply to build the robot arm.&lt;br&gt;
I want to use this inexpensive hardware platform to explore how far an individual can go today with robot learning, VLA, and Physical AI.&lt;/p&gt;

&lt;p&gt;In the next article, I’ll walk through how to assign an ID to each motor and prepare the SO-101 for the next steps.&lt;/p&gt;

&lt;p&gt;👉 Part 1:&lt;br&gt;
&lt;a href="https://dev.to/takeofuture/trying-vla-part-1-preparing-lerobot-and-assigning-ids-to-the-motors-538g"&gt;https://dev.to/takeofuture/trying-vla-part-1-preparing-lerobot-and-assigning-ids-to-the-motors-538g&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>hardware</category>
      <category>machinelearning</category>
      <category>robotics</category>
    </item>
    <item>
      <title>From Sentinel-1 SLC to InSAR with Python: A Kumamoto Earthquake Example</title>
      <dc:creator>Takeo</dc:creator>
      <pubDate>Sat, 29 Aug 2026 02:45:17 +0000</pubDate>
      <link>https://dev.to/takeofuture/from-sentinel-1-slc-to-insar-with-python-a-kumamoto-earthquake-example-30h6</link>
      <guid>https://dev.to/takeofuture/from-sentinel-1-slc-to-insar-with-python-a-kumamoto-earthquake-example-30h6</guid>
      <description>&lt;p&gt;In my previous article, I introduced how to download and visualize SAR polarization data using Google Earth Engine.&lt;br&gt;
&lt;a href="https://dev.to/takeofuture/visualizing-surface-changes-after-the-2026-kumamoto-earthquake-with-sentinel-1-sar-and-google-earth-2ob3"&gt;https://dev.to/takeofuture/visualizing-surface-changes-after-the-2026-kumamoto-earthquake-with-sentinel-1-sar-and-google-earth-2ob3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, I will take a different approach.&lt;br&gt;
Instead of relying on Google Earth Engine, we will use NASA's Alaska Satellite Facility (ASF) to search for and download Sentinel-1 data directly.&lt;br&gt;
Then we will generate InSAR (Interferometric Synthetic Aperture Radar) products using ASF HyP3, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wrapped Phase&lt;/li&gt;
&lt;li&gt;Unwrapped Phase&lt;/li&gt;
&lt;li&gt;Coherence&lt;/li&gt;
&lt;li&gt;LOS Displacement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a practical example, I will use Sentinel-1 observations around the 2026 Kumamoto earthquake in Japan.&lt;br&gt;
The goal of this article is not yet to analyze the earthquake itself.&lt;br&gt;
Instead, the goal is to build the dataset required for later analysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Quick Review: What Are VV and VH in SAR?&lt;/strong&gt;&lt;br&gt;
Before moving on to InSAR, let's quickly review the VV and VH polarization channels introduced in the previous article.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What Is SAR Polarization?&lt;br&gt;
SAR stands for Synthetic Aperture Radar.&lt;br&gt;
A SAR satellite sends microwave signals toward the Earth's surface and measures the signals that are reflected or scattered back toward the satellite.&lt;br&gt;
One important property of these signals is polarization.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A Quick Review: What Are VV and VH in SAR?&lt;br&gt;
Before moving on to InSAR, let's quickly review the VV and VH polarization channels introduced in the previous article.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What Is SAR Polarization?&lt;br&gt;
SAR stands for Synthetic Aperture Radar.&lt;br&gt;
A SAR satellite sends microwave signals toward the Earth's surface and measures the signals that are reflected or scattered back toward the satellite.&lt;br&gt;
One important property of these signals is polarization.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ln51w097zqo2s4pgapt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ln51w097zqo2s4pgapt.png" alt=" " width="549" height="325"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Polarization describes the orientation in which the electric field of the electromagnetic wave oscillates.&lt;br&gt;
SAR commonly uses two polarization directions:&lt;br&gt;
H: Horizontal polarization&lt;br&gt;
V: Vertical polarization&lt;br&gt;
SAR products describe the transmitted and received polarization using two letters.&lt;br&gt;
For example:&lt;br&gt;
VV: transmitted vertically and received vertically&lt;br&gt;
VH: transmitted vertically and received horizontally&lt;br&gt;
HH: transmitted horizontally and received horizontally&lt;br&gt;
HV: transmitted horizontally and received vertically&lt;/p&gt;

&lt;p&gt;VV and HH are called co-polarized channels.&lt;br&gt;
VH and HV are called cross-polarized channels.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuf8wv0aol7w2bneji2qn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuf8wv0aol7w2bneji2qn.png" alt=" " width="674" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Do VV and VH Look Different?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Microwaves interact differently with soil, vegetation, buildings, and other surface structures.&lt;/p&gt;

&lt;p&gt;Because of that, VV and VH can provide different information even when observing exactly the same location.&lt;/p&gt;

&lt;p&gt;In general:&lt;br&gt;
VV often responds strongly to direct surface and structural reflections.&lt;br&gt;
VH is often more sensitive to vegetation and complex multiple scattering.&lt;/p&gt;

&lt;p&gt;In the previous article, I used SAR backscatter intensity and visualized how VV changed before and after the earthquake.&lt;br&gt;
I also experimented with treating VV and VH as two input channels for image models.&lt;br&gt;
For example, a conventional RGB image contains three channels:&lt;br&gt;
R,G,B&lt;br&gt;
A SAR-based model might instead use:&lt;br&gt;
VV,VH&lt;br&gt;
as two channels.&lt;br&gt;
However, VV and VH backscatter do not respond only to earthquakes.&lt;/p&gt;

&lt;p&gt;They are also affected by factors such as:&lt;/p&gt;

&lt;p&gt;vegetation&lt;br&gt;
soil moisture&lt;br&gt;
rainfall&lt;br&gt;
surface roughness&lt;br&gt;
building orientation&lt;br&gt;
satellite viewing geometry&lt;/p&gt;

&lt;p&gt;For this reason, I decided to move from simple backscatter comparison to InSAR, which uses phase information to estimate changes in the distance between the satellite and the ground.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Is InSAR?&lt;/strong&gt;&lt;br&gt;
InSAR stands for Interferometric Synthetic Aperture Radar.&lt;br&gt;
VV and VH mainly describe the strength of the reflected radar signal.&lt;br&gt;
InSAR goes one step further and also uses the phase of the microwave signal.&lt;br&gt;
A simplified way to think about the difference is:&lt;br&gt;
VV / VH: How did the radar signal reflect from the surface?&lt;br&gt;
InSAR: How much did the radar phase change between two observations?&lt;br&gt;
SAR satellites repeatedly observe the same area.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
Observation 1: before an earthquake&lt;br&gt;
Observation 2: after an earthquake&lt;/p&gt;

&lt;p&gt;If the ground moves between the two observations, the distance traveled by the radar wave also changes.&lt;br&gt;
That produces a change in the phase of the returned radar signal.&lt;br&gt;
InSAR analyzes this phase difference to detect very small changes in the Earth's surface.&lt;br&gt;
In other words, instead of simply asking:&lt;/p&gt;

&lt;p&gt;"Did the image look different?"&lt;br&gt;
we can ask:&lt;br&gt;
"Did the distance between the satellite and the ground change?"&lt;br&gt;
However, InSAR does not directly measure pure vertical displacement.&lt;br&gt;
The measurement is projected along the satellite's viewing direction, called the Line of Sight (LOS).&lt;/p&gt;

&lt;p&gt;A simple interpretation is:&lt;br&gt;
LOS displacement = how much the ground moved along the satellite's viewing direction&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three InSAR Products Used in This Project&lt;/strong&gt;&lt;br&gt;
For this project, I mainly focus on three InSAR products:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wrapped Phase&lt;/li&gt;
&lt;li&gt;Coherence&lt;/li&gt;
&lt;li&gt;LOS Displacement&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Wrapped Phase&lt;br&gt;
Radar signals are waves, so they have a phase.&lt;br&gt;
When two SAR observations are compared, changes in the satellite-to-ground path length produce a phase difference.&lt;br&gt;
The phase is typically represented within the range:&lt;br&gt;
-π to +π&lt;br&gt;
This is called the Wrapped Phase.&lt;br&gt;
Because phase is periodic, values repeat after one full cycle.&lt;br&gt;
When visualized, this can produce repeating colored bands known as interferometric fringes.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsjqgzb8fmdmcolvmdq9j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsjqgzb8fmdmcolvmdq9j.png" alt=" " width="545" height="298"&gt;&lt;/a&gt;&lt;br&gt;
These fringes can indicate spatial changes in radar phase.&lt;br&gt;
However, because the values are wrapped repeatedly between -π and +π, we cannot directly read a displacement such as "10 cm" from the Wrapped Phase alone.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Coherence&lt;br&gt;
Another important InSAR product is Coherence.&lt;br&gt;
Coherence describes how consistently the radar signals from two observations correspond to each other.&lt;br&gt;
Its value is generally between:&lt;br&gt;
0 and 1&lt;br&gt;
A rough interpretation is:&lt;br&gt;
close to 1: the two SAR observations correspond well, and the phase is relatively reliable&lt;br&gt;
close to 0: the correspondence is weak, possibly because of noise or significant surface changes&lt;br&gt;
Coherence can decrease because of:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;vegetation changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;water surfaces&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;rainfall&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;soil moisture changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;major surface changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;differences in observation conditions&lt;br&gt;
Coherence is therefore useful when deciding which LOS displacement values are reliable enough to analyze.&lt;br&gt;
For example, in a later analysis I use only pixels satisfying:&lt;br&gt;
Coherence &amp;gt;= 0.5&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LOS Displacement&lt;br&gt;
Wrapped Phase contains periodic phase values.&lt;br&gt;
To estimate physical displacement, the phase wrapping first needs to be resolved using phase unwrapping.&lt;br&gt;
The result is an Unwrapped Phase, where phase changes are represented continuously.&lt;br&gt;
The radar wavelength can then be used to convert the phase difference into a distance change.&lt;br&gt;
This produces LOS Displacement.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp9f6x0pwib34gtfd3xbh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp9f6x0pwib34gtfd3xbh.png" alt=" " width="674" height="305"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fri3ku5c69juo6zs4lb8e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fri3ku5c69juo6zs4lb8e.png" alt=" " width="799" height="132"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The processing concept is:&lt;br&gt;
Wrapped Phase&lt;br&gt;
      ↓&lt;br&gt;
Phase Unwrapping&lt;br&gt;
      ↓&lt;br&gt;
Unwrapped Phase&lt;br&gt;
      ↓&lt;br&gt;
Convert phase using radar wavelength&lt;br&gt;
      ↓&lt;br&gt;
LOS Displacement&lt;/p&gt;

&lt;p&gt;One important point is that Unwrapped Phase is still phase, not yet distance.&lt;br&gt;
LOS Displacement is the product expressed as physical distance.&lt;br&gt;
For the HyP3 LOS products used here, the sign convention is generally interpreted as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;positive: displacement toward the satellite&lt;/li&gt;
&lt;li&gt;negative: displacement away from the satellite
A LOS displacement of 10 cm does not necessarily mean that the ground moved vertically upward by 10 cm.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It means that the ground displacement projected onto the satellite's viewing direction was 10 cm.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VV/VH vs. InSAR
We can summarize the difference as follows:
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5lytu5tjmi7cuoaege2q.png" alt=" " width="648" height="179"&gt;
In very simplified terms:
VV/VH asks whether the way the surface reflects radar has changed.
InSAR asks whether the satellite-to-ground distance has changed.
Now let's obtain the actual data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Create a NASA Earthdata Login&lt;/strong&gt;&lt;br&gt;
To download Sentinel-1 data from ASF, first create a NASA Earthdata Login account.&lt;br&gt;
Registration instructions:&lt;br&gt;
&lt;a href="https://urs.earthdata.nasa.gov/documentation/for_users/how_to_register" rel="noopener noreferrer"&gt;https://urs.earthdata.nasa.gov/documentation/for_users/how_to_register&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because we will use Python tools such as asf_search and hyp3_sdk, you may also need to pre-authorize the appropriate ASF/HyP3 applications for your Earthdata account.&lt;br&gt;
Instructions:&lt;br&gt;
&lt;a href="https://urs.earthdata.nasa.gov/documentation/for_users/how_to_preauth_app" rel="noopener noreferrer"&gt;https://urs.earthdata.nasa.gov/documentation/for_users/how_to_preauth_app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this workflow, we will:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Search Sentinel-1
        ↓
Download SLC data
        ↓
Create observation pairs
        ↓
Submit InSAR jobs to HyP3
        ↓
Download the processed InSAR products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install the Python Libraries
The main libraries used in this article are:
asf_search: search and download Sentinel-1 data from ASF
hyp3_sdk: submit and retrieve HyP3 processing jobs
shapely: work with geographical areas and geometries
Create a requirements.txt file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;asf_search&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;=12.3.1&lt;/span&gt;
&lt;span class="py"&gt;hyp3_sdk&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;=7.7.7&lt;/span&gt;
&lt;span class="py"&gt;shapely&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;=2.1.2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then install them in your Python virtual environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Search for Sentinel-1 SLC Data
The earthquake used in this example occurred in Kumamoto, Japan, on July 28, 2026.
I searched for Sentinel-1 acquisitions from June through August 16, 2026.
Rather than searching only at a single epicenter coordinate, I define a rectangular Area of Interest (AOI) around the epicenter.
The bounding box is given as:
west
south
east
north
I also restrict the search to Relative Orbit 156.
This matters because InSAR compares phase between acquisitions, so observation geometry should be as consistent as possible.
Create:
0.list_up.py
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asf_search&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;asf&lt;/span&gt;

&lt;span class="c1"&gt;# Kumamoto earthquake epicenter
&lt;/span&gt;&lt;span class="n"&gt;EPICENTER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;130.6783333333&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;32.625&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Area of Interest
&lt;/span&gt;&lt;span class="n"&gt;AOI_BBOX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mf"&gt;130.515&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# west
&lt;/span&gt;    &lt;span class="mf"&gt;32.480&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# south
&lt;/span&gt;    &lt;span class="mf"&gt;130.845&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# east
&lt;/span&gt;    &lt;span class="mf"&gt;32.765&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# north
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;RELATIVE_ORBIT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;156&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bbox_wkt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bbox&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;west&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;south&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;east&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;north&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bbox&lt;/span&gt;

    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POLYGON((&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;west&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;south&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;east&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;south&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;east&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;north&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;west&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;north&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;west&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;south&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;))&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;asf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;geo_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;asf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DATASET&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SENTINEL1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;processingLevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SLC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;beamMode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;IW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;relativeOrbit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;RELATIVE_ORBIT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;intersectsWith&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;bbox_wkt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AOI_BBOX&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-06-01T00:00:00Z&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-08-16T23:59:59Z&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;maxResults&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search results:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sceneName&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;startTime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;flightDirection&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;polarization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;frame =&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;frameNumber&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;python 0.list_up.py

The result in this case was:

Search results: 7

S1C_IW_SLC__1SDV_20260815T091320_20260815T091347_009004_011DF6_CC4C 2026-08-15T09:13:20Z ASCENDING VV+VH frame = 102
S1C_IW_SLC__1SDV_20260803T091319_20260803T091346_008829_011833_BE60 2026-08-03T09:13:19Z ASCENDING VV+VH frame = 102
S1C_IW_SLC__1SDV_20260722T091318_20260722T091345_008654_01125E_4884 2026-07-22T09:13:18Z ASCENDING VV+VH frame = 102
S1C_IW_SLC__1SDV_20260710T091318_20260710T091345_008479_010C8A_76D5 2026-07-10T09:13:18Z ASCENDING VV+VH frame = 102
S1C_IW_SLC__1SDV_20260628T091317_20260628T091344_008304_0106DC_85C8 2026-06-28T09:13:17Z ASCENDING VV+VH frame = 102
S1D_IW_SLC__1SDV_20260622T091330_20260622T091357_003347_005E09_DD43 2026-06-22T09:13:30Z ASCENDING VV+VH frame = 102
S1D_IW_SLC__1SDV_20260610T091329_20260610T091356_003172_005852_B0A1 2026-06-10T09:13:29Z ASCENDING VV+VH frame = 102

Seven SLC acquisitions were found.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
S1C_IW_SLC__1SDV_20260722...&lt;br&gt;
contains information such as:&lt;br&gt;
S1C        Sentinel-1C&lt;br&gt;
IW         Interferometric Wide Swath mode&lt;br&gt;
SLC        Single Look Complex&lt;br&gt;
20260722   Acquisition date&lt;/p&gt;

&lt;p&gt;The results also show consistent:&lt;br&gt;
ASCENDING&lt;br&gt;
VV+VH&lt;br&gt;
frame = 102&lt;br&gt;
ASCENDING means the satellite was traveling generally from south to north during the acquisition.&lt;br&gt;
VV+VH means both VV and VH polarization channels are included.&lt;br&gt;
Frame 102 is one of the observation-geometry parameters used to keep the acquisitions comparable.&lt;br&gt;
At this stage, we have not generated any InSAR products yet.&lt;br&gt;
We are only checking whether suitable Sentinel-1 SLC acquisitions exist before and after the earthquake.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Download Sentinel-1 SLC Data&lt;/strong&gt;&lt;br&gt;
ASF metadata search can be performed without authentication, but downloading the actual Sentinel-1 SLC files requires NASA Earthdata authentication.&lt;br&gt;
Instead of writing credentials directly inside the source code, store them as environment variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;EARTHDATA_USERNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-earthdata-username"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;EARTHDATA_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-earthdata-password"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create:&lt;br&gt;
1.download_s1_slc.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asf_search&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;asf&lt;/span&gt;


&lt;span class="c1"&gt;# --------------------------------------------------
# Search configuration
# --------------------------------------------------
&lt;/span&gt;
&lt;span class="n"&gt;AOI_BBOX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mf"&gt;130.515&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# west
&lt;/span&gt;    &lt;span class="mf"&gt;32.480&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# south
&lt;/span&gt;    &lt;span class="mf"&gt;130.845&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# east
&lt;/span&gt;    &lt;span class="mf"&gt;32.765&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# north
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;RELATIVE_ORBIT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;156&lt;/span&gt;
&lt;span class="n"&gt;FRAME_NUMBER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;102&lt;/span&gt;
&lt;span class="n"&gt;FLIGHT_DIRECTION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ASCENDING&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;SEARCH_START&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-06-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;SEARCH_END&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-08-16&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;DOWNLOAD_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./data/slc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bbox_wkt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bbox&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;west&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;south&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;east&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;north&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bbox&lt;/span&gt;

    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POLYGON((&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;west&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;south&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;east&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;south&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;east&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;north&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;west&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;north&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;west&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;south&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;))&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# --------------------------------------------------
# Earthdata Login
# --------------------------------------------------
&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EARTHDATA_USERNAME&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EARTHDATA_PASSWORD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Please set EARTHDATA_USERNAME and EARTHDATA_PASSWORD.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;asf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ASFSession&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;auth_with_creds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# --------------------------------------------------
# Search Sentinel-1 SLC
# --------------------------------------------------
&lt;/span&gt;
&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;asf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;geo_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;asf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DATASET&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SENTINEL1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;processingLevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SLC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;beamMode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;IW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;relativeOrbit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;RELATIVE_ORBIT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;intersectsWith&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;bbox_wkt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AOI_BBOX&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;SEARCH_START&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;T00:00:00Z&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;SEARCH_END&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;T23:59:59Z&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;maxResults&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# --------------------------------------------------
# Filter by observation geometry
# --------------------------------------------------
&lt;/span&gt;
&lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;

    &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;flightDirection&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;frameNumber&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;polarization&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;polarization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;FLIGHT_DIRECTION&lt;/span&gt;
        &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;FRAME_NUMBER&lt;/span&gt;
        &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VV&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;polarization&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Products to download:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


&lt;span class="c1"&gt;# --------------------------------------------------
# Download
# --------------------------------------------------
&lt;/span&gt;
&lt;span class="n"&gt;DOWNLOAD_DIR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Downloading:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sceneName&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;download&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DOWNLOAD_DIR&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Download complete.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Output:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DOWNLOAD_DIR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because these files can be large, I ran the script in the background:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;nohup &lt;/span&gt;python 1.download_s1_slc.py &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 1.download_s1_slc.log 2&amp;gt;&amp;amp;1 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the download completed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data/slc/
├── S1C_IW_SLC__1SDV_20260628T091317_20260628T091344_008304_0106DC_85C8.zip
├── S1C_IW_SLC__1SDV_20260710T091318_20260710T091345_008479_010C8A_76D5.zip
├── S1C_IW_SLC__1SDV_20260722T091318_20260722T091345_008654_01125E_4884.zip
├── S1C_IW_SLC__1SDV_20260803T091319_20260803T091346_008829_011833_BE60.zip
├── S1C_IW_SLC__1SDV_20260815T091320_20260815T091347_009004_011DF6_CC4C.zip
├── S1D_IW_SLC__1SDV_20260610T091329_20260610T091356_003172_005852_B0A1.zip
└── S1D_IW_SLC__1SDV_20260622T091330_20260622T091357_003347_005E09_DD43.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Look Inside an SLC Product&lt;/strong&gt;&lt;br&gt;
Let's inspect one downloaded ZIP file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;unzip &lt;span class="nt"&gt;-l&lt;/span&gt; data/slc/S1C_IW_SLC__1SDV_20260722T091318_20260722T091345_008654_01125E_4884.zip &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; preview
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One of the files inside the archive is:&lt;br&gt;
preview/quick-look.png&lt;br&gt;
We can extract only that preview:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; preview
unzip &lt;span class="nt"&gt;-j&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
 data/slc/S1C_IW_SLC__1SDV_20260722T091318_20260722T091345_008654_011DF6_CC4C.zip &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'*/preview/quick-look.png'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; preview
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your filename differs, replace it with the actual downloaded granule name.&lt;br&gt;
Here is an example of the Sentinel-1 SLC quick-look image:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fapp54x4yba4uamp4xqhn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fapp54x4yba4uamp4xqhn.png" alt=" " width="494" height="735"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is not yet an InSAR image.&lt;br&gt;
It is a preview of one SAR acquisition covering a much larger area than the Kumamoto AOI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generate InSAR Products with ASF HyP3&lt;/strong&gt;&lt;br&gt;
Now we have the Sentinel-1 SLC acquisitions.&lt;br&gt;
The next step is to combine observations from two different dates and generate InSAR products.&lt;br&gt;
For this, I use ASF HyP3 InSAR GAMMA.&lt;br&gt;
InSAR requires a pair of compatible SLC acquisitions observing the same area.&lt;br&gt;
In this example, I automatically select acquisitions separated by 12 days.&lt;br&gt;
For example:&lt;br&gt;
2026/07/10 → 2026/07/22   PRE-earthquake&lt;br&gt;
2026/07/22 → 2026/08/03   COSEISMIC&lt;br&gt;
2026/08/03 → 2026/08/15   POST-earthquake&lt;br&gt;
The important point is that the local SLC ZIP files are not uploaded to HyP3.&lt;br&gt;
Instead, the script extracts the Sentinel-1 granule IDs from the filenames and submits those IDs to HyP3.&lt;br&gt;
ASF performs the InSAR processing on its side.&lt;br&gt;
Make sure the Earthdata credentials are still available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;EARTHDATA_USERNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-earthdata-username"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;EARTHDATA_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-earthdata-password"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create:&lt;br&gt;
2.make_insar.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;zipfile&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hyp3_sdk&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sdk&lt;/span&gt;


&lt;span class="c1"&gt;# --------------------------------------------------
# Configuration
# --------------------------------------------------
&lt;/span&gt;
&lt;span class="n"&gt;SLC_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./data/slc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;RESULT_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./data/insar&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;EARTHQUAKE_DATE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2026&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;PAIR_DAYS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;


&lt;span class="c1"&gt;# --------------------------------------------------
# Earthdata Login
# --------------------------------------------------
&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EARTHDATA_USERNAME&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EARTHDATA_PASSWORD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Please set EARTHDATA_USERNAME and EARTHDATA_PASSWORD.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;hyp3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HyP3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# --------------------------------------------------
# Read acquisition date and granule ID
# --------------------------------------------------
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_slc_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zip_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;granule_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;zip_path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stem&lt;/span&gt;

    &lt;span class="c1"&gt;# Example:
&lt;/span&gt;    &lt;span class="c1"&gt;# S1C_IW_SLC__1SDV_20260722T091318_...
&lt;/span&gt;
    &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;_(\d{8})T\d{6}_&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;granule_id&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Could not parse acquisition date: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;granule_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strptime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y%m%d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;zip_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;granule&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;granule_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;slcs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;get_slc_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SLC_DIR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*.zip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;slcs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SLC acquisitions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;slcs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;granule&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# --------------------------------------------------
# Build 12-day InSAR pairs
# --------------------------------------------------
&lt;/span&gt;
&lt;span class="n"&gt;pairs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slcs&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slcs&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;

        &lt;span class="n"&gt;reference&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;slcs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;secondary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;slcs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="n"&gt;delta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;reference&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;PAIR_DAYS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;EARTHQUAKE_DATE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pre&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

        &lt;span class="nf"&gt;elif &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;reference&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;EARTHQUAKE_DATE&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;coseismic&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;post&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

        &lt;span class="n"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reference&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;reference&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;secondary&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;


&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Selected InSAR pairs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reference&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;secondary&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# --------------------------------------------------
# Submit HyP3 InSAR jobs
# --------------------------------------------------
&lt;/span&gt;
&lt;span class="n"&gt;RESULT_DIR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;reference&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reference&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;secondary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;secondary&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;ref_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reference&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y%m%d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sec_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y%m%d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;pair_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kumamoto_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ref_date&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;sec_date&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;pair_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RESULT_DIR&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;pair_name&lt;/span&gt;
    &lt;span class="n"&gt;download_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pair_dir&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;download&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;product_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pair_dir&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;product&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="n"&gt;download_dir&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;product_dir&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SUBMIT &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;pair_name&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Reference:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;reference&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;granule&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Secondary:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;granule&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# ----------------------------------------------
&lt;/span&gt;    &lt;span class="c1"&gt;# HyP3 InSAR GAMMA
&lt;/span&gt;    &lt;span class="c1"&gt;# ----------------------------------------------
&lt;/span&gt;
    &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hyp3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;submit_insar_job&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;reference&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;granule&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;granule&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;pair_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="n"&gt;looks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10x2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="n"&gt;include_wrapped_phase&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;include_displacement_maps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="n"&gt;include_look_vectors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;include_inc_map&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;include_dem&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="n"&gt;apply_water_mask&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="n"&gt;phase_filter_parameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# ----------------------------------------------
&lt;/span&gt;    &lt;span class="c1"&gt;# Wait for processing
&lt;/span&gt;    &lt;span class="c1"&gt;# ----------------------------------------------
&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Waiting for HyP3 processing...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;completed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hyp3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# ----------------------------------------------
&lt;/span&gt;    &lt;span class="c1"&gt;# Download completed product
&lt;/span&gt;    &lt;span class="c1"&gt;# ----------------------------------------------
&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Downloading InSAR product...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;downloaded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;download_files&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;download_dir&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# ----------------------------------------------
&lt;/span&gt;    &lt;span class="c1"&gt;# Extract ZIP
&lt;/span&gt;    &lt;span class="c1"&gt;# ----------------------------------------------
&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;file_path&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;downloaded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

        &lt;span class="n"&gt;file_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;suffix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.zip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;

        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;zipfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ZipFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extractall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;product_dir&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Completed:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;pair_name&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ALL InSAR PROCESSING COMPLETE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Output:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RESULT_DIR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HyP3 processing can take some time, so I recommend running it in the background:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;nohup &lt;/span&gt;python 2.make_insar.py &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 2.make_insar.log 2&amp;gt;&amp;amp;1 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can monitor progress with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; 2.make_insar.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*InSAR Data Is Ready&lt;br&gt;
After HyP3 finishes processing and the product is downloaded, each observation pair contains a set of InSAR products.&lt;br&gt;
For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data/
└── insar/
    └── kumamoto_pre_20260610_20260622/
        ├── download/
        │   └── ...zip
        └── product/
            └── S1DD_20260610T091329_20260622T091330_.../
                ├── *_corr.tif
                ├── *_wrapped_phase.tif
                ├── *_unw_phase.tif
                ├── *_los_disp.tif
                ├── *_dem.tif
                ├── *_inc_map.tif
                ├── *_water_mask.tif
                └── ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main products used later are:&lt;br&gt;
*_wrapped_phase.tif   Wrapped Phase&lt;br&gt;
*_unw_phase.tif       Unwrapped Phase&lt;br&gt;
*_corr.tif            Coherence&lt;br&gt;
*_los_disp.tif        LOS Displacement&lt;br&gt;
At this point, we have completed the process of turning Sentinel-1 SLC acquisitions into a dataset that can be used for quantitative InSAR analysis.&lt;br&gt;
Example: Wrapped Phase&lt;br&gt;
Below is an example of a Wrapped Phase visualization generated by HyP3.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkyw50u5amy43r76tdoph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkyw50u5amy43r76tdoph.png" alt=" " width="674" height="537"&gt;&lt;/a&gt;&lt;br&gt;
The colors represent wrapped phase values.&lt;br&gt;
The repeating color pattern does not mean that the ground moved by a corresponding physical color-coded distance.&lt;br&gt;
The phase still repeats periodically between approximately -π and +π.&lt;/p&gt;

&lt;p&gt;Example: Unwrapped Phase&lt;br&gt;
The following image shows the corresponding Unwrapped Phase.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkhg8qrpcvb7f4bpvlj83.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkhg8qrpcvb7f4bpvlj83.png" alt=" " width="669" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The important distinction is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Wrapped Phase
phase angle with wrapping
        ↓
Unwrapped Phase
continuous phase
        ↓
LOS Displacement
physical distance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Unwrapped Phase is not yet the final distance measurement.&lt;br&gt;
It is still phase, but the periodic wrapping has been resolved.&lt;br&gt;
The radar wavelength is then used to convert the phase into physical LOS displacement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's Next?&lt;/strong&gt;&lt;br&gt;
In this article, I focused only on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sentinel-1 search
        ↓
SLC download
        ↓
Observation pairing
        ↓
HyP3 InSAR processing
        ↓
InSAR GeoTIFF products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have not yet evaluated whether the earthquake produced a large displacement signal.&lt;br&gt;
That will be the next step.&lt;br&gt;
Using the products generated here, we can investigate questions such as:&lt;br&gt;
How much did LOS displacement change before and after the earthquake?&lt;br&gt;
Which pixels should be trusted based on Coherence?&lt;br&gt;
What spatial patterns appear in the Wrapped Phase?&lt;br&gt;
Can machine learning detect the earthquake as an anomaly?&lt;br&gt;
Can self-supervised models such as MAE + Vision Transformer detect abnormal InSAR patterns?&lt;br&gt;
The important point for this article is that the InSAR dataset is now ready.&lt;br&gt;
We can now move from data preparation to actual earthquake deformation analysis.&lt;/p&gt;

&lt;p&gt;Data and Processing&lt;br&gt;
Data source:&lt;br&gt;
ESA / Copernicus Sentinel-1 IW SLC&lt;br&gt;
Distributed through:&lt;br&gt;
NASA Alaska Satellite Facility (ASF) DAAC&lt;/p&gt;

&lt;p&gt;InSAR processing:&lt;br&gt;
ASF HyP3 InSAR GAMMA&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Visualizing Surface Changes After the 2026 Kumamoto Earthquake with Sentinel-1 SAR and Google Earth Engine</title>
      <dc:creator>Takeo</dc:creator>
      <pubDate>Sun, 02 Aug 2026 17:18:29 +0000</pubDate>
      <link>https://dev.to/takeofuture/visualizing-surface-changes-after-the-2026-kumamoto-earthquake-with-sentinel-1-sar-and-google-earth-2ob3</link>
      <guid>https://dev.to/takeofuture/visualizing-surface-changes-after-the-2026-kumamoto-earthquake-with-sentinel-1-sar-and-google-earth-2ob3</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On July 28, 2026, at approximately 4:27 p.m. Japan Standard Time, a magnitude 7.1 earthquake struck the Kumamoto region of southwestern Japan at a depth of about 10 kilometers.&lt;/p&gt;

&lt;p&gt;The Japan Meteorological Agency reported a maximum seismic intensity of 7, the highest level on Japan’s seismic intensity scale. For readers outside Japan, this is not another expression of earthquake magnitude. Magnitude represents the energy released by an earthquake, while the Japanese seismic intensity scale describes the strength of shaking observed at individual locations. At intensity 7, unsecured furniture may move or topple, buildings may suffer serious damage, and landslides or major ground failures may occur.&lt;br&gt;
&lt;a href="https://www.data.jma.go.jp/multi/quake/quake_detail.html?eventID=20260728163528&amp;amp;lang=en" rel="noopener noreferrer"&gt;https://www.data.jma.go.jp/multi/quake/quake_detail.html?eventID=20260728163528&amp;amp;lang=en&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The earthquake caused fatalities, injuries, structural damage, power outages, transportation disruptions, and continuing emergency-response operations. One of the most widely reported locations was AEON Mall Kumamoto, where the earthquake was followed by an explosion and severe building damage.&lt;br&gt;
&lt;a href="https://www.reuters.com/business/environment/magnitude-71-earthquake-hits-japans-kyushu-region-jma-says-2026-07-28/" rel="noopener noreferrer"&gt;https://www.reuters.com/business/environment/magnitude-71-earthquake-hits-japans-kyushu-region-jma-says-2026-07-28/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where is Kumamoto?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Kumamoto Prefecture is located in Kyushu, the southwesternmost of Japan’s four main islands.&lt;/p&gt;

&lt;p&gt;Tokyo, Kyoto, and Osaka are located on the much larger island of Honshu. Kumamoto lies considerably farther southwest, near the center of Kyushu. The prefecture includes Kumamoto City, Mount Aso, coastal and agricultural areas, and numerous smaller communities.&lt;/p&gt;

&lt;p&gt;The study area used in this article covers Kumamoto City and surrounding areas including Kashima, Uki, Yatsushiro, and parts of the Aso region.&lt;br&gt;
&lt;a href="https://www.japan.travel/en/destinations/kyushu/kumamoto/" rel="noopener noreferrer"&gt;https://www.japan.travel/en/destinations/kyushu/kumamoto/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The historical context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The 2026 earthquake occurred only a little more than ten years after the devastating 2016 Kumamoto earthquake sequence.&lt;/p&gt;

&lt;p&gt;In April 2016, the region was first struck by a strong foreshock and then by a larger earthquake at 1:25 a.m. local time on April 16. The Japan Meteorological Agency measured the later event as magnitude 7.3, while the USGS reported a moment magnitude of 7.0.&lt;/p&gt;

&lt;p&gt;The 2016 sequence involved the Hinagu and Futagawa fault systems and caused major damage across Kumamoto Prefecture.&lt;/p&gt;

&lt;p&gt;This article does not attempt to establish a direct seismological relationship between the 2016 and 2026 earthquakes. However, the geographic proximity and the region’s recent history make satellite-based change monitoring especially relevant.&lt;br&gt;
&lt;a href="https://www.usgs.gov/news/featured-story/magnitude-70-earthquake-japan" rel="noopener noreferrer"&gt;https://www.usgs.gov/news/featured-story/magnitude-70-earthquake-japan&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What this article does&lt;/strong&gt;&lt;br&gt;
This is the first article in a planned series.&lt;br&gt;
In this initial step, I use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Earth Engine&lt;/li&gt;
&lt;li&gt;Google Colab&lt;/li&gt;
&lt;li&gt;Sentinel-1 Synthetic Aperture Radar imagery&lt;/li&gt;
&lt;li&gt;Python and geemap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieve a Sentinel-1 SAR image acquired before the earthquake.&lt;/li&gt;
&lt;li&gt;Retrieve the first available image acquired after the earthquake.&lt;/li&gt;
&lt;li&gt;Calculate the difference in VV-polarized radar backscatter.&lt;/li&gt;
&lt;li&gt;Display areas with large changes on an interactive map.&lt;/li&gt;
&lt;li&gt;Mark the location of AEON Mall Kumamoto as a geographic reference point.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a rapid, first-pass visualization rather than a final damage-classification product.&lt;/p&gt;

&lt;p&gt;The objective is to identify locations that may deserve closer inspection using optical imagery, official damage reports, aerial photographs, field observations, and additional satellite analysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is SAR?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SAR stands for Synthetic Aperture Radar.&lt;/p&gt;

&lt;p&gt;Optical satellites observe sunlight reflected from Earth’s surface. This means that clouds, darkness, smoke, and other atmospheric conditions can limit what an optical sensor can see.&lt;/p&gt;

&lt;p&gt;SAR satellites transmit microwave signals toward Earth and measure the signals reflected back to the sensor. This allows radar satellites to observe the surface during both day and night and through most cloud cover.&lt;/p&gt;

&lt;p&gt;For this analysis, I use Sentinel-1, a European C-band SAR mission.&lt;/p&gt;

&lt;p&gt;The Google Earth Engine collection:&lt;/p&gt;

&lt;p&gt;COPERNICUS/S1_GRD&lt;br&gt;
&lt;a href="https://developers.google.com/earth-engine/datasets/catalog/COPERNICUS_S1_GRD" rel="noopener noreferrer"&gt;https://developers.google.com/earth-engine/datasets/catalog/COPERNICUS_S1_GRD&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;contains calibrated and terrain-corrected Ground Range Detected imagery. Its backscatter values are provided in decibels. Earth Engine applies preprocessing that includes orbit information, thermal-noise removal, radiometric calibration, and terrain correction.&lt;/p&gt;

&lt;p&gt;Radar backscatter is affected by several factors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Surface roughness&lt;/li&gt;
&lt;li&gt;Building geometry&lt;/li&gt;
&lt;li&gt;Soil moisture&lt;/li&gt;
&lt;li&gt;Vegetation&lt;/li&gt;
&lt;li&gt;Water coverage&lt;/li&gt;
&lt;li&gt;Radar incidence angle&lt;/li&gt;
&lt;li&gt;Satellite orbit direction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A major change in backscatter can therefore indicate a meaningful surface change, but it does not identify the cause by itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the required libraries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run the following cell in Google Colab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;!&lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-U&lt;/span&gt; earthengine-api geemap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then import the libraries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ee&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;geemap&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;About Earth Engine access and pricing&lt;/strong&gt;&lt;br&gt;
earthengine-api is Google’s official Python client library for Earth Engine. The library itself can be installed free of charge.&lt;/p&gt;

&lt;p&gt;Commercial Earth Engine use is available through usage-based and subscription plans. As of August 2026, the Basic plan has a platform fee of $500 per month, while the Professional plan costs $2,000 per month. A Limited plan is also available without a fixed monthly platform fee, but compute and storage usage may still be charged.&lt;/p&gt;

&lt;p&gt;Verified noncommercial projects—including qualifying educational, research, nonprofit, and personal-learning projects—can use monthly free compute quotas. Registration as a noncommercial project is required; simply being a student does not automatically configure the project for free access.&lt;/p&gt;

&lt;p&gt;*Official information:&lt;br&gt;
Google Earth Engine pricing&lt;br&gt;
&lt;a href="https://cloud.google.com/earth-engine/pricing" rel="noopener noreferrer"&gt;https://cloud.google.com/earth-engine/pricing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Earth Engine noncommercial tiers&lt;br&gt;
&lt;a href="https://developers.google.com/earth-engine/guides/noncommercial_tiers" rel="noopener noreferrer"&gt;https://developers.google.com/earth-engine/guides/noncommercial_tiers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating and registering an Earth Engine project&lt;br&gt;
&lt;a href="https://developers.google.com/earth-engine/guides/access" rel="noopener noreferrer"&gt;https://developers.google.com/earth-engine/guides/access&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Earth Engine configuration in Google Cloud&lt;br&gt;
&lt;a href="https://console.cloud.google.com/earth-engine/welcome" rel="noopener noreferrer"&gt;https://console.cloud.google.com/earth-engine/welcome&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authenticate and initialize Earth Engine&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Authenticate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;YOUR_GOOGLE_CLOUD_PROJECT_ID&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace YOUR_GOOGLE_CLOUD_PROJECT_ID with the ID of a registered Google Cloud project.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Authenticate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ee-takeofuture&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The authentication step opens a Google account authorization flow. The project passed to ee.Initialize() is then used for Earth Engine requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a map centered on Kumamoto&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;geemap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;32.72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;130.70&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;zoom&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_basemap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;HYBRID&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The center is placed between the broader epicentral region and AEON Mall Kumamoto.&lt;br&gt;
The HYBRID basemap combines satellite imagery with geographic labels, roads, and place names.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Define the area of interest&lt;/strong&gt;&lt;br&gt;
The selected area covers a relatively broad portion of Kumamoto Prefecture, including Kumamoto City, Kashima, Uki, Yatsushiro, and areas toward Aso and Amakusa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;kumamoto_aoi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Geometry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mf"&gt;130.40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mf"&gt;32.45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mf"&gt;131.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mf"&gt;32.95&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ee.Geometry.BBox() uses the following coordinate order:&lt;br&gt;
west longitude,&lt;br&gt;
south latitude,&lt;br&gt;
east longitude,&lt;br&gt;
north latitude&lt;/p&gt;

&lt;p&gt;The selected bounds are:&lt;br&gt;
West:  130.40° E&lt;br&gt;
South:  32.45° N&lt;br&gt;
East:  131.10° E&lt;br&gt;
North:  32.95° N&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Load the Sentinel-1 collection&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ImageCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;COPERNICUS/S1_GRD&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;instrumentMode&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;IW&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listContains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;transmitterReceiverPolarisation&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;VV&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterBounds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kumamoto_aoi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Interferometric Wide Swath mode
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;instrumentMode&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;IW&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IW stands for Interferometric Wide Swath. It is a common Sentinel-1 acquisition mode for wide-area land observations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VV polarization
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listContains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;transmitterReceiverPolarisation&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;VV&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;VV means that the radar signal is transmitted with vertical polarization and received with vertical polarization.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Geographic filtering
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterBounds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kumamoto_aoi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This retains scenes that overlap the Kumamoto study area.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Handle the time-zone conversion
The earthquake occurred at approximately:
July 28, 2026, 16:27 JST
Earth Engine date strings are interpreted in UTC unless a time zone is explicitly handled.
Japan Standard Time is nine hours ahead of UTC, so the corresponding UTC time is:
July 28, 2026, 07:27 UTC
I therefore define the event boundary as follows:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;EARTHQUAKE_TIME_UTC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2026-07-28T07:27:00Z&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents an image acquired after the earthquake from accidentally being classified as a pre-earthquake observation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Select the latest pre-earthquake image&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pre_eq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;s1&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2026-07-15T00:00:00Z&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;EARTHQUAKE_TIME_UTC&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;system:time_start&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;VV&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The collection is sorted from newest to oldest, and first() selects the most recent available observation before the earthquake.&lt;/p&gt;

&lt;p&gt;“Pre-earthquake” does not necessarily mean that the satellite passed over Kumamoto only minutes before the event. It means that this is the closest available Sentinel-1 acquisition within the specified period.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Select the first post-earthquake image&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;post_eq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;s1&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;EARTHQUAKE_TIME_UTC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2026-08-05T00:00:00Z&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;system:time_start&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;VV&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time, the images are sorted from oldest to newest so that the first available acquisition after the earthquake is selected.&lt;/p&gt;

&lt;p&gt;Only scenes already ingested into Earth Engine are available. Setting an end date in the future does not create or predict an image.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Print the actual acquisition times&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The actual satellite observation times should be included in any interpretation of the result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pre_date_jst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;pre_eq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;system:time_start&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;YYYY-MM-dd HH:mm:ss&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Asia/Tokyo&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;post_date_jst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;post_eq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;system:time_start&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;YYYY-MM-dd HH:mm:ss&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Asia/Tokyo&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Pre-earthquake image, JST:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pre_date_jst&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getInfo&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Post-earthquake image, JST:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_date_jst&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getInfo&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prints the acquisition times in Japan Standard Time rather than UTC.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calculate the SAR difference&lt;/strong&gt;&lt;br&gt;
Subtract the pre-earthquake VV image from the post-earthquake image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post_eq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pre_eq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conceptually:&lt;br&gt;
SAR change = post-earthquake VV − pre-earthquake VV&lt;/p&gt;

&lt;p&gt;A strongly negative value means that radar backscatter decreased after the earthquake.&lt;br&gt;
A strongly positive value means that radar backscatter increased.&lt;br&gt;
Possible causes include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Changes to buildings or structures&lt;/li&gt;
&lt;li&gt;Collapsed or tilted surfaces&lt;/li&gt;
&lt;li&gt;Rubble or newly exposed objects&lt;/li&gt;
&lt;li&gt;Landslides and sediment movement&lt;/li&gt;
&lt;li&gt;Flooding or new water surfaces&lt;/li&gt;
&lt;li&gt;Changes in soil moisture&lt;/li&gt;
&lt;li&gt;Vegetation changes&lt;/li&gt;
&lt;li&gt;Differences in orbit geometry&lt;/li&gt;
&lt;li&gt;SAR speckle noise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The difference map is therefore best treated as a change indicator, not as a direct label for one specific type of damage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configure the visualization&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;vis_diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;min&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;max&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;palette&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#d73027&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#fc8d59&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#fee08b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#ffffff&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#e0f3f8&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#91bfdb&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The approximate interpretation is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Red and orange: backscatter decreased
These areas returned a weaker radar signal after the earthquake.
Possible explanations include:&lt;/li&gt;
&lt;li&gt;A building changed orientation or partially collapsed&lt;/li&gt;
&lt;li&gt;A formerly complex surface became smoother&lt;/li&gt;
&lt;li&gt;Ground failure altered the local geometry&lt;/li&gt;
&lt;li&gt;An area became covered by water&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These locations may represent earthquake-related changes and deserve closer examination.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;White: relatively little change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The difference between the two observations is relatively small.&lt;br&gt;
This does not prove that no damage occurred. Smaller changes, indoor damage, and changes below the effective spatial resolution may not appear clearly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Light blue and blue: backscatter increased
These areas returned a stronger radar signal after the earthquake.
Possible explanations include:&lt;/li&gt;
&lt;li&gt;Debris increased surface roughness&lt;/li&gt;
&lt;li&gt;Fallen structures created new radar-reflecting geometry&lt;/li&gt;
&lt;li&gt;Sediment or exposed materials changed the surface&lt;/li&gt;
&lt;li&gt;Objects became oriented in a way that reflected more energy toward the satellite&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both strong red and strong blue regions can therefore be treated as locations of interest.&lt;/p&gt;

&lt;p&gt;The values -12 and 4 are visualization limits chosen to make large changes easier to see. They are not universal damage thresholds. However, strongly colored areas can help narrow a broad region into a smaller set of locations for follow-up analysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add the SAR layers to the map&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;pre_eq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kumamoto_aoi&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;min&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;max&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1. Pre-earthquake SAR&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;post_eq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kumamoto_aoi&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;min&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;max&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2. Post-earthquake SAR&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kumamoto_aoi&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;vis_diff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3. SAR backscatter change&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pre- and post-earthquake layers are initially hidden.&lt;br&gt;
The difference layer is visible when the map first loads.&lt;br&gt;
Users can switch between the following layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pre-earthquake SAR&lt;/li&gt;
&lt;li&gt;Post-earthquake SAR&lt;/li&gt;
&lt;li&gt;SAR backscatter change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Mark AEON Mall Kumamoto&lt;/strong&gt;&lt;br&gt;
AEON Mall Kumamoto is located in Kashima Town, south of central Kumamoto City.&lt;br&gt;
Because the mall was one of the most widely reported damage locations, I add it as a geographic reference point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;aeon_kumamoto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Geometry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="mf"&gt;130.7414&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mf"&gt;32.7431&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;aeon_kumamoto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;color&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cyan&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;AEON Mall Kumamoto&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Earth Engine point coordinates use:&lt;br&gt;
[longitude, latitude]&lt;br&gt;
This is the reverse of the [latitude, longitude] order commonly displayed by some mapping services.&lt;br&gt;
A single Sentinel-1 pixel cannot describe the condition of an entire shopping mall. However, if strong red or blue changes appear around a location with independently reported damage, that spatial correspondence becomes a useful clue.&lt;br&gt;
The mall marker therefore provides a reference for comparing the SAR change pattern with a known real-world location of serious impact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Display the map&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_layer_control&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Map&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The map can now be explored interactively in Google Colab.&lt;br&gt;
Users can enable and disable each layer from the layer control in the upper-right corner.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg6u2134rpbv5yk96b25q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg6u2134rpbv5yk96b25q.png" alt=" " width="799" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to interpret the result&lt;/strong&gt;&lt;br&gt;
The resulting map shows several red and orange areas across Kumamoto Prefecture. These are locations where VV backscatter decreased substantially between the selected observations.&lt;/p&gt;

&lt;p&gt;Changes to buildings, slopes, ground surfaces, sediment, and water coverage can alter the radar signal. Areas with unusually large differences may therefore indicate locations affected by the earthquake.&lt;/p&gt;

&lt;p&gt;The map cannot, by itself, tell us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exactly what changed&lt;/li&gt;
&lt;li&gt;Whether a building completely collapsed&lt;/li&gt;
&lt;li&gt;Whether a change was caused by the earthquake&lt;/li&gt;
&lt;li&gt;How severe the damage was&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nevertheless, the analysis is useful.&lt;/p&gt;

&lt;p&gt;Satellite radar can scan a broad area and highlight places where the surface response changed significantly. Those locations can then be compared with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RGB optical imagery&lt;/li&gt;
&lt;li&gt;Government damage reports&lt;/li&gt;
&lt;li&gt;News reports&lt;/li&gt;
&lt;li&gt;Aerial photography&lt;/li&gt;
&lt;li&gt;Rainfall records&lt;/li&gt;
&lt;li&gt;Elevation and slope data&lt;/li&gt;
&lt;li&gt;Field observations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this sense, the SAR difference map acts as a guide for narrowing the search area, rather than as a final damage map.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limitations of this first-pass analysis&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Orbit direction is not matched
Sentinel-1 observes Earth from both ascending and descending orbits.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Buildings and slopes may appear very different when viewed from opposite radar directions. Some of the measured difference may therefore be caused by observation geometry rather than physical surface change.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Relative orbit numbers are not matched
Even if two images cover the same region, differences in relative orbit number and incidence angle can affect backscatter.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A more rigorous comparison should use scenes with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The same orbit direction&lt;/li&gt;
&lt;li&gt;The same relative orbit number&lt;/li&gt;
&lt;li&gt;Similar incidence angles&lt;/li&gt;
&lt;li&gt;The same polarization and acquisition mode&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Only one image is used for each period&lt;br&gt;
SAR imagery contains granular noise known as speckle.&lt;br&gt;
Using several pre-earthquake and post-earthquake scenes and calculating a median or mean composite can reduce random variation and make persistent changes easier to identify.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rainfall and moisture may affect the result&lt;br&gt;
Radar backscatter responds to soil moisture, standing water, vegetation, and wet surfaces.&lt;br&gt;
Any location with a large difference should therefore be checked against rainfall and weather data from the same period.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This is a screening analysis&lt;br&gt;
The purpose of this first article is not to issue a final damage assessment.&lt;br&gt;
It is to locate areas where the radar response changed enough to justify closer investigation.&lt;br&gt;
Known damaged locations such as AEON Mall Kumamoto can also help evaluate whether satellite-observed changes correspond to documented real-world impacts.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Next step: matched SAR, RGB imagery, and AI&lt;/strong&gt;&lt;br&gt;
In the next article, I plan to make the analysis more precise by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Matching the Sentinel-1 orbit direction.&lt;/li&gt;
&lt;li&gt;Matching the relative orbit number.&lt;/li&gt;
&lt;li&gt;Comparing multiple pre- and post-earthquake observations.&lt;/li&gt;
&lt;li&gt;Reducing SAR speckle noise.&lt;/li&gt;
&lt;li&gt;Adding rainfall, elevation, and terrain information.&lt;/li&gt;
&lt;li&gt;Incorporating Sentinel-2 or other RGB optical imagery.&lt;/li&gt;
&lt;li&gt;Applying AI-based image analysis to identify consistent change candidates.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;SAR and RGB imagery provide complementary information.&lt;/p&gt;

&lt;p&gt;SAR can detect changes in radar scattering even through clouds and at night. RGB imagery can help visually distinguish buildings, landslides, exposed soil, vegetation, and water when cloud-free observations are available.&lt;/p&gt;

&lt;p&gt;AI can then be used to compare the two data sources, prioritize locations where both indicate change, and classify possible forms of damage.&lt;/p&gt;

&lt;p&gt;This first visualization is therefore the initial screening stage. The next step will combine matched multi-temporal SAR, RGB imagery, additional geospatial data, and AI to produce a more reliable list of possible damage locations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complete code&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;U&lt;/span&gt; &lt;span class="n"&gt;earthengine&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="n"&gt;geemap&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ee&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;geemap&lt;/span&gt;

&lt;span class="c1"&gt;# Authenticate and initialize Earth Engine.
&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Authenticate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ee-takeofuture&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create a map centered on Kumamoto.
&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;geemap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;32.72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;130.70&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;zoom&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_basemap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;HYBRID&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Define the study area.
&lt;/span&gt;&lt;span class="n"&gt;kumamoto_aoi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Geometry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mf"&gt;130.40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mf"&gt;32.45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mf"&gt;131.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mf"&gt;32.95&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Load Sentinel-1 IW scenes containing VV polarization.
&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ImageCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;COPERNICUS/S1_GRD&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;instrumentMode&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;IW&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listContains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;transmitterReceiverPolarisation&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;VV&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterBounds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kumamoto_aoi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# July 28, 2026, 16:27 JST = July 28, 2026, 07:27 UTC.
&lt;/span&gt;&lt;span class="n"&gt;EARTHQUAKE_TIME_UTC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2026-07-28T07:27:00Z&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;# Select the latest available pre-earthquake image.
&lt;/span&gt;&lt;span class="n"&gt;pre_eq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;s1&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2026-07-15T00:00:00Z&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;EARTHQUAKE_TIME_UTC&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;system:time_start&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;VV&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Select the first available post-earthquake image.
&lt;/span&gt;&lt;span class="n"&gt;post_eq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;s1&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;EARTHQUAKE_TIME_UTC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2026-08-05T00:00:00Z&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;system:time_start&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;VV&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Print acquisition times in Japan Standard Time.
&lt;/span&gt;&lt;span class="n"&gt;pre_date_jst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;pre_eq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;system:time_start&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;YYYY-MM-dd HH:mm:ss&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Asia/Tokyo&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;post_date_jst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;post_eq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;system:time_start&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;YYYY-MM-dd HH:mm:ss&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Asia/Tokyo&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Pre-earthquake image, JST:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pre_date_jst&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getInfo&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Post-earthquake image, JST:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_date_jst&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getInfo&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="c1"&gt;# Calculate post-earthquake minus pre-earthquake VV backscatter.
&lt;/span&gt;&lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post_eq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pre_eq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Configure the difference visualization.
&lt;/span&gt;&lt;span class="n"&gt;vis_diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;min&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;max&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;palette&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#d73027&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#fc8d59&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#fee08b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#ffffff&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#e0f3f8&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#91bfdb&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Add the three SAR layers.
&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;pre_eq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kumamoto_aoi&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;min&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;max&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1. Pre-earthquake SAR&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;post_eq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kumamoto_aoi&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;min&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;max&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2. Post-earthquake SAR&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kumamoto_aoi&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;vis_diff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3. SAR backscatter change&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Add AEON Mall Kumamoto as a reference point.
&lt;/span&gt;&lt;span class="n"&gt;aeon_kumamoto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Geometry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="mf"&gt;130.7414&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mf"&gt;32.7431&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;aeon_kumamoto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;color&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cyan&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;AEON Mall Kumamoto&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_layer_control&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Map&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
This article used Google Earth Engine, Google Colab, and Sentinel-1 VV-polarized SAR data to visualize radar-backscatter changes before and after the 2026 Kumamoto earthquake.&lt;/p&gt;

&lt;p&gt;The resulting difference map does not provide a final building-damage classification. However, it can reveal locations where the radar response changed substantially and help prioritize areas for further investigation.&lt;/p&gt;

&lt;p&gt;By marking AEON Mall Kumamoto, the analysis also provides a way to compare a documented damage location with the surrounding satellite-observed change pattern.&lt;/p&gt;

&lt;p&gt;In the next stage, I will improve the comparison by matching Sentinel-1 orbital conditions, using multiple observations, incorporating RGB optical imagery and additional geospatial data, and applying AI to identify more reliable earthquake-related change candidates.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Use an NVIDIA GPU Inside a Docker Container</title>
      <dc:creator>Takeo</dc:creator>
      <pubDate>Mon, 27 Jul 2026 18:00:38 +0000</pubDate>
      <link>https://dev.to/takeofuture/how-to-use-an-nvidia-gpu-inside-a-docker-container-4l36</link>
      <guid>https://dev.to/takeofuture/how-to-use-an-nvidia-gpu-inside-a-docker-container-4l36</guid>
      <description>&lt;p&gt;I do not normally use Docker very often. However, I recently needed to install PyTorch3D, a library that is no longer actively updated, and I could not get it working properly in my current environment.&lt;/p&gt;

&lt;p&gt;I could have launched a separate GPU machine running the older Ubuntu 22.04 or installed another CUDA version on the host system. However, I was concerned that adding multiple CUDA versions might cause problems with library paths and symbolic links.&lt;/p&gt;

&lt;p&gt;So, somewhat reluctantly, I decided to use Docker.&lt;/p&gt;

&lt;p&gt;Running a normal Docker container is relatively straightforward: pull an image and start the container. However, when using a GPU machine, some additional configuration is required to make the host GPU available inside the container.&lt;/p&gt;

&lt;p&gt;This article is a short memo describing the setup process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Host environment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My host environment is Ubuntu 24.04 with CUDA 13.1.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Futi3tktjql3bvle9pdbm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Futi3tktjql3bvle9pdbm.png" alt=" " width="394" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following command also displays information about the NVIDIA driver and the GPU:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# nvidia-smi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6et5cmjjml23yh57psph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6et5cmjjml23yh57psph.png" alt=" " width="659" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although nvidia-smi may display a different CUDA version, the CUDA Toolkit installed on the host is CUDA 13.1, as shown by the output of nvcc --version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target Docker environment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For this test, I wanted to launch a container with the following combination:&lt;/p&gt;

&lt;p&gt;Ubuntu 22.04&lt;br&gt;
CUDA 12.4.1&lt;/p&gt;

&lt;p&gt;To make the host GPU available inside Docker containers, the NVIDIA Container Toolkit must first be installed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing the NVIDIA Container Toolkit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I installed it using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
  sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
  tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

# apt update
# apt install nvidia-container-toolkit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The installation completed without any problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configuring Docker to use the NVIDIA runtime&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, configure Docker to use the NVIDIA Container Runtime and restart the Docker service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# nvidia-ctk runtime configure --runtime=docker
# systemctl restart docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can confirm that the NVIDIA runtime has been registered by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# docker info | grep -i runtime
 Runtimes: nvidia runc io.containerd.runc.v2
 Default Runtime: runc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also inspect Docker's configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# cat /etc/docker/daemon.json
{
    "runtimes": {
        "nvidia": {
            "args": [],
            "path": "nvidia-container-runtime"
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default runtime remains runc, but the NVIDIA runtime is now available when a container is started with GPU support.&lt;/p&gt;

&lt;p&gt;Selecting a CUDA Docker image&lt;/p&gt;

&lt;p&gt;For this example, I used a CUDA 12.4.1 runtime image based on Ubuntu 22.04.&lt;/p&gt;

&lt;p&gt;Other CUDA and Ubuntu combinations can be found on the NVIDIA CUDA image page on Docker Hub:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Selecting a CUDA Docker image&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For this example, I used a CUDA 12.4.1 runtime image based on Ubuntu 22.04.&lt;/p&gt;

&lt;p&gt;Other CUDA and Ubuntu combinations can be found on the NVIDIA CUDA image page on Docker Hub:&lt;br&gt;
&lt;a href="https://hub.docker.com/r/nvidia/cuda/tags" rel="noopener noreferrer"&gt;CUDA Image&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing GPU access inside the container&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To confirm that the GPU is available inside the Docker container, run nvidia-smi in the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# docker run --rm --gpus all \
  nvidia/cuda:12.4.1-runtime-ubuntu22.04 \
  nvidia-smi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The options used here are:&lt;/p&gt;

&lt;p&gt;--rm: Automatically removes the container after it exits.&lt;br&gt;
--gpus all: Makes all available host GPUs accessible inside the container.&lt;br&gt;
nvidia/cuda:12.4.1-runtime-ubuntu22.04: Specifies the CUDA 12.4.1 runtime image based on Ubuntu 22.04.&lt;br&gt;
nvidia-smi: Runs the NVIDIA system management command inside the container.&lt;/p&gt;

&lt;p&gt;If the setup is working correctly, information about the host GPU should be displayed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fteg7jt3nqutad1k1e3hp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fteg7jt3nqutad1k1e3hp.png" alt=" " width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The downloaded Docker image can also be confirmed with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# docker image ls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcd08mnsg3vjnjae4lwbi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcd08mnsg3vjnjae4lwbi.png" alt=" " width="720" height="40"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By installing the NVIDIA Container Toolkit and starting the container with the --gpus all option, I was able to use the host GPU from a Docker container running an older combination of Ubuntu and CUDA.&lt;/p&gt;

&lt;p&gt;This approach is useful when a library requires an older CUDA or operating-system environment and you do not want to modify the CUDA configuration of the host machine.&lt;/p&gt;

&lt;p&gt;In my case, Docker allowed me to prepare an Ubuntu 22.04 and CUDA 12.4.1 environment without adding another CUDA installation directly to my Ubuntu 24.04 host.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
