<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[NudgeLabs Blog]]></title><description><![CDATA[Charting my path to becoming a Full-stack Robotics Engineer.]]></description><link>https://blog.nudgelabs.net</link><generator>RSS for Node</generator><lastBuildDate>Sun, 19 Apr 2026 09:11:26 GMT</lastBuildDate><atom:link href="https://blog.nudgelabs.net/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[[Paper Review] Robot Operating System 2: Design, Architecture, and Uses In The Wild]]></title><description><![CDATA[Brief Summary
This paper explains the ROS 2 framework, which provides essential components for robotics development environments. It also introduces real-world case studies to demonstrate how ROS 2 ca]]></description><link>https://blog.nudgelabs.net/paper-review-robot-operating-system-2-design-architecture-and-uses-in-the-wild</link><guid isPermaLink="true">https://blog.nudgelabs.net/paper-review-robot-operating-system-2-design-architecture-and-uses-in-the-wild</guid><category><![CDATA[ros2]]></category><category><![CDATA[robotics]]></category><category><![CDATA[Paper Review]]></category><category><![CDATA[robot-operating-system]]></category><category><![CDATA[DDS ]]></category><category><![CDATA[Ubuntu]]></category><dc:creator><![CDATA[Milo]]></dc:creator><pubDate>Sun, 08 Mar 2026 13:24:56 GMT</pubDate><content:encoded><![CDATA[<h3>Brief Summary</h3>
<p>This paper explains the ROS 2 framework, which provides essential components for robotics development environments. It also introduces real-world case studies to demonstrate how ROS 2 can be utilized and what makes it so useful.</p>
<h3>Motivation</h3>
<p>It is almost impossible to discuss modern robotics development without mentioning ROS 2. As an open-source platform, it has a dominant market share compared to other robot operating systems. This is why I wanted to learn deeply about ROS 2. I firmly believe that properly mastering one foundational robot OS will help me easily adapt to other development environments, and even build a strong foundation if I ever design a new robot OS in the future.</p>
<h3>Key Takeaways</h3>
<p>This paper offers a comprehensive breakdown of ROS 2. First, it introduces the background of ROS 2 and highlights the key differences and improvements over ROS 1. Then, it dives into specific topics: scope, design principles, design requirements, communication patterns, middleware architecture, software quality, performance, reliability, and security. Notably, the paper provides benchmarking test data in the performance section, offering a clear visual representation of its capabilities. Finally, it presents real-world use cases, showing ROS 2 as an enabler, an equalizer, and an accelerator in the robotics industry.</p>
<h3>Personal Insights</h3>
<p>From a current perspective, ROS 2 is undoubtedly an excellent framework. However, if I had to point out one downside, it would be its practical reliance on Ubuntu. It is not that you cannot develop on Windows or macOS, but the limitations are quite clear. This practical limitation feels a bit disappointing.</p>
<h3><strong>Reference</strong></h3>
<ul>
<li><a href="https://arxiv.org/abs/2211.07752">Robot Operating System 2: Design, Architecture, and Uses In The Wild</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Implementation of a Pick-and-Place Task with a 6-Axis Robot]]></title><description><![CDATA[Related Post:

Exploring Robotic Dynamics with MuJoCo: 2-DOF Modeling

Exploring Robotic Dynamics with MuJoCo: Calculating 3-DOF coordinates


In this post, I will demonstrate a simple pick-and-place ]]></description><link>https://blog.nudgelabs.net/implementation-of-a-pick-and-place-task-with-a-6-axis-robot</link><guid isPermaLink="true">https://blog.nudgelabs.net/implementation-of-a-pick-and-place-task-with-a-6-axis-robot</guid><category><![CDATA[MuJoCo]]></category><category><![CDATA[C++]]></category><category><![CDATA[dynamics]]></category><category><![CDATA[robotics]]></category><category><![CDATA[kinematics]]></category><dc:creator><![CDATA[Milo]]></dc:creator><pubDate>Sun, 01 Mar 2026 10:31:23 GMT</pubDate><content:encoded><![CDATA[<p><strong>Related Post:</strong></p>
<ul>
<li><p><a href="https://blog.nudgelabs.net/exploring-robotic-dynamics-with-mujoco-2-dof-modeling">Exploring Robotic Dynamics with MuJoCo: 2-DOF Modeling</a></p>
</li>
<li><p><a href="https://blog.nudgelabs.net/exploring-robotic-dynamics-with-mujoco-calculating-3-dof-coordinates">Exploring Robotic Dynamics with MuJoCo: Calculating 3-DOF coordinates</a></p>
</li>
</ul>
<p>In this post, I will demonstrate a simple pick-and-place operation using a UR5e robotic arm. The sequence follows a standard workflow: starting from the home position, moving to the red box, grasping it, transferring it to the target location, and finally releasing it.</p>
<p>Since the UR5e features the updated offset wrist design (unlike older models), I performed some calibration for accuracy. However, please note that there is still a slight margin of error in the final movements.</p>
<p>This image below</p>
<img src="https://cdn.hashnode.com/uploads/covers/697a014233686646a792dd2d/29e91d13-8e78-4016-9482-1d898f311bf5.png" alt="" style="display:block;margin:0 auto" />

