<?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: Harsh Pandhe</title>
    <description>The latest articles on DEV Community by Harsh Pandhe (@harshpandhe).</description>
    <link>https://dev.to/harshpandhe</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%2F1175047%2F7552cfdf-ec8d-44c9-a902-7d52b1ba4fe9.png</url>
      <title>DEV Community: Harsh Pandhe</title>
      <link>https://dev.to/harshpandhe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/harshpandhe"/>
    <language>en</language>
    <item>
      <title>Building a Custom Autonomous Drone Stack - Part 3: The Zero-Velocity Hover</title>
      <dc:creator>Harsh Pandhe</dc:creator>
      <pubDate>Thu, 25 Jun 2026 01:33:00 +0000</pubDate>
      <link>https://dev.to/harshpandhe/building-a-custom-autonomous-drone-stack-part-3-the-zero-velocity-hover-46n7</link>
      <guid>https://dev.to/harshpandhe/building-a-custom-autonomous-drone-stack-part-3-the-zero-velocity-hover-46n7</guid>
      <description>&lt;h2&gt;
  
  
  Surviving GPS-Denied Environments with &lt;code&gt;VELOCITY_MASK&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;If you're flying a micro-UAV indoors using only an optical flow sensor and a downward-facing LiDAR, standard autonomous flight commands will quickly disappoint you.&lt;/p&gt;

&lt;p&gt;When you issue a traditional &lt;code&gt;MAV_CMD_NAV_TAKEOFF&lt;/code&gt;, ArduPilot expects to have access to global position information. Without GPS, the navigation stack may refuse to move.&lt;/p&gt;

&lt;p&gt;To work around this, we bypassed the higher-level navigation controller and injected raw MAVLink commands over serial using &lt;code&gt;set_attitude_target_send()&lt;/code&gt;. This allowed the drone to climb using only its onboard sensors.&lt;/p&gt;

&lt;p&gt;Getting airborne, however, is only half the battle.&lt;/p&gt;

&lt;p&gt;Keeping the drone in the air is where things get interesting.&lt;/p&gt;




&lt;h2&gt;
  
  
  The "Zero-Throttle Drop" Trap
&lt;/h2&gt;

&lt;p&gt;During our first tethered test flights, we managed to climb to roughly one meter in &lt;code&gt;GUIDED&lt;/code&gt; mode.&lt;/p&gt;

&lt;p&gt;To command a stable hover, we switched the vehicle into &lt;code&gt;LOITER&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The instant the mode changed, the motors slowed down and the drone dropped.&lt;/p&gt;

&lt;p&gt;What happened?&lt;/p&gt;

&lt;p&gt;The issue wasn't hardware.&lt;/p&gt;

&lt;p&gt;It was a software conflict.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GUIDED&lt;/code&gt; mode is completely autonomous and ignores pilot stick inputs.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;LOITER&lt;/code&gt;, on the other hand, is a hybrid mode.&lt;/p&gt;

&lt;p&gt;As soon as the flight controller entered &lt;code&gt;LOITER&lt;/code&gt;, it checked the RC transmitter.&lt;/p&gt;

&lt;p&gt;Our throttle stick was resting at zero.&lt;/p&gt;

&lt;p&gt;ArduPilot interpreted that as a pilot command to descend.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Pure Autonomy Fix: &lt;code&gt;VELOCITY_MASK&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Instead of relying on physical joysticks, we stayed entirely inside &lt;code&gt;GUIDED&lt;/code&gt; mode and continuously sent a zero-velocity command.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;set_position_target_local_ned_send()&lt;/code&gt;, we can specify a bitmask that tells the Pixhawk exactly which fields matter.&lt;/p&gt;

&lt;p&gt;A mask value of &lt;code&gt;3527&lt;/code&gt; (&lt;code&gt;0b110111000111&lt;/code&gt;) means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ignore position coordinates&lt;/li&gt;
&lt;li&gt;Ignore acceleration&lt;/li&gt;
&lt;li&gt;Ignore yaw&lt;/li&gt;
&lt;li&gt;Enforce X, Y, and Z velocity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By commanding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vx = 0
Vy = 0
Vz = 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we are effectively telling the flight controller:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hold perfectly still.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Velocity Hold Loop
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;VELOCITY_MASK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3527&lt;/span&gt;

&lt;span class="c1"&gt;# Maintain hover for 10 seconds
&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="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mav&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_position_target_local_ned_send&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="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target_system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target_component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;mavutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mavlink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAV_FRAME_LOCAL_NED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="n"&gt;VELOCITY_MASK&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="mi"&gt;0&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="c1"&gt;# Position (ignored)
&lt;/span&gt;        &lt;span class="mi"&gt;0&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;# Velocity = 0 m/s
&lt;/span&gt;        &lt;span class="mi"&gt;0&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;# Acceleration (ignored)
&lt;/span&gt;        &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;         &lt;span class="c1"&gt;# Yaw and yaw rate (ignored)
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this loop running, optical flow measurements continuously feed the EKF3.&lt;/p&gt;

&lt;p&gt;If the drone drifts due to airflow or frame vibrations, the Pixhawk automatically adjusts motor outputs to force the physical velocity back toward zero.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Velocity Commands Work Better Than Position Commands Indoors
&lt;/h2&gt;

&lt;p&gt;Position commands assume absolute position knowledge.&lt;/p&gt;

&lt;p&gt;Indoors, position estimates often drift.&lt;/p&gt;

&lt;p&gt;Velocity control is far more forgiving.&lt;/p&gt;

&lt;p&gt;Instead of saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Be exactly at coordinate X=0.52 meters.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;we say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Maintain zero velocity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This lets the flight controller use optical flow and LiDAR to make tiny corrections without fighting an imperfect global reference frame.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Panic Button
&lt;/h2&gt;

&lt;p&gt;Never fly without an emergency failsafe.&lt;/p&gt;

&lt;p&gt;If your Python script crashes unexpectedly while the vehicle remains armed, the drone will continue executing the last command it received.&lt;/p&gt;

&lt;p&gt;That's a bad day.&lt;/p&gt;

&lt;p&gt;We wrapped the entire flight sequence inside an emergency interceptor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Emergency Landing Function
&lt;/h3&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;sys&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;emergency_land&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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;[!!!] EMERGENCY: INITIATING LAND&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;mode_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mode_mapping&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;LAND&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mav&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_mode_send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target_system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;mavutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mavlink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAV_MODE_FLAG_CUSTOM_MODE_ENABLED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;mode_id&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mav&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;command_long_send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target_system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target_component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;mavutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mavlink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAV_CMD_NAV_LAND&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="mi"&gt;0&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="mi"&gt;0&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="mi"&gt;0&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="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Wrapping the Flight Loop
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="c1"&gt;# 1. Arm
&lt;/span&gt;
    &lt;span class="c1"&gt;# 2. Takeoff
&lt;/span&gt;
    &lt;span class="c1"&gt;# 3. Velocity hold
&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;KeyboardInterrupt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="nf"&gt;emergency_land&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&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;ERROR: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&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="nf"&gt;emergency_land&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, pressing &lt;code&gt;Ctrl+C&lt;/code&gt; immediately overrides the current mission and forces a controlled descent.&lt;/p&gt;

&lt;p&gt;The flight controller handles the landing sequence and disarms automatically after touchdown.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;One of the biggest lessons we learned was this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Separate high-level logic from low-level reflexes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let your companion computer make decisions.&lt;/p&gt;

&lt;p&gt;Let the flight controller do what it does best:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sensor fusion&lt;/li&gt;
&lt;li&gt;State estimation&lt;/li&gt;
&lt;li&gt;Motor control&lt;/li&gt;
&lt;li&gt;Stabilization&lt;/li&gt;
&lt;li&gt;Recovery&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By respecting this separation, you can build an autonomous stack that remains reliable even in GPS-denied environments.&lt;/p&gt;

&lt;p&gt;And that's exactly what robotics is all about.&lt;/p&gt;

&lt;p&gt;Not replacing the flight controller.&lt;/p&gt;

&lt;p&gt;Working with it.&lt;/p&gt;

</description>
      <category>robotics</category>
      <category>drones</category>
      <category>python</category>
      <category>automation</category>
    </item>
    <item>
      <title>Building a Custom Autonomous Drone Stack - Part 2: Defeating the Safety Engine</title>
      <dc:creator>Harsh Pandhe</dc:creator>
      <pubDate>Tue, 23 Jun 2026 13:30:00 +0000</pubDate>
      <link>https://dev.to/harshpandhe/building-a-custom-autonomous-drone-stack-part-2-defeating-the-safety-engine-34f2</link>
      <guid>https://dev.to/harshpandhe/building-a-custom-autonomous-drone-stack-part-2-defeating-the-safety-engine-34f2</guid>
      <description>&lt;h2&gt;
  
  
  Stop Using &lt;code&gt;time.sleep()&lt;/code&gt;. Start Polling the EKF3 State Machine.
&lt;/h2&gt;

&lt;p&gt;Writing a Python script to tell a drone to "Take Off" is easy.&lt;/p&gt;

&lt;p&gt;Getting the drone to actually listen to you is the hard part.&lt;/p&gt;

&lt;p&gt;Flight controllers are designed to be extremely paranoid. When you tell ArduPilot to arm the motors in an autonomous mode like &lt;code&gt;GUIDED&lt;/code&gt;, it runs an extensive internal safety checklist. If it isn't completely confident in its sensors, it will silently reject your command.&lt;/p&gt;




&lt;h2&gt;
  
  
  The "Dumb Timer" Trap
&lt;/h2&gt;

&lt;p&gt;When developers first start automating drones, their scripts usually look something like this:&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="c1"&gt;# Tell the drone to arm
&lt;/span&gt;&lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mav&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;command_long_send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;...,&lt;/span&gt; &lt;span class="n"&gt;MAV_CMD_COMPONENT_ARM_DISARM&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="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Hope it armed...
&lt;/span&gt;
&lt;span class="c1"&gt;# Tell the drone to take off
&lt;/span&gt;&lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mav&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;command_long_send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;...,&lt;/span&gt; &lt;span class="n"&gt;MAV_CMD_NAV_TAKEOFF&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&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 is the &lt;strong&gt;Dumb Timer Trap&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If the Pixhawk rejected the arming command because the optical flow camera couldn't see the floor properly (&lt;code&gt;PreArm: Need Position Estimate&lt;/code&gt;), your Python script has no idea.&lt;/p&gt;

&lt;p&gt;It waits three seconds, assumes everything worked, and blindly sends a takeoff command while the drone sits motionless on the table.&lt;/p&gt;




&lt;h2&gt;
  
  
  Active Polling: Reading the Pixhawk's Mind
&lt;/h2&gt;

&lt;p&gt;To build a reliable autonomous stack, your code must actively interrogate the flight controller.&lt;/p&gt;

