<?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[My Da Vincis notebook]]></title><description><![CDATA[My Da Vincis notebook]]></description><link>https://wahab-engineering.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6af0fdfa5f7d12325796cfc4/face46fb-a1eb-41f3-9331-1c9f88224337.png</url><title>My Da Vincis notebook</title><link>https://wahab-engineering.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 12 Nov 2026 07:22:20 GMT</lastBuildDate><atom:link href="https://wahab-engineering.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[i thought adding knees will help my walking bot but it backfired due to my own policies]]></title><description><![CDATA[I added knees to an evolving walking bot. Every test failed. Here's how joint limits, reward hacking, and flawed physics exposed my mistakes.]]></description><link>https://wahab-engineering.hashnode.dev/i-thought-adding-knees-will-help-my-walking-bot-but-it-backfired-due-to-my-own-policies</link><guid isPermaLink="true">https://wahab-engineering.hashnode.dev/i-thought-adding-knees-will-help-my-walking-bot-but-it-backfired-due-to-my-own-policies</guid><category><![CDATA[Artificial Intelligence]]></category><category><![CDATA[artificial life]]></category><category><![CDATA[MuJoCo]]></category><category><![CDATA[Python]]></category><category><![CDATA[walkingbot]]></category><category><![CDATA[simulation]]></category><dc:creator><![CDATA[wahab.]]></dc:creator><pubDate>Sun, 08 Nov 2026 23:19:00 GMT</pubDate><content:encoded><![CDATA[<p>so the vision was that a normal walking bot should contain knees because i was hitting my limit - 2000px max to max on whatever i did so took inspiration from the Evolving Virtual Creatures by Karl Sims</p>
<p>and in that paper he talked about how an evolving creature should make graph node system with if else statements and the end result should result in generalizing it just like how humans have done though the history</p>
<img src="https://cdn.hashnode.com/uploads/covers/6af0fdfa5f7d12325796cfc4/be828fdc-17fe-43d7-9e67-f4f3c517a30e.png" alt="" style="display:block;margin:0 auto" />

<p>and this was the inspiration ,Now the main goal was that to make a neural network like this which will help the body perform via a set of command instead of just letting it change all output it should command its individual places and such</p>
<img src="https://cdn.hashnode.com/uploads/covers/6af0fdfa5f7d12325796cfc4/0b8a1687-d59c-42cc-9e7f-ef03158e4d36.png" alt="" style="display:block;margin:0 auto" />

<h2>The Project</h2>
<p>Evolution-1 is a 2D Pymunk quadruped Walking bot. Its brain is an MLP with 16 hidden units, evolved by a genetic algorithm (population 50, 100 generations, 25,000 training episodes per run). Training courses are random slopes up to 5% to 8%, fresh each generation. Every 1,250 episodes, the Genetic algorithms best is kept if it beats the champion basically elitism</p>
<p>The final score comes from 10 held-out test courses with 5-8% slopes, which nobody saw in their training simulation so similar to a black box environment.</p>
<p>I compared two bodies. The kneed leg has the same total length and mass.</p>
<p>so the knee part was again taken inspiration from the paper and also check out - <a href="https://www.karlsims.com/evolved-virtual-creatures.html">https://www.karlsims.com/evolved-virtual-creatures.html</a></p>
<img src="https://cdn.hashnode.com/uploads/covers/6af0fdfa5f7d12325796cfc4/f1142f74-48b0-4419-9c03-d8900944990a.png" alt="" style="display:block;margin:0 auto" />

<table>
<thead>
<tr>
<th></th>
<th>Straight</th>
<th>Knees</th>
</tr>
</thead>
<tbody><tr>
<td>Leg</td>
<td>one 40 px stick, mass 2</td>
<td>20 px thigh + 20 px shin, mass 1 each</td>
</tr>
<tr>
<td>Motors</td>
<td>hip only (max force 150,000)</td>
<td>hip + knee (knee 75,000)</td>
</tr>
<tr>
<td>Inputs / outputs</td>
<td>15 / 4</td>
<td>23 / 8</td>
</tr>
<tr>
<td>Weights</td>
<td>324</td>
<td>520</td>
</tr>
</tbody></table>
<p>The knee motor gets half the hip force, following Sims 1994 3.3 part since strength scales with cross-section basic physics .</p>
<p>now the reward per step is +2 times forward torso movement, and -0.1 for standing still after step 45 (why 45 so that it will build momentum iykyk) . A fall costs -100 ( probably need to make it more ), once. An episode ends on a fall, when the walker is stuck (still for 60+ steps, no -100), or at 600 steps.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6af0fdfa5f7d12325796cfc4/dab8bc39-0e5b-48db-879e-6b63ec1b5651.png" alt="" style="display:block;margin:0 auto" />