<p>The image above shows the robot's home position. First, we calculate \(\theta_1\) using the base and target coordinates. During this step, a calibration is applied based on Link 5, which serves as the virtual wrist center. Then, \(\theta_2\) and \(\theta_3\) are derived using the Law of Cosines, with a slight compensation applied to the height value.</p>
<p>After moving to the calculated position and grasping the box, the next coordinates are re-calculated using the same method for the transfer and release. Throughout the process, the state of each step is recorded, and subsequent commands are executed based on the displacement and the gripping force.</p>
<p>Below is an animation demonstrating the full pick-and-place workflow.</p>
<img src="https://cdn.hashnode.com/uploads/covers/697a014233686646a792dd2d/a36a6342-2e88-4652-b6ed-d8b1ce580998.gif" alt="" style="display:block;margin:0 auto" />

<h3>Post-Implementation Review</h3>
<p>Since the UR5e doesn't have the traditional wrist design, I had to spend quite a bit of time studying and applying various calibrations. While the results weren't perfectly precise, it was a deeply rewarding experience because I learned so much by tackling the challenges head-on.</p>
<p>You can find the complete simulation source code <a href="https://github.com/RustSynx/robot-simulation/tree/main/example/pick_and_place"><strong>here</strong></a>.</p>
]]></content:encoded></item><item><title><![CDATA[Exploring Robotic Dynamics with MuJoCo: Calculating 3-DOF coordinates]]></title><description><![CDATA[Related Post:

Exploring Robotic Dynamics with MuJoCo: 2-DOF Modeling

In this session, to handle a 6-DOF robot, we will first learn about calculating 3-DOF coordinates. This practice will help us und]]></description><link>https://blog.nudgelabs.net/exploring-robotic-dynamics-with-mujoco-calculating-3-dof-coordinates</link><guid isPermaLink="true">https://blog.nudgelabs.net/exploring-robotic-dynamics-with-mujoco-calculating-3-dof-coordinates</guid><category><![CDATA[C++]]></category><category><![CDATA[MuJoCo]]></category><category><![CDATA[dynamics]]></category><category><![CDATA[robotics]]></category><category><![CDATA[kinematics]]></category><dc:creator><![CDATA[Milo]]></dc:creator><pubDate>Sun, 22 Feb 2026 13:08:08 GMT</pubDate><content:encoded><![CDATA[<p><strong>Related Post:</strong></p>
<ul>
<li><a href="https://blog.nudgelabs.net/exploring-robotic-dynamics-with-mujoco-2-dof-modeling">Exploring Robotic Dynamics with MuJoCo: 2-DOF Modeling</a></li>
</ul>
<p>In this session, to handle a 6-DOF robot, we will first learn about calculating 3-DOF coordinates. This practice will help us understand how to move the robot. We will fix 3 axes and manipulate the other 3, because starting with full 6-DOF control might be difficult to understand.</p>
<p>This image below shows robot's initial position. We will keep axes 4, 5, and 6 fixed at 0 degrees, and use axes 1, 2, and 3 to move the robot arm toward the target, the red ball.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/697a014233686646a792dd2d/f88f2acd-383f-4aee-8f63-39c28e34b7ae.png" alt="" style="display:block;margin:0 auto" />

