[forum知見] Thyme で物理機構を構築・制御
- Algodoo Forum http://www.algodoo.com/forum/ の会話ログから、codex (GPT-5.6 Sol) に抜粋させた
- 単なるシーン紹介やコンテスト投稿は除外し、API の使い方、動作確認、失敗例、開発者回答を優先した。
- 確度は次の意味で付けた。
- 確認済み: 開発者回答、複数投稿での照合、または質問者による動作確認がある。
- 有力: 実働コードまたは熟練ユーザーの説明があるが、バージョン横断の確認が弱い。
- 要検証: 古い版限定、既知バグ、提案段階、または投稿間で矛盾する。
まず押さえるべき結論
- 車輪や可動リンクは、形を重ねるだけでは接続されない。
Scene.addHingeに実在する 2 つのgeomIDと接続位置を渡す必要がある。 - ジョイントには
geom0pos/geom1posまたはposを必ず指定する。ID だけのヒンジは古い版でクラッシュ原因にもなった。 glued := true単独は生成時に効かなかった例がある。背景固定の確実な旧来手法はbody := 0、または背景とのScene.addFixjoint。entityID、geomID、bodyを保存済みオブジェクトから丸ごとコピーして生成コードに残すと、誤結合・接着・Bad body not in sceneの原因になる。生成テンプレートは必要な属性だけに絞る。materialVelocityは物体そのものの速度ではなく、接触面の搬送速度である。接触と摩擦がなければ駆動しない。- 高速車輪の震えは、真円を使う、ヒンジを
legacyMode := 0にする、密度やsim.frequencyを上げる、という順で切り分ける。
1. geometry / body / entity の識別と生成
1.1 最小限の属性だけで生成する
Scene.addCircle、Scene.addBox、Scene.addPolygon の {} 内に必要な属性だけを書く。省略した属性にはシーン既定値が入る。生成時の代入には := を使う。イベント内で = を使うと、生成元オブジェクトの属性を変更してしまうことがある。
wheel := Scene.addCircle({
pos := [-1.5, 0.5];
radius := 0.45;
density := 2.0;
friction := 1.0;
restitution := 0.0;
collideSet := 1
})
- 根拠: topic 11146, post 80566 は主要属性と
:=/=の違いを説明。 - 照合: topic 9966, posts 68471/68483 はコピーした
entityIDやbodyが「勝手に接着する」原因になり得るため、不要属性を除くよう勧告。 - 確度: 確認済み
- バージョン注意: 2.1.0 のシリアライズ出力には多数の読み取り専用・派生属性が含まれる。保存データ全体を生成テンプレートとして再利用しない。
1.2 body は「接着・固定で一体化した剛体グループ」
フォーラムの変数表では body は「この geometry が属する、互いに固定された物体グループの ID」。geomID は geometry の ID、entityID は hinge や tracer を含む entity の ID と整理されている。
// 背景ボディに所属させる旧来の固定方法
Scene.addBox({pos := [0, -1]; size := [8, 0.5]; body := 0})
- 根拠: topic 83, post 1038 の属性定義。
- 罠: topic 10452, post 71259 ではコピーされた
body/ ID を持つ生成物からBad body not in sceneが出ている。 - 確度: 確認済み
- バージョン注意:
bodyの数値は永続的なユーザー ID とみなさない。生成物を既存 body に結合する用途は特に 2.1 の既知問題がある。
1.3 Scene.add* の戻り値を保持して操作できる
Scene.addCircle 等は生成 entity を返し、その参照を変数に保持して属性を変更できる。
o := Scene.addCircle({pos := [0, 2]; radius := 0.2});
o.vel = [5, 0];
o.color = [1, 0, 0, 1]
- 根拠: topic 1714, post 18686 は
(scene.addBox({})).density = 2の戻り値操作を説明。 - 照合: topic 9033, post 66290 は
scene.my.box = scene.addBox({...})とイベント参照e.this/e.other/e.geomを推奨。 - 確度: 有力
- バージョン注意: topic 3285 では動的 entity の参照を
Scene.myに保存すると save/load 後に壊れるという旧版バグが報告されている。長期参照は再取得または再初期化する。
1.4 ID は save/load や undo 後に変わり得る
ハードコードした geomID / entityID をシーン再読込後も不変と仮定しない。
// entity 側の onSpawn などで、その実行時の ID を保存する案
onSpawn := (e) => { Scene.my.wheelGeom = (readable(e.this)).geomID }
- 根拠: topic 10224, posts 69742-69787 は
geomIDとentityIDが再読込で変化することを実測。 - 照合: topic 2279, post 29035 は undo 後の ID 変化で動的チェーン生成が壊れると報告。
- 確度: 確認済み
- 矛盾: 2009-2015 年の多数の例は
geomID := 1のような指定 ID を利用する一方、topic 11146, post 85891 は 2.1 系で任意 ID の強制はできないと指摘。現在ランタイムでの実測が必要。
2. hinge / axle / motor
2.1 ヒンジ生成の最小要件
ヒンジ(UI 上の axle)は 2 つの geometry、または geometry と背景を接続する。geom0、geom1 と接続位置が必要。
Scene.addHinge({
geom0 := chassisGeom;
geom1 := wheelGeom;
geom0pos := [-1.5, -0.5]; // chassis のローカル座標
geom1pos := [0, 0]; // wheel のローカル座標
size := 0.12;
legacyMode := 0
})
- 根拠: topic 83, post 3400 は 2 geometry と背景接続の両方を例示。
- 照合: topic 12132, posts 86258/86403 は
posとsizeだけでは不足し、4 つの geom/pos 属性が必要だったと解決報告。 - 座標の根拠: topic 795, post 45569 は
geom0pos := [0,0]がその geometry の重心であり、ローカル接続位置だと説明。 - 確度: 確認済み
- バージョン注意: 古い形式では
world0posまたはposでも設置できる。現行生成でどの形式を採るかはランタイムで統一して検証する。
2.2 接続位置を省略しない
Scene.addBox({geomID := 1755});
Scene.addHinge({geom0 := 1755; geom1 := 0; pos := [0, 0]})
- 根拠: 開発者 emilk の topic 2279, post 29018 は
geom0pos/geom1posまたはposを必ず指定すべきで、省略は旧版でクラッシュにつながり得たと説明。 - 確度: 確認済み
- バージョン注意: 上の
geomID := 1755は 1.7.4 の再現例であり、2.1 で任意 ID 指定が保証されるという意味ではない。
2.3 背景は geometry ID 0
Scene.addHinge({
geom0 := wheelGeom;
geom1 := 0;
geom0pos := [0, 0];
geom1pos := [3, 2]
})
- 根拠: topic 83, post 3400 の「one hinged object」。
- 照合: topic 10551, post 72228 は axle が 2 geometry または geometry と背景を結ぶと説明。
- 確度: 確認済み
- 注意:
geom0 = 0とgeom1 = 0の両方を指定した無効ヒンジは保存時に消される。
2.4 モーター化と単位
Scene.addHinge({
geom0 := chassisGeom;
geom1 := wheelGeom;
geom0pos := [-1.5, -0.5];
geom1pos := [0, 0];
motor := true;
motorSpeed := 10.0; // rad/s
motorTorque := 200.0; // 新しい版では Nm
autoBrake := true
})
- 速度: topic 795, posts 42005/42015 は
motorSpeedが RPM ではなく rad/s だと照合。 - 旧仕様: 開発者 emilk の topic 1572, posts 31384/31440 は旧
motor strengthが rad/s² で、実トルクは「2 body の合成慣性 × strength」だったと説明。 - 新仕様: topic 2649, post 31816 は 1.7.5 から
motorTorqueが真の Nm になり、旧版は同名フィールドを rad/s² と解釈すると説明。 - 確度: 確認済み
- バージョン注意: 1.7.5 以降で保存したシーンを 1.7.4 以前で開くとトルクが誤解釈される。現行 2.1 を対象にするなら Nm として扱い、旧シーンの移植時だけ変換を疑う。
2.5 モーター属性の動的制御
ヒンジの motorTorque や motorSpeed に {Scene.my.*} の動的式を設定し、イベント側で値を更新する方法が使われていた。
// console/init
Scene.my.driveTorque = 100.0;
// hinge property
motorTorque := {Scene.my.driveTorque}
// event
Scene.my.driveTorque = 500.0
- 根拠: topic 3689, posts 41887/41941 は変数を宣言して hinge の
motorTorqueに動的式を入れる手順を説明。 - 確度: 有力
- バージョン注意: topic 2625, posts 31612/31861 では 1.7.5 に
{Scene.my.torque}を含む Thyme 生成ヒンジの不具合があり、修正予定と回答。現行で再現しなければ歴史的注意でよい。
2.6 servo / bend のトルク関係
bendConstant == 0 ならトルクは motorTorque。非ゼロなら、おおむね「目標角との差 × bendConstant」を motorTorque で上限クリップする弾性サーボとして働く。
// 概念式
torque = clamp(bendConstant * angleDelta, -motorTorque, motorTorque)
- 根拠: topic 10163, posts 69165/69198 の実験結果と説明。
- 確度: 有力
- バージョン注意: 正式仕様式ではなくユーザーのリバースエンジニアリング。符号、dead-zone、solver 依存は要実測。
2.7 既存 geometry にイベント中から joint を追加する問題
Scene.addHinge({
geom0 := (readable(e.other)).geomID;
geom1 := (readable(e.this)).geomID;
geom0pos := [0, 0];
geom1pos := [0, 0]
})
- 根拠: topic 9597, posts 67508-82878 では上記が
Couldn't find geomになり、2016 年にも未修正との回答。 - 照合: topic 11894, posts 85767/85768 は Algodoo 2.1 で既存 geometry への接続・glue が壊れており、稀に fixate が動いても undo で壊れると報告。
- 確度: 要検証
- 矛盾: 1.7.x の開発者例と新規生成直後の joint は動く一方、2.1 のイベント経由・既存物接続で失敗報告がある。MCP では「形状生成 → 実 ID 取得 → 同一スクリプト/直後に joint 生成」をまず実測し、後付け接続を別テストにする。
3. fixate / glued / static
3.1 2 geometry を fixate する
Scene.addFixjoint({
geom0 := geomA;
geom1 := geomB;
world0pos := [0, 0]
})
- 根拠: topic 795, post 8014 は hinge と同じ要領で
geom0/geom1/world0posを指定する例を掲載。 - 属性一覧: topic 83, post 1038 は
Scene.addFixjointの geom/world position 属性を列挙。 - 確度: 確認済み
- バージョン注意: 表記は
addFixjointとaddFixJointが混在する。Thyme は例で大文字小文字が混用されているが、生成コードではScene.addFixjointに統一する。
3.2 背景固定は body := 0 が簡単
Scene.addCircle({pos := [0, 1]; radius := 0.2; body := 0})
- 根拠: topic 1010, posts 9951-9995 で
glued := true単独は生成時に効かず、body := 0は実際に背景へ glue されたと確認。 - 照合: topic 1768, post 19193 も同じ生成例を掲載。
- 確度: 確認済み
- バージョン注意: 現在の保存データは
body := 0; glued := trueの組を持つことがある。明示したい場合は両方を設定するが、glued単独には頼らない。
3.3 density := +inf は「固定に近い代用」で、glue と同じではない
e.this.density = +inf
- 根拠: topic 2856, posts 33679-34876 で動作確認される一方、最終的に通常の背景 glue は
body := 0; glued := trueと区別。 - 確度: 確認済み
- 罠: 無限密度は solver、慣性、接触計算に副作用がある。背景固定の意味が必要なら
body := 0または fixjoint を使う。
3.4 static := true は確認できない
抽出コーパスの geometry 属性一覧と実働例に static フィールドは見つからなかった。Algodoo の静的物体を他エンジン風に static := true で生成できるとは仮定しない。
// 推奨
body := 0;
glued := true
- 根拠:
body/gluedの複数スレッドと topic 83 の属性表。 - 確度: 有力
- バージョン注意: MCP 側で独自に
staticを変換する場合は別だが、Thyme の生属性としては要検証。
4. spring
4.1 旧来の直接生成
2 geometry の ID、両端の位置、必要なら length、constant、dampingFactor を指定する。
Scene.addSpring({
geom0 := geomA;
geom1 := geomB;
world0pos := [0, 2];
world1pos := [2, 2];
length := 1.5;
constant := 100.0;
dampingFactor := 0.2
})
- 根拠: topic 795, post 8014 の生成例と属性説明。
- 照合: topic 83, post 3400 は背景接続と 2 geometry 接続の要件を説明。
- 確度: 確認済み(旧 API)
- バージョン注意:
geom0pos/geom1posとworld0pos/world1posの意味・対応は版により混乱がある。生成後に端点位置を目視検証する。
4.2 1.9 以降の LineEndPoint 形式
新しい保存形式では spring 本体と 2 つの LineEndPoint が別 entity になり、spring が endpoint の entity ID を参照する。
ep0 := Scene.addLineEndPoint({geom := geomA; relPoint := [0, 0]});
ep1 := Scene.addLineEndPoint({geom := geomB; relPoint := [0, 0]});
Scene.addSpring({
lineEndPoint0 := (readable(ep0)).entityID;
lineEndPoint1 := (readable(ep1)).entityID;
length := 1.0;
constant := 100.0;
dampingFactor := 0.2;
legacyMode := 3
})
- 根拠: topic 4036, post 46053 は 1.9.4 spring が spring + 2 endpoint になったと報告。
- 2.1 例: topic 12675, post 87550 の保存コードは
Scene.addLineEndPoint2 個とScene.addSpring { lineEndPoint0; lineEndPoint1; ... }を使用。 - 確度: 有力
- バージョン注意: 上の
(readable(ep)).entityID取得形はコーパス内で直接動作確認されていない合成例。2.1 の実 ID 取得をランタイムで検証する。
4.3 Scene.addSpring の版別不具合
Scene.addSpring({
geom0 := 0;
geom1 := 13;
geom0pos := [1, 1];
geom1pos := [0, 0];
length := 1
})
- 根拠: topic 4442, posts 49479/49489 は 1.9.8 で戻り値は spring でも表示されない回帰を再現し、開発者が修正すると回答。
- 確度: 確認済み(1.9.8 回帰)
- 対応: 現行で direct API が出ない場合は endpoint 形式を試す。逆に direct API が動くなら簡潔な方を使う。
4.4 spring パラメータの安定性
constant と dampingFactor を質量に対して大きくしすぎると振動・爆発しやすい。サスペンションでは damping 最大が常に最適ではない。
// 初期値は控えめにし、実行テストで上げる
constant := 100.0;
dampingFactor := 0.2
- 根拠: topic 2826, post 33406 の suspension ガイド。
- 確度: 有力
- バージョン注意: 安定限界は
sim.frequency、質量、長さ、solver に依存する固定値ではない。
5. wheel / car の実装指針
5.1 最小の駆動輪
車体 box、車輪 circle、各輪を車体へ接続する motorized hinge の 3 要素が最小構成。
// 形状を作った後、実際の geomID を取得した前提
Scene.addHinge({
geom0 := chassisGeom;
geom1 := rearWheelGeom;
geom0pos := [-1.4, -0.45];
geom1pos := [0, 0];
motor := true;
motorSpeed := -12.0;
motorTorque := 250.0;
autoBrake := false;
legacyMode := 0
})
- 根拠: hinge/motor の上記各スレッドを組み合わせた合成例。
- 確度: 有力
- 最重要検証: 生成した車輪の中心とヒンジ位置が一致すること、ヒンジの両
geomIDが 0 ではないことを再生前に確認する。
5.2 collision 用の真円と見た目を分離する
複雑な polygon rim は高速で不安定になりやすい。透明な真円を実際のタイヤにし、装飾 rim は低密度・no-collision にする。
// collision circle
friction := 1.0;
restitution := 0.0;
collideSet := 1;
// decorative rim
density := 0.001;
collideSet := 0
- 根拠: topic 5450, post 56088 の修正法。
- 照合: topic 1019, post 10036 は circle/box より polygon collision が不安定で、特に車輪に注意と説明。
- 確度: 確認済み
5.3 高速で車輪・ヒンジが震える場合
優先順位は次の通り。
- 車輪が polygon ではなく真円か確認。
- wheel hinge を
legacyMode := 0。 - 車輪・接続部の密度を上げる。
sim.frequencyを上げる。- 必要なら
Sim.limitAngVelを上げるが、安全性は低い。
sim.frequency = 200;
// hinge property
legacyMode := 0
legacyMode=0: topic 8658, posts 65413/65418 で wheel wobble が解消。- 密度/frequency: topic 10994, post 78595 と topic 11006, posts 78848-78912。
- 時間刻み限界: topic 5450, post 64596 は 100 Hz で 1500 RPM が 1 step 90°進むことを説明。
- 確度: 確認済み
- バージョン注意: frequency を変えると break limit や旧シーンの挙動も変わる。
5.4 +inf motorTorque でも滑ることがある
低密度 body では hinge が solver 上「滑る」ため、無限トルクでも完全固定にならない。密度を上げる。
motorTorque := +inf;
// connected body
density := 10.0
- 根拠: topic 3778, posts 42651-42653。
- 確度: 有力
- 注意:
+infは数値不安定の原因にもなるため、必要十分な有限値を優先する。
6. collision layers / self collision / water
6.1 collideSet はビット和
// A=1, B=2, C=4, D=8 ... J=512
// B + C + D
collideSet := 14;
// A-J 全部
collideSet := 1023
- 根拠: topic 1057, posts 10569/10642 は binary 表現を説明。
- 拡張確認: topic 10811, post 76803 は A-J の 1..512、topic 11763, posts 84700/84884 は全層 1023 を確認。
- 確度: 確認済み
6.2 イベント対象の collision layer を変更する
// laser が当たった geometry
e.geom.collideSet = 2;
// 衝突相手
e.other.collideSet = 4
- 根拠: topic 10778, posts 75779/75782/86087 は
e.geom、e.laser、e.this、e.otherの使い分けを説明。 - 確度: 確認済み
- バージョン注意: 旧
onLazerHit/onLaserHitと新onHitByLaserの命名が混在する。どちら側の callback かでe.geom/e.laserが変わる。
6.3 self collision と水
heteroCollide := true; // 同一 collideSet 同士の扱いを変更
collideWater := false
- 根拠: topic 11151, posts 80285/80567 と topic 83, post 1038。
- 確度: 有力
- 注意:
heteroCollideの説明は投稿内でも紛らわしい。UI の「No self collision」と期待が一致するか、小さな 2-object テストで確認する。
6.4 Algodoo には bitwise operator がない
ランダムな collision layer 組み合わせは、各 bit の 2^i を足し上げる。
collideSet = 0;
for(10, (i) => {
collideSet = collideSet + rand.boolean * 2^i
})
- 根拠: topic 12141, post 86280。
- 確度: 有力
7. friction / restitution / density
7.1 2 物体間の摩擦・反発は幾何平均
2 geometry の係数を x1, x2 とすると、接触で使われる係数は sqrt(x1*x2)。
// 接触係数を 0.7 にしたい対称設定
friction := math.sqrt(0.7)
- 摩擦: topic 11312, posts 82211/83126。
- 反発: topic 8338, post 64823。
- 開発者由来の照合引用: topic 3272, post 37336 は friction と restitution の両方に
sqrt(r1*r2)を使用すると記録。 - 確度: 確認済み
- 罠: 一方だけ負値にすると平方根が NaN になり、速度や位置まで壊れる旧実装がある。通常の機構では負の摩擦・反発を使わない。
7.2 static friction は独立パラメータとして存在しない
// 疑似 static friction の一例
math.vec.len(vel) <= 0.1 ? { friction = 2.0 } : { friction = 0.5 }
- 根拠: topic 11312, posts 82215/82225。
- 確度: 確認済み
- 注意: 疑似実装は速度閾値で不連続になり、solver jitter を起こし得る。
7.3 density は kg/m²、質量は面積との積
mass = area * density
- 根拠: topic 83, post 1038 は density 単位を kg/m² と記載。
- 照合: topic 83, posts 16858-17170 で mass は area × density と説明。
- 確度: 確認済み
- 機構上の含意: 同じ density でも wheel radius や chassis size を変えると質量・慣性が変わり、motorTorque や spring tuning を再調整する必要がある。
7.4 density = 0 を削除 API とみなさない
Algodoo では削除に使われた歴史があるが、Phun 5.28 ではクラッシュする既知バグだった。
// 旧 Phun の代替例
collideSet = 0;
airFrictionMult = NaN
- 根拠: topic 1175, posts 12099-12105。
- 確度: 確認済み(歴史的)
- 現行注意: NaN を入れる手法も周囲を巻き込む危険がある。MCP では正式な削除/kill 操作を優先し、物理属性を壊して消さない。
8. velocity / torque / impulse / materialVelocity
8.1 直接速度を与える
Scene.addCircle({
pos := [0, 2];
radius := 0.2;
vel := [10, 0];
angvel := 5.0
})
- 根拠: topic 5127, post 54300 は生成物の初速を
vel := [10,0]で設定すると説明。angvelは topic 83, post 1038 の属性表。 - 確度: 確認済み
- 注意:
velの直接代入は力積を物理的に積分した結果ではなく、状態の上書き。物理応答を保ちたい制御には motor、spring、thruster を使う。
8.2 materialVelocity は conveyor surface
Scene.addBox({
pos := [0, 0];
size := [4, 0.2];
materialVelocity := 2.0;
friction := 1.0;
body := 0
})
- 根拠: topic 496, post 4171 は conveyor belt と説明。
- 方向/接触: topic 3375, posts 38506/38509 は接触しないと効かず、垂直移動には垂直面が必要と説明。
- 確度: 確認済み
- 罠:
materialVelocityは surface tangent 方向。velの代わりではなく、摩擦を介して接触物へ力を伝える。
8.3 materialVelocity を簡易モーター代わりにする場合
接触 box の materialVelocity を速度、friction を伝達力のように使えるが、片側だけで押すとヒンジを横に引っ張り、車体が跳ねる。両側から対称に当てる。
e.geom.materialVelocity = 100;
e.geom.friction = 500
- 根拠: topic 3689, posts 42022-42148 は実働と不安定化、その対称配置対策まで記載。
- 確度: 有力
- バージョン注意: topic 4094 では 1.9.4 新 solver で消失、topic 4426 では 1.9.9b で修正と記録。現行でも experimental な挙動として回帰テストする。
8.4 applyForce / externalForce はコーパス上では提案段階
// 以下は「欲しい API」として提案された形で、実装確認ではない
object.applyForce([fx, fy])
- 根拠: topic 2472, post 29636 は機能提案。
- 照合: topic 1734, posts 18933/38391 の
externalForceも要望で、入力しても動かなかったと報告。 - 確度: 確認済み(未実装/少なくとも当時は利用不可)
- 推奨: 初速は
vel/angvel、継続力はScene.addThruster、回転は hinge motor、弾性は spring を使う。
8.5 正確な impulse を作るには thruster を時間積分する
Algodoo には直接 impulse API がなかったため、短時間の thruster force を sim.tick / sim.frequency で積分して目標力積へ収束させる方法が使われた。
// 概念: J = integral(F dt)
force := {Scene.my.impRelease}
- 根拠: topic 4637, posts 51056/51064 は周波数・simulation scale に依存しにくい impulse quantizer を掲載。
- 確度: 有力
- 注意: 元コードは長く、半分ずつ誤差を詰める実装。通常の車両制御には過剰で、発射・打撃の再現に限定する。
8.6 hinge の実力・反力・トルクを読む
totImp3 は [Fx impulse, Fy impulse, moment impulse]。1 step 分の impulse なので sim.frequency を掛けると N / Nm 相当になる。
forceX = (readable(entity)).totImp3(0) * sim.frequency;
forceY = (readable(entity)).totImp3(1) * sim.frequency;
torque = (readable(entity)).totImp3(2) * sim.frequency
- 根拠: topic 10984, posts 78509/78514。
- 照合: topic 11255, posts 81101/81151 で hinge update 内の torque 読み出しが質問者により採用。
- 確度: 確認済み
- 注意:
readable()は linked geom、impulse、surfaces など通常アクセスできない読み取り属性に必要。topic 11677, post 84192。
8.7 breakability は impulseLimit と distanceLimit
Scene.addHinge({
geom0 := geomA;
geom1 := geomB;
pos := [0, 0];
impulseLimit := 10.0;
distanceLimit := 0.02
})
- 根拠: topic 83, post 1038 の hinge 属性表。
- 照合: topic 10984, post 81644 は
totImp3は読み取り専用で、破断はimpulseLimit/distanceLimitと回答。 - 確度: 確認済み
- バージョン注意: topic 7130, post 62575 と topic 9940, post 68338 は break limit が step impulse であるため
sim.frequency変更で破断性が変わると指摘。
9. 物理機構を壊しにくくする開発・検証手順
9.1 生成と接続を分けて検証する
- body / wheel geometry だけ生成する。
- 実際に割り当てられた
geomIDを確認する。 - motor なし hinge を追加し、再生して接続だけを確認する。
motor := trueと低いmotorSpeed/motorTorqueを追加する。- 速度を上げ、wobble、penetration、constraint stretch を見る。
この順序にすると「形がない」「ID が無効」「接続位置が違う」「motor が強すぎる」を分離できる。
9.2 デバッグ表示と console
App.drawBodyCenters = true;
App.drawCollisions = true
- 根拠: topic 1019, post 10036 は body center と collision force 表示を複雑機構の診断に推奨。
F11console はエラー確認に使う。同投稿および topic 10004, post 68605 は console の行番号・例外表示を具体例で説明。- 確度: 確認済み
9.3 solver の切り分け
薄い geometry の貫通や cam/follower の接触不良では、geometry を厚く・高密度にし、frequency を上げ、それでも必要なら direct contact solve を試す。
sim.frequency = 200;
Sim.directContactSolveAll = true
- 根拠: topic 11006, posts 78832-78912 で実際に機構が改善。
- 確度: 確認済み
- 注意: global solver 設定はシーン全体の速度・互換性・break limit に影響する。最後の手段として使う。
9.4 joint spawn の歴史的な回帰を前提にテストする
- 1.7.4: position 省略や undo 後の ID で hinge spawn 問題。
- 1.7.5: 「rare bug with spawning joints from Thyme」を修正。
- 1.9.8: addSpring が表示されない回帰。
-
2.1: 既存 geometry への runtime hinge/fixate/glue 追加失敗報告。
-
根拠: topic 2279, posts 29018/31602、topic 4442、topic 9597、topic 11894。
- 確度: 確認済み(各版の報告)
MCP / スキルへ反映する際の推奨ルール
- geometry 生成後に実 ID を取得できたことを検証してから constraint を生成する。
- hinge/fixjoint/spring に endpoint geometry と endpoint position を必須入力として要求する。
- 車輪には既定で
legacyMode := 0、低 restitution、適度な friction を使う。 staticは Thyme へそのまま渡さず、body := 0; glued := trueに正規化する。- serializer からコピーした
entityID/geomID/bodyを生成テンプレートに残さない。 materialVelocityをvelと混同しない型・説明にする。- joint 生成後は短時間再生し、接続切れ、constraint stretch、wheel wobble を観測してから完成扱いにする。
- active Algodoo 2.1 で「新規生成直後の joint」と「既存 geometry への後付け joint」を別々に回帰テストする。