<p><strong>Why it matters:</strong> A fall costs 100 and a pixel pays 2, so 50 px of progress buys back a fall, and the dive hypothesis rests on that trade.</p>
<p>The fall rule matters most. A "fall" is any of these: tilt above 1.2 rad, the torso sinking 25 px below ground, or the lowest corner of the torso box reaching ground height. That last check is purely geometric, so a level but low torso counts as a fall. Optional tilt and energy terms were off (default <code>baseline</code> mode).</p>
<img src="https://cdn.hashnode.com/uploads/covers/6af0fdfa5f7d12325796cfc4/346d3351-24ec-4f87-a2a1-0fc6a92ba6ba.png" alt="" style="display:block;margin:0 auto" />

<p>you can see the condition i wrote backfired since they kill the walker</p>
<h2>How I built the knees</h2>
<p>Each leg is a thigh and a shin, two boxes of 20 × 10 px with mass 1, friction 1.2 and collision group 1.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6af0fdfa5f7d12325796cfc4/de32b7c7-4ff8-427e-bb59-2b962e79ed89.png" alt="" style="display:block;margin:0 auto" />

<p>The hip pivots at the torso anchor, with a ±60° limit and motor force 150,000. The knee pivots between the thigh's bottom and the shin's top. Its limit is −90° to 0, so it bends one way, and its Simplemotor gets half the hip force, 75,000. ( why 75k? its i just did it on different and this one worked)</p>
<img src="https://cdn.hashnode.com/uploads/covers/6af0fdfa5f7d12325796cfc4/386de361-39d9-43c9-8a52-bc453703de4f.png" alt="" style="display:block;margin:0 auto" />

<blockquote>
<p>The knee code as it was during the experiment, so you can check my description.</p>
</blockquote>
<p>The brain has 8 outputs, hips first and then knees. The step function scales each output by 10 for a hip and by −10 for a knee. −1 bends the knee, putting the foot forward of it, and +1 straightens it.</p>
<p>and the reason why a following this is because of this particular rule am going off</p>
<img src="https://cdn.hashnode.com/uploads/covers/6af0fdfa5f7d12325796cfc4/b64ae07a-d750-4089-860d-4dd2aa752f7e.png" alt="" style="display:block;margin:0 auto" />

<p>Each knee adds two inputs: the relative angle (shin minus thigh) and the shin's angular velocity times 0.1. Four knees add 8, so 15 inputs become 23. Weights:</p>
<pre><code class="language-plaintext">straight: 16×15 + 16 + 4×16 + 4  = 324
knees:    16×23 + 16 + 8×16 + 8  = 520
</code></pre>
<p>The limit is a soft <code>RotaryLimitJoint</code>. It corrects only after it has been crossed, which is why the motor could push the knee past 90°. That is the <a href="#mm9rd3ptvk6.7618">bug described below</a>.</p>
<p>Knees is an opt-in flag, off by default, so the old creature is unchanged.</p>
<h2>Results</h2>
<p>Before training</p>
<p>I wrote down two predictions knees go further on the test courses knees fall less. I ran 10 seeds per body to test whether they are true and in fact they weren't here are the details from the run</p>
<p>IQM basically means the middle 50% only not top and not bottom and the</p>
<table>
<thead>
<tr>
<th>Test courses</th>
<th>Straight</th>
<th>Knees</th>
</tr>
</thead>
<tbody><tr>
<td>Distance, IQM [95% CI]</td>
<td>394 px [190, 718]</td>
<td>160 px [148, 187]</td>
</tr>
<tr>
<td>Fall rate</td>
<td>17/100 episodes</td>
<td>100/100 episodes</td>
</tr>
</tbody></table>
<p>The 100 episodes per body are 10 seeds times 10 courses. A random kneed seed beats a random straight seed 24% of the time. which is not great due to a policy</p>
<img src="https://cdn.hashnode.com/uploads/covers/6af0fdfa5f7d12325796cfc4/d4dfa99e-b554-40f9-9c9b-ddee732c2a31.png" alt="" style="display:block;margin:0 auto" />