<p>First, looking at the robotic arm and the target point from a top-down view, we will calculate how much the arm needs to rotate to face the target. Second, just as we did with the 2-axis robot, we will calculate the angles for axes 2 and 3 using the law of cosines. Below is the source code for the calculation process based on the UR5e.</p>
<pre><code class="language-cpp">JointAngles InverseKinematics::solve_ik_3dof(double x, double y, double z) {
  // First link length
  const double L1 = 0.425;
  // Second link length
  const double L2 = 0.392;
  joint_angles.theta1 = std::atan2(y, x);

  // The horizontal distance from the base link to the target.
  double r = std::sqrt(x*x + y*y);
  // The vertical distance from the base link to the target, adjusting for the base link's height.
  double r_v = z - 0.163;
  // The distance from the base link to the target.
  double d = std::sqrt(r*r + r_v*r_v);
  double cos_ratio = (d*d - L1*L1 - L2*L2) / (2*L1*L2);

  if (cos_ratio &gt; 1.0) cos_ratio = 1.0;
  if (cos_ratio &lt; -1.0) cos_ratio = -1.0;

  joint_angles.theta3 = std::acos(cos_ratio);

  // The angle between L1 and the line from the base link to the target.
  double inner_angle_1 = std::acos((L2*L2 - d*d - L1*L1) / (2*L1*d));
  // The angle of elevation to the target.
  double inner_angle_2 = std::atan2(z-0.163, r);
  joint_angles.theta2 = inner_angle_1 + inner_angle_2;
  return joint_angles;
}
</code></pre>
<p>Next, here is the simulation result.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/697a014233686646a792dd2d/ec419a7b-8e81-44c8-b7f4-968125b7f55b.gif" alt="" style="display:block;margin:0 auto" />