&lt;p&gt;Instead of guessing, we continuously listen for the formal &lt;code&gt;COMMAND_ACK&lt;/code&gt; response.&lt;/p&gt;

&lt;p&gt;Here's how to properly arm a drone:&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;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mav&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;command_long_send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target_system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target_component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;mavutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mavlink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAV_CMD_COMPONENT_ARM_DISARM&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="mi"&gt;1&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="mi"&gt;0&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="mi"&gt;0&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="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;armed_successfully&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="n"&gt;start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Listen for 5 seconds
&lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start_time&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;5.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv_match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nb"&gt;type&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;STATUSTEXT&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;COMMAND_ACK&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;blocking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&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;msg&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;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_type&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;STATUSTEXT&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[PIXHAWK STATUS]: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&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="nf"&gt;elif &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_type&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;COMMAND_ACK&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
            &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt;
            &lt;span class="n"&gt;mavutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mavlink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAV_CMD_COMPONENT_ARM_DISARM&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;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&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;--&amp;gt; Pixhawk accepted arming!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;armed_successfully&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;

            &lt;span class="k"&gt;else&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;--&amp;gt; Pixhawk rejected arming! &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;(Error Code: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;result&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="k"&gt;break&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;armed_successfully&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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;[!!!] Flight aborted.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Let the Flight Controller Tell You What's Wrong
&lt;/h2&gt;

&lt;p&gt;By listening to the &lt;code&gt;STATUSTEXT&lt;/code&gt; packets, your terminal will display the exact reason why the Pixhawk refuses to fly.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PreArm: Need Position Estimate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PreArm: Gyros inconsistent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PreArm: GPS 1: Bad fix&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PreArm: Battery below minimum voltage&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This one loop can save you hundreds of hours of hardware debugging.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 32-Bit Overflow Bug
&lt;/h2&gt;

&lt;p&gt;Once we finally got the drone armed, we started sending raw MAVLink thrust commands.&lt;/p&gt;

&lt;p&gt;The instant the thrust command executed, Python crashed with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct.error:
'I' format requires 0 &amp;lt;= number &amp;lt;= 4294967295
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, this error makes absolutely no sense.&lt;/p&gt;

&lt;p&gt;What happened?&lt;/p&gt;




&lt;h2&gt;
  
  
  Understanding &lt;code&gt;time_boot_ms&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Many MAVLink messages require a parameter called:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;time_boot_ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Internally, this field is defined as an unsigned 32-bit integer (&lt;code&gt;uint32_t&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Its maximum value is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4,294,967,295
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our code looked like this:&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="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, &lt;code&gt;time.time()&lt;/code&gt; returns the Unix epoch timestamp.&lt;/p&gt;

&lt;p&gt;Today, that's roughly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1,700,000,000,000 milliseconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python then tried to cram a 1.7 trillion millisecond timestamp into a field that can only hold 4.29 billion.&lt;/p&gt;

&lt;p&gt;The MAVLink packet serializer immediately overflowed and crashed.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;The flight controller doesn't care about global Unix time.&lt;/p&gt;

&lt;p&gt;It only cares about elapsed time since your script started.&lt;/p&gt;

&lt;p&gt;Anchor a start time:&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;SCRIPT_START_TIME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then calculate the delta:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_time_boot_ms&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;SCRIPT_START_TIME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This guarantees that the value always fits inside a 32-bit integer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The biggest lesson we learned was this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Never assume the drone did what you asked.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Always wait for confirmation.&lt;/p&gt;

&lt;p&gt;Always inspect &lt;code&gt;COMMAND_ACK&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Always monitor &lt;code&gt;STATUSTEXT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And never use &lt;code&gt;time.sleep()&lt;/code&gt; as a substitute for state feedback.&lt;/p&gt;

&lt;p&gt;In robotics, assumptions become bugs.&lt;/p&gt;

&lt;p&gt;Bugs become crashes.&lt;/p&gt;

&lt;p&gt;Crashes become broken propellers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Up Next
&lt;/h2&gt;

&lt;p&gt;In Part 3, we'll tackle one of the most frustrating problems in indoor flight:&lt;/p&gt;

&lt;h3&gt;
  
  
  The Zero-Throttle Drop
&lt;/h3&gt;

&lt;p&gt;We'll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why drones suddenly fall after takeoff&lt;/li&gt;
&lt;li&gt;Why thrust values don't behave linearly&lt;/li&gt;
&lt;li&gt;How to achieve a stable indoor hover without GPS&lt;/li&gt;
&lt;li&gt;Raw MAVLink thrust control&lt;/li&gt;
&lt;li&gt;Tuning for smooth altitude hold&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay tuned.&lt;/p&gt;

</description>
      <category>robotics</category>
      <category>python</category>
      <category>ardupilot</category>
      <category>drones</category>
    </item>
    <item>
      <title>Building a Custom Autonomous Drone Stack - Part 1: The Black Box Flight Recorder</title>
      <dc:creator>Harsh Pandhe</dc:creator>
      <pubDate>Mon, 22 Jun 2026 20:27:25 +0000</pubDate>
      <link>https://dev.to/harshpandhe/building-a-custom-autonomous-drone-stack-part-1-the-black-box-flight-recorder-4kbh</link>
      <guid>https://dev.to/harshpandhe/building-a-custom-autonomous-drone-stack-part-1-the-black-box-flight-recorder-4kbh</guid>
      <description>&lt;h2&gt;
  
  
  Why We Ditched MAVROS for Raw PyMAVLink and systemd
&lt;/h2&gt;

&lt;p&gt;If you're building an autonomous UAV, MAVROS is the undisputed industry standard for bridging a companion computer (like a Raspberry Pi or Jetson Nano) to your flight controller (like a Pixhawk). It wraps the MAVLink serial protocol into the ROS ecosystem. For most projects, it's the perfect tool.&lt;/p&gt;

&lt;p&gt;But what if you're building a micro-UAV for a strictly GPS-denied environment?&lt;/p&gt;

&lt;p&gt;What if your Raspberry Pi needs every ounce of CPU and RAM to run heavy, tightly-coupled LiDAR SLAM algorithms like FAST-LIO?&lt;/p&gt;

&lt;p&gt;During the development of our autonomous drone stack, we hit a massive computational bottleneck. We simply couldn't afford to burn precious CPU cycles and deal with middleware overhead just to log telemetry.&lt;/p&gt;

&lt;p&gt;We needed a zero-latency &lt;strong&gt;"Black Box" flight recorder&lt;/strong&gt;. It needed to capture Optical Flow drift, Barometer altitude, CPU load, and frame vibrations at a strict 10 Hz frequency so we could mathematically verify stability before autonomous flight.&lt;/p&gt;

&lt;p&gt;Our solution?&lt;/p&gt;

&lt;p&gt;We bypassed ROS and MAVROS entirely for the telemetry layer and went straight to the metal using raw &lt;code&gt;pymavlink&lt;/code&gt; over a blazing &lt;strong&gt;921600 baud&lt;/strong&gt; serial connection.&lt;/p&gt;




&lt;h2&gt;
  
  
  The PyMAVLink Interceptor
&lt;/h2&gt;

&lt;p&gt;Instead of wrestling with ROS nodes, topic publishers, and XML configurations, we wrote a lightweight procedural Python script. It opens a direct UART connection to the Pixhawk, intercepts the binary MAVLink stream, and logs only the data we care about directly into a CSV file.&lt;/p&gt;

&lt;p&gt;One important detail: flight controllers won't continuously spam data unless you explicitly ask them to.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Connect to the Pixhawk 6C
&lt;/h3&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;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pymavlink&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;mavutil&lt;/span&gt;

&lt;span class="n"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/dev/ttyAMA0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;BAUD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;921600&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;Connecting to Pixhawk on &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;PORT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; at &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BAUD&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; baud...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;master&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mavutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mavlink_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;baud&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BAUD&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use a &lt;strong&gt;921600 baud rate&lt;/strong&gt; to avoid bottlenecking the telemetry stream.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Wait for the First Heartbeat
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait_heartbeat&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;Connected! Target System: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target_system&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This guarantees the Pixhawk is fully booted and speaking MAVLink before we continue.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Request All Data Streams at 10 Hz
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mav&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request_data_stream_send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target_system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target_component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;mavutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mavlink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAV_DATA_STREAM_ALL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;10&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;MAV_DATA_STREAM_ALL&lt;/code&gt; tells ArduPilot to actively send telemetry rather than waiting for individual requests.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Async Logging Loop
&lt;/h2&gt;

&lt;p&gt;By sending &lt;code&gt;request_data_stream_send()&lt;/code&gt;, we tell the Pixhawk to start continuously flooding the serial port with MAVLink packets.&lt;/p&gt;

&lt;p&gt;Different messages arrive at different frequencies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attitude → 50 Hz&lt;/li&gt;
&lt;li&gt;Battery Status → 1 Hz&lt;/li&gt;
&lt;li&gt;Optical Flow → varies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Writing directly to CSV every time a packet arrives would create inconsistent rows.&lt;/p&gt;

&lt;p&gt;Instead, we maintain a state dictionary, continuously update it, and snapshot it every 0.1 seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Simplified Logging Loop
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;state&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;Alt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.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;Flow_X&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.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;Flow_Y&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.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;Quality&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="n"&gt;last_write&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;while&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;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv_match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blocking&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;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.1&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;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;

    &lt;span class="n"&gt;msg_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_type&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;msg_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VFR_HUD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alt&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;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;

    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;msg_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OPTICAL_FLOW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Flow_X&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;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flow_comp_m_x&lt;/span&gt;
        &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Flow_Y&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;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flow_comp_m_y&lt;/span&gt;
        &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Quality&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;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quality&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;last_write&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;write_to_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;last_write&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps all asynchronous packets synchronized into a single telemetry snapshot.&lt;/p&gt;




&lt;h2&gt;
  
  
  The systemd Autopilot
&lt;/h2&gt;

&lt;p&gt;A flight recorder is useless if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You forget to start it before takeoff.&lt;/li&gt;
&lt;li&gt;You need to SSH into the drone after every battery swap.&lt;/li&gt;
&lt;li&gt;The script crashes mid-flight.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To make the logger production-ready, we wrapped it inside a Linux &lt;code&gt;systemd&lt;/code&gt; service.&lt;/p&gt;

&lt;p&gt;Unlike &lt;code&gt;cron&lt;/code&gt; or &lt;code&gt;rc.local&lt;/code&gt;, systemd automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Starts the logger when the Raspberry Pi boots.&lt;/li&gt;
&lt;li&gt;Restarts it if it crashes.&lt;/li&gt;
&lt;li&gt;Runs silently in the background.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Create &lt;code&gt;/etc/systemd/system/drone_blackbox.service&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Unit]&lt;/span&gt;
&lt;span class="py"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Autonomous Drone Black Box Flight Recorder&lt;/span&gt;
&lt;span class="py"&gt;After&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target network.target&lt;/span&gt;

&lt;span class="nn"&gt;[Service]&lt;/span&gt;
&lt;span class="py"&gt;User&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;pi&lt;/span&gt;
&lt;span class="py"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/home/pi/drone_project&lt;/span&gt;
&lt;span class="py"&gt;ExecStart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/bin/python3 /home/pi/drone_project/drone_blackbox.py&lt;/span&gt;
&lt;span class="py"&gt;Restart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;
&lt;span class="py"&gt;RestartSec&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5&lt;/span&gt;

&lt;span class="nn"&gt;[Install]&lt;/span&gt;
&lt;span class="py"&gt;WantedBy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Enable the Service
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl daemon-reload
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;drone_blackbox.service
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start drone_blackbox.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Raspberry Pi is now a professional-grade auto-starting telemetry recorder.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚨 The Serial Port "Gotcha"
&lt;/h2&gt;

&lt;p&gt;Suppose your logger is already running in the background and you launch another Python script for autonomous takeoff.&lt;/p&gt;

&lt;p&gt;Linux will throw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;serial.serialutil.SerialException:
device reports readiness to read but returned no data
(device disconnected or multiple access on port)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A hardware serial port can only be owned by one process at a time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1
&lt;/h3&gt;

&lt;p&gt;Stop the logger temporarily:&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;sudo &lt;/span&gt;systemctl stop drone_blackbox.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Option 2
&lt;/h3&gt;

&lt;p&gt;Use a MAVLink router like &lt;strong&gt;MAVProxy&lt;/strong&gt; to split one physical serial connection into multiple virtual UDP ports.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;By ditching ROS and MAVROS for telemetry logging, we achieved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lower CPU overhead&lt;/li&gt;
&lt;li&gt;Near-zero latency&lt;/li&gt;
&lt;li&gt;Deterministic 10 Hz logging&lt;/li&gt;
&lt;li&gt;Automatic startup with systemd&lt;/li&gt;
&lt;li&gt;Improved reliability during indoor autonomous flights&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes the best architecture isn't adding another layer of abstraction.&lt;/p&gt;

&lt;p&gt;Sometimes it's removing one.&lt;/p&gt;




&lt;h2&gt;
  
  
  Up Next
&lt;/h2&gt;

&lt;p&gt;Logging data is easy.&lt;/p&gt;

&lt;p&gt;Making the drone fly itself is hard.&lt;/p&gt;

&lt;p&gt;In Part 2 of this series, we'll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Autonomous takeoff without GPS&lt;/li&gt;
&lt;li&gt;ArduPilot's EKF3 safety engine&lt;/li&gt;
&lt;li&gt;State polling and pre-arm checks&lt;/li&gt;
&lt;li&gt;Safe operation in GPS-denied environments&lt;/li&gt;
&lt;li&gt;The realities of indoor autonomous flight&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay tuned.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>python</category>
      <category>robotics</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Why I’m Learning Blender to Build Better Autonomous Systems 🚀</title>
      <dc:creator>Harsh Pandhe</dc:creator>
      <pubDate>Tue, 12 May 2026 10:54:04 +0000</pubDate>
      <link>https://dev.to/harshpandhe/why-im-learning-blender-to-build-better-autonomous-systems-5g3d</link>
      <guid>https://dev.to/harshpandhe/why-im-learning-blender-to-build-better-autonomous-systems-5g3d</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;For robotics engineers, simulation environments are just as important as the code running inside the robot.&lt;/p&gt;
&lt;/blockquote&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.amazonaws.com%2Fuploads%2Farticles%2F7q58euah757zysiopm3c.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.amazonaws.com%2Fuploads%2Farticles%2F7q58euah757zysiopm3c.png" alt="Mars" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As developers, we often spend our lives inside:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;terminals&lt;/li&gt;
&lt;li&gt;IDEs&lt;/li&gt;
&lt;li&gt;Jupyter notebooks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our world is built from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;logic&lt;/li&gt;
&lt;li&gt;loops&lt;/li&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;data structures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But while working on &lt;strong&gt;Project ASCEND&lt;/strong&gt;, I eventually hit a major wall:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Environment Problem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;How do you properly test drone navigation logic without crashing a real-world prototype every five minutes?&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.amazonaws.com%2Fuploads%2Farticles%2Fpa2bua3jyutuw7u3yns5.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.amazonaws.com%2Fuploads%2Farticles%2Fpa2bua3jyutuw7u3yns5.png" alt="Blender" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The answer lies in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Digital Twins&lt;/li&gt;
&lt;li&gt;High-fidelity simulations&lt;/li&gt;
&lt;li&gt;Synthetic environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So instead of relying on stock assets, I recently started building my own &lt;strong&gt;Martian simulation sandbox in Blender&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 The Goal: A Stylized Martian Testbed
&lt;/h2&gt;

&lt;p&gt;I didn’t need a perfect 1:1 replica of Mars.&lt;/p&gt;

&lt;p&gt;I needed an environment that was:&lt;/p&gt;

&lt;h3&gt;
  
  
  Computationally Efficient
&lt;/h3&gt;

&lt;p&gt;Low-poly assets that wouldn’t destroy frame rates during simulation runs.&lt;/p&gt;

&lt;p&gt;Efficient rendering matters when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;testing SLAM pipelines&lt;/li&gt;
&lt;li&gt;running reinforcement learning&lt;/li&gt;
&lt;li&gt;generating synthetic datasets&lt;/li&gt;
&lt;li&gt;simulating autonomous agents&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Geometrically Challenging
&lt;/h3&gt;

&lt;p&gt;I intentionally added:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;vertical pillars&lt;/li&gt;
&lt;li&gt;jagged rocks&lt;/li&gt;
&lt;li&gt;uneven terrain&lt;/li&gt;
&lt;li&gt;debris shards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;to stress-test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;obstacle avoidance&lt;/li&gt;
&lt;li&gt;path planning&lt;/li&gt;
&lt;li&gt;depth estimation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A "perfect" environment teaches robots nothing.&lt;/p&gt;

&lt;p&gt;Edge cases do.&lt;/p&gt;




&lt;h3&gt;
  
  
  Visually Consistent
&lt;/h3&gt;

&lt;p&gt;I also optimized the environment for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;visual odometry&lt;/li&gt;
&lt;li&gt;depth perception&lt;/li&gt;
&lt;li&gt;feature tracking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;high-contrast lighting&lt;/li&gt;
&lt;li&gt;exaggerated shadows&lt;/li&gt;
&lt;li&gt;strong silhouettes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;because perception systems depend heavily on environmental consistency.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠 The Learning Curve: From Python to Poly-Editing
&lt;/h2&gt;

&lt;p&gt;Coming from a pure programming background, Blender initially felt like an alien spacecraft dashboard.&lt;/p&gt;

&lt;p&gt;But eventually something clicked:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;3D environments are just structured data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vertices.&lt;/p&gt;

&lt;p&gt;Normals.&lt;/p&gt;

&lt;p&gt;Meshes.&lt;/p&gt;

&lt;p&gt;Transforms.&lt;/p&gt;

&lt;p&gt;Once I started viewing Blender as an environment-generation engine instead of an art tool, the learning process became much easier.&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.amazonaws.com%2Fuploads%2Farticles%2F310e00ilh3yqli98lj57.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.amazonaws.com%2Fuploads%2Farticles%2F310e00ilh3yqli98lj57.png" alt="Blender" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  My Workflow
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Low-Poly Modeling
&lt;/h3&gt;

&lt;p&gt;I used simple primitives like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cylinders&lt;/li&gt;
&lt;li&gt;Ico-spheres&lt;/li&gt;
&lt;li&gt;Planes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;combined with Blender’s &lt;strong&gt;Decimate Modifier&lt;/strong&gt; to achieve a stylized low-poly aesthetic.&lt;/p&gt;

&lt;p&gt;This helped keep scenes lightweight while still visually readable.&lt;/p&gt;




&lt;h3&gt;
  
  
  Procedural Terrain Displacement
&lt;/h3&gt;

&lt;p&gt;Using noise textures and displacement modifiers, I warped flat geometry into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dunes&lt;/li&gt;
&lt;li&gt;cliffs&lt;/li&gt;
&lt;li&gt;rocky terrain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This created a more natural Martian landscape without manually sculpting every surface.&lt;/p&gt;




&lt;h3&gt;
  
  
  Lighting the Red Planet
&lt;/h3&gt;

&lt;p&gt;Mars has a very distinct visual feel.&lt;/p&gt;

&lt;p&gt;To mimic that, I used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a single directional sun lamp&lt;/li&gt;
&lt;li&gt;warm orange/red tones&lt;/li&gt;
&lt;li&gt;sharp shadow contrast&lt;/li&gt;
&lt;li&gt;higher light intensity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result looked stylized, but also became useful for testing perception systems under harsh lighting conditions.&lt;/p&gt;




&lt;h3&gt;
  
  
  Camera Rigging
&lt;/h3&gt;

&lt;p&gt;To simulate drone flyovers consistently, I created camera rigs using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bezier curves&lt;/li&gt;
&lt;li&gt;Follow Path constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allowed repeatable trajectories for testing navigation and visual tracking algorithms.&lt;/p&gt;

&lt;p&gt;Repeatability is critical when debugging autonomous systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  📈 Iteration: v1 → v3
&lt;/h2&gt;

&lt;p&gt;In software engineering, we iterate on features.&lt;/p&gt;

&lt;p&gt;In simulation engineering, we iterate on environmental complexity.&lt;/p&gt;




&lt;h3&gt;
  
  
  v1
&lt;/h3&gt;

&lt;p&gt;The first version was extremely simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;flat terrain&lt;/li&gt;
&lt;li&gt;a few cylinders&lt;/li&gt;
&lt;li&gt;minimal obstacles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good enough for proof-of-concept testing.&lt;/p&gt;

&lt;p&gt;But far too easy for navigation systems.&lt;/p&gt;




&lt;h3&gt;
  
  
  v3 (Current Version)
&lt;/h3&gt;

&lt;p&gt;The latest environment includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;varied terrain elevation&lt;/li&gt;
&lt;li&gt;debris shards&lt;/li&gt;
&lt;li&gt;complex shadows&lt;/li&gt;
&lt;li&gt;irregular obstacle geometry&lt;/li&gt;
&lt;li&gt;varied rock sizes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These additions introduced realistic edge cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the drone mistake a shard for a landing hazard?&lt;/li&gt;
&lt;li&gt;Do shadows confuse depth estimation?&lt;/li&gt;
&lt;li&gt;Can obstacle avoidance handle narrow passages?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By building the world myself, I can intentionally inject test cases directly into the environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Engineering Takeaway
&lt;/h2&gt;

&lt;p&gt;Learning Blender isn’t just about creating cool visuals.&lt;/p&gt;

&lt;p&gt;For robotics and AI engineers, it’s about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;simulation&lt;/li&gt;
&lt;li&gt;synthetic data generation&lt;/li&gt;
&lt;li&gt;digital twins&lt;/li&gt;
&lt;li&gt;environment control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I can build a scene in Blender, I can generate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;thousands of labeled images&lt;/li&gt;
&lt;li&gt;synthetic training datasets&lt;/li&gt;
&lt;li&gt;depth maps&lt;/li&gt;
&lt;li&gt;segmentation masks&lt;/li&gt;
&lt;li&gt;navigation scenarios&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;for machine learning systems.&lt;/p&gt;

&lt;p&gt;That’s incredibly powerful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Matters for Autonomous Systems
&lt;/h2&gt;

&lt;p&gt;Real-world robotics is expensive.&lt;/p&gt;

&lt;p&gt;Simulation allows us to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fail safely&lt;/li&gt;
&lt;li&gt;iterate faster&lt;/li&gt;
&lt;li&gt;scale testing&lt;/li&gt;
&lt;li&gt;generate data cheaply&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The better your simulated environments become, the more robust your real-world systems become.&lt;/p&gt;

&lt;p&gt;Simulation isn’t a side tool anymore.&lt;/p&gt;

&lt;p&gt;It’s part of the core engineering stack.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Project ASCEND is slowly teaching me that modern robotics engineers need to think beyond code.&lt;/p&gt;

&lt;p&gt;We’re no longer just writing algorithms.&lt;/p&gt;

&lt;p&gt;We’re building:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;environments&lt;/li&gt;
&lt;li&gt;datasets&lt;/li&gt;
&lt;li&gt;simulations&lt;/li&gt;
&lt;li&gt;digital ecosystems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And tools like Blender are becoming surprisingly important in that workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;p&gt;For those working in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;robotics&lt;/li&gt;
&lt;li&gt;simulation&lt;/li&gt;
&lt;li&gt;game engines&lt;/li&gt;
&lt;li&gt;AI systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;what does your simulation stack look like?&lt;/p&gt;

&lt;p&gt;Do you use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blender?&lt;/li&gt;
&lt;li&gt;Gazebo?&lt;/li&gt;
&lt;li&gt;Isaac Sim?&lt;/li&gt;
&lt;li&gt;Unreal Engine?&lt;/li&gt;
&lt;li&gt;Unity?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And how much effort do you invest into your environments compared to your actual autonomous logic?&lt;/p&gt;

&lt;p&gt;I’d genuinely love to hear how other engineers approach simulation-first development.&lt;/p&gt;

</description>
      <category>robotics</category>
      <category>blender</category>
      <category>python</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Architecting for Trust: Building a Multi-Role Admin Platform with React and Express</title>
      <dc:creator>Harsh Pandhe</dc:creator>
      <pubDate>Fri, 08 May 2026 16:52:59 +0000</pubDate>
      <link>https://dev.to/harshpandhe/architecting-for-trust-building-a-multi-role-admin-platform-with-react-and-express-18kb</link>
      <guid>https://dev.to/harshpandhe/architecting-for-trust-building-a-multi-role-admin-platform-with-react-and-express-18kb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;How I designed a secure multi-role admin platform with JWT authentication, layered authorization, and role-specific workflows for Project Morpheus.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When building an admin tool like &lt;strong&gt;Project Morpheus&lt;/strong&gt;, the biggest security threat usually isn’t an external hacker.&lt;/p&gt;

&lt;p&gt;It’s &lt;strong&gt;Privilege Escalation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In a system with four distinct roles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Admin&lt;/li&gt;
&lt;li&gt;Warden&lt;/li&gt;
&lt;li&gt;Auditor&lt;/li&gt;
&lt;li&gt;Desk Operator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;how do you ensure that a desk volunteer can’t accidentally—or intentionally—delete audit logs or modify hostel configurations?&lt;/p&gt;

&lt;p&gt;Here’s how I architected a robust &lt;strong&gt;Role-Based Access Control (RBAC)&lt;/strong&gt; system using React and Express.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The "Single Point of Truth" Authentication Model
&lt;/h2&gt;

&lt;p&gt;The foundation of the architecture is &lt;strong&gt;JWT-based authentication&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When a user logs in, the backend issues a signed token containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;userId&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;role&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hostelId&lt;/code&gt; (for Warden accounts)&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.amazonaws.com%2Fuploads%2Farticles%2Fypc6ubwdihy35yes3paw.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.amazonaws.com%2Fuploads%2Farticles%2Fypc6ubwdihy35yes3paw.png" alt="Website" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This token is stored in the browser and sent with every API request through the &lt;code&gt;Authorization&lt;/code&gt; header.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Authorization: Bearer &amp;lt;jwt_token&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;hostelId&lt;/code&gt; field allows wardens to be automatically restricted to their assigned building.&lt;/p&gt;

&lt;p&gt;This became the foundation for permission-aware APIs and role-specific dashboards.&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.amazonaws.com%2Fuploads%2Farticles%2Fqqsmflgnpq5azhvm7gz8.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.amazonaws.com%2Fuploads%2Farticles%2Fqqsmflgnpq5azhvm7gz8.png" alt="Website" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Hybrid API: Performance Meets Portability
&lt;/h2&gt;

&lt;p&gt;I wanted the platform to work seamlessly in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local development&lt;/li&gt;
&lt;li&gt;Cloud/serverless deployments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I used a &lt;strong&gt;Hybrid Express + Serverless Architecture&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.amazonaws.com%2Fuploads%2Farticles%2Fuws0t0rv8j3bu4y8h1ca.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.amazonaws.com%2Fuploads%2Farticles%2Fuws0t0rv8j3bu4y8h1ca.png" alt="Website" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Local Development
&lt;/h3&gt;

&lt;p&gt;A central Express &lt;code&gt;server.js&lt;/code&gt; handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Routing&lt;/li&gt;
&lt;li&gt;Middleware&lt;/li&gt;
&lt;li&gt;JWT validation&lt;/li&gt;
&lt;li&gt;Local API orchestration&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.amazonaws.com%2Fuploads%2Farticles%2Fugc0h5xzbj2am726r6mm.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.amazonaws.com%2Fuploads%2Farticles%2Fugc0h5xzbj2am726r6mm.png" alt="Website" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Production Deployment
&lt;/h3&gt;

&lt;p&gt;Each route is structured as an independent serverless function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/api/teams/verify.js
/api/hostels/allocate.js
/api/audit/logs.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach gave me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better modularity&lt;/li&gt;
&lt;li&gt;Easier debugging&lt;/li&gt;
&lt;li&gt;Isolated feature testing&lt;/li&gt;
&lt;li&gt;Cloud portability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;without maintaining two different codebases.&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.amazonaws.com%2Fuploads%2Farticles%2F4tx6vq21xhx3y39axqkp.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.amazonaws.com%2Fuploads%2Farticles%2F4tx6vq21xhx3y39axqkp.png" alt="Website" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Defense in Depth: The "Double Lock" Strategy
&lt;/h2&gt;

&lt;p&gt;One of the most common security mistakes in frontend-heavy applications is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Protecting only the UI.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hiding buttons in React does &lt;strong&gt;not&lt;/strong&gt; secure your system.&lt;/p&gt;

&lt;p&gt;Anyone with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Postman&lt;/li&gt;
&lt;li&gt;curl&lt;/li&gt;
&lt;li&gt;browser devtools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;can still hit your APIs directly.&lt;/p&gt;

&lt;p&gt;So Morpheus uses a &lt;strong&gt;Two-Layer Guard Architecture&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.amazonaws.com%2Fuploads%2Farticles%2F0ar2yyt0okmygcs6vqr9.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.amazonaws.com%2Fuploads%2Farticles%2F0ar2yyt0okmygcs6vqr9.png" alt="Website" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Layer 1: Frontend Route Guards (UX Protection)
&lt;/h3&gt;

&lt;p&gt;In React, I implemented a wrapper component that validates roles before rendering routes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ProtectedRoute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;allowedRoles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAuth&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;allowedRoles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Navigate&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/unauthorized"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;children&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;&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.amazonaws.com%2Fuploads%2Farticles%2Fzr3jem78jlfpr3cv0hmz.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.amazonaws.com%2Fuploads%2Farticles%2Fzr3jem78jlfpr3cv0hmz.png" alt="Website" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wardens never see admin settings&lt;/li&gt;
&lt;li&gt;Desk operators never access audit tools&lt;/li&gt;
&lt;li&gt;Auditors only see verification workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The frontend becomes cleaner and less error-prone.&lt;/p&gt;




&lt;h3&gt;
  
  
  Layer 2: Backend Middleware (Real Security)
&lt;/h3&gt;

&lt;p&gt;Every API route is wrapped in authorization middleware.&lt;/p&gt;

&lt;p&gt;Even if someone bypasses the UI, the server validates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JWT authenticity&lt;/li&gt;
&lt;li&gt;User role&lt;/li&gt;
&lt;li&gt;Permission level&lt;/li&gt;
&lt;li&gt;Resource ownership&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;before processing the request.&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.amazonaws.com%2Fuploads%2Farticles%2Fbzdtk4akvii055yegqml.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.amazonaws.com%2Fuploads%2Farticles%2Fbzdtk4akvii055yegqml.png" alt="Website" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Access denied&lt;/span&gt;&lt;span class="dl"&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 creates true defense-in-depth security.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Designing for Specific Roles
&lt;/h2&gt;

&lt;p&gt;One of the most impactful decisions in Morpheus was making the interface adapt to the user’s identity.&lt;/p&gt;

&lt;p&gt;Different users think differently.&lt;/p&gt;

&lt;p&gt;So the UI itself changes depending on the role.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Desk Operator
&lt;/h3&gt;

&lt;p&gt;Their workflow is optimized for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Speed&lt;/li&gt;
&lt;li&gt;Search&lt;/li&gt;
&lt;li&gt;Verification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find teams instantly&lt;/li&gt;
&lt;li&gt;Search by phone number or ID&lt;/li&gt;
&lt;li&gt;Verify attendance rapidly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Minimal distractions.&lt;/p&gt;

&lt;p&gt;Maximum efficiency.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Warden
&lt;/h3&gt;

&lt;p&gt;Their workflow is visual.&lt;/p&gt;

&lt;p&gt;They need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Occupancy heatmaps&lt;/li&gt;
&lt;li&gt;Room status visibility&lt;/li&gt;
&lt;li&gt;Floor-level overview dashboards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of forms, they interact with live hostel state.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Auditor
&lt;/h3&gt;

&lt;p&gt;Auditors care about process integrity.&lt;/p&gt;

&lt;p&gt;Their interface is workflow-oriented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step-by-step validation&lt;/li&gt;
&lt;li&gt;Approval pipelines&lt;/li&gt;
&lt;li&gt;Verification checkpoints&lt;/li&gt;
&lt;li&gt;Historical records&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They don’t need dashboards.&lt;/p&gt;

&lt;p&gt;They need structured operational flows.&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.amazonaws.com%2Fuploads%2Farticles%2Fdl346cqnz4r49zs6guh7.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.amazonaws.com%2Fuploads%2Farticles%2Fdl346cqnz4r49zs6guh7.png" alt="Website" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Key Architecture Takeaways
&lt;/h2&gt;

&lt;p&gt;Building Morpheus taught me several important engineering lessons.&lt;/p&gt;




&lt;h3&gt;
  
  
  Never Trust the Client
&lt;/h3&gt;

&lt;p&gt;Always verify permissions on the backend.&lt;/p&gt;

&lt;p&gt;Frontend validation improves UX.&lt;/p&gt;

&lt;p&gt;Backend validation provides security.&lt;/p&gt;

&lt;p&gt;You need both.&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.amazonaws.com%2Fuploads%2Farticles%2Fmeab8q6spy8ck7f3ujnu.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.amazonaws.com%2Fuploads%2Farticles%2Fmeab8q6spy8ck7f3ujnu.png" alt="Website" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Modular APIs Scale Better
&lt;/h3&gt;

&lt;p&gt;Small domain-focused handlers are easier to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test&lt;/li&gt;
&lt;li&gt;Maintain&lt;/li&gt;
&lt;li&gt;Secure&lt;/li&gt;
&lt;li&gt;Deploy independently&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Context is King
&lt;/h3&gt;

&lt;p&gt;Using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React Context&lt;/li&gt;
&lt;li&gt;Custom Hooks&lt;/li&gt;
&lt;li&gt;Global Auth Providers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;allowed me to avoid painful prop-drilling across deeply nested dashboards.&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.amazonaws.com%2Fuploads%2Farticles%2Fgrupmnkhebdjqtegbnyh.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.amazonaws.com%2Fuploads%2Farticles%2Fgrupmnkhebdjqtegbnyh.png" alt="Website" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Is Also About Preventing Mistakes
&lt;/h2&gt;

&lt;p&gt;One of the biggest realizations during this project was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Security isn’t just about stopping attackers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s also about designing systems that prevent normal users from making catastrophic mistakes.&lt;/p&gt;

&lt;p&gt;Good architecture guides users toward safe behavior by default.&lt;/p&gt;

&lt;p&gt;That matters just as much as encryption and middleware.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Building Project Morpheus pushed me to think beyond CRUD applications and into operational system design.&lt;/p&gt;

&lt;p&gt;Once you introduce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple roles&lt;/li&gt;
&lt;li&gt;Real-world workflows&lt;/li&gt;
&lt;li&gt;Permissions&lt;/li&gt;
&lt;li&gt;Auditability&lt;/li&gt;
&lt;li&gt;Physical asset management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;your application becomes less about pages and more about trust boundaries.&lt;/p&gt;

&lt;p&gt;And designing those trust boundaries correctly is where backend architecture becomes truly interesting.&lt;/p&gt;




&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;p&gt;How would you design RBAC in a large-scale operational platform?&lt;/p&gt;

&lt;p&gt;Would you use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attribute-Based Access Control (ABAC)?&lt;/li&gt;
&lt;li&gt;Policy Engines like OPA?&lt;/li&gt;
&lt;li&gt;Role hierarchies?&lt;/li&gt;
&lt;li&gt;Permission matrices?&lt;/li&gt;
&lt;li&gt;Microservice authorization gateways?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’d love to hear how other engineers approach multi-role security systems.&lt;/p&gt;

</description>
      <category>react</category>
      <category>node</category>
      <category>security</category>
      <category>fullstack</category>
    </item>
    <item>
      <title>The "Double-Booking" Nightmare: Building a Rule-Driven Hostel Allocator with MongoDB Transactions</title>
      <dc:creator>Harsh Pandhe</dc:creator>
      <pubDate>Thu, 07 May 2026 11:51:33 +0000</pubDate>
      <link>https://dev.to/harshpandhe/the-double-booking-nightmare-building-a-rule-driven-hostel-allocator-with-mongodb-transactions-21ni</link>
      <guid>https://dev.to/harshpandhe/the-double-booking-nightmare-building-a-rule-driven-hostel-allocator-with-mongodb-transactions-21ni</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;How I built a transactional hostel allocation engine that eliminates race conditions and double-bookings using MongoDB sessions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Handling logistics for a 500+ person event—like a major hackathon or campus festival—is easy on paper.&lt;/p&gt;

&lt;p&gt;It becomes significantly harder at &lt;strong&gt;2:00 AM&lt;/strong&gt; when multiple exhausted teams arrive at the registration desk simultaneously while operators manually juggle room assignments.&lt;/p&gt;

&lt;p&gt;In this article, I’m pulling back the curtain on the "brain" of &lt;strong&gt;Project Morpheus&lt;/strong&gt;: a transactional allocation engine designed to handle complex accommodation logic without risking data corruption or double-bookings.&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.amazonaws.com%2Fuploads%2Farticles%2F52lozgg2i0ix6fnjpho8.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.amazonaws.com%2Fuploads%2Farticles%2F52lozgg2i0ix6fnjpho8.png" alt="The Challenge: Why CRUD Isn’t Enough" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Challenge: Why CRUD Isn’t Enough
&lt;/h2&gt;

&lt;p&gt;When most people think of a Hostel Management System, they imagine a basic CRUD application.&lt;/p&gt;

&lt;p&gt;But in high-concurrency environments—where multiple operators may click &lt;strong&gt;Allocate&lt;/strong&gt; at the exact same moment—traditional CRUD logic introduces dangerous race conditions.&lt;/p&gt;

&lt;h3&gt;
  
  
  The "Overbooking" Scenario
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Operator A queries for the next available bed.&lt;/li&gt;
&lt;li&gt;The database responds:&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Room 101, Bed A is free.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Operator B performs the same query simultaneously.&lt;/li&gt;
&lt;li&gt;The database again responds:&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Room 101, Bed A is free.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Both operators hit &lt;strong&gt;Confirm&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Result?&lt;/p&gt;

&lt;p&gt;The same physical bed gets assigned twice.&lt;/p&gt;

&lt;p&gt;I’ve seen this happen in real operational environments, and I decided that Project Morpheus would move the complexity from the operator’s brain into the system itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Morpheus Solution: Rule-Driven Automation
&lt;/h2&gt;

&lt;p&gt;The allocator doesn’t randomly assign rooms.&lt;/p&gt;

&lt;p&gt;It follows a strict hierarchy of business rules modeled after real-world campus accommodation systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  The "Golden Rules" of Allocation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Gender Segregation
&lt;/h4&gt;

&lt;p&gt;This is the most critical rule.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Male participants → &lt;strong&gt;Devgiri&lt;/strong&gt; or &lt;strong&gt;Raigad&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Female participants → &lt;strong&gt;Godavari&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  2. The Verification Gate
&lt;/h4&gt;

&lt;p&gt;To prevent ghost bookings and spreadsheet inconsistencies:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A team cannot be allocated unless every member has been verified at the registration desk.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ID verification&lt;/li&gt;
&lt;li&gt;Physical presence confirmation&lt;/li&gt;
&lt;li&gt;Attendance validation&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  3. Team Integrity
&lt;/h4&gt;

&lt;p&gt;The allocator prioritizes keeping teams:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the same room&lt;/li&gt;
&lt;li&gt;Or in adjacent rooms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It avoids splitting teams across multiple floors unless absolutely necessary.&lt;/p&gt;




&lt;h4&gt;
  
  
  4. Sequential Optimization
&lt;/h4&gt;

&lt;p&gt;To simplify operations for wardens and housekeeping staff, rooms are filled in a deterministic order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Block → Room → Bed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Technical Deep-Dive: The Transactional Sequence
&lt;/h2&gt;

&lt;p&gt;In Project Morpheus, an allocation request is treated as an:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Atomic Unit of Work&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Meaning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Either every database operation succeeds&lt;/li&gt;
&lt;li&gt;Or the entire request rolls back safely&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This guarantees consistency even during crashes or network failures.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 1: Concurrency Check
&lt;/h3&gt;

&lt;p&gt;The allocator first performs an atomic validation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;team&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isAllocated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Team already allocated&lt;/span&gt;&lt;span class="dl"&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 prevents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Double-click allocation issues&lt;/li&gt;
&lt;li&gt;Duplicate operator requests&lt;/li&gt;
&lt;li&gt;Multiple transaction executions&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 2: Gender-Specific Scouting
&lt;/h3&gt;

&lt;p&gt;The engine separates members by gender and searches eligible hostel blocks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;availableBeds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hostels&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;teamGender&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="na"&gt;$unwind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$rooms&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$unwind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$rooms.beds&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rooms.beds.isOccupied&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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="na"&gt;$limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;memberCount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This dynamically finds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Empty beds&lt;/li&gt;
&lt;li&gt;Nearby room availability&lt;/li&gt;
&lt;li&gt;Contiguous placements for teams&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.amazonaws.com%2Fuploads%2Farticles%2Fi8cxx0sdhw7fd3r0f2pf.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.amazonaws.com%2Fuploads%2Farticles%2Fi8cxx0sdhw7fd3r0f2pf.png" alt="Info" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: The "Big Write" (MongoDB Transaction)
&lt;/h3&gt;

&lt;p&gt;Using MongoDB sessions, the allocator wraps all mutations into a single transaction.&lt;/p&gt;

&lt;p&gt;Inside the transaction:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Generate Allocation Records
&lt;/h4&gt;

&lt;p&gt;Create accommodation records for every participant.&lt;/p&gt;

&lt;p&gt;This becomes the system’s:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Source of Truth&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;for room mapping.&lt;/p&gt;




&lt;h4&gt;
  
  
  2. Update Hostel State
&lt;/h4&gt;

&lt;p&gt;Selected beds are marked as occupied using MongoDB positional operators.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&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;h4&gt;
  
  
  3. Update Team Metadata
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;isAllocated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Why Transactions Matter
&lt;/h3&gt;

&lt;p&gt;Imagine this scenario:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accommodation slips are printed&lt;/li&gt;
&lt;li&gt;The server crashes before hostel state updates&lt;/li&gt;
&lt;li&gt;The database still believes those beds are empty&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without transactions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Duplicate allocations become possible&lt;/li&gt;
&lt;li&gt;Database consistency breaks&lt;/li&gt;
&lt;li&gt;Physical occupancy mismatches system state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With MongoDB transactions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everything commits together&lt;/li&gt;
&lt;li&gt;Or everything rolls back safely&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Operational Impact: From 5 Minutes to 2 Seconds
&lt;/h2&gt;

&lt;p&gt;Before Project Morpheus:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manual room hunting&lt;/li&gt;
&lt;li&gt;Spreadsheet coordination&lt;/li&gt;
&lt;li&gt;Warden communication over calls&lt;/li&gt;
&lt;li&gt;~5 minutes per team allocation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After automation:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Allocation Time&lt;/td&gt;
&lt;td&gt;~5 mins&lt;/td&gt;
&lt;td&gt;~2.5 sec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Double Bookings&lt;/td&gt;
&lt;td&gt;Frequent Risk&lt;/td&gt;
&lt;td&gt;Impossible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manual Coordination&lt;/td&gt;
&lt;td&gt;Heavy&lt;/td&gt;
&lt;td&gt;Minimal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Slip Generation&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Real-World Results
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Zero Double-Bookings
&lt;/h4&gt;

&lt;p&gt;The transactional lock mechanism makes over-allocation mathematically impossible.&lt;/p&gt;




&lt;h4&gt;
  
  
  Massive Efficiency
&lt;/h4&gt;

&lt;p&gt;Allocation now takes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~2.5 seconds per team
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;regardless of team size.&lt;/p&gt;




&lt;h4&gt;
  
  
  Clean Operational Hand-Offs
&lt;/h4&gt;

&lt;p&gt;The system instantly generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Printable accommodation slips&lt;/li&gt;
&lt;li&gt;Accurate hostel mappings&lt;/li&gt;
&lt;li&gt;Verified room assignments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Students receive the exact data stored in the database.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Key Takeaway for Developers
&lt;/h2&gt;

&lt;p&gt;The biggest lesson I learned while building the Morpheus allocator:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Consistency matters more than speed in operational systems.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When software manages physical assets—beds, inventory, seats, reservations—it’s always better to have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slightly slower&lt;/li&gt;
&lt;li&gt;Transaction-heavy&lt;/li&gt;
&lt;li&gt;Fully consistent operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;than ultra-fast systems that corrupt data under load.&lt;/p&gt;




&lt;h2&gt;
  
  
  Designing for the "2:00 AM Scenario"
&lt;/h2&gt;

&lt;p&gt;Good backend systems are not designed for ideal conditions.&lt;/p&gt;

&lt;p&gt;They are designed for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Failures&lt;/li&gt;
&lt;li&gt;Concurrency&lt;/li&gt;
&lt;li&gt;Human mistakes&lt;/li&gt;
&lt;li&gt;Crashes&lt;/li&gt;
&lt;li&gt;Unpredictable operational pressure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your system can survive &lt;strong&gt;2:00 AM chaos&lt;/strong&gt;, it can survive production.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&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.amazonaws.com%2Fuploads%2Farticles%2Fla0e83f0otanekt8ng0c.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.amazonaws.com%2Fuploads%2Farticles%2Fla0e83f0otanekt8ng0c.png" alt="Demo projects from Production-grade infrastructure" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Building Project Morpheus taught me that backend engineering is less about writing APIs and more about designing reliable systems under pressure.&lt;/p&gt;

&lt;p&gt;Handling concurrency correctly is what separates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Demo projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;from&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Production-grade infrastructure.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;p&gt;How would you design this allocator differently?&lt;/p&gt;

&lt;p&gt;Would you use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redis distributed locks?&lt;/li&gt;
&lt;li&gt;PostgreSQL row-level locking?&lt;/li&gt;
&lt;li&gt;Event sourcing?&lt;/li&gt;
&lt;li&gt;Queue-based allocation?&lt;/li&gt;
&lt;li&gt;Optimistic concurrency control?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’d genuinely love to hear production-grade approaches from other backend engineers.&lt;/p&gt;




</description>
      <category>mongodb</category>
      <category>backend</category>
      <category>javascript</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>GitHub Bootcamp: Day 5 – Contributing to Open Source Like a Pro 🧑‍💻🌍</title>
      <dc:creator>Harsh Pandhe</dc:creator>
      <pubDate>Thu, 22 May 2025 18:30:00 +0000</pubDate>
      <link>https://dev.to/harshpandhe/github-bootcamp-day-5-contributing-to-open-source-like-a-pro-4lje</link>
      <guid>https://dev.to/harshpandhe/github-bootcamp-day-5-contributing-to-open-source-like-a-pro-4lje</guid>
      <description>&lt;p&gt;Welcome to the final day of our GitHub crash course! Today’s topic is a favorite among devs and job recruiters alike — &lt;strong&gt;Open Source Contributions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Yes, it sounds intimidating. But trust me — you don’t need to be a 10x developer or a command-line wizard to contribute meaningfully. Let’s break it down!&lt;/p&gt;




&lt;h2&gt;
  
  
  🌱 Why Contribute to Open Source?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Learn by doing&lt;/strong&gt; – Hands-on experience beats theory any day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build your portfolio&lt;/strong&gt; – Real-world code &amp;gt; tutorial projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grow your network&lt;/strong&gt; – Meet collaborators, mentors, and friends.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Give back to the community&lt;/strong&gt; – Many of the tools you use daily are open source!&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.amazonaws.com%2Fuploads%2Farticles%2Ftgmgtle12vyp161osilz.jpg" 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.amazonaws.com%2Fuploads%2Farticles%2Ftgmgtle12vyp161osilz.jpg" alt="Github" width="786" height="443"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 How to Find Projects to Contribute To
&lt;/h2&gt;

&lt;h3&gt;
  
  
  💡 Start here:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/search?q=label%3A%22good+first+issue%22" rel="noopener noreferrer"&gt;Good First Issue&lt;/a&gt;&lt;/strong&gt; – Curated list of beginner-friendly issues&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://up-for-grabs.net/" rel="noopener noreferrer"&gt;Up-for-Grabs&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://github.com/firstcontributions/first-contributions" rel="noopener noreferrer"&gt;First Contributions Repo&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explore trending repos on GitHub&lt;/strong&gt; – Look under the “issues” tab for low-hanging fruit.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✅ What Can You Contribute?
&lt;/h2&gt;

&lt;p&gt;You don’t need to refactor the entire codebase. Open source thrives on &lt;strong&gt;small, meaningful contributions&lt;/strong&gt;. Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fixing typos in documentation&lt;/li&gt;
&lt;li&gt;Improving README files&lt;/li&gt;
&lt;li&gt;Updating dependencies&lt;/li&gt;
&lt;li&gt;Fixing bugs&lt;/li&gt;
&lt;li&gt;Adding tests&lt;/li&gt;
&lt;li&gt;Suggesting features&lt;/li&gt;
&lt;li&gt;Reviewing other people’s PRs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ How to Make a Contribution (The Friendly Way)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fork the repo&lt;/strong&gt; 🍴&lt;br&gt;
Creates your own copy where you can make changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clone it locally&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   git clone https://github.com/your-username/project-name.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a new branch&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   git checkout -b fix-typo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Make your changes &amp;amp; commit&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   git add .
   git commit -m "Fix typo in README"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Push to your fork&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   git push origin fix-typo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Open a Pull Request (PR)&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Explain what you did clearly.&lt;/li&gt;
&lt;li&gt;Be polite and open to feedback!&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💬 Pro Tips for Contributing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Read the &lt;strong&gt;Contributing.md&lt;/strong&gt; file if available.&lt;/li&gt;
&lt;li&gt;Follow &lt;strong&gt;code style guidelines&lt;/strong&gt; of the project.&lt;/li&gt;
&lt;li&gt;Engage positively in issue discussions.&lt;/li&gt;
&lt;li&gt;Be patient — maintainers are often volunteers!&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Bonus: Hacktoberfest
&lt;/h2&gt;

&lt;p&gt;Every October, GitHub and DigitalOcean host &lt;strong&gt;Hacktoberfest&lt;/strong&gt;, where contributing to open source earns you swag, stickers, and GitHub street cred. Perfect for beginners!&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.amazonaws.com%2Fuploads%2Farticles%2Ffkd5tu83a0jr5rh7ejha.jpg" 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.amazonaws.com%2Fuploads%2Farticles%2Ffkd5tu83a0jr5rh7ejha.jpg" alt="Github" width="800" height="1077"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 That’s a Wrap!
&lt;/h2&gt;

&lt;p&gt;You just finished a 5-day journey covering:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is GitHub&lt;/li&gt;
&lt;li&gt;Setting up GitHub &amp;amp; Git&lt;/li&gt;
&lt;li&gt;Branching and Collaboration&lt;/li&gt;
&lt;li&gt;GitHub Actions for Automation&lt;/li&gt;
&lt;li&gt;Open Source Contributions&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Whether you're building solo or contributing globally, GitHub is your dev playground.&lt;/p&gt;

</description>
      <category>github</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>GitHub Series: Day 4 – Automate Like a Boss with GitHub Actions 🤖⚙️</title>
      <dc:creator>Harsh Pandhe</dc:creator>
      <pubDate>Wed, 21 May 2025 18:30:00 +0000</pubDate>
      <link>https://dev.to/harshpandhe/github-series-day-4-automate-like-a-boss-with-github-actions-22o1</link>
      <guid>https://dev.to/harshpandhe/github-series-day-4-automate-like-a-boss-with-github-actions-22o1</guid>
      <description>&lt;p&gt;Welcome back, developers! Yesterday, we learned how to branch and merge like Git ninjas. Today, we’re going full automation mode with &lt;strong&gt;GitHub Actions&lt;/strong&gt; — your new best friend for building, testing, and deploying code without lifting a finger (well, almost 😎).&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What are GitHub Actions?
&lt;/h2&gt;

&lt;p&gt;Imagine having a robot that checks your code, runs tests, deploys apps, makes you coffee (okay, not that last one… yet) — all triggered by events like pushing to a branch or opening a pull request.&lt;br&gt;
That’s &lt;strong&gt;GitHub Actions&lt;/strong&gt;. It's a powerful CI/CD (Continuous Integration / Continuous Deployment) system built right into GitHub.&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.amazonaws.com%2Fuploads%2Farticles%2Fwodiz7rngnwwfbalahjn.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.amazonaws.com%2Fuploads%2Farticles%2Fwodiz7rngnwwfbalahjn.png" alt="Github" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  🔥 Why Use GitHub Actions?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ Automate repetitive tasks&lt;/li&gt;
&lt;li&gt;🧪 Run tests every time code is pushed&lt;/li&gt;
&lt;li&gt;🚀 Deploy apps automatically&lt;/li&gt;
&lt;li&gt;📦 Build and publish packages&lt;/li&gt;
&lt;li&gt;🤝 Boost collaboration with teams&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🛠️ Setting Up Your First GitHub Action
&lt;/h2&gt;

&lt;p&gt;Here’s how to build a simple GitHub Action that runs tests when code is pushed:&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Create a workflow file
&lt;/h3&gt;

&lt;p&gt;Inside your repo, make this folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.github/workflows/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create a file like &lt;code&gt;ci.yml&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Add this starter config:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Python Tests&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Python&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-python@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.10'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pip install -r requirements.txt&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pytest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And boom — your tests will now run automatically whenever you push code!&lt;/p&gt;




&lt;h2&gt;
  
  
  🚦 Common Use Cases
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Trigger&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Linting&lt;/td&gt;
&lt;td&gt;&lt;code&gt;on: push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Auto-check code style (e.g., with ESLint or Black)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;&lt;code&gt;on: push to main&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deploy app to Vercel, Heroku, Netlify, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Notifications&lt;/td&gt;
&lt;td&gt;&lt;code&gt;on: issues&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Send Slack or Discord alerts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Testing&lt;/td&gt;
&lt;td&gt;&lt;code&gt;on: pull_request&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run unit tests before merging&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🧩 Pro Tip: Use Actions from the Marketplace
&lt;/h2&gt;

&lt;p&gt;Why reinvent the wheel? Head over to &lt;a href="https://github.com/marketplace?type=actions" rel="noopener noreferrer"&gt;GitHub Marketplace&lt;/a&gt; and use thousands of pre-built actions.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;actions/checkout&lt;/code&gt; → Pulls repo code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;actions/setup-node&lt;/code&gt; → Sets up Node.js&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docker/build-push-action&lt;/code&gt; → Builds &amp;amp; pushes Docker images&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.amazonaws.com%2Fuploads%2Farticles%2F2kqhzarq6whxvp2hzy63.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.amazonaws.com%2Fuploads%2Farticles%2F2kqhzarq6whxvp2hzy63.png" alt="Github" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ Keep workflows small and focused&lt;/li&gt;
&lt;li&gt;🔁 Use reusable workflows to avoid duplication&lt;/li&gt;
&lt;li&gt;🧪 Run tests &lt;em&gt;before&lt;/em&gt; deploying&lt;/li&gt;
&lt;li&gt;⏱️ Don’t trigger workflows on every tiny change — be specific with paths and branches&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Conclusion
&lt;/h2&gt;

&lt;p&gt;GitHub Actions is your personal DevOps assistant. Whether you're solo-building a portfolio site or working in a team on a massive app, automation will save your time and sanity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tomorrow?
&lt;/h3&gt;

&lt;p&gt;We’ll wrap this series with something close to every developer’s heart — &lt;strong&gt;Open Source Contributions&lt;/strong&gt; 💖&lt;br&gt;
How to find cool projects, make meaningful PRs, and become a contributor!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>github</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>GitHub Bootcamp: Day 3 - Branching and Merging Like a Pro</title>
      <dc:creator>Harsh Pandhe</dc:creator>
      <pubDate>Tue, 20 May 2025 18:30:00 +0000</pubDate>
      <link>https://dev.to/harshpandhe/github-bootcamp-day-3-branching-and-merging-like-a-pro-1ecc</link>
      <guid>https://dev.to/harshpandhe/github-bootcamp-day-3-branching-and-merging-like-a-pro-1ecc</guid>
      <description>&lt;p&gt;Welcome to &lt;strong&gt;Day 3&lt;/strong&gt; of our GitHub series! Today we're diving into &lt;strong&gt;branching and merging&lt;/strong&gt;—the secret sauce behind collaborative development. If GitHub was a movie, branches would be the plot twists, and merges would be the dramatic reunions. Let's get into it!&lt;/p&gt;




&lt;h2&gt;
  
  
  🌐 What is a Branch?
&lt;/h2&gt;

&lt;p&gt;A branch in Git is like a sandbox where you can work on changes without affecting the main (production) version of your code.&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.amazonaws.com%2Fuploads%2Farticles%2F09l05cwc2rkoddh72wf1.webp" 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.amazonaws.com%2Fuploads%2Farticles%2F09l05cwc2rkoddh72wf1.webp" alt="Github" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine you're writing a novel. Your main branch is the final version, but you want to try out an alternate ending. Instead of rewriting everything, you create a branch called &lt;code&gt;alternate-ending&lt;/code&gt; and work there. Genius, right?&lt;/p&gt;

&lt;h3&gt;
  
  
  🔄 Creating a Branch
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch feature-cool-button
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🚀 Switching to Your Branch
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout feature-cool-button
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OR&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git switch feature-cool-button
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you're in your own bubble. Make changes, commit them, and live your best dev life.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ Merging: The Reunion Episode
&lt;/h2&gt;

&lt;p&gt;Once you’re happy with your changes in a branch, it’s time to bring them back into the &lt;code&gt;main&lt;/code&gt; branch. That’s merging.&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.amazonaws.com%2Fuploads%2Farticles%2Fe9ep83vxmqy7me8v92hz.jpg" 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.amazonaws.com%2Fuploads%2Farticles%2Fe9ep83vxmqy7me8v92hz.jpg" alt="Github" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🔐 First, Switch to Main
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔄 Merge Your Branch
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git merge feature-cool-button
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boom! Your changes are now part of the main storyline.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚠️ What About Merge Conflicts?
&lt;/h2&gt;

&lt;p&gt;Sometimes Git gets confused if the same part of a file has been changed in both branches. It’ll raise a &lt;strong&gt;merge conflict&lt;/strong&gt; and ask you to resolve it.&lt;/p&gt;

&lt;p&gt;Don't panic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git will mark the conflicts in the file.&lt;/li&gt;
&lt;li&gt;You decide which version to keep.&lt;/li&gt;
&lt;li&gt;After editing, mark the conflict as resolved:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add conflicted-file.js
git commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎓 Pro Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Name your branches clearly: &lt;code&gt;bugfix-login-issue&lt;/code&gt;, &lt;code&gt;feature-dark-mode&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Always pull latest changes before you merge.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;git log --graph&lt;/code&gt; to visualize branches.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;git status&lt;/code&gt; to stay aware of what’s going on.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤖 Pull Requests: Collaborate the GitHub Way
&lt;/h2&gt;

&lt;p&gt;If you're working with a team or contributing to open source, don’t just merge directly. Open a &lt;strong&gt;pull request&lt;/strong&gt; on GitHub.&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.amazonaws.com%2Fuploads%2Farticles%2Fpcrtgyt24s982j4i8z4q.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.amazonaws.com%2Fuploads%2Farticles%2Fpcrtgyt24s982j4i8z4q.png" alt="Github" width="624" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It allows others to review your code.&lt;/li&gt;
&lt;li&gt;You can discuss changes before merging.&lt;/li&gt;
&lt;li&gt;Ensures cleaner, safer code.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🌟 Summary
&lt;/h2&gt;

&lt;p&gt;Branching and merging are powerful tools for working independently without chaos. Master these, and you’re halfway to becoming a Git wizard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coming Up: Day 4 - GitHub Actions ✨
&lt;/h3&gt;

&lt;p&gt;Next, we’ll explore how to automate workflows and save time with &lt;strong&gt;GitHub Actions&lt;/strong&gt;. Get ready for some dev magic!&lt;/p&gt;

&lt;p&gt;#GitHub #Git #VersionControl #GitTips #CodeCollaboration #OpenSource&lt;/p&gt;

</description>
      <category>github</category>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>GitHub Bootcamp: Day 2 - Setting Up GitHub</title>
      <dc:creator>Harsh Pandhe</dc:creator>
      <pubDate>Mon, 19 May 2025 18:30:00 +0000</pubDate>
      <link>https://dev.to/harshpandhe/github-for-developers-day-2-setting-up-github-hh6</link>
      <guid>https://dev.to/harshpandhe/github-for-developers-day-2-setting-up-github-hh6</guid>
      <description>&lt;p&gt;Welcome to &lt;strong&gt;Day 2&lt;/strong&gt; of our 5-day GitHub series! Today we’re setting up GitHub, the digital garage where developers store, collaborate on, and show off their code. If GitHub were a superhero, it’d be Batman: mysterious, powerful, and full of cool gadgets (like Actions and Pull Requests). Let's get you set up and ready to push code like a pro.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 1: Create a GitHub Account&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Go to &lt;a href="https://github.com" rel="noopener noreferrer"&gt;github.com&lt;/a&gt; and hit &lt;strong&gt;Sign up&lt;/strong&gt;
&lt;/h3&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.amazonaws.com%2Fuploads%2Farticles%2Fnmror7s1ci2bv44umtvj.webp" 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.amazonaws.com%2Fuploads%2Farticles%2Fnmror7s1ci2bv44umtvj.webp" alt="Github" width="640" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pick a memorable username (bonus points for geeky puns).&lt;/li&gt;
&lt;li&gt;Add your email and a strong password.&lt;/li&gt;
&lt;li&gt;Choose your plan (the free one is plenty to get started).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You're officially a GitHubber now. 🎉&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 2: Create Your First Repository&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A repository (or “repo”) is where your project lives—kind of like a folder, but cooler.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Create a Repo:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Click the &lt;strong&gt;+&lt;/strong&gt; icon on the top-right → &lt;strong&gt;New repository&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Give it a name like &lt;code&gt;awesome-project&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add a description (optional but classy).&lt;/li&gt;
&lt;li&gt;Choose public (anyone can see) or private (for your eyes only).&lt;/li&gt;
&lt;li&gt;Check &lt;strong&gt;“Initialize this repository with a README”&lt;/strong&gt; if you want to add one.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create repository&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&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.amazonaws.com%2Fuploads%2Farticles%2Faykiqxihx47ytzomzjjn.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.amazonaws.com%2Fuploads%2Farticles%2Faykiqxihx47ytzomzjjn.png" alt="Github" width="800" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Boom. Your project home is ready.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 3: Install Git Locally&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To push code from your computer to GitHub, you’ll need Git installed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install Git:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Windows&lt;/strong&gt;: &lt;a href="https://git-scm.com/download/win" rel="noopener noreferrer"&gt;Download Git&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;macOS&lt;/strong&gt;: Use Homebrew → &lt;code&gt;brew install git&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux&lt;/strong&gt;: Use your package manager → &lt;code&gt;sudo apt install git&lt;/code&gt; (for Debian/Ubuntu)&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.amazonaws.com%2Fuploads%2Farticles%2F9qk8in333jz3bb8mrr6y.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.amazonaws.com%2Fuploads%2Farticles%2F9qk8in333jz3bb8mrr6y.png" alt="Github" width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure Git:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.name &lt;span class="s2"&gt;"Your Name"&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.email &lt;span class="s2"&gt;"your@email.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells Git who you are (like a signature on your code).&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 4: Push Your Code to GitHub&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let’s say you created a project on your computer called &lt;code&gt;hello-github&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Push it to GitHub:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;hello-github
git init
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Initial commit"&lt;/span&gt;
git branch &lt;span class="nt"&gt;-M&lt;/span&gt; main
git remote add origin https://github.com/yourusername/hello-github.git
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&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.amazonaws.com%2Fuploads%2Farticles%2F5b242dq00fgyjgf19ew0.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.amazonaws.com%2Fuploads%2Farticles%2F5b242dq00fgyjgf19ew0.png" alt="Github" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And boom 💥 your code is now live on GitHub!&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;GitHub UI Tips for Beginners&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;README.md&lt;/strong&gt;: A welcome message for your repo. Make it fun and informative.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commits Tab&lt;/strong&gt;: Shows your code history like a time-travel diary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Branches&lt;/strong&gt;: Parallel universes for your code. We’ll talk more tomorrow!&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Bonus: Learn Git Basics&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here are a few must-know Git commands:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Check what’s going on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stage all changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git commit -m "message"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Save changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Upload changes to GitHub&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fetch latest code&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Today you created a GitHub account, made a repo, and learned how to push your first code. You’re officially dangerous (in a good way).&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s Coming Next?
&lt;/h3&gt;

&lt;p&gt;Tomorrow, we dive into &lt;strong&gt;Branching and Merging&lt;/strong&gt;—aka how not to break stuff while working with others. Stay tuned!&lt;/p&gt;

&lt;p&gt;#GitHub #Git #DeveloperTools #VersionControl #OpenSource #Day2&lt;/p&gt;

</description>
      <category>github</category>
      <category>programming</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>GitHub Bootcamp: Day 1 - What is GitHub?</title>
      <dc:creator>Harsh Pandhe</dc:creator>
      <pubDate>Mon, 19 May 2025 12:45:41 +0000</pubDate>
      <link>https://dev.to/harshpandhe/github-bootcamp-day-1-what-is-github-lg3</link>
      <guid>https://dev.to/harshpandhe/github-bootcamp-day-1-what-is-github-lg3</guid>
      <description>&lt;p&gt;Welcome to &lt;strong&gt;Day 1&lt;/strong&gt; of our 5-day GitHub series! If you've ever heard developers say, "Push it to GitHub" and wondered if they meant a gym workout, you're in the right place.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is GitHub?
&lt;/h2&gt;

&lt;p&gt;GitHub is like social media for code—except instead of selfies and cat memes, you'll find commits, pull requests, and branches. It's a web-based platform built on top of &lt;strong&gt;Git&lt;/strong&gt;, a version control system that helps developers track changes in their code.&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.amazonaws.com%2Fuploads%2Farticles%2Fg9ibtuw408xsdfypyvdb.webp" 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.amazonaws.com%2Fuploads%2Farticles%2Fg9ibtuw408xsdfypyvdb.webp" alt="GitHub" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  TL;DR:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Git&lt;/strong&gt; = A tool to track code changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt; = A cloud platform to store, manage, and collaborate on Git repositories.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If Git is your notebook, GitHub is your bookshelf in the cloud.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Use GitHub?
&lt;/h2&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.amazonaws.com%2Fuploads%2Farticles%2Fcdbx5n4qr6h3ba9e6rgk.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.amazonaws.com%2Fuploads%2Farticles%2Fcdbx5n4qr6h3ba9e6rgk.png" alt="GitHub" width="600" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ✨ Features &amp;amp; Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Version Control&lt;/strong&gt;: Never lose progress. Revert to older versions anytime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration&lt;/strong&gt;: Work on the same project with friends, teammates, or strangers across the globe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Issue Tracking&lt;/strong&gt;: Report bugs or suggest features with Issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pull Requests&lt;/strong&gt;: Review, discuss, and merge changes smoothly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: Use README files and Wikis to explain your code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Pages&lt;/strong&gt;: Host static websites directly from your repo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community and Open Source&lt;/strong&gt;: Find projects, contribute, or get help from fellow devs.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Real-Life Examples
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Solo Developer&lt;/strong&gt;: You’re building a personal portfolio site. GitHub tracks changes and lets you host it using GitHub Pages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Startup Team&lt;/strong&gt;: Your team of 5 is working on a web app. Everyone pushes code to the same repo and uses branches to prevent chaos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open Source Contributor&lt;/strong&gt;: You find a bug in a cool tool. Fork the repo, fix the bug, and submit a pull request!&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  A Quick Glossary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repository (Repo)&lt;/strong&gt;: A project folder tracked by Git.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit&lt;/strong&gt;: A snapshot of your project at a specific time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Branch&lt;/strong&gt;: A parallel version of your project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Merge&lt;/strong&gt;: Bringing branches together.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pull Request (PR)&lt;/strong&gt;: Proposing changes to be added to a repo.&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.amazonaws.com%2Fuploads%2Farticles%2F0g1jb83tfvswfqrf6sic.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.amazonaws.com%2Fuploads%2Farticles%2F0g1jb83tfvswfqrf6sic.png" alt="Github" width="489" height="605"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought for Today
&lt;/h2&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.amazonaws.com%2Fuploads%2Farticles%2Flx61rlu7ia758uxbsywt.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.amazonaws.com%2Fuploads%2Farticles%2Flx61rlu7ia758uxbsywt.png" alt="Github" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub isn’t just for developers—it’s for creators. Writers, designers, data scientists, and more use GitHub to manage versioned work. By learning it, you’re joining a global community of builders and innovators.&lt;/p&gt;




&lt;h3&gt;
  
  
  What’s Next?
&lt;/h3&gt;

&lt;p&gt;Tomorrow, we’ll walk you through &lt;strong&gt;Setting Up GitHub&lt;/strong&gt;, creating your first repository, and mastering Git basics. No worries—we'll keep it fun, hands-on, and beginner-friendly.&lt;/p&gt;

</description>
      <category>github</category>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Day 05: System Administration Like a Pro</title>
      <dc:creator>Harsh Pandhe</dc:creator>
      <pubDate>Thu, 13 Feb 2025 18:30:00 +0000</pubDate>
      <link>https://dev.to/harshpandhe/day-05-system-administration-like-a-pro-29g8</link>
      <guid>https://dev.to/harshpandhe/day-05-system-administration-like-a-pro-29g8</guid>
      <description>&lt;p&gt;Welcome to the final day of our Linux series! Today, we’re stepping into the shoes of a Linux System Administrator. You’ll learn how to manage users, processes, and services like a seasoned pro. Ready to level up? Let’s dive in!&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What is System Administration?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;System administration is all about keeping a Linux system running smoothly. It involves managing users, monitoring processes, configuring services, and ensuring everything works together harmoniously. Think of it as being the conductor of a tech orchestra.&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.amazonaws.com%2Fuploads%2Farticles%2Fnu2w84md07m4j3amdv3x.gif" 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.amazonaws.com%2Fuploads%2Farticles%2Fnu2w84md07m4j3amdv3x.gif" alt=" " width="760" height="380"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Managing Users and Groups&lt;/strong&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;1. Add a New User&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Add a user with the &lt;code&gt;adduser&lt;/code&gt; 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="nb"&gt;sudo &lt;/span&gt;adduser username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the prompts to set up a password and basic user info.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Delete a User&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Remove a user 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;sudo &lt;/span&gt;deluser username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a clean slate, delete their home directory too:&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;sudo &lt;/span&gt;deluser &lt;span class="nt"&gt;--remove-home&lt;/span&gt; username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3. Switch Users&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Switch to another user with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;su - username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;4. Manage Groups&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Add a user to a group:&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;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; groupname username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example: Adding &lt;code&gt;jane&lt;/code&gt; to the &lt;code&gt;sudo&lt;/code&gt; group:&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;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;jane
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Monitoring and Managing Processes&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Processes are the programs running on your system. Here’s how to keep an eye on them:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. View Running Processes&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;top&lt;/code&gt; to see a live list of running processes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;top
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exit with &lt;code&gt;q&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Or, use &lt;code&gt;ps&lt;/code&gt; for a snapshot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps aux
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2. Kill a Process&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Terminate a misbehaving process with its PID (Process ID):&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;kill &lt;/span&gt;PID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it refuses to die, use:&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;kill&lt;/span&gt; &lt;span class="nt"&gt;-9&lt;/span&gt; PID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3. Monitor System Resources&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Check memory and CPU usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;free &lt;span class="nt"&gt;-h&lt;/span&gt;
&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="nb"&gt;uptime&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Managing Services&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Linux services (a.k.a. daemons) are background processes that handle tasks like web servers, databases, and more. Here’s how to manage them:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Start, Stop, and Restart Services&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Control services with &lt;code&gt;systemctl&lt;/code&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="nb"&gt;sudo &lt;/span&gt;systemctl start servicename
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl stop servicename
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart servicename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example: Restarting the Apache web server:&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;sudo &lt;/span&gt;systemctl restart apache2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2. Check Service Status&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;See if a service is running:&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;sudo &lt;/span&gt;systemctl status servicename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3. Enable and Disable Services&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Enable a service to start on boot:&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;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;servicename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Disable 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="nb"&gt;sudo &lt;/span&gt;systemctl disable servicename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Scheduling Tasks with Cron&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Automate repetitive tasks using Cron. Cron jobs are scheduled tasks defined in a special file called the crontab.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Edit the Crontab&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Open the crontab editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;crontab &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2. Add a Cron Job&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Cron jobs follow this format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;minute hour day month day_of_week &lt;span class="nb"&gt;command&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example: Run a backup script every day at 2 AM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;0 2 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /path/to/backup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3. List Cron Jobs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;View your scheduled tasks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;crontab &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Backing Up Your System&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Backups are a sysadmin’s best friend. Here’s a simple way to back up files and directories:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Using rsync&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-av&lt;/span&gt; /source/directory /backup/directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example: Back up your home directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-av&lt;/span&gt; /home/username /mnt/backup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Tips and Best Practices&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keep Your System Updated&lt;/strong&gt;: Use &lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade&lt;/code&gt; (or your distro’s equivalent) regularly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor Logs&lt;/strong&gt;: Check logs for errors and anomalies. System logs are often in &lt;code&gt;/var/log&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limit Root Access&lt;/strong&gt;: Use &lt;code&gt;sudo&lt;/code&gt; instead of logging in as root.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup Regularly&lt;/strong&gt;: Always have a backup plan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document Everything&lt;/strong&gt;: Keep notes on what you configure for future reference.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Resources to Explore&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://linuxjourney.com/" rel="noopener noreferrer"&gt;Linux System Administration Basics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jlevy/the-art-of-command-line" rel="noopener noreferrer"&gt;The Art of Command Line&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linux.die.net/man/" rel="noopener noreferrer"&gt;Linux Man Pages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Congratulations! You’ve completed the 5-day Linux journey. You’ve gone from learning what Linux is to mastering system administration. Whether you’re managing users, processes, or services, you now have the skills to navigate Linux like a pro.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Keep Learning&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This is just the beginning. Linux is a vast and fascinating world. Keep exploring, practicing, and experimenting. The command line is your canvas—go create something amazing.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>beginners</category>
      <category>cli</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