<p>And the kneed champions also fell on every easy course ,Most of them never reached a slope. Every course starts with 200 px of flat ground, and 8 of the 10 kneed champions fell on that flat start, at the same spot (within 1 px) on all 20 courses they were scored on. The gap is large but uncertain: the straight interval runs from 190 to 718 px, and the two-sided p of 0.054 does not clear 0.05.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6af0fdfa5f7d12325796cfc4/2efbb1cd-e609-43f8-86b2-fc547fff3467.png" alt="" style="display:block;margin:0 auto" />

<p>Deviation: My pre-registration said 30 seeds per variant. I ran 10 to save laptop time ,34 core-hours, and the CPU hit 95 °C :( , and I did not record that as a deviation at the time. to properly test whethere they will perform better if given more training or even compute</p>
<img src="https://cdn.hashnode.com/uploads/covers/6af0fdfa5f7d12325796cfc4/5f44f4dc-0e7d-451b-b485-2e557f161e6c.png" alt="" style="display:block;margin:0 auto" />

<blockquote>
<p>x is training episodes and y is champion test distance in px</p>
</blockquote>
<p>So to combat this inefficiency i toke a deep dive into the code and this is what i got</p>
<h2>What I measured, what I found, what I'm guessing</h2>
<p>so why is this not working , in nature those with knees run or even walk ever better then those with straight legs so</p>
<p>I inspected the code and replayed every champion on its held-out courses with the code that ran. Two things came out of it.</p>
<p>First, all 100 kneed test falls had small tilt, between 0.1 and 0.8 rad, under the 1.2 rad limit. These were low torsos, not tip-overs: the geometric check from the experiment section fired every time, never tilt or sinking basically my whole rule shooting me in my knee (hehe)</p>
<p>And the main thing which is breaking my experiment ,in all ten kneed seeds the knees bent to 103-143°, past the 90° limit, and up to 81° the wrong way past straight. The limit is a soft joint that corrects only after it is violated, and the 10 rad/s motor outran it. The ±60° hip limits leaked the same way, in both bodies: up to 90° with straight legs and 150°ish with knees. This was my breaking point or the hole in boat which is the reason we are sinking or whatevers</p>
<p><strong>Hypothesis.</strong> Here is why I think the Genetic algorithms settles on a dive. No experiment has isolated this, so the arithmetic is hypothetical</p>
<p>With +2 per pixel and one -100 fall, a 200 px lunge earns about +400 minus 100, so about +300. The kneed champions' per-seed test means were 138-245 px. That beats an early clumsy walker, so the GA can settle there.</p>
<p>Summary of the whole thing - python kinda sucks and the knees are clipping onto each other and giving it self a lot of reward and rewarding hacking my policys</p>
<h2>Lessons from this case</h2>
<ul>
<li><strong>Test what ends an episode on its own.</strong> A level torso can be "dead" under a geometric rule, and I only saw that after replaying the falls.</li>
<li><strong>Check that limits hold under full motor power.</strong> My 90° knee limit let knees reach 143°, and the hips passed their 60° limit in both bodies.</li>
<li><strong>Trust your gut as well not just numbers</strong></li>
<li><strong>One change can be three.</strong> "Add knees" was a body, four motors and a bigger brain, so I cannot say which mattered.</li>
</ul>
<h2>What's next (Part 2)</h2>
<p>I'm switching over to MuJoCo. It's a Python physics library that handles joint limits and collision penalties way better than what I was using and plus its what people use and can get me that novelty points :D , so it should fix the knee clipping issues and i can test it again although compute time is gonna be big</p>
<h2>Code and data</h2>
<p>Repo: <a href="https://github.com/000wahab000/Evolution">github.com/000wahab000/Evolution</a>. Experiment config: <a href="https://github.com/000wahab000/Evolution/blob/main/experiments/exp3_knees.json"><code>experiments/exp3_knees.json</code></a>. Hypotheses: <a href="https://github.com/000wahab000/Evolution/blob/main/experiments/HYPOTHESES.md"><code>experiments/HYPOTHESES.md</code></a>. Fall and reward code as it ran: <a href="https://github.com/000wahab000/Evolution/blob/76a2da5/src/environment.py"><code>src/environment.py</code> at 76a2da5</a>. Full numbers: <a href="https://github.com/000wahab000/Evolution/blob/main/docs/evolving-virtual-creatures/01-knees/results.md"><code>results.md</code></a>.<br />check this out as well great paper<br /><a href="https://www.karlsims.com/evolved-virtual-creatures.html">https://www.karlsims.com/evolved-virtual-creatures.html</a></p>
]]></content:encoded></item></channel></rss>