<h3>Summary</h3>
<p>Before diving into the full robotic arm control, I ran into a simple simulation using only three degrees of freedom (3-DOF). You can find the complete simulation source code <a href="https://github.com/RustSynx/robot-simulation/tree/main/example/3dof_control">here</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Exploring Robotic Dynamics with MuJoCo: 2-DOF Modeling]]></title><description><![CDATA[In this post, we’re going to dive into a simple simulation of a 2-DOF robot using MuJoCo.
Before we get into complex robot manipulation, it’s essential to understand the fundamentals of how to get a robot to a desired location. We will focus on a str...]]></description><link>https://blog.nudgelabs.net/exploring-robotic-dynamics-with-mujoco-2-dof-modeling</link><guid isPermaLink="true">https://blog.nudgelabs.net/exploring-robotic-dynamics-with-mujoco-2-dof-modeling</guid><category><![CDATA[MuJoCo]]></category><category><![CDATA[C++]]></category><category><![CDATA[robotics]]></category><category><![CDATA[dynamics]]></category><category><![CDATA[kinematics]]></category><dc:creator><![CDATA[Milo]]></dc:creator><pubDate>Sun, 15 Feb 2026 15:17:16 GMT</pubDate><content:encoded><![CDATA[<p>In this post, we’re going to dive into a simple simulation of a 2-DOF robot using MuJoCo.</p>
<p>Before we get into complex robot manipulation, it’s essential to understand the fundamentals of how to get a robot to a desired location. We will focus on a straightforward simulation: moving the robotic arm from its current state to a specific target coordinate.</p>
<p>If we know the target coordinates and the robot’s current position, we can calculate exactly how the arm needs to move to reach that point. This method is called Inverse Kinematics (IK).</p>
<p>Conversely, if we already know the specific angles for each joint and want to calculate where the robot’s end-effector will end up, that process is called Forward Kinematics (FK).</p>
<p>In this first scenario, we will explore how to use Inverse Kinematics to calculate the required joint angles within a 2D XY coordinate system. Fortunately, in this planar setup, we can determine the angle for each joint simply by applying the Law of Cosines.</p>
<p>First, let’s establish our known variables: the robot’s base position, the link lengths, and the target coordinates.</p>
<p>For this simulation, we will define the robot’s base at the origin (0,0) and set the length of each link (joint) to 20cm. The target destination is set to x = 10cm and y = 30cm.</p>
<ol>
<li>Calculate the distance to the target (\(r\))</li>
</ol>
<p>$$r^2 = x^2+y^2$$</p><p> $$ r^2=10^2+30^2=100+900=1000$$</p>
<ol start="2">
<li>Solve for Joint 2 (\(\theta_2\)) using the Law of Cosines</li>
</ol>
<p>$$r^2 = L_1^2 + L_2^2 - 2L_1L_2\cos(180^\circ - \theta_2)$$</p><p>$$1000 = 20^2 + 20^2 - 2(20)(20)\cos(\pi - \theta_2)$$</p><p>$$1000 = 400 + 400 - 800\cos(\pi - \theta_2)$$</p><p>$$200 = -800\cos(\pi - \theta_2)$$</p><p>$$\cos(\pi - \theta_2)=-cos(\theta_2) = -0.25$$</p><p>$$\theta_2 = \arccos(0.25) \approx \mathbf{1.318 \text{ rad}}$$</p><ol start="3">
<li>Solve for Joint 1 (\(\theta_1\))</li>
</ol>
<p>$$\phi = \arctan(\frac{30}{10}) \approx 1.249 \text{ rad}$$</p><p>Although we could calculate this angle using arccos(x/r), the cosine function cannot differentiate between “up” (+y) and “down” (-y). It would return the same positive angle for both (10,30) and (10,-30). By using arctan, we preserve the sign information, allowing the robot to navigate the full \(360^\circ\) range.</p>
<p>$$\alpha = \frac{\theta_2}{2} \approx 0.659 \text{ rad}$$</p><p>$$\theta_1 = \phi - \alpha$$</p><p>$$ \theta_1 = 1.249 - 0.659 \approx \mathbf{0.590 \text{ rad}}$$</p><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771166634530/c3e00147-f0f2-4439-8ace-29bc01074c30.png" alt class="image--center mx-auto" /></p>
<p>The figure above visualizes the calculation process to aid your understanding.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771167720515/b45afc4c-25da-4658-a26c-45797391ab72.gif" alt class="image--center mx-auto" /></p>
<p>The video above shows a simple simulation of the scenario using MuJoCo. In this demo, I simply hardcoded the calculated values. You can press the Spacebar to start the simulation.</p>
<h2 id="heading-summary"><strong>Summary</strong></h2>
<p>In this post, we explored the basics of Inverse Kinematics and calculation methods using a simple 2-DOF robot, followed by a simulation in MuJoCo.</p>
<p><a target="_blank" href="https://gist.github.com/RustSynx/90b80f6f03141728bf093250a0276d14"><strong>The full code is available here.</strong></a></p>
]]></content:encoded></item><item><title><![CDATA[Elasticity & Safety: From Hooke’s Law to Smart Design]]></title><description><![CDATA[What would happen if we couldn't predict how much weight a bridge could support? We would either be unable to build it at all or, worse, it could collapse under heavy traffic. To prevent such disasters, we must be able to quantify and predict how mat...]]></description><link>https://blog.nudgelabs.net/elasticity-and-safety-from-hookes-law-to-smart-design</link><guid isPermaLink="true">https://blog.nudgelabs.net/elasticity-and-safety-from-hookes-law-to-smart-design</guid><category><![CDATA[engineering]]></category><category><![CDATA[Materials Science]]></category><category><![CDATA[learning]]></category><category><![CDATA[mechanics]]></category><category><![CDATA[Matlab]]></category><dc:creator><![CDATA[Milo]]></dc:creator><pubDate>Sun, 08 Feb 2026 02:06:19 GMT</pubDate><content:encoded><![CDATA[<p>What would happen if we couldn't predict how much weight a bridge could support? We would either be unable to build it at all or, worse, it could collapse under heavy traffic. To prevent such disasters, we must be able to quantify and predict how materials react to external forces. This process is mathematically formulated through <strong>Hooke’s Law</strong>.</p>
<h3 id="heading-modeling-normal-stress-axial-loading"><strong>Modeling Normal Stress (Axial Loading)</strong></h3>
<p>Normal stress occurs when a force acts perpendicular to a material's cross-section, causing it to stretch or compress.</p>
<p>$$\sigma = E\epsilon$$</p><ul>
<li><p>\(\sigma\) (Normal Stress): The intensity of internal force per unit area.</p>
</li>
<li><p>\(E\) (Young’s Modulus): A fundamental material property representing its resistance to elastic deformation.</p>
</li>
<li><p>\(\epsilon\) (Normal Strain): The ratio of deformation relative to the original length.</p>
</li>
</ul>
<h3 id="heading-modeling-shear-stress-torsional-loading">Modeling Shear Stress (Torsional Loading)</h3>
<p>While normal stress involves stretching, shear stress involves sliding or twisting forces acting parallel to the surface.</p>
<p>$$\tau = G\gamma$$</p><ul>
<li><p>\(\tau\) <strong>(Shear Stress):</strong> The force per unit area acting parallel to the surface.</p>
</li>
<li><p>\(G\) <strong>(Shear Modulus):</strong> The material's resistance to shape change, also known as rigidity.</p>
</li>
<li><p>\(\gamma\) <strong>(Shear Strain):</strong> A measure of the angular deformation (how much the object has been tilted or twisted).</p>
</li>
</ul>
<h2 id="heading-poissons-ratio-nu">Poisson's Ratio (\(\nu\))</h2>
<p>Next is <strong>Poisson's ratio</strong>(\(\nu\)). It serves as a fundamental <strong>measure of volumetric change</strong> and is a key parameter in determining a material's <strong>stiffness</strong>. The following formulas define the strain ratios <strong>under tensile loading</strong>, where the material is elongated along its axis:</p>
<h3 id="heading-sectional-strain-epsilonarea">Sectional Strain (\(\epsilon_{area}\))</h3>
<p>This represents the ratio of the change in cross-sectional area to the original area.</p>
<p>ϵarea=ΔAA≈−2νϵ (where ϵ&gt;0 denotes the axial tensile strain)</p>
<h3 id="heading-volumetric-strain-epsilonv">Volumetric Strain (\(\epsilon_v\))</h3>
<p>This is the ratio of the change in volume to the original volume. A Poisson's ratio of <strong>0.5</strong> implies that the material is <strong>incompressible</strong>, resulting in zero volumetric strain.</p>
<p>$$\epsilon_v = \frac{\Delta V}{V} = \epsilon (1 - 2\nu)$$</p><h4 id="heading-shear-modulus-g"><strong>Shear Modulus (</strong>\(G\)<strong>)</strong></h4>
<p>The Shear Modulus relates the shear stress to the shear strain.</p>
<p>$$G = \frac{E}{2(1+\nu)}$$</p><h4 id="heading-bulk-modulus-k"><strong>Bulk Modulus (</strong>\(K\)<strong>)</strong></h4>
<p>The Bulk Modulus measures a substance's resistance to uniform compression.</p>
<p>$$K = \frac{E}{3(1-2\nu)}$$</p><p>The graph below illustrates the variation of G and K with respect to Poisson’s ratio using MATLAB.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770513694679/953753a6-a280-40fa-a88f-723308fea88f.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-summary">Summary</h2>
<p>In this post, we explored Hooke’s Law and Poisson’s ratio, specifically focusing on how \(G\) and \(K\) each relate to Poisson’s ratio.</p>
<p><a target="_blank" href="https://gist.github.com/RustSynx/133034b9b86aefc9646fff1ee61500cd">The full code is available here.</a></p>
]]></content:encoded></item><item><title><![CDATA[Why Do Materials Deform? Visualizing Stress and Strain with MATLAB]]></title><description><![CDATA[When designing bridges or mechanical components, how can we ensure they won’t deform or fail? To answer this, we must first understand the forces at play. Let’s dive into the types of loads first.
Loads are primarily classified into static loads and ...]]></description><link>https://blog.nudgelabs.net/visualizing-stress-strain-matlab</link><guid isPermaLink="true">https://blog.nudgelabs.net/visualizing-stress-strain-matlab</guid><category><![CDATA[Matlab]]></category><category><![CDATA[Materials Science]]></category><category><![CDATA[learning]]></category><category><![CDATA[engineering]]></category><category><![CDATA[mechanics]]></category><dc:creator><![CDATA[Milo]]></dc:creator><pubDate>Sun, 01 Feb 2026 12:44:30 GMT</pubDate><content:encoded><![CDATA[<p>When designing bridges or mechanical components, how can we ensure they won’t deform or fail? To answer this, we must first understand the forces at play. Let’s dive into the types of loads first.</p>
<p>Loads are primarily classified into <strong>static loads</strong> and <strong>dynamic loads</strong>. First, <strong>static loads</strong> are forces applied slowly that remain constant over time.</p>
<ul>
<li><p><strong>Normal Load</strong>: A force acting perpendicular to a surface, such as a book resting on a table.</p>
</li>
<li><p><strong>Shear Load</strong>: A force causing layers of a material to slide past one another, like the action of scissors.</p>
</li>
</ul>
<p>In contrast, <strong>dynamic loads</strong> are forces that vary with time.</p>
<ul>
<li><p><strong>Repeated Load</strong>: A load applied repeatedly in a single direction, typically varying in magnitude.</p>
</li>
<li><p><strong>Alternating Load</strong>: A load that cycles between opposite directions.</p>
</li>
<li><p><strong>Impact Load</strong>: A sudden, high-force load applied over a very short period.</p>
</li>
</ul>
<p>Now, let’s look at Stress and Strain. <strong>Stress</strong> is defined as the force acting per unit area. Essentially, it represents the intensity of the internal force distributed within the material. <strong>Strain</strong> describes the deformation resulting from that stress. It is defined as the ratio of the change in dimension to the original dimension.</p>
<p>The graph below shows a stress-strain diagram generated from a MATLAB simulation of a mild steel tensile test. <strong>Note that</strong> the data has been slightly modified for educational purposes to make it easier to understand.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1769931112289/4b44f5da-ee32-4b88-bbd0-00cdd23f613a.gif" alt="Stress-Strain Curve Simulation" class="image--center mx-auto" /></p>
<ul>
<li><p><strong>Elastic Region</strong>: The initial phase up to the Upper Yield Point. This point is the peak stress before the transition to plastic deformation.</p>
</li>
<li><p><strong>Yield Drop &amp; Plateau Region</strong>: After the stress drops to the Lower Yield Point, the Yield Plateau Region begins. Here, strain increases significantly with constant or fluctuating stress.</p>
</li>
<li><p><strong>Strain Hardening Region</strong>: Stress begins to rise again until it reaches the peak, known as the Ultimate Tensile Strength (UTS).</p>
</li>
<li><p><strong>Necking Region &amp; Fracture</strong>: Beyond the UTS, the material enters the Necking Region, where it deforms under less force until final fracture occurs.</p>
</li>
</ul>
<h2 id="heading-summary">Summary</h2>
<p>In conclusion, materials deform because the internal stress caused by external loads exceeds the material's limits. This is why plotting the stress-strain curve is so important—it allows us to make more informed decisions when selecting materials for our structural designs.</p>
<p><a target="_blank" href="https://gist.github.com/RustSynx/51dbf9489eccb4042a70f5564c263cae">The full code is available here.</a></p>
]]></content:encoded></item></channel></rss>