<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.wiegert.link/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Damme</id>
	<title>World Wide Wiegert Wiki - WWWW - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.wiegert.link/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Damme"/>
	<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php/Special:Contributions/Damme"/>
	<updated>2026-08-04T19:16:14Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Furuno_Radar&amp;diff=551</id>
		<title>Furuno Radar</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Furuno_Radar&amp;diff=551"/>
		<updated>2026-08-02T08:27:25Z</updated>

		<summary type="html">&lt;p&gt;Damme: Created page with &amp;quot;= Furuno MD-7918 Modulator — Field Reference &amp;amp; Measurement Plan =  &amp;#039;&amp;#039;&amp;#039;For: RSB-0034 scanner (MODEL 1830), MD-7918 modulator, IF-7758 IF amp&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;Symptom: receiver noise present, no main bang, no echoes, empty tuning bar, after a soft grounding&amp;#039;&amp;#039;&amp;#039;  ----  == 0. Source of this data and how much to trust it ==  There is no public MODEL 1830 service manual. Everything below is taken from the &amp;#039;&amp;#039;&amp;#039;Furuno MODEL 1832/1932/1942 service manual&amp;#039;&amp;#039;&amp;#039; (97 pages, includes full schemati...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Furuno MD-7918 Modulator — Field Reference &amp;amp; Measurement Plan =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;For: RSB-0034 scanner (MODEL 1830), MD-7918 modulator, IF-7758 IF amp&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;Symptom: receiver noise present, no main bang, no echoes, empty tuning bar, after a soft grounding&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 0. Source of this data and how much to trust it ==&lt;br /&gt;
&lt;br /&gt;
There is no public MODEL 1830 service manual. Everything below is taken from the &#039;&#039;&#039;Furuno MODEL 1832/1932/1942 service manual&#039;&#039;&#039; (97 pages, includes full schematics), which documents &#039;&#039;&#039;MD-7918A&#039;&#039;&#039; (MODEL 1932) and &#039;&#039;&#039;MD-7918E&#039;&#039;&#039; (MODEL 1942) — the same board family, same designators (TP801/802/803, VR801/802, JP801), same FET-switching modulator topology as your MD-7918.&lt;br /&gt;
&lt;br /&gt;
Confidence key used throughout:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;[CONFIRMED]&#039;&#039;&#039; — read cleanly out of the manual text.&lt;br /&gt;
* &#039;&#039;&#039;[OCR]&#039;&#039;&#039; — reconstructed from a rotated table that OCR&#039;d badly. Directionally right, treat the exact digits as approximate.&lt;br /&gt;
* &#039;&#039;&#039;[INFERRED]&#039;&#039;&#039; — my reasoning from the topology, not stated in the manual.&lt;br /&gt;
&lt;br /&gt;
⚠️ &#039;&#039;&#039;Your 1830 is an earlier model than the 1832/1932/1942.&#039;&#039;&#039; Expect the topology and designators to match and the exact numbers to be close but not guaranteed. Verify against the board silkscreen and your own schematic where you can.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 1. First, the mystery part: FCX73 is your circulator ==&lt;br /&gt;
&lt;br /&gt;
From the 1832 service manual, scanner unit parts location (p. 3-10):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Inside of Scanner Unit — IF AMP Board (IF-9214), Magnetron &#039;&#039;&#039;V801 (E3571)&#039;&#039;&#039;, MIC &#039;&#039;&#039;(RU-9360)&#039;&#039;&#039;, &#039;&#039;&#039;Circulator HY801 (FCX73)&#039;&#039;&#039; [CONFIRMED]&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So &#039;&#039;&#039;FCX73 = the ferrite circulator&#039;&#039;&#039;, reference designator &#039;&#039;&#039;HY801&#039;&#039;&#039;. That explains exactly what you described:&lt;br /&gt;
&lt;br /&gt;
* Three ports, numbered &#039;&#039;&#039;1-2-3&#039;&#039;&#039; on the body.&lt;br /&gt;
* The &#039;&#039;&#039;arrow&#039;&#039;&#039; shows the direction of circulation (1 → 2 → 3 → 1).&lt;br /&gt;
&lt;br /&gt;
Typical port assignment [INFERRED]: &#039;&#039;&#039;port 1 = magnetron&#039;&#039;&#039;, &#039;&#039;&#039;port 2 = antenna/radiator&#039;&#039;&#039;, &#039;&#039;&#039;port 3 = MIC (receiver front end)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Why this matters for you:&#039;&#039;&#039; a circulator is a permanent-magnet + ferrite device, and it is one of the few RF parts in the radome that a &#039;&#039;&#039;mechanical shock can genuinely damage&#039;&#039;&#039; — cracked ferrite, cracked or shifted magnet, disturbed alignment. A degraded circulator kills transmit into the antenna and receive out of it, while leaving the IF amplifier happily generating noise. That fits your screen exactly.&lt;br /&gt;
&lt;br /&gt;
It is not, however, my &#039;&#039;first&#039;&#039; suspect — see §6.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 2. How the MD-7918 works ==&lt;br /&gt;
&lt;br /&gt;
From p. 2-16, &amp;quot;Principle of FET switching modulator&amp;quot; [CONFIRMED]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
High voltage is charged into C through R while the magnetron is inactive. When the trigger is applied to the power MOS-FET, the FET turns on and the high voltage appears at the primary winding of the pulse transformer.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Chain, end to end:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Display (SPU board)&lt;br /&gt;
   │  TRIGGER  (positive pulse, ~8–12 V)&lt;br /&gt;
   │  PL/A, PL/B  (2-bit pulse-length select)&lt;br /&gt;
   │  TUNE  (0–12 V analogue)&lt;br /&gt;
   │  ANT +12 V / ANT -12 V&lt;br /&gt;
   ▼&lt;br /&gt;
MD-7918 ──► DC-DC converter ──► HV rail ~300–370 Vdc ──► charge C through R&lt;br /&gt;
   │                                                          │&lt;br /&gt;
   │  trigger ──► gate driver ──► power MOSFET ───────────────┘&lt;br /&gt;
   │                                    │&lt;br /&gt;
   │                            pulse transformer primary (~300 V pulse)&lt;br /&gt;
   │                                    │&lt;br /&gt;
   │                            secondary (several kV negative)&lt;br /&gt;
   │                                    ▼&lt;br /&gt;
   │                            MAGNETRON cathode  (V801)&lt;br /&gt;
   │  heater supply 7.4–7.6 Vdc ──────► magnetron heater&lt;br /&gt;
   ▼&lt;br /&gt;
Magnetron ──► CIRCULATOR HY801 (FCX73) port 1&lt;br /&gt;
                  ├─ port 2 ──► radiator (antenna)&lt;br /&gt;
                  └─ port 3 ──► limiter ──► MIC ──► IF-7758 ──► VIDEO ──► display&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 3. MD-7918 test points ==&lt;br /&gt;
&lt;br /&gt;
Board features: &#039;&#039;&#039;TP801, TP802, TP803, VR801, VR802, JP801&#039;&#039;&#039;, connectors &#039;&#039;&#039;J811, J812&#039;&#039;&#039; (and &#039;&#039;&#039;J701&#039;&#039;&#039; on the bearing/signal board next to it). [CONFIRMED]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Point&lt;br /&gt;
! Function&lt;br /&gt;
! Expected&lt;br /&gt;
! Confidence&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;TP803&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;GND&#039;&#039;&#039; — reference for everything else&lt;br /&gt;
| 0 V&lt;br /&gt;
| [CONFIRMED]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;TP801&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;TRIGGER&#039;&#039;&#039; input, same signal as the SPU/display trigger output&lt;br /&gt;
| positive pulse, ~8–12 V, at the PRF&lt;br /&gt;
| [CONFIRMED function], [OCR amplitude]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;TP802&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;Magnetron current monitor&#039;&#039;&#039;&lt;br /&gt;
| ST-BY: ~0 V. TX: roughly &#039;&#039;&#039;0.2 – 1.2 Vdc&#039;&#039;&#039;, varying with pulse length (short / medium / long)&lt;br /&gt;
| [OCR]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;VR801&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;Magnetron heater voltage adjust&#039;&#039;&#039;&lt;br /&gt;
| set heater to 7.4–7.6 Vdc at ST-BY&lt;br /&gt;
| [CONFIRMED]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;VR802&#039;&#039;&#039;&lt;br /&gt;
| Second adjustment, almost certainly &#039;&#039;&#039;magnetron current / TX HV&#039;&#039;&#039;&lt;br /&gt;
| —&lt;br /&gt;
| [INFERRED]&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;JP801&#039;&#039;&#039;&lt;br /&gt;
| Configuration jumper (model / pulse-length option)&lt;br /&gt;
| —&lt;br /&gt;
| [INFERRED]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The manual also lists a 6-way connector on the board [OCR]:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Pin&lt;br /&gt;
! Signal&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| TX(-)&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| GND&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| +14 V&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Mag. (heater)&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Mag. (heater)&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| GND&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;This is very likely the unpopulated test header you found.&#039;&#039;&#039; Pins 4 and 5 are where you measure heater voltage.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 4. Manufacturer&#039;s target values ==&lt;br /&gt;
&lt;br /&gt;
=== TX high voltage, measured at ST-BY [CONFIRMED] ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Spec&lt;br /&gt;
|-&lt;br /&gt;
| 1832&lt;br /&gt;
| 300 – 370 Vdc&lt;br /&gt;
|-&lt;br /&gt;
| 1932&lt;br /&gt;
| 300 – 370 Vdc&lt;br /&gt;
|-&lt;br /&gt;
| 1942&lt;br /&gt;
| 350 – 390 Vdc&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Out of range → &#039;&#039;&#039;faulty modulator PCB&#039;&#039;&#039; (MD-9208 on 1832, MD-7918A on 1932, MD-7918E on 1942).&lt;br /&gt;
&lt;br /&gt;
Your 1830 is a 4 kW radome like the 1832/1932, so &#039;&#039;&#039;expect ~300–370 Vdc&#039;&#039;&#039;. [INFERRED]&lt;br /&gt;
&lt;br /&gt;
=== Magnetron heater voltage, measured at ST-BY [CONFIRMED] ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Spec&lt;br /&gt;
! Adjust with&lt;br /&gt;
|-&lt;br /&gt;
| 1832&lt;br /&gt;
| 7.4 – 7.6 Vdc&lt;br /&gt;
| R106 on PTU-9335&lt;br /&gt;
|-&lt;br /&gt;
| 1932&lt;br /&gt;
| 7.4 – 7.6 Vdc&lt;br /&gt;
| &#039;&#039;&#039;VR801 on MD-7918&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| 1942&lt;br /&gt;
| 7.5 – 7.7 Vdc&lt;br /&gt;
| &#039;&#039;&#039;VR801 on MD-7918&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Measure at &#039;&#039;&#039;ST-BY&#039;&#039;&#039;, not TX — the heater voltage is deliberately reduced during transmit.&lt;br /&gt;
&lt;br /&gt;
=== Signals from the display&#039;s DJ-1 connector [OCR — pin numbers cross-checked against flow charts] ===&lt;br /&gt;
&lt;br /&gt;
All measured &#039;&#039;&#039;positive lead on the listed pin, negative lead on DJ-1 #20 (GND)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Signal&lt;br /&gt;
! DJ-1 pin&lt;br /&gt;
! Expected&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;TRIGGER&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;#2&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;Positive&#039;&#039;&#039; polarity, &#039;&#039;&#039;8 – 12 V&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| TUNE&lt;br /&gt;
| #6&lt;br /&gt;
| 0 → 13 V on 1832 class; sweeps when switching ST-BY → TX during auto-tune search&lt;br /&gt;
|-&lt;br /&gt;
| PL/A&lt;br /&gt;
| #8&lt;br /&gt;
| Logic level: 0–1.0 V = L, 7–12 V = H&lt;br /&gt;
|-&lt;br /&gt;
| PL/B&lt;br /&gt;
| #7&lt;br /&gt;
| Logic level: 0–1.0 V = L, 8–12 V = H&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
PL/A and PL/B together form the 2-bit pulse-length code (short / medium / long).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PRF&#039;&#039;&#039; reads as roughly &#039;&#039;&#039;2000 – 2300 Hz&#039;&#039;&#039; on short pulse [OCR]. The trigger &#039;&#039;pulse width&#039;&#039; figure did not OCR reliably — don&#039;t chase a number, just confirm a clean pulse train at the right rate.&lt;br /&gt;
&lt;br /&gt;
Line voltages in the display [OCR, approximate]: +12 V rail ≈ 12.1–13.5 V, +5 V ≈ 4.9 V, −12 V ≈ −11.6 to −12.8 V, ANT ±12 V ≈ 12.0 V.&lt;br /&gt;
&lt;br /&gt;
⚠️ &#039;&#039;&#039;DJ-1 pin numbering is from the 1832-generation display.&#039;&#039;&#039; Your 1830 display may differ — confirm against the 1830 installation/interconnection diagram before trusting the pin numbers. The &#039;&#039;signal names&#039;&#039; and &#039;&#039;levels&#039;&#039; will be right regardless.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 5. Safety before you probe ==&lt;br /&gt;
&lt;br /&gt;
* The HV rail is &#039;&#039;&#039;300–370 V&#039;&#039;&#039; and sits on a reservoir capacitor. &#039;&#039;&#039;Discharge it and verify 0 V&#039;&#039;&#039; before touching the board.&lt;br /&gt;
* The pulse transformer secondary reaches &#039;&#039;&#039;several kilovolts negative&#039;&#039;&#039;. Do not probe it with a standard 10:1 probe.&lt;br /&gt;
* Do not stand in front of the radiator while testing for transmission.&lt;br /&gt;
* Do not run the set in TX with the magnetron removed.&lt;br /&gt;
* The magnetron contains &#039;&#039;&#039;beryllium oxide ceramic&#039;&#039;&#039; — do not break, grind, or file it.&lt;br /&gt;
* Remove your watch and use a non-magnetic screwdriver near the magnetron (strong magnetic field).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 6. Measurement plan, in order ==&lt;br /&gt;
&lt;br /&gt;
Do these in sequence and stop at the first failure.&lt;br /&gt;
&lt;br /&gt;
=== Step 0 — repair the bad negative first ===&lt;br /&gt;
&lt;br /&gt;
Then verify it under load: with the set &#039;&#039;&#039;transmitting&#039;&#039;&#039;, measure between the display&#039;s negative terminal and the radome chassis. &#039;&#039;&#039;&amp;gt; 0.2 V means you still have a return-path problem&#039;&#039;&#039; and every other measurement is suspect.&lt;br /&gt;
&lt;br /&gt;
=== Step 1 — supply current, STBY vs TX ===&lt;br /&gt;
&lt;br /&gt;
You haven&#039;t done this yet and it&#039;s a 30-second answer.&lt;br /&gt;
&lt;br /&gt;
* Note DC input current in ST-BY, then in TX.&lt;br /&gt;
* &#039;&#039;&#039;Same current in both = the modulator is not pulsing.&#039;&#039;&#039; That immediately points at trigger / FET / HV.&lt;br /&gt;
* Higher in TX = something is firing; move on to find out what.&lt;br /&gt;
&lt;br /&gt;
=== Step 2 — ±12 V arriving at the radome, under load ===&lt;br /&gt;
&lt;br /&gt;
Measure ANT +12 V and ANT −12 V &#039;&#039;at the radome connector&#039;&#039;, in TX, while the antenna is turning. A sag here (especially with your ground history) explains a dead DC-DC converter output.&lt;br /&gt;
&lt;br /&gt;
=== Step 3 — TRIGGER, with the scope ===&lt;br /&gt;
&lt;br /&gt;
Setup: DC coupled, 5 V/div, 200 µs/div, trigger on rising edge, ground clip to &#039;&#039;&#039;TP803&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
# First at the &#039;&#039;&#039;display end&#039;&#039;&#039;, DJ-1 #2 to #20. Expect positive pulses, &#039;&#039;&#039;8–12 V&#039;&#039;&#039;, at ~2 kHz on a short-pulse range.&lt;br /&gt;
# Then at &#039;&#039;&#039;TP801 on the MD-7918&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Present at the display but absent or degraded at TP801 = broken trigger conductor in the multi-signal cable.&#039;&#039;&#039; This is the cheapest possible fix and the cable is the one thing you have not substituted — both of your display swaps ran through it.&lt;br /&gt;
&lt;br /&gt;
Flex the cable at both connectors and at the strain relief while watching the scope.&lt;br /&gt;
&lt;br /&gt;
=== Step 4 — magnetron heater, at ST-BY ===&lt;br /&gt;
&lt;br /&gt;
Across the two &amp;quot;Mag.&amp;quot; pins (4 and 5 on that test header). Expect &#039;&#039;&#039;7.4 – 7.6 Vdc&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* Absent or low → MD-7918 fault. Do &#039;&#039;&#039;not&#039;&#039;&#039; simply wind VR801 up to compensate; find out why it&#039;s low first.&lt;br /&gt;
* Note that heater voltage is normal in many &amp;quot;no TX&amp;quot; faults, so passing this step proves little on its own.&lt;br /&gt;
&lt;br /&gt;
=== Step 5 — TX high voltage, at ST-BY ===&lt;br /&gt;
&lt;br /&gt;
Expect &#039;&#039;&#039;~300 – 370 Vdc&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;0 V or very low:&#039;&#039;&#039; the DC-DC converter isn&#039;t running, the charging resistor R is open, or the modulator FET is &#039;&#039;&#039;shorted&#039;&#039;&#039; and clamping the rail. A shorted FET commonly takes the charging resistor with it — check that resistor for an open circuit, it&#039;s a classic.&lt;br /&gt;
* &#039;&#039;&#039;Present and stable:&#039;&#039;&#039; the supply side is fine, the fault is downstream.&lt;br /&gt;
&lt;br /&gt;
A shorted modulator FET is a very plausible consequence of your floating-ground condition. Check it with the board unpowered and discharged: diode-test drain–source and gate–source, and look for gate–source short (0 Ω) or a drain–source dead short.&lt;br /&gt;
&lt;br /&gt;
=== Step 6 — TP802, magnetron current, in TX ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;This is the decisive measurement.&#039;&#039;&#039; DMM on DC volts, TP802 to TP803, radar in TX.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;~0 V in TX = the magnetron is drawing no current = you are definitively not transmitting.&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;~0.2–1.2 V depending on pulse length = the magnetron IS firing&#039;&#039;&#039;, and your problem is downstream of the magnetron — i.e. the &#039;&#039;&#039;circulator (FCX73/HY801)&#039;&#039;&#039;, the limiter, the MIC, or the radiator feed.&lt;br /&gt;
&lt;br /&gt;
That single reading splits your remaining fault tree in half. Do it before you buy anything.&lt;br /&gt;
&lt;br /&gt;
=== Step 7 — pulse transformer primary ===&lt;br /&gt;
&lt;br /&gt;
Only if steps 3–5 pass and step 6 reads zero. With a &#039;&#039;&#039;100:1 or high-voltage probe&#039;&#039;&#039; (not a 10:1), look at the FET drain / transformer primary: you should see a clean ~300 V pulse at the PRF, of the selected pulse width. No pulse with good trigger + good HV = dead FET or dead gate driver. Ringing, a slow collapse, or a much-reduced amplitude = suspect the &#039;&#039;&#039;pulse transformer&#039;&#039;&#039; — a shock-cracked ferrite core is a known post-grounding failure and it looks perfect to the eye and to a DMM.&lt;br /&gt;
&lt;br /&gt;
=== Step 8 — if TP802 shows current but there is still no echo ===&lt;br /&gt;
&lt;br /&gt;
Then the RF path is the fault, and Furuno&#039;s flow chart lands on &#039;&#039;&#039;&amp;quot;faulty magnetron or MIC.&amp;quot;&#039;&#039;&#039; You&#039;ve already replaced the magnetron, so:&lt;br /&gt;
&lt;br /&gt;
* Inspect &#039;&#039;&#039;HY801 (FCX73)&#039;&#039;&#039; closely: cracked ferrite, cracked or displaced magnet, deformed housing, disturbed mounting, corrosion at the port interfaces.&lt;br /&gt;
* Inspect the &#039;&#039;&#039;limiter diode&#039;&#039;&#039; between circulator port 3 and the MIC — a shorted limiter kills both main bang and echoes while leaving IF noise intact.&lt;br /&gt;
* Check the small coax and the connector at the &#039;&#039;&#039;IF-7758&#039;&#039;&#039;.&lt;br /&gt;
* Check the radiator feed / slot array for physical damage or water ingress.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 7. Post-shock mechanical inspection checklist ==&lt;br /&gt;
&lt;br /&gt;
Independent of the electrical tests, go over the radome for shock damage:&lt;br /&gt;
&lt;br /&gt;
* Cracked solder joints on &#039;&#039;&#039;heavy parts&#039;&#039;&#039;: pulse transformer, chokes, large electrolytics, magnetron terminals.&lt;br /&gt;
* &#039;&#039;&#039;Pulse transformer ferrite core&#039;&#039;&#039; — inspect under magnification, this is the sneaky one.&lt;br /&gt;
* Circulator HY801 ferrite/magnet.&lt;br /&gt;
* Magnetron mounting and its seating into the launcher.&lt;br /&gt;
* Every connector: J811, J812, J701, the video coax, the MIC coax.&lt;br /&gt;
* Fuses on the MD-7918.&lt;br /&gt;
* Any sign of water ingress if the radome seal was disturbed.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 8. Getting the real documentation ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Highest-value action:&#039;&#039;&#039; the &#039;&#039;&#039;Furuno MODEL 1832/1932/1942 service manual&#039;&#039;&#039; is available on ManualsLib as a 97-page PDF, and pages 79–97 are &#039;&#039;&#039;full schematic diagrams&#039;&#039;&#039; including the MD-7918A and MD-7918E. That is by far the closest thing to your board&#039;s schematic that exists in public:&lt;br /&gt;
https://www.manualslib.com/manual/3545387/Furuno-1832.html&lt;br /&gt;
&lt;br /&gt;
Also worth doing:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;furunousaforum.com&#039;&#039;&#039; — Furuno&#039;s own technicians answer there and have handled MD-7918 questions specifically.&lt;br /&gt;
* A &#039;&#039;&#039;Furuno dealer or Furuno service department&#039;&#039;&#039; can reference the actual MODEL 1830 service manual.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 9. Summary — ranked suspects ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! #&lt;br /&gt;
! Suspect&lt;br /&gt;
! Why&lt;br /&gt;
! Test&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| &#039;&#039;&#039;Broken trigger conductor in multi-signal cable&#039;&#039;&#039;&lt;br /&gt;
| Only untested common element; both display swaps ran through it; matches symptoms exactly; the cable is where your ground fault was&lt;br /&gt;
| Step 3&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| &#039;&#039;&#039;MD-7918 modulator: FET shorted / charging resistor open / DC-DC dead&#039;&#039;&#039;&lt;br /&gt;
| Floating ground is a credible kill mechanism; Furuno&#039;s own chart lands here on noise-but-no-echo&lt;br /&gt;
| Steps 5, 7&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| &#039;&#039;&#039;Pulse transformer, cracked core&#039;&#039;&#039;&lt;br /&gt;
| Classic shock failure, invisible to DMM&lt;br /&gt;
| Step 7&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| &#039;&#039;&#039;Circulator HY801 (FCX73) or limiter/MIC&#039;&#039;&#039;&lt;br /&gt;
| Shock-sensitive ferrite/magnet assembly; where Furuno&#039;s chart ends after magnetron is excluded&lt;br /&gt;
| Steps 6, 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do Step 1 and Step 6 first.&#039;&#039;&#039; Between them they tell you whether the magnetron is firing at all, which halves the problem for the cost of two meter readings.&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Dammes_other_stuff&amp;diff=550</id>
		<title>Dammes other stuff</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Dammes_other_stuff&amp;diff=550"/>
		<updated>2026-08-02T07:53:03Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Diverse =&lt;br /&gt;
[[ Furuno Radar ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Windows XP SMP ==&lt;br /&gt;
https://forums.virtualbox.org/viewtopic.php?f=1&amp;amp;t=24823&amp;amp;start=15#p111502&lt;br /&gt;
&lt;br /&gt;
== Windows 10+ Media Creation Tool ==&lt;br /&gt;
https://github.com/AveYo/MediaCreationTool.bat&lt;br /&gt;
&lt;br /&gt;
== Powershell ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;Set-PSReadlineKeyHandler -Key ctrl+d -Function ViExit&amp;quot; &amp;gt;&amp;gt; $PROFILE&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Unicode ==&lt;br /&gt;
https://unicode-table.com/en/&lt;br /&gt;
* ° Degree Sign U+00B0&lt;br /&gt;
* ℃ Degree Celsius U+2103&lt;br /&gt;
* K Kelvin Sign U+212A&lt;br /&gt;
* ✓ Check Mark tick, checkmark U+2713&lt;br /&gt;
* ⏎ Return Symbol U+23CE&lt;br /&gt;
* ⮰ Ribbon Arrow Down Left U+2BB0&lt;br /&gt;
* ␍ Symbol for Carriage Return U+240D&lt;br /&gt;
* ™ Trade Mark Sign Emoji trademark, tm U+2122&lt;br /&gt;
* © Copyright Sign Emoji copy, (c) U+00A9&lt;br /&gt;
* ▀ U+2580 ▁ U+2581 ▂ U+2582 ▃ U+2583 ▄ U+2584 ▅ U+2585 ▆ U+2586 ▇ U+2587 █ U+2588 ▉ U+2589 ▊ U+258A ▋ U+258B ▌ U+258C ▍ U+258D ▎ U+258E ▏ U+258F ▐&lt;br /&gt;
* 51° 28′ 38″ N Coordinate&lt;br /&gt;
 ␀␁␂␃␄␅␆␇&lt;br /&gt;
 ␈␉␊␋␌␍␎␏&lt;br /&gt;
 ␐␑␒␓␔␕␖␗␘&lt;br /&gt;
 ␙␚␛␜␝␞␟␠␡&lt;br /&gt;
 ␢␣␤␥␦&lt;br /&gt;
 ␧␨␩␪␫␬␭␮␯␰␱␲␳␴␵␶␷␸␹␺␻␼␽␾␿⑀⑁⑂⑃⑄⑅⑆&lt;br /&gt;
 ⑇⑈⑉⑊⑋⑌⑍⑎⑏⑐⑑⑒⑓⑔⑕⑖⑗⑘⑙⑚⑛⑜⑝⑞⑟&lt;br /&gt;
 ①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳&lt;br /&gt;
 ⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇&lt;br /&gt;
 ⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛&lt;br /&gt;
 ⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵&lt;br /&gt;
 ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ&lt;br /&gt;
 ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ&lt;br /&gt;
 ⓪⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾&lt;br /&gt;
 ⓿─━│┃┄┅┆┇┈┉┊┋&lt;br /&gt;
 ┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫&lt;br /&gt;
 ┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋&lt;br /&gt;
 ╌╍╎╏═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬&lt;br /&gt;
 ╭╮╯╰╱╲╳╴╵╶╷╸╹╺╻╼╽╾╿▀▁▂▃▄▅▆▇█▉▊▋▌▍▎▏▐&lt;br /&gt;
 ░▒▓▔▕▖▗▘▙▚▛▜▝▞▟■□▢▣▤▥▦▧▨▩&lt;br /&gt;
 ▪▫▬▭▮▯▰▱▲△▴▵▶▷▸▹►▻▼▽▾▿◀◁◂◃◄◅◆◇◈◉◊○◌◍◎&lt;br /&gt;
 ●◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿ &lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/Mathematical_operators_and_symbols_in_Unicode&lt;br /&gt;
&lt;br /&gt;
== Virtualbox ==&lt;br /&gt;
https://technet.microsoft.com/en-us/sysinternals/bb897443&lt;br /&gt;
 sdelete.exe c: -z &lt;br /&gt;
 &lt;br /&gt;
 zerofree -v /dev/sda1 &lt;br /&gt;
&lt;br /&gt;
 VBoxManage.exe modifymedium disk &amp;quot;C:\path\to\disk.vdi&amp;quot; --compact&lt;br /&gt;
&lt;br /&gt;
== DJI ==&lt;br /&gt;
* https://mavic-mini-ce-boost.github.io&lt;br /&gt;
* https://gist.github.com/sergiks/687415247eca5a2f2e1ed8677c3b4749&lt;br /&gt;
* https://github.com/444A49/minifindings&lt;br /&gt;
* https://github.com/Bin4ry/deejayeye-modder#want-to-contribute-or-learn-some-stuff&lt;br /&gt;
&lt;br /&gt;
== Rost ==&lt;br /&gt;
Rostbehandling med fosforsyra: Iron(II,III)oxide, iron(III) oxide-hydroxide --&amp;gt;  Iron(III) phosphate&lt;br /&gt;
&lt;br /&gt;
Pensla på, pensla flera gånger och torka sedan av överflödet.&lt;br /&gt;
&lt;br /&gt;
== Peugeot ==&lt;br /&gt;
* Excessive Oil consumption | Peugeot Forums - https://www.peugeotforums.com/threads/excessive-oil-consumption.341756/&lt;br /&gt;
* How to replace the cylinder head cover on Peugeot 1.2 VTi - https://www.nomaallim.com/eb2-cylinder-head-cover-replacement.html&lt;br /&gt;
* Timing belt replacement on Peugeot EB2 1.2 VTi PureTech engine - https://www.nomaallim.com/psa-eb2-timing-belt-replacement.html - https://www.nomaallim.com/psa-eb2-timing-belt-replacement-2.html - https://www.nomaallim.com/psa-eb2-timing-belt-replacement-3.html&lt;br /&gt;
* Part 1 of 2 - 2012 PSA Peugeot 208 1.2 VTi Puretech Timing Belt Replacement - https://www.youtube.com/watch?v=ekFr2N9aM2Q&lt;br /&gt;
* Part 2 of 2 - 2012 PSA Peugeot 208 1.2 VTi Puretech Timing Belt Replacement - https://www.youtube.com/watch?v=uKqVPD13u98&lt;br /&gt;
* https://www.nomaallim.com/car-maintenance--repair.html&lt;br /&gt;
* https://www.youtube.com/watch?v=2YQAydJfCd0&lt;br /&gt;
&lt;br /&gt;
* https://catalogs.ssg.asia/peugeot/?lang=en#c3Q9PTQwfHxzdHM9PXsiMTAiOiJNb2RlbCIsIjIwIjoiMjA4IiwiNDAiOiJCb2R5OiA1IERPT1IgU0FMT09OIFwvIEVuZ2luZTogMS4yIGkgVlRpIChFQjIpIn18fGNvZGU9PTFQSUF8fGJvZHk9PUIwREE1fHxlbmdpbmU9PUIwRkNHfHxjYXRfaWQ9PUZDVDAxMDB8fHN1YkdycF9pZD09RkNUMDExMnx8cmVmZG9jcz09QTlGNzcwSDAxQSIsIkE5Rjc3MEgxMEF8fHJlZmRvYz09QTlGNzcwSDAxQXx8c3ViR3JwTmFtZT09VU5ERVJCT0RZIFBST1RFQ1RJT058fHN1cHBsaWVyPT0=&lt;br /&gt;
* https://www.youtube.com/watch?v=QLx2kCVYRiY&lt;br /&gt;
&lt;br /&gt;
== Other stuff ==&lt;br /&gt;
* COUPONFCNC&lt;br /&gt;
* https://shop.soy.com.tr&lt;br /&gt;
&lt;br /&gt;
=== Retro Computing ===&lt;br /&gt;
* https://github.com/erichelgeson/BlueSCSI&lt;br /&gt;
* https://www.retrorgb.com/ossc.html&lt;br /&gt;
&lt;br /&gt;
=== Zigbee2Mqtt ===&lt;br /&gt;
* CC265R connected to zigbee2mqtt with S2E module https://github.com/Koenkk/zigbee2mqtt/discussions/5266#discussioncomment-323703&lt;br /&gt;
&lt;br /&gt;
=== HAN Interface Aidon ===&lt;br /&gt;
* https://aleel.se/wp-content/uploads/2020/11/AIDONFD-RJ45-HAN-Interface-EN-v14A.pdf&lt;br /&gt;
* https://www.nek.no/wp-content/uploads/2019/02/Aidon-HAN-Interface-Description-v11A-ID-34331.pdf&lt;br /&gt;
* https://community.openenergymonitor.org/t/electricity-meters-with-han-interface/11813/3&lt;br /&gt;
* https://www.hjemmeautomasjon.no/forums/topic/2873-lesing-av-han-the-easy-way-tm-wip/?&amp;amp;page=28#comments&lt;br /&gt;
* https://github.com/HWal/ESP8266_HAN_Receive_Web_Relay_Output&lt;br /&gt;
* https://github.com/roarfred/AmsToMqttBridge&lt;br /&gt;
* https://www.ti.com/lit/ds/symlink/tss721a.pdf?HQS=dis-mous-null-mousermode-dsf-pf-null-wwe&amp;amp;ts=1611500746407&amp;amp;ref_url=https%253A%252F%252Fwww.mouser.se%252F&lt;br /&gt;
&lt;br /&gt;
=== Volvo V70 ===&lt;br /&gt;
* https://www.myvolvolibrary.info/Tech_files2_ficheiros/V70XC70XC90MY03_Wiring.pdf&lt;br /&gt;
&lt;br /&gt;
=== Heat systems ===&lt;br /&gt;
* https://www.youtube.com/watch?v=D5mznXjkhQM stratification&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=FreeCad_Tutorial&amp;diff=549</id>
		<title>FreeCad Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=FreeCad_Tutorial&amp;diff=549"/>
		<updated>2026-07-28T13:19:06Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&lt;br /&gt;
  FreeCAD 1.1.3 for Fusion 360 Users&lt;br /&gt;
  MediaWiki source. Requires the accompanying SVG files to be uploaded to this&lt;br /&gt;
  wiki first (Special:Upload, or maintenance/importImages.php for a batch).&lt;br /&gt;
  SVG uploads must be enabled in LocalSettings.php:&lt;br /&gt;
      $wgFileExtensions[] = &#039;svg&#039;;&lt;br /&gt;
      $wgAllowTitlesInSVG = true;&lt;br /&gt;
      $wgSVGConverter = &#039;rsvg&#039;;   # or ImageMagick&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  Article written by Claude AI.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;A conversion guide for people who only design parts for 3D printing.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Written for a brand-new FreeCAD 1.1.3 install, default settings, metric. No CAM, no drawings, no simulation — just getting from an idea to a good STL or 3MF.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
== 1. The five things that will confuse you ==&lt;br /&gt;
&lt;br /&gt;
Read this section twice. Nearly every &amp;quot;FreeCAD is unusable&amp;quot; post comes from one of these five.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1. There is no single modelling environment. There are workbenches.&#039;&#039;&#039;&lt;br /&gt;
Fusion gives you the Design workspace and everything lives in it. FreeCAD splits the same functionality across separate toolsets you switch between with a dropdown. For 3D printing you will live in [[File:FC-WB-PartDesign.svg|24px|link=|alt=Part Design workbench]] &#039;&#039;&#039;Part Design&#039;&#039;&#039; and its child [[File:FC-WB-Sketcher.svg|24px|link=|alt=Sketcher workbench]] &#039;&#039;&#039;Sketcher&#039;&#039;&#039;, and visit [[File:FC-WB-Mesh.svg|24px|link=|alt=Mesh workbench]] &#039;&#039;&#039;Mesh&#039;&#039;&#039; and [[File:FC-WB-Assembly.svg|24px|link=|alt=Assembly workbench]] &#039;&#039;&#039;Assembly&#039;&#039;&#039; occasionally. That&#039;s it. Ignore the other twelve.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2. Everything must live inside a Body.&#039;&#039;&#039;&lt;br /&gt;
In Fusion you can just start sketching. In FreeCAD, a Part Design feature has to belong to a [[File:FC-Body.svg|24px|link=|alt=Create body]] &#039;&#039;&#039;Body&#039;&#039;&#039; — a container that holds one continuous solid and its own origin planes. First action in every new document: create a Body. If you skip this, the Pad button will be greyed out and you&#039;ll wonder why.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3. A Body holds exactly one solid.&#039;&#039;&#039;&lt;br /&gt;
This is the rule Fusion users trip over hardest. Fusion happily lets one component contain several disconnected bodies. FreeCAD&#039;s Part Design will not. If you Pad a sketch that creates a lump floating away from the existing material, you get an error telling you the result is not a single solid. Two disconnected shapes = two Bodies. See [[#11. Multiple bodies, and assemblies for fit checks|section 11]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4. Sketches want to be fully constrained, and FreeCAD nags until they are.&#039;&#039;&#039;&lt;br /&gt;
Fusion tolerates half-constrained sketches indefinitely. FreeCAD technically does too, but a half-constrained sketch is a booby trap: geometry drifts when you edit something upstream. There&#039;s a degrees-of-freedom counter in the status bar, and the sketch turns fully green when it hits zero. Chase the green.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;5. Tools stay active after you use them.&#039;&#039;&#039;&lt;br /&gt;
Draw a line in Fusion and the tool stays armed too — but FreeCAD&#039;s version, called &#039;&#039;continue mode&#039;&#039;, applies to constraints as well, and it catches people out constantly. Press &#039;&#039;&#039;Esc&#039;&#039;&#039; or right-click to drop the current tool. Press &#039;&#039;&#039;Esc&#039;&#039;&#039; again with no tool active and you&#039;ll leave sketch edit mode entirely. There&#039;s a preference to stop that, and you should turn it on (see [[#2.6 Sketcher|2.6]]).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 2. First-run setup — 20 minutes that saves you months ==&lt;br /&gt;
&lt;br /&gt;
FreeCAD&#039;s defaults are conservative and a bit dated. These changes make it behave much more like the tool you&#039;re used to. All of them are in &#039;&#039;&#039;Edit → Preferences&#039;&#039;&#039; unless stated.&lt;br /&gt;
&lt;br /&gt;
=== 2.1 Navigation — make the mouse work like Fusion ===&lt;br /&gt;
&lt;br /&gt;
This is the single highest-value change. FreeCAD ships with &#039;&#039;&#039;CAD navigation&#039;&#039;&#039;, where orbit requires holding the middle button &#039;&#039;and then&#039;&#039; the left button. Fusion uses middle-drag to pan and Shift+middle-drag to orbit. FreeCAD has a preset that matches this exactly, and confusingly it&#039;s called &#039;&#039;&#039;Revit&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → Display → Navigation → 3D Navigation → &amp;lt;code&amp;gt;Revit&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Action&lt;br /&gt;
! Fusion 360&lt;br /&gt;
! FreeCAD &amp;quot;Revit&amp;quot; style&lt;br /&gt;
|-&lt;br /&gt;
| Pan&lt;br /&gt;
| Middle-drag&lt;br /&gt;
| Middle-drag&lt;br /&gt;
|-&lt;br /&gt;
| Orbit&lt;br /&gt;
| Shift + middle-drag&lt;br /&gt;
| Shift + middle-drag&lt;br /&gt;
|-&lt;br /&gt;
| Zoom&lt;br /&gt;
| Scroll wheel&lt;br /&gt;
| Scroll wheel&lt;br /&gt;
|-&lt;br /&gt;
| Select&lt;br /&gt;
| Left-click&lt;br /&gt;
| Left-click&lt;br /&gt;
|-&lt;br /&gt;
| Multi-select&lt;br /&gt;
| Ctrl + click&lt;br /&gt;
| Ctrl + click&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You can also change this any time by clicking the navigation-style button in the bottom-right status bar, or right-clicking empty space in the 3D view → &#039;&#039;&#039;Navigation styles&#039;&#039;&#039;. If you&#039;d rather learn the native CAD style, it&#039;s fine too — but don&#039;t fight two muscle memories at once while you&#039;re also learning the software.&lt;br /&gt;
&lt;br /&gt;
While you&#039;re on that page:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Zoom step&#039;&#039;&#039; — bump to about &amp;lt;code&amp;gt;0.4&amp;lt;/code&amp;gt; if the default feels sluggish.&lt;br /&gt;
* &#039;&#039;&#039;Enable animation&#039;&#039;&#039; — off. The spin-after-release is distracting.&lt;br /&gt;
* &#039;&#039;&#039;Rotation mode&#039;&#039;&#039; — &amp;lt;code&amp;gt;Drag at cursor&amp;lt;/code&amp;gt;. Orbits around whatever&#039;s under the pointer instead of the scene centre. Much closer to Fusion&#039;s feel.&lt;br /&gt;
* &#039;&#039;&#039;Invert zoom&#039;&#039;&#039; — set this if your scroll direction feels backwards.&lt;br /&gt;
&lt;br /&gt;
=== 2.2 Units and precision ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → General → Units&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Unit system&#039;&#039;&#039;: &amp;lt;code&amp;gt;Standard (mm/kg/s/degree)&amp;lt;/code&amp;gt; — already correct on a metric install.&lt;br /&gt;
* &#039;&#039;&#039;Number of decimals&#039;&#039;&#039;: change &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; → &#039;&#039;&#039;&amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt;&#039;&#039;&#039;. This matters. With 2 decimals a 0.125 mm tolerance displays as 0.13 and you&#039;ll chase a phantom error for an hour.&lt;br /&gt;
* &#039;&#039;&#039;Minimum fractional inch&#039;&#039;&#039;: irrelevant, ignore.&lt;br /&gt;
&lt;br /&gt;
=== 2.3 Start behaviour ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → General → General&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Auto load module after start-up&#039;&#039;&#039;: set to &amp;lt;code&amp;gt;Part Design&amp;lt;/code&amp;gt;. Saves a click every session.&lt;br /&gt;
* &#039;&#039;&#039;Enable tiled background&#039;&#039;&#039; / theme: &#039;&#039;&#039;Preferences → General → Themes&#039;&#039;&#039; has a proper theme picker, and 1.1 added a &#039;&#039;&#039;Theme Editor&#039;&#039;&#039; if you want to tune colours. &amp;lt;code&amp;gt;FreeCAD Dark&amp;lt;/code&amp;gt; is a reasonable Fusion-adjacent starting point.&lt;br /&gt;
* &#039;&#039;&#039;Size of recent file list&#039;&#039;&#039;: raise to 10.&lt;br /&gt;
&lt;br /&gt;
=== 2.4 Document and save behaviour ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → General → Document&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Storage → Save thumbnail into project file&#039;&#039;&#039;: on, makes the Start page useful.&lt;br /&gt;
* &#039;&#039;&#039;Run AutoRecovery&#039;&#039;&#039;: on, every &amp;lt;code&amp;gt;300&amp;lt;/code&amp;gt; seconds. FreeCAD is far more stable than its reputation but this is free insurance.&lt;br /&gt;
* &#039;&#039;&#039;Save transactions (Undo/Redo)&#039;&#039;&#039; and &#039;&#039;&#039;Maximum Undo/Redo steps&#039;&#039;&#039;: leave defaults; the undo stack is per-document and generous.&lt;br /&gt;
* &#039;&#039;&#039;Authoring and license&#039;&#039;&#039;: fill in your name once so exported STEP files aren&#039;t authored by &amp;quot;Unknown&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== 2.5 Part Design behaviour ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → Part Design → General&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Automatically refine model after boolean operation&#039;&#039;&#039;: &#039;&#039;&#039;on&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;Automatically refine model after sketch-based operation&#039;&#039;&#039;: &#039;&#039;&#039;on&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Refining removes the redundant seam edges left behind after a Pad or a Boolean. Without it you get invisible splits across flat faces, and then fillets fail on those faces for no visible reason. Turning this on removes a whole category of confusing failure. There&#039;s a small recompute cost; you will not notice it on printable-sized parts.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → Part Design → Shape view&#039;&#039;&#039; (this controls on-screen display quality only):&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Maximum deviation depending on the model bounding box&#039;&#039;&#039;: lower from &amp;lt;code&amp;gt;0.50&amp;lt;/code&amp;gt; to about &#039;&#039;&#039;&amp;lt;code&amp;gt;0.05&amp;lt;/code&amp;gt;&#039;&#039;&#039;. This only affects on-screen smoothness, not exported geometry, but curved surfaces look far better and it costs nothing on parts this size.&lt;br /&gt;
* &#039;&#039;&#039;Maximum angular deflection&#039;&#039;&#039;: lower from &amp;lt;code&amp;gt;28.5°&amp;lt;/code&amp;gt; to about &#039;&#039;&#039;&amp;lt;code&amp;gt;10°&amp;lt;/code&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== 2.6 Sketcher ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → Sketcher → General&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Esc can leave sketch edit mode&#039;&#039;&#039;: &#039;&#039;&#039;uncheck it.&#039;&#039;&#039; With continue mode on, you press Esc constantly to drop tools, and every so often you&#039;ll press it once too often and get dumped out of the sketch. Unchecking this makes Esc only ever cancel the active tool; you leave the sketch with the &#039;&#039;&#039;Close&#039;&#039;&#039; button instead.&lt;br /&gt;
* &#039;&#039;&#039;Dimensioning constraints&#039;&#039;&#039;: leave on &amp;lt;code&amp;gt;Single tool&amp;lt;/code&amp;gt;. This gives you the unified [[File:FC-Sk-Dimension.svg|24px|link=|alt=Dimension constraint]] &#039;&#039;&#039;Dimension&#039;&#039;&#039; tool on &#039;&#039;&#039;D&#039;&#039;&#039;, which behaves like Fusion&#039;s single dimension command — pick geometry and it works out whether you want a length, a radius, an angle or a distance.&lt;br /&gt;
* &#039;&#039;&#039;Unify Coincident and PointOnObject&#039;&#039;&#039;: leave on. One [[File:FC-Sk-Coincident.svg|24px|link=|alt=Coincident constraint]] &#039;&#039;&#039;C&#039;&#039;&#039; key handles coincident, concentric and point-on-edge.&lt;br /&gt;
* &#039;&#039;&#039;Auto tool for Horizontal/Vertical&#039;&#039;&#039;: leave on. One [[File:FC-Sk-HorVer.svg|24px|link=|alt=Horizontal/vertical constraint]] &#039;&#039;&#039;A&#039;&#039;&#039; key applies whichever of horizontal/vertical is closer.&lt;br /&gt;
* &#039;&#039;&#039;On-View-Parameters&#039;&#039;&#039;: set to &#039;&#039;&#039;&amp;lt;code&amp;gt;Dimensional and positional&amp;lt;/code&amp;gt;&#039;&#039;&#039;. This gives you the little input boxes that appear next to the cursor as you draw, so you can type &amp;lt;code&amp;gt;40&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;Tab&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;25&amp;lt;/code&amp;gt; instead of clicking approximately and dimensioning afterwards. It&#039;s very close to how you already sketch in Fusion, and it creates the constraints for you automatically.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → Sketcher → Display&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Show coordinates beside cursor&#039;&#039;&#039;: on.&lt;br /&gt;
* &#039;&#039;&#039;Ask for value after creating a dimensional constraint&#039;&#039;&#039;: on (default). Keeps the type-the-number rhythm.&lt;br /&gt;
* &#039;&#039;&#039;Grid&#039;&#039;&#039; and &#039;&#039;&#039;Snap&#039;&#039;&#039;: personal taste. Snapping does &#039;&#039;not&#039;&#039; create constraints by itself, so don&#039;t rely on it for accuracy.&lt;br /&gt;
&lt;br /&gt;
=== 2.7 Turn on the panels you&#039;ll want ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;View → Panels&#039;&#039;&#039;: enable &#039;&#039;&#039;Report view&#039;&#039;&#039; and &#039;&#039;&#039;Selection view&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;Report view&#039;&#039;&#039; is where FreeCAD tells you &#039;&#039;why&#039;&#039; something failed. When a Pad refuses and the dialog just says &amp;quot;failed&amp;quot;, the real reason is in here. Non-negotiable.&lt;br /&gt;
* The &#039;&#039;&#039;Selection view&#039;&#039;&#039; shows the internal name of whatever you clicked (&amp;lt;code&amp;gt;Body.Face7&amp;lt;/code&amp;gt;). Useful when a fillet complains about a face you can&#039;t identify.&lt;br /&gt;
&lt;br /&gt;
Also set &#039;&#039;&#039;Preferences → General → Report view → Redirect internal Python errors to report view&#039;&#039;&#039;: on, and give warnings a colour.&lt;br /&gt;
&lt;br /&gt;
=== 2.8 Save your setup ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tools → Save preferences to file&#039;&#039;&#039; (or just copy &amp;lt;code&amp;gt;user.cfg&amp;lt;/code&amp;gt; from your FreeCAD config folder). Do it now so a reinstall doesn&#039;t cost you this half hour again.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 3. The interface ==&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Fig-Interface.svg|thumb|center|800px|Annotated FreeCAD 1.1 window with Fusion equivalents]]&lt;br /&gt;
&lt;br /&gt;
The layout is fixed panels rather than Fusion&#039;s floating dialogs. Two things deserve special attention:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The Tasks panel shares a dock with the Model tree.&#039;&#039;&#039; When you start a Pad, the panel switches from Model to Tasks and the tree disappears. That&#039;s normal — it&#039;s not a bug, and the tabs at the top of the panel switch back. This is why you can&#039;t easily click tree items mid-command the way you can in Fusion&#039;s browser.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The Property editor is the thing Fusion doesn&#039;t have.&#039;&#039;&#039; Select any feature in the tree and its full parameter list appears at the bottom-left, live-editable. You do not need to re-open a Pad&#039;s dialog to change its length — click the Pad, click the Length field, type. Once this clicks, it&#039;s faster than Fusion for parametric tweaking. Two tabs at the bottom: &#039;&#039;&#039;Data&#039;&#039;&#039; (the parametric properties) and &#039;&#039;&#039;View&#039;&#039;&#039; (colour, transparency, display mode).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 4. Vocabulary: Fusion → FreeCAD ==&lt;br /&gt;
&lt;br /&gt;
Before the table, the structural difference — Fusion&#039;s Browser and Timeline are one thing in FreeCAD:&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Fig-TreeVsTimeline.svg|thumb|center|760px|Fusion browser and timeline vs the FreeCAD model tree]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Fusion 360&lt;br /&gt;
! FreeCAD 1.1&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Design workspace&lt;br /&gt;
| Part Design workbench&lt;br /&gt;
| Plus Sketcher, which opens automatically&lt;br /&gt;
|-&lt;br /&gt;
| Project / design file&lt;br /&gt;
| Document (&amp;lt;code&amp;gt;.FCStd&amp;lt;/code&amp;gt;)&lt;br /&gt;
| A plain zip file. Local, not cloud. One document can hold many Bodies.&lt;br /&gt;
|-&lt;br /&gt;
| Component&lt;br /&gt;
| [[File:FC-Body.svg|24px|link=|alt=Create body]] Body (or a &#039;&#039;&#039;Part&#039;&#039;&#039; container for grouping)&lt;br /&gt;
| Body = one solid. Part = a folder with its own placement.&lt;br /&gt;
|-&lt;br /&gt;
| Body&lt;br /&gt;
| The solid inside a Body&lt;br /&gt;
| Not the same word. Painful, but true.&lt;br /&gt;
|-&lt;br /&gt;
| Browser&lt;br /&gt;
| Model tree&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Timeline&lt;br /&gt;
| Also the Model tree&lt;br /&gt;
| Order top-to-bottom = history&lt;br /&gt;
|-&lt;br /&gt;
| Timeline marker position&lt;br /&gt;
| &#039;&#039;&#039;Tip&#039;&#039;&#039;&lt;br /&gt;
| Right-click a feature → &#039;&#039;Set tip&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| Suppress feature&lt;br /&gt;
| Right-click → &#039;&#039;&#039;Suppressed&#039;&#039;&#039;&lt;br /&gt;
| Checkbox, added in 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Origin planes&lt;br /&gt;
| &#039;&#039;&#039;Origin&#039;&#039;&#039; group inside each Body&lt;br /&gt;
| XY, XZ, YZ planes plus the three axes&lt;br /&gt;
|-&lt;br /&gt;
| Construction plane / axis / point&lt;br /&gt;
| &#039;&#039;&#039;Datum&#039;&#039;&#039; plane / line / point / coordinate system&lt;br /&gt;
| Rebuilt in 1.1 as core datums&lt;br /&gt;
|-&lt;br /&gt;
| Parameters dialog&lt;br /&gt;
| &#039;&#039;&#039;Spreadsheet&#039;&#039;&#039; workbench + aliases&lt;br /&gt;
| See [[#10. Parameters and expressions|section 10]]&lt;br /&gt;
|-&lt;br /&gt;
| Joint&lt;br /&gt;
| Assembly workbench &#039;&#039;&#039;Joint&#039;&#039;&#039;&lt;br /&gt;
| Only needed for fit checks and print-in-place&lt;br /&gt;
|-&lt;br /&gt;
| Extrude&lt;br /&gt;
| [[File:FC-Pad.svg|24px|link=|alt=Pad]] &#039;&#039;&#039;Pad&#039;&#039;&#039; (adds) / [[File:FC-Pocket.svg|24px|link=|alt=Pocket]] &#039;&#039;&#039;Pocket&#039;&#039;&#039; (removes)&lt;br /&gt;
| Two separate commands, not one with a direction&lt;br /&gt;
|-&lt;br /&gt;
| Revolve&lt;br /&gt;
| [[File:FC-Revolution.svg|24px|link=|alt=Revolution]] &#039;&#039;&#039;Revolution&#039;&#039;&#039; / [[File:FC-Groove.svg|24px|link=|alt=Groove]] &#039;&#039;&#039;Groove&#039;&#039;&#039;&lt;br /&gt;
| Same additive/subtractive split&lt;br /&gt;
|-&lt;br /&gt;
| Sweep&lt;br /&gt;
| [[File:FC-Pipe.svg|24px|link=|alt=Additive pipe]] &#039;&#039;&#039;Additive pipe&#039;&#039;&#039; / Subtractive pipe&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Loft&lt;br /&gt;
| [[File:FC-Loft.svg|24px|link=|alt=Additive loft]] &#039;&#039;&#039;Additive loft&#039;&#039;&#039; / Subtractive loft&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Coil&lt;br /&gt;
| [[File:FC-Helix.svg|24px|link=|alt=Additive helix]] &#039;&#039;&#039;Additive helix&#039;&#039;&#039; / Subtractive helix&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Hole&lt;br /&gt;
| [[File:FC-Hole.svg|24px|link=|alt=Hole]] &#039;&#039;&#039;Hole&#039;&#039;&#039;&lt;br /&gt;
| Sketch circles first, then apply Hole to them&lt;br /&gt;
|-&lt;br /&gt;
| Fillet&lt;br /&gt;
| [[File:FC-Fillet.svg|24px|link=|alt=Fillet]] &#039;&#039;&#039;Fillet&#039;&#039;&#039;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Chamfer&lt;br /&gt;
| [[File:FC-Chamfer.svg|24px|link=|alt=Chamfer]] &#039;&#039;&#039;Chamfer&#039;&#039;&#039;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Shell&lt;br /&gt;
| [[File:FC-Thickness.svg|24px|link=|alt=Thickness]] &#039;&#039;&#039;Thickness&#039;&#039;&#039;&lt;br /&gt;
| Select the face(s) to open, then run it&lt;br /&gt;
|-&lt;br /&gt;
| Draft&lt;br /&gt;
| [[File:FC-Draft.svg|24px|link=|alt=Draft]] &#039;&#039;&#039;Draft&#039;&#039;&#039;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Rectangular pattern&lt;br /&gt;
| [[File:FC-LinearPattern.svg|24px|link=|alt=LinearPattern]] &#039;&#039;&#039;LinearPattern&#039;&#039;&#039;&lt;br /&gt;
| Patterns &#039;&#039;features&#039;&#039;, not faces&lt;br /&gt;
|-&lt;br /&gt;
| Circular pattern&lt;br /&gt;
| [[File:FC-PolarPattern.svg|24px|link=|alt=PolarPattern]] &#039;&#039;&#039;PolarPattern&#039;&#039;&#039;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Mirror&lt;br /&gt;
| [[File:FC-Mirrored.svg|24px|link=|alt=Mirrored]] &#039;&#039;&#039;Mirrored&#039;&#039;&#039;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Combine (cut/join/intersect)&lt;br /&gt;
| [[File:FC-Boolean.svg|24px|link=|alt=Boolean]] &#039;&#039;&#039;Boolean&#039;&#039;&#039; (in Part Design, between Bodies) or the &#039;&#039;&#039;Part&#039;&#039;&#039; workbench booleans&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Move/Copy&lt;br /&gt;
| &#039;&#039;&#039;Transform&#039;&#039;&#039; (overhauled in 1.1 — draggers + numeric input)&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Measure&lt;br /&gt;
| [[File:FC-Std-Measure.svg|24px|link=|alt=Measure]] &#039;&#039;&#039;Measure&#039;&#039;&#039; (Tools menu)&lt;br /&gt;
| Unified tool, works across workbenches&lt;br /&gt;
|-&lt;br /&gt;
| Project geometry&lt;br /&gt;
| [[File:FC-Sk-External.svg|24px|link=|alt=External geometry]] &#039;&#039;&#039;External geometry&#039;&#039;&#039; — in 1.1, &#039;&#039;Projection&#039;&#039; and &#039;&#039;Intersection&#039;&#039;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Construction geometry&lt;br /&gt;
| [[File:FC-Sk-Construction.svg|24px|link=|alt=Construction geometry]] &#039;&#039;&#039;Toggle construction geometry&#039;&#039;&#039;&lt;br /&gt;
| Blue dashed&lt;br /&gt;
|-&lt;br /&gt;
| Capture Position / Ground&lt;br /&gt;
| Constrain the sketch, and attach it properly&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Export STL&lt;br /&gt;
| [[File:FC-Std-Export.svg|24px|link=|alt=Export]] &#039;&#039;&#039;File → Export&#039;&#039;&#039;, pick &amp;lt;code&amp;gt;.stl&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;.3mf&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 5. The modelling loop ==&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Fig-ModellingLoop.svg|thumb|center|760px|The Part Design modelling loop]]&lt;br /&gt;
&lt;br /&gt;
Concretely, from an empty FreeCAD:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Ctrl+N&#039;&#039;&#039; — new document.&lt;br /&gt;
# Workbench dropdown → &#039;&#039;&#039;Part Design&#039;&#039;&#039;.&lt;br /&gt;
# [[File:FC-Body.svg|24px|link=|alt=Create body]] &#039;&#039;&#039;Create body&#039;&#039;&#039; (the first button on the Part Design toolbar). A Body appears in the tree with an Origin inside it.&lt;br /&gt;
# [[File:FC-NewSketch.svg|24px|link=|alt=Create sketch]] &#039;&#039;&#039;Create sketch&#039;&#039;&#039;. Because nothing is selected, the Tasks panel asks which plane. Pick &#039;&#039;&#039;XY_Plane&#039;&#039;&#039; for a part that sits flat on the print bed — this is the right default answer nearly every time for FDM.&lt;br /&gt;
# Draw and constrain. Close the sketch.&lt;br /&gt;
# With the sketch selected, [[File:FC-Pad.svg|24px|link=|alt=Pad]] &#039;&#039;&#039;Pad&#039;&#039;&#039;. Enter a length. OK.&lt;br /&gt;
# Click a flat face of the result, [[File:FC-NewSketch.svg|24px|link=|alt=Create sketch]] &#039;&#039;&#039;Create sketch&#039;&#039;&#039; again — it lands on that face.&lt;br /&gt;
# Draw, constrain, close, [[File:FC-Pocket.svg|24px|link=|alt=Pocket]] &#039;&#039;&#039;Pocket&#039;&#039;&#039;.&lt;br /&gt;
# Repeat. Add [[File:FC-Fillet.svg|24px|link=|alt=Fillet]] fillets and [[File:FC-Chamfer.svg|24px|link=|alt=Chamfer]] chamfers last.&lt;br /&gt;
# &#039;&#039;&#039;Ctrl+S&#039;&#039;&#039;. Then export.&lt;br /&gt;
&lt;br /&gt;
That&#039;s the whole workflow. Everything else in this document is detail hanging off those ten steps.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;One orientation note specific to printing:&#039;&#039;&#039; decide early which face is the bed. Sketch your footprint on the &#039;&#039;&#039;XY plane&#039;&#039;&#039; and pad upward. FreeCAD&#039;s XY plane is the ground plane in the 3D view, and every slicer will import the part in the same orientation you modelled it. Getting this right means you never have to re-orient in the slicer, which in turn means your overhang and support decisions stay in one place.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 6. Sketching — where the real difference is ==&lt;br /&gt;
&lt;br /&gt;
Fusion&#039;s sketcher is forgiving and quietly fixes things for you. FreeCAD&#039;s is stricter, more explicit, and — once you adapt — more predictable. It is also where you&#039;ll spend most of your first week.&lt;br /&gt;
&lt;br /&gt;
=== 6.1 The rules for a sketch that will actually extrude ===&lt;br /&gt;
&lt;br /&gt;
A profile sketch must be:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Closed.&#039;&#039;&#039; No gaps, however microscopic. A 0.001 mm gap gives you a surface instead of a solid.&lt;br /&gt;
* &#039;&#039;&#039;Non-self-intersecting.&#039;&#039;&#039; No crossing lines.&lt;br /&gt;
* &#039;&#039;&#039;Free of shared edges and T-junctions.&#039;&#039;&#039; More than two edges meeting at a point is not allowed. No duplicate overlapping lines.&lt;br /&gt;
&lt;br /&gt;
Nested closed loops are fine and produce holes — draw a rectangle with a circle inside it and Pad it, and you get a plate with a hole. This is the cheapest way to make holes and often better than the Hole feature.&lt;br /&gt;
&lt;br /&gt;
Anything you don&#039;t want extruded should be [[File:FC-Sk-Construction.svg|24px|link=|alt=Construction geometry]] &#039;&#039;&#039;construction geometry&#039;&#039;&#039; (blue dashed). Construction lines are enormously useful: draw a construction line between two points, constrain it, and hang real geometry off it.&lt;br /&gt;
&lt;br /&gt;
=== 6.2 Constraints, and the DoF counter ===&lt;br /&gt;
&lt;br /&gt;
The status bar shows something like &amp;lt;code&amp;gt;Under-constrained: 4 DoF&amp;lt;/code&amp;gt;. Click that message and FreeCAD selects the elements still free to move. When it reads &#039;&#039;&#039;Fully constrained&#039;&#039;&#039;, the whole sketch turns green and you&#039;re done.&lt;br /&gt;
&lt;br /&gt;
Two rules of thumb:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Geometric constraints first, dimensions second.&#039;&#039;&#039; Get everything horizontal/vertical/tangent/equal, &#039;&#039;then&#039;&#039; add numbers. Doing it in the other order produces sketches that fight you.&lt;br /&gt;
* &#039;&#039;&#039;Anchor to the origin.&#039;&#039;&#039; At least one point in every sketch should be tied to the sketch origin — with a coincident constraint, or a symmetry constraint about an axis. A sketch floating in space is one edit away from sliding sideways.&lt;br /&gt;
&lt;br /&gt;
If your part is symmetric, [[File:FC-Sk-Symmetric.svg|24px|link=|alt=Symmetric constraint]] &#039;&#039;&#039;symmetry about the Y axis&#039;&#039;&#039; is worth two dimensions and makes the whole thing behave when you change widths later.&lt;br /&gt;
&lt;br /&gt;
The constraints you&#039;ll actually use, with their default keys:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Constraint&lt;br /&gt;
! Key&lt;br /&gt;
! Fusion equivalent&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Dimension.svg|24px|link=|alt=Dimension constraint]]&lt;br /&gt;
| Dimension (context-sensitive)&lt;br /&gt;
| &#039;&#039;&#039;D&#039;&#039;&#039;&lt;br /&gt;
| Sketch Dimension&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Coincident.svg|24px|link=|alt=Coincident constraint]]&lt;br /&gt;
| Coincident / concentric / point-on-object&lt;br /&gt;
| &#039;&#039;&#039;C&#039;&#039;&#039;&lt;br /&gt;
| Coincident&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-HorVer.svg|24px|link=|alt=Horizontal/vertical constraint]]&lt;br /&gt;
| Horizontal or vertical (auto)&lt;br /&gt;
| &#039;&#039;&#039;A&#039;&#039;&#039;&lt;br /&gt;
| Horizontal/Vertical&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Equal.svg|24px|link=|alt=Equal constraint]]&lt;br /&gt;
| Equal&lt;br /&gt;
| &#039;&#039;&#039;E&#039;&#039;&#039;&lt;br /&gt;
| Equal&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Tangent.svg|24px|link=|alt=Tangent constraint]]&lt;br /&gt;
| Tangent or collinear&lt;br /&gt;
| &#039;&#039;&#039;T&#039;&#039;&#039;&lt;br /&gt;
| Tangent&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Symmetric.svg|24px|link=|alt=Symmetric constraint]]&lt;br /&gt;
| Symmetric&lt;br /&gt;
| &#039;&#039;&#039;S&#039;&#039;&#039;&lt;br /&gt;
| Symmetry&lt;br /&gt;
|-&lt;br /&gt;
| —&lt;br /&gt;
| Parallel&lt;br /&gt;
| &#039;&#039;&#039;P&#039;&#039;&#039;&lt;br /&gt;
| Parallel&lt;br /&gt;
|-&lt;br /&gt;
| —&lt;br /&gt;
| Perpendicular&lt;br /&gt;
| &#039;&#039;&#039;N&#039;&#039;&#039;&lt;br /&gt;
| Perpendicular&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Lock.svg|24px|link=|alt=Lock constraint]]&lt;br /&gt;
| Lock (X and Y distance to origin)&lt;br /&gt;
| &#039;&#039;&#039;K, L&#039;&#039;&#039;&lt;br /&gt;
| Fix/Unfix&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The unified &#039;&#039;&#039;D&#039;&#039;&#039; key is the workhorse. Select one line → D → length. Select two circles → D → centre distance. Select a circle → D → diameter. Select two lines → D → angle. If it proposes the wrong constraint, press &#039;&#039;&#039;M&#039;&#039;&#039; to cycle through the alternatives before you click to place it.&lt;br /&gt;
&lt;br /&gt;
=== 6.3 Drawing tools ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Tool&lt;br /&gt;
! Key&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Line.svg|24px|link=|alt=Line]]&lt;br /&gt;
| Line&lt;br /&gt;
| &#039;&#039;&#039;G, L&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Polyline.svg|24px|link=|alt=Polyline]]&lt;br /&gt;
| Polyline (line/arc chains)&lt;br /&gt;
| &#039;&#039;&#039;G, M&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Rectangle.svg|24px|link=|alt=Rectangle]]&lt;br /&gt;
| Rectangle&lt;br /&gt;
| &#039;&#039;&#039;G, R&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Circle.svg|24px|link=|alt=Circle]]&lt;br /&gt;
| Circle&lt;br /&gt;
| &#039;&#039;&#039;G, C&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Arc.svg|24px|link=|alt=Arc]]&lt;br /&gt;
| Arc&lt;br /&gt;
| &#039;&#039;&#039;G, A&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Slot.svg|24px|link=|alt=Slot]]&lt;br /&gt;
| Slot&lt;br /&gt;
| &#039;&#039;&#039;G, S&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Fillet.svg|24px|link=|alt=Sketch fillet]]&lt;br /&gt;
| Fillet / chamfer between two edges&lt;br /&gt;
| &#039;&#039;&#039;G, F&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Trim.svg|24px|link=|alt=Trim]]&lt;br /&gt;
| Trim&lt;br /&gt;
| &#039;&#039;&#039;G, T&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Construction.svg|24px|link=|alt=Construction geometry]]&lt;br /&gt;
| Toggle construction geometry&lt;br /&gt;
| &#039;&#039;&#039;G, N&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Polyline&#039;&#039;&#039; is the tool to learn properly. It&#039;s FreeCAD&#039;s equivalent of Fusion&#039;s line tool with the arc-drag trick: while drawing, press &#039;&#039;&#039;M&#039;&#039;&#039; to cycle between line and several arc modes, so you can lay out a rounded outline in one continuous chain with the tangency constraints already applied.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rectangle&#039;&#039;&#039; in 1.0+ has modes too — press &#039;&#039;&#039;M&#039;&#039;&#039; to switch between corner-to-corner, centred, rounded-corner and offset-copy variants.&lt;br /&gt;
&lt;br /&gt;
=== 6.4 External geometry — and what changed in 1.1 ===&lt;br /&gt;
&lt;br /&gt;
Fusion&#039;s &amp;quot;project geometry&amp;quot; pulls edges of existing solids into your sketch. FreeCAD&#039;s equivalent is [[File:FC-Sk-External.svg|24px|link=|alt=External geometry]] &#039;&#039;&#039;External geometry&#039;&#039;&#039; (&#039;&#039;&#039;G, X&#039;&#039;&#039;), and &#039;&#039;&#039;1.1 changed it in a way that matters&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In 1.0 and earlier, projected external geometry came in as reference-only construction lines — you had to trace over them with real geometry to use them in a profile. &#039;&#039;&#039;In 1.1, projected external geometry is real, defining geometry by default.&#039;&#039;&#039; You can extrude directly against it. You can also toggle it to construction like anything else.&lt;br /&gt;
&lt;br /&gt;
1.1 also split it into two tools:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Projection&#039;&#039;&#039; — projects edges/faces flat onto the sketch plane. This is the Fusion &amp;quot;project&amp;quot; behaviour.&lt;br /&gt;
* &#039;&#039;&#039;Intersection&#039;&#039;&#039; — creates the edges where a solid actually &#039;&#039;crosses&#039;&#039; your sketch plane. There&#039;s no direct Fusion analogue and it&#039;s genuinely useful for cutting a slot through a curved wall.&lt;br /&gt;
&lt;br /&gt;
Both can now be driven by selecting a whole face rather than picking edges one at a time.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Two limitations worth knowing up front:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* You can only reference geometry in the &#039;&#039;&#039;same coordinate system&#039;&#039;&#039; — the same Body, the same Part container, or both at document level. To pull in geometry from a &#039;&#039;different&#039;&#039; Body, add a [[File:FC-SubShapeBinder.svg|24px|link=|alt=SubShapeBinder]] &#039;&#039;&#039;SubShapeBinder&#039;&#039;&#039; first. This is exactly the &amp;quot;make a lid that matches this box&amp;quot; situation.&lt;br /&gt;
* Every external reference creates a dependency on a specific face or edge of the upstream solid, and changing the upstream geometry enough can break it. Links to &#039;&#039;other sketches&#039;&#039; are more robust than links to solid faces, and the FreeCAD docs actively encourage them. Where you can get the same result by referencing an origin plane or a datum, do that instead.&lt;br /&gt;
&lt;br /&gt;
=== 6.5 Editing a sketch afterwards ===&lt;br /&gt;
&lt;br /&gt;
Double-click the sketch in the tree, or select it and press the &#039;&#039;&#039;Edit sketch&#039;&#039;&#039; button. To move a whole sketch to a different plane, select it and use &#039;&#039;&#039;Attach sketch&#039;&#039;&#039; (&amp;lt;code&amp;gt;Sketcher_MapSketch&amp;lt;/code&amp;gt;) — that&#039;s the Fusion &amp;quot;redefine sketch plane&amp;quot; equivalent.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 7. Part Design tools, mapped from Fusion ==&lt;br /&gt;
&lt;br /&gt;
=== 7.1 Additive ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Tool&lt;br /&gt;
! Notes for a Fusion user&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Pad.svg|24px|link=|alt=Pad]]&lt;br /&gt;
| &#039;&#039;&#039;Pad&#039;&#039;&#039;&lt;br /&gt;
| Fusion&#039;s Extrude-Join. Types: &amp;lt;code&amp;gt;Dimension&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;To last&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;To first&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Up to face&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Two dimensions&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Midplane&#039;&#039;&#039; checkbox = Fusion&#039;s symmetric extrude. &#039;&#039;&#039;Reversed&#039;&#039;&#039; flips direction. Set a &#039;&#039;&#039;taper angle&#039;&#039;&#039; here rather than adding a draft feature later.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Revolution.svg|24px|link=|alt=Revolution]]&lt;br /&gt;
| &#039;&#039;&#039;Revolution&#039;&#039;&#039;&lt;br /&gt;
| Needs an axis: a sketch construction line, an origin axis, or a datum line. Sketch must be closed and must not cross the axis.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Loft.svg|24px|link=|alt=Additive loft]]&lt;br /&gt;
| &#039;&#039;&#039;Additive loft&#039;&#039;&#039;&lt;br /&gt;
| Select the first sketch, run the tool, then add the others in the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Pipe.svg|24px|link=|alt=Additive pipe]]&lt;br /&gt;
| &#039;&#039;&#039;Additive pipe&#039;&#039;&#039;&lt;br /&gt;
| Sweep. Profile sketch + path sketch on different planes.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Helix.svg|24px|link=|alt=Additive helix]]&lt;br /&gt;
| &#039;&#039;&#039;Additive helix&#039;&#039;&#039;&lt;br /&gt;
| Coil. This is how you model threads if you want real modelled threads.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Primitive.svg|24px|link=|alt=Additive primitive]]&lt;br /&gt;
| &#039;&#039;&#039;Additive primitives&#039;&#039;&#039;&lt;br /&gt;
| Box, cylinder, sphere, cone, torus, prism, wedge — dropped straight into the Body without a sketch. Genuinely handy for quick blocking-out; Fusion has no clean equivalent inside a timeline.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 7.2 Subtractive ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Tool&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Pocket.svg|24px|link=|alt=Pocket]]&lt;br /&gt;
| &#039;&#039;&#039;Pocket&#039;&#039;&#039;&lt;br /&gt;
| Extrude-Cut. Same type options as Pad, plus &amp;lt;code&amp;gt;Through all&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Hole.svg|24px|link=|alt=Hole]]&lt;br /&gt;
| &#039;&#039;&#039;Hole&#039;&#039;&#039;&lt;br /&gt;
| Draw circles in a sketch, then run Hole. Gives you counterbore, countersink, tapered/straight, and real or cosmetic threads. 1.1 added Whitworth-family threads (BSW, BSF, BSP, NPT) and made modelled threads noticeably faster. &#039;&#039;&#039;For 3D printing, usually skip the thread modelling&#039;&#039;&#039; — print a plain hole and tap it, or print an oversized hole for a heat-set insert.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Groove.svg|24px|link=|alt=Groove]]&lt;br /&gt;
| &#039;&#039;&#039;Groove&#039;&#039;&#039;&lt;br /&gt;
| Revolved cut.&lt;br /&gt;
|-&lt;br /&gt;
| —&lt;br /&gt;
| &#039;&#039;&#039;Subtractive loft / pipe / helix / primitives&#039;&#039;&#039;&lt;br /&gt;
| Mirror images of the additive versions.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 7.3 Dress-up ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Tool&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Fillet.svg|24px|link=|alt=Fillet]]&lt;br /&gt;
| &#039;&#039;&#039;Fillet&#039;&#039;&#039;&lt;br /&gt;
| Select edges or a whole face (fillets every edge of it). 1.1 added interactive draggers so you can pull the radius in the 3D view.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Chamfer.svg|24px|link=|alt=Chamfer]]&lt;br /&gt;
| &#039;&#039;&#039;Chamfer&#039;&#039;&#039;&lt;br /&gt;
| Equal-distance, two-distance, or distance-and-angle. Draggers in 1.1 as well.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Draft.svg|24px|link=|alt=Draft]]&lt;br /&gt;
| &#039;&#039;&#039;Draft&#039;&#039;&#039;&lt;br /&gt;
| Needs a neutral plane, same as Fusion.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Thickness.svg|24px|link=|alt=Thickness]]&lt;br /&gt;
| &#039;&#039;&#039;Thickness&#039;&#039;&#039;&lt;br /&gt;
| Shell. Select the face(s) to remove, then run it. Positive thickness goes outward, negative inward — the opposite of what most people expect, so check the preview.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fillets are the most failure-prone feature in FreeCAD, exactly as in Fusion but slightly more so.&#039;&#039;&#039; Rules that keep you out of trouble:&lt;br /&gt;
&lt;br /&gt;
* Add them &#039;&#039;&#039;last&#039;&#039;&#039;, as the final features in the tree.&lt;br /&gt;
* Group edges that will get the same radius into &#039;&#039;&#039;one&#039;&#039;&#039; fillet feature rather than several — fewer, larger features are more robust than many small ones.&lt;br /&gt;
* Never fillet an edge where three or more fillets will meet at a corner in one go. Do the big ones first as a separate feature, then the small ones.&lt;br /&gt;
* If a fillet fails, halve the radius and try again. If that works, the geometry is too tight, not the software.&lt;br /&gt;
* Turn on the &#039;&#039;&#039;refine&#039;&#039;&#039; preferences from [[#2.5 Part Design behaviour|2.5]] — a surprising number of &amp;quot;impossible&amp;quot; fillets are actually failing on an invisible seam edge.&lt;br /&gt;
* &#039;&#039;&#039;For 3D printing, prefer chamfers on the bottom edge.&#039;&#039;&#039; A 0.6 mm chamfer on the first layer perimeter removes elephant&#039;s foot and prints better than a fillet.&lt;br /&gt;
&lt;br /&gt;
=== 7.4 Transformations ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Tool&lt;br /&gt;
! The important difference&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-LinearPattern.svg|24px|link=|alt=LinearPattern]]&lt;br /&gt;
| &#039;&#039;&#039;LinearPattern&#039;&#039;&#039;&lt;br /&gt;
| Patterns &#039;&#039;&#039;features&#039;&#039;&#039;, not faces or bodies. You select which features from the tree get repeated.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-PolarPattern.svg|24px|link=|alt=PolarPattern]]&lt;br /&gt;
| &#039;&#039;&#039;PolarPattern&#039;&#039;&#039;&lt;br /&gt;
| Same. Needs an axis.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Mirrored.svg|24px|link=|alt=Mirrored]]&lt;br /&gt;
| &#039;&#039;&#039;Mirrored&#039;&#039;&#039;&lt;br /&gt;
| Same. Mirror plane is usually an Origin plane.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Transform.svg|24px|link=|alt=Transform]]&lt;br /&gt;
| &#039;&#039;&#039;MultiTransform&#039;&#039;&#039;&lt;br /&gt;
| Chains several transforms into one feature — e.g. mirror then pattern. Also the only place to get &#039;&#039;&#039;Scaled&#039;&#039;&#039;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This &amp;quot;patterns operate on features&amp;quot; model is different from Fusion, where you pattern faces or bodies. It&#039;s stricter, but it means the pattern updates correctly when you change the original feature. If you want to pattern something that isn&#039;t a feature — a whole Body, say — use the &#039;&#039;&#039;Draft&#039;&#039;&#039; workbench&#039;s array tools, or the Part workbench.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 8. Reference geometry and attachment ==&lt;br /&gt;
&lt;br /&gt;
Every Body contains an &#039;&#039;&#039;Origin&#039;&#039;&#039; group: XY, XZ, YZ planes and X, Y, Z axes. They&#039;re hidden by default; select one in the tree and press &#039;&#039;&#039;Space&#039;&#039;&#039; to show it. These are your primary references and you should prefer them over faces wherever you can.&lt;br /&gt;
&lt;br /&gt;
When you need more, FreeCAD 1.1 replaced the old Part Design datum tools with &#039;&#039;&#039;core datums&#039;&#039;&#039;, available from the Part Design toolbar and now usable in the Assembly workbench too:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Datum&lt;br /&gt;
! Fusion equivalent&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-DatumPlane.svg|24px|link=|alt=Datum plane]]&lt;br /&gt;
| Datum plane&lt;br /&gt;
| Construction plane&lt;br /&gt;
|-&lt;br /&gt;
| —&lt;br /&gt;
| Datum line&lt;br /&gt;
| Construction axis&lt;br /&gt;
|-&lt;br /&gt;
| —&lt;br /&gt;
| Datum point&lt;br /&gt;
| Construction point&lt;br /&gt;
|-&lt;br /&gt;
| —&lt;br /&gt;
| Local coordinate system&lt;br /&gt;
| — (no direct equivalent)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The mechanism behind them is &#039;&#039;&#039;attachment&#039;&#039;&#039;, and it&#039;s more powerful than Fusion&#039;s offset-plane dialog but less obvious. Select the reference geometry first, then create the datum; the &#039;&#039;&#039;Attachment&#039;&#039;&#039; dialog offers modes (&amp;lt;code&amp;gt;FlatFace&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Object&#039;s XY&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Concentric&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Normal to edge&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Plane by 3 points&amp;lt;/code&amp;gt;…) plus numeric offsets in the attachment&#039;s own coordinate system.&lt;br /&gt;
&lt;br /&gt;
Any sketch has the same &#039;&#039;&#039;Attachment&#039;&#039;&#039; properties in the Property editor — an offset sketch plane is just a sketch attached to &amp;lt;code&amp;gt;XY_Plane&amp;lt;/code&amp;gt; with a Z offset, no datum needed. That&#039;s usually the quickest route.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Practical advice:&#039;&#039;&#039; for printed parts, 90% of your sketches should attach to an Origin plane or a flat face, and you&#039;ll rarely need a datum at all. Reach for them for angled features and for revolve axes.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 9. Editing history: the tip, suppression, reordering ==&lt;br /&gt;
&lt;br /&gt;
The tree &#039;&#039;is&#039;&#039; the timeline. Four operations you&#039;ll want:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Roll back — &amp;quot;Set tip&amp;quot;.&#039;&#039;&#039; Right-click a feature → [[File:FC-Std-Tip.svg|24px|link=|alt=Tip]] &#039;&#039;&#039;Set tip&#039;&#039;&#039;. Everything below it is hidden and any new feature you create is inserted at that point. This is Fusion&#039;s drag-the-marker-back. The tip feature is shown in bold. Remember to set the tip back to the last feature when you&#039;re done, or you&#039;ll export an incomplete part.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Suppress.&#039;&#039;&#039; Right-click → &#039;&#039;&#039;Suppressed&#039;&#039;&#039; (checkbox, added in 1.0). Switches a feature off without deleting it. Useful for making a &amp;quot;no holes&amp;quot; variant, or for isolating which feature broke a fillet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reorder.&#039;&#039;&#039; Right-click → &#039;&#039;&#039;Move object after other object&#039;&#039;&#039;. Fusion&#039;s drag-in-timeline. Use it to push fillets to the end where they belong.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Move between bodies.&#039;&#039;&#039; Right-click → &#039;&#039;&#039;Move object to other body&#039;&#039;&#039;. Useful when you realise a feature should have been a separate part.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Edit a feature&#039;s parameters&#039;&#039;&#039; — just click it and use the Property editor. Double-click opens the full dialog if you need the face selections.&lt;br /&gt;
&lt;br /&gt;
One behaviour to know: FreeCAD recomputes eagerly. If a downstream feature can&#039;t rebuild after your edit, it goes red in the tree with a marker. Fix the cause and hit [[File:FC-Std-Refresh.svg|24px|link=|alt=Refresh]] &#039;&#039;&#039;Refresh&#039;&#039;&#039; (Std_Refresh) to force a full recompute. If the tree looks stale, right-click the document → &#039;&#039;&#039;Mark to recompute&#039;&#039;&#039; → then Refresh.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 10. Parameters and expressions ==&lt;br /&gt;
&lt;br /&gt;
Fusion has a Parameters dialog. FreeCAD&#039;s equivalent is a [[File:FC-WB-Spreadsheet.svg|24px|link=|alt=Spreadsheet workbench]] &#039;&#039;&#039;Spreadsheet&#039;&#039;&#039; inside the document, and it&#039;s more capable once set up.&lt;br /&gt;
&lt;br /&gt;
# Workbench dropdown → &#039;&#039;&#039;Spreadsheet&#039;&#039;&#039; → &#039;&#039;&#039;Create spreadsheet&#039;&#039;&#039;.&lt;br /&gt;
# Put a label in column A and the value in column B: &amp;lt;code&amp;gt;wall_thickness&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;2.4&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Click the B cell, and in the &#039;&#039;&#039;Alias&#039;&#039;&#039; box (or right-click → Properties → Alias) type &amp;lt;code&amp;gt;wall_thickness&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Back in Part Design, anywhere you can type a number, click the small &#039;&#039;&#039;fx&#039;&#039;&#039; (blue circle) icon at the right of the field and enter &amp;lt;code&amp;gt;Spreadsheet.wall_thickness&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Now change the spreadsheet and the model follows. You can use full arithmetic in expressions: &amp;lt;code&amp;gt;Spreadsheet.wall_thickness * 2 + 0.4&amp;lt;/code&amp;gt;, and reference other features: &amp;lt;code&amp;gt;Pad.Length / 2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;A printing-specific setup that pays for itself immediately&#039;&#039;&#039; — put these in a spreadsheet at the top of every project:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Alias&lt;br /&gt;
! Typical value&lt;br /&gt;
! Used for&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;nozzle&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;0.4&amp;lt;/code&amp;gt;&lt;br /&gt;
| Making wall thicknesses exact multiples&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;layer&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;0.2&amp;lt;/code&amp;gt;&lt;br /&gt;
| Making heights exact multiples&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;wall&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;=nozzle * 6&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;2.4&amp;lt;/code&amp;gt;&lt;br /&gt;
| Every wall in the part&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clearance_slip&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;0.2&amp;lt;/code&amp;gt;&lt;br /&gt;
| Holes that parts slide into&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clearance_press&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;0.05&amp;lt;/code&amp;gt;&lt;br /&gt;
| Press fits&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clearance_moving&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;0.4&amp;lt;/code&amp;gt;&lt;br /&gt;
| Print-in-place hinges&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Then a hole for a 5 mm rod becomes &amp;lt;code&amp;gt;5 + Spreadsheet.clearance_slip * 2&amp;lt;/code&amp;gt;, and when you switch filament or printer you retune one cell instead of forty dimensions. This is the single biggest quality-of-life win available in FreeCAD for print design, and it&#039;s better than Fusion&#039;s parameters because the spreadsheet can do arithmetic between its own cells.&lt;br /&gt;
&lt;br /&gt;
You can also name individual sketch constraints (there&#039;s a name field in the dimension dialog) and reference them as &amp;lt;code&amp;gt;Sketch.Constraints.hole_dia&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 11. Multiple bodies, and assemblies for fit checks ==&lt;br /&gt;
&lt;br /&gt;
=== 11.1 Two parts in one file ===&lt;br /&gt;
&lt;br /&gt;
Because a Body holds one solid, a two-piece design means two Bodies in the same document. Create the second with [[File:FC-Body.svg|24px|link=|alt=Create body]] &#039;&#039;&#039;Create body&#039;&#039;&#039; — note that this makes it the &#039;&#039;active&#039;&#039; body (shown in bold), and all new features go into it. Double-click a Body in the tree to switch which one is active. Forgetting this is the classic &amp;quot;why did my pocket cut the wrong part&amp;quot; mistake.&lt;br /&gt;
&lt;br /&gt;
To position them relative to each other without a full assembly, select a Body and edit its &#039;&#039;&#039;Placement&#039;&#039;&#039; in the Property editor, or use the 1.1 &#039;&#039;&#039;Transform&#039;&#039;&#039; tool, which now has proper draggers, numeric entry, alignment to any element, and a move-to-target function.&lt;br /&gt;
&lt;br /&gt;
To make a second body reference geometry from the first, use [[File:FC-SubShapeBinder.svg|24px|link=|alt=SubShapeBinder]] &#039;&#039;&#039;SubShapeBinder&#039;&#039;&#039; — it pulls a face or edge across as a reference you can sketch on. This is the correct answer to &amp;quot;how do I make a lid that matches this box&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== 11.2 The Assembly workbench ===&lt;br /&gt;
&lt;br /&gt;
For anything with moving parts, or where you want to check clearances before committing to a 6-hour print, use [[File:FC-WB-Assembly.svg|24px|link=|alt=Assembly workbench]] &#039;&#039;&#039;Assembly&#039;&#039;&#039; (built in since 1.0, improved in 1.1 with &#039;&#039;Insert new part&#039;&#039; and &#039;&#039;Create simulation&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Basic flow: create an Assembly container, insert your Bodies (or link parts from other documents), then add &#039;&#039;&#039;Joints&#039;&#039;&#039; — Fixed, Revolute, Slider, Cylindrical, Ball, Distance. It&#039;s conceptually the same as Fusion&#039;s joints, and the solver is decent.&lt;br /&gt;
&lt;br /&gt;
For print-in-place mechanisms, the assembly is how you verify a hinge actually swings before you print it. 1.1 added kinematic &#039;&#039;&#039;simulation&#039;&#039;&#039; with animation preview, which makes this genuinely quick.&lt;br /&gt;
&lt;br /&gt;
Honest assessment: FreeCAD&#039;s assembly is younger and less polished than Fusion&#039;s. For the scale of thing most 3D printing involves — a handful of parts, a couple of joints — it&#039;s perfectly adequate. Don&#039;t try to build a 200-part machine in it yet.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 12. Exporting for the slicer ==&lt;br /&gt;
&lt;br /&gt;
=== 12.1 The quick way ===&lt;br /&gt;
&lt;br /&gt;
# Select the &#039;&#039;&#039;Body&#039;&#039;&#039; in the tree (the Body, not a feature inside it).&lt;br /&gt;
# &#039;&#039;&#039;File → Export…&#039;&#039;&#039; (&#039;&#039;&#039;Ctrl+E&#039;&#039;&#039;).&lt;br /&gt;
# Choose the file type: &#039;&#039;&#039;&amp;lt;code&amp;gt;STL Mesh (*.stl)&amp;lt;/code&amp;gt;&#039;&#039;&#039; or &#039;&#039;&#039;&amp;lt;code&amp;gt;3MF (*.3mf)&amp;lt;/code&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
# Save.&lt;br /&gt;
&lt;br /&gt;
FreeCAD tessellates the solid on the fly using the settings below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Use 3MF if your slicer supports it&#039;&#039;&#039; (PrusaSlicer, OrcaSlicer, Bambu Studio, Cura all do). It&#039;s a modern container format, it stores units unambiguously, the files are smaller, and it survives multi-body exports better. FreeCAD 1.x imports and exports it. STL remains the safe universal fallback.&lt;br /&gt;
&lt;br /&gt;
Other formats worth knowing:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;STEP&#039;&#039;&#039; (&amp;lt;code&amp;gt;.step&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;.stp&amp;lt;/code&amp;gt;) — exact solid geometry, not a mesh. This is what you send to someone else for CAD work, and what you use to archive. Fusion can import it.&lt;br /&gt;
* &#039;&#039;&#039;OBJ&#039;&#039;&#039;, &#039;&#039;&#039;PLY&#039;&#039;&#039;, &#039;&#039;&#039;AMF&#039;&#039;&#039; — supported, rarely needed for printing.&lt;br /&gt;
&lt;br /&gt;
=== 12.2 Mesh quality — the setting that actually matters ===&lt;br /&gt;
&lt;br /&gt;
Default export settings will give you visibly faceted holes on small parts. Fix it once:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → Import-Export → Mesh formats&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Maximum mesh deviation (surface deviation)&#039;&#039;&#039;: default &amp;lt;code&amp;gt;0.10&amp;lt;/code&amp;gt; mm → set to &#039;&#039;&#039;&amp;lt;code&amp;gt;0.01&amp;lt;/code&amp;gt;&#039;&#039;&#039; mm&lt;br /&gt;
* &#039;&#039;&#039;Maximum angular deviation&#039;&#039;&#039;: default &amp;lt;code&amp;gt;30°&amp;lt;/code&amp;gt; → set to &#039;&#039;&#039;&amp;lt;code&amp;gt;10°&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Mesher&#039;&#039;&#039;: &amp;lt;code&amp;gt;Standard&amp;lt;/code&amp;gt; is fine. &amp;lt;code&amp;gt;Mefisto&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Netgen&amp;lt;/code&amp;gt; exist for special cases.&lt;br /&gt;
* &#039;&#039;&#039;STL format&#039;&#039;&#039;: leave on &#039;&#039;&#039;binary&#039;&#039;&#039; — ASCII STL files are roughly five times larger for no benefit.&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Fig-MeshDeviation.svg|thumb|center|760px|How mesh deviation affects a curved surface]]&lt;br /&gt;
&lt;br /&gt;
The resulting files are bigger — perhaps 2–4 MB instead of 500 KB for a typical part. No slicer or printer built in the last decade will care, and your curved surfaces will be smooth.&lt;br /&gt;
&lt;br /&gt;
=== 12.3 Checking the part before you print it ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Part → Check geometry&#039;&#039;&#039; (also on the Part Design toolbar as [[File:FC-Std-Measure.svg|24px|link=|alt=Measure]] a validation tool) runs an OpenCASCADE geometry check and reports invalid faces, self-intersections and open shells. It&#039;s improved in 1.1 — it now reports valid shapes and skipped objects too, and writes to the Report view.&lt;br /&gt;
&lt;br /&gt;
Run it on any part that took real effort, especially after lots of booleans. A solid that passes here will slice cleanly.&lt;br /&gt;
&lt;br /&gt;
For a visual check, switch the 3D view to &#039;&#039;&#039;View → Draw style → Wireframe&#039;&#039;&#039; or turn on transparency (&#039;&#039;&#039;View&#039;&#039;&#039; tab in the Property editor) to spot internal voids you didn&#039;t intend.&lt;br /&gt;
&lt;br /&gt;
=== 12.4 A note on scale ===&lt;br /&gt;
&lt;br /&gt;
FreeCAD works in millimetres and exports in millimetres. Slicers expect millimetres. Nothing to configure — this just works. If a part arrives in the slicer at 1/25.4 scale, you built it in inches by accident.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 13. Worked example: a parametric wall bracket ==&lt;br /&gt;
&lt;br /&gt;
An L-bracket with a reinforcing rib and mounting holes. Roughly twenty minutes, and it exercises everything above.&lt;br /&gt;
&lt;br /&gt;
=== Setup ===&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Ctrl+N&#039;&#039;&#039;.&lt;br /&gt;
# Switch to &#039;&#039;&#039;Spreadsheet&#039;&#039;&#039;, &#039;&#039;&#039;Create spreadsheet&#039;&#039;&#039;. Enter and alias:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Cell&lt;br /&gt;
! Content&lt;br /&gt;
! Alias&lt;br /&gt;
|-&lt;br /&gt;
| A1&lt;br /&gt;
| &amp;lt;code&amp;gt;thickness&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| B1&lt;br /&gt;
| &amp;lt;code&amp;gt;4&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;thickness&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| A2&lt;br /&gt;
| &amp;lt;code&amp;gt;width&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| B2&lt;br /&gt;
| &amp;lt;code&amp;gt;40&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;width&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| A3&lt;br /&gt;
| &amp;lt;code&amp;gt;arm&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| B3&lt;br /&gt;
| &amp;lt;code&amp;gt;60&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;arm&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| A4&lt;br /&gt;
| &amp;lt;code&amp;gt;bolt_dia&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| B4&lt;br /&gt;
| &amp;lt;code&amp;gt;5.4&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;bolt_dia&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
: (5.4 = M5 clearance plus a little printing allowance.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Switch to &#039;&#039;&#039;Part Design&#039;&#039;&#039; → [[File:FC-Body.svg|24px|link=|alt=Create body]] &#039;&#039;&#039;Create body&#039;&#039;&#039;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The L profile ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;4&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[File:FC-NewSketch.svg|24px|link=|alt=Create sketch]] &#039;&#039;&#039;Create sketch&#039;&#039;&#039; → &#039;&#039;&#039;XZ_Plane&#039;&#039;&#039;. This is the vertical plane facing you, so the L profile is drawn in elevation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Draw the L with [[File:FC-Sk-Polyline.svg|24px|link=|alt=Polyline]] &#039;&#039;&#039;Polyline&#039;&#039;&#039; (&#039;&#039;&#039;G, M&#039;&#039;&#039;): six segments, roughly L-shaped, closing back on itself. Don&#039;t aim for accuracy — get the shape.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Constrain it:&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;The bottom-left corner point → [[File:FC-Sk-Coincident.svg|24px|link=|alt=Coincident constraint]] &#039;&#039;&#039;C&#039;&#039;&#039; onto the sketch origin.&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Each segment → [[File:FC-Sk-HorVer.svg|24px|link=|alt=Horizontal/vertical constraint]] &#039;&#039;&#039;A&#039;&#039;&#039; for horizontal/vertical (auto-constraints will have caught most already).&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;The vertical arm&#039;s outer edge → &#039;&#039;&#039;D&#039;&#039;&#039;, and in the value box click &#039;&#039;&#039;fx&#039;&#039;&#039; and enter &amp;lt;code&amp;gt;Spreadsheet.arm&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Horizontal arm&#039;s outer edge → &#039;&#039;&#039;D&#039;&#039;&#039; → &amp;lt;code&amp;gt;Spreadsheet.arm&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Both wall thicknesses → &#039;&#039;&#039;D&#039;&#039;&#039; → &amp;lt;code&amp;gt;Spreadsheet.thickness&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Status bar should read &#039;&#039;&#039;Fully constrained&#039;&#039;&#039;, sketch fully green. If not, click the DoF message to see what&#039;s still loose.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Close&#039;&#039;&#039;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The body ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;9&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Select the sketch → [[File:FC-Pad.svg|24px|link=|alt=Pad]] &#039;&#039;&#039;Pad&#039;&#039;&#039;. Length: &#039;&#039;&#039;fx&#039;&#039;&#039; → &amp;lt;code&amp;gt;Spreadsheet.width&amp;lt;/code&amp;gt;. Tick &#039;&#039;&#039;Symmetric to plane&#039;&#039;&#039; so it grows evenly either side of the origin — this makes mirroring behave later. &#039;&#039;&#039;OK&#039;&#039;&#039;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The rib ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;10&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click the inside corner face — or easier, [[File:FC-NewSketch.svg|24px|link=|alt=Create sketch]] &#039;&#039;&#039;Create sketch&#039;&#039;&#039; on &#039;&#039;&#039;XZ_Plane&#039;&#039;&#039; again.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Draw a right triangle in the inner corner with &#039;&#039;&#039;Polyline&#039;&#039;&#039;. Constrain its two straight edges coincident with the projected inner faces (use [[File:FC-Sk-External.svg|24px|link=|alt=External geometry]] &#039;&#039;&#039;External geometry&#039;&#039;&#039;, &#039;&#039;&#039;G, X&#039;&#039;&#039;, to pull those edges in — remember in 1.1 they come in as real geometry you can constrain directly to).&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dimension the two legs to something like &amp;lt;code&amp;gt;arm * 0.5&amp;lt;/code&amp;gt; via expressions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Close → [[File:FC-Pad.svg|24px|link=|alt=Pad]] &#039;&#039;&#039;Pad&#039;&#039;&#039;, symmetric, length &amp;lt;code&amp;gt;Spreadsheet.thickness&amp;lt;/code&amp;gt;. &#039;&#039;&#039;OK&#039;&#039;&#039;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The holes ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;14&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click the outer face of the vertical arm. [[File:FC-NewSketch.svg|24px|link=|alt=Create sketch]] &#039;&#039;&#039;Create sketch&#039;&#039;&#039; — it attaches to that face.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Draw two [[File:FC-Sk-Circle.svg|24px|link=|alt=Circle]] circles (&#039;&#039;&#039;G, C&#039;&#039;&#039;).&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Constrain: [[File:FC-Sk-Symmetric.svg|24px|link=|alt=Symmetric constraint]] &#039;&#039;&#039;S&#039;&#039;&#039; to make them symmetric about the vertical axis, [[File:FC-Sk-Equal.svg|24px|link=|alt=Equal constraint]] &#039;&#039;&#039;E&#039;&#039;&#039; to make them equal diameter, then &#039;&#039;&#039;D&#039;&#039;&#039; on one → &#039;&#039;&#039;fx&#039;&#039;&#039; → &amp;lt;code&amp;gt;Spreadsheet.bolt_dia&amp;lt;/code&amp;gt;. Add a &#039;&#039;&#039;D&#039;&#039;&#039; from the top edge to fix their height.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Close. Select the sketch → [[File:FC-Hole.svg|24px|link=|alt=Hole]] &#039;&#039;&#039;Hole&#039;&#039;&#039;. Set &#039;&#039;&#039;Profile → Diameter&#039;&#039;&#039; to inherit from the sketch, &#039;&#039;&#039;Depth → Through all&#039;&#039;&#039;. If you want countersinks for M5 screws, set &#039;&#039;&#039;Hole cut type → Countersink&#039;&#039;&#039;. &#039;&#039;&#039;OK&#039;&#039;&#039;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Repeat on the horizontal arm.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dress up ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;19&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Select the two outer vertical edges of the bracket → [[File:FC-Fillet.svg|24px|link=|alt=Fillet]] &#039;&#039;&#039;Fillet&#039;&#039;&#039; → 3 mm.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Select the bottom face&#039;s perimeter edges → [[File:FC-Chamfer.svg|24px|link=|alt=Chamfer]] &#039;&#039;&#039;Chamfer&#039;&#039;&#039; → 0.6 mm. This is your elephant&#039;s-foot insurance.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Export ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;21&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Select the &#039;&#039;&#039;Body&#039;&#039;&#039; in the tree.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Ctrl+E&#039;&#039;&#039; → &amp;lt;code&amp;gt;3MF&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;STL&amp;lt;/code&amp;gt;) → save.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Now prove it&#039;s parametric ===&lt;br /&gt;
&lt;br /&gt;
Go back to the spreadsheet and change &amp;lt;code&amp;gt;thickness&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;4&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;6&amp;lt;/code&amp;gt;. Switch to Part Design. The whole bracket — profile, rib, chamfers — thickens, and the holes stay put. That&#039;s the payoff for constraining properly, and it&#039;s the moment FreeCAD usually starts to feel worth it.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 14. When things break ==&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;&amp;quot;Result has multiple solids&amp;quot;&#039;&#039;&#039; on a Pad or Pocket.&lt;br /&gt;
Your feature created material disconnected from the rest of the Body. Either connect it, or put it in its own Body. This is the one-solid-per-Body rule biting.&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;Pad button is greyed out.&#039;&#039;&#039;&lt;br /&gt;
No active Body, or no sketch selected. Double-click a Body in the tree to activate it (it goes bold).&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;&amp;quot;Cannot use this sketch — it is not closed&amp;quot; / you get a surface instead of a solid.&#039;&#039;&#039;&lt;br /&gt;
There&#039;s a gap or a duplicate edge. Close the sketch, select it, and run &#039;&#039;&#039;Sketch → Validate sketch&#039;&#039;&#039; — it will find and optionally repair missing coincidences.&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;Fillet or chamfer fails with no useful message.&#039;&#039;&#039;&lt;br /&gt;
Read the &#039;&#039;&#039;Report view&#039;&#039;&#039; for the real error. Then: reduce the radius; split it into two features; check that the refine preferences from [[#2.5 Part Design behaviour|2.5]] are on; make sure the fillet is the last feature in the tree.&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;A feature turns red after you edit something upstream.&#039;&#039;&#039;&lt;br /&gt;
Usually a broken face or edge reference. Double-click the failing feature, and re-pick the geometry. FreeCAD 1.0 and 1.1 substantially improved the topological naming problem — the classic FreeCAD complaint — and this happens far less than its reputation suggests, but it still happens. Referencing origin planes and datums instead of model faces is the prevention.&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;Everything is grey / you can&#039;t select the thing you want.&#039;&#039;&#039;&lt;br /&gt;
Try the 1.1 &#039;&#039;&#039;Clarify selection&#039;&#039;&#039; tool, which makes nearby geometry temporarily transparent so you can pick the entity underneath. Or hover and press the mouse-over selection cycling.&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;You padded into the wrong body.&#039;&#039;&#039;&lt;br /&gt;
Right-click the feature → &#039;&#039;&#039;Move object to other body&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;The model looks faceted in the 3D view.&#039;&#039;&#039;&lt;br /&gt;
That&#039;s display tessellation only, not your geometry. Fix it in [[#2.5 Part Design behaviour|2.5]]; it does not affect exports (those use the separate mesh-export settings in [[#12.2 Mesh quality — the setting that actually matters|12.2]]).&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;Esc dumped you out of the sketch.&#039;&#039;&#039;&lt;br /&gt;
Turn off &#039;&#039;Esc can leave sketch edit mode&#039;&#039; — see [[#2.6 Sketcher|2.6]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 15. Keyboard cheat sheet ==&lt;br /&gt;
&lt;br /&gt;
=== Global ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key&lt;br /&gt;
! Action&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Ctrl+N&#039;&#039;&#039; / &#039;&#039;&#039;Ctrl+O&#039;&#039;&#039; / &#039;&#039;&#039;Ctrl+S&#039;&#039;&#039;&lt;br /&gt;
| New / Open / Save&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Ctrl+E&#039;&#039;&#039;&lt;br /&gt;
| Export&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Ctrl+Z&#039;&#039;&#039; / &#039;&#039;&#039;Ctrl+Shift+Z&#039;&#039;&#039;&lt;br /&gt;
| Undo / Redo&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Space&#039;&#039;&#039;&lt;br /&gt;
| Toggle visibility of selected object&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;1&#039;&#039;&#039;–&#039;&#039;&#039;6&#039;&#039;&#039;&lt;br /&gt;
| Standard views (front, top, right, rear, bottom, left)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;0&#039;&#039;&#039;&lt;br /&gt;
| Isometric / axonometric&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;V, F&#039;&#039;&#039;&lt;br /&gt;
| Fit all (zoom to fit)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sketcher — geometry ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key&lt;br /&gt;
! Tool&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, L&#039;&#039;&#039;&lt;br /&gt;
| Line&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, M&#039;&#039;&#039;&lt;br /&gt;
| Polyline&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, R&#039;&#039;&#039;&lt;br /&gt;
| Rectangle&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, C&#039;&#039;&#039;&lt;br /&gt;
| Circle&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, A&#039;&#039;&#039;&lt;br /&gt;
| Arc&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, S&#039;&#039;&#039;&lt;br /&gt;
| Slot&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, H&#039;&#039;&#039;&lt;br /&gt;
| Regular polygon&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, B&#039;&#039;&#039;&lt;br /&gt;
| B-spline&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, F&#039;&#039;&#039;&lt;br /&gt;
| Fillet / chamfer&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, T&#039;&#039;&#039;&lt;br /&gt;
| Trim&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, Q&#039;&#039;&#039;&lt;br /&gt;
| Extend&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, X&#039;&#039;&#039;&lt;br /&gt;
| External geometry&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, N&#039;&#039;&#039;&lt;br /&gt;
| Toggle construction geometry&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;M&#039;&#039;&#039;&lt;br /&gt;
| Cycle the active tool&#039;s mode (while drawing)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Esc&#039;&#039;&#039; / right-click&lt;br /&gt;
| Drop the active tool&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sketcher — constraints ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key&lt;br /&gt;
! Constraint&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;D&#039;&#039;&#039;&lt;br /&gt;
| Dimension (context-sensitive)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;C&#039;&#039;&#039;&lt;br /&gt;
| Coincident / concentric / point-on-object&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;A&#039;&#039;&#039;&lt;br /&gt;
| Horizontal or vertical (auto)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;P&#039;&#039;&#039;&lt;br /&gt;
| Parallel&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;N&#039;&#039;&#039;&lt;br /&gt;
| Perpendicular&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T&#039;&#039;&#039;&lt;br /&gt;
| Tangent / collinear&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;E&#039;&#039;&#039;&lt;br /&gt;
| Equal&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;S&#039;&#039;&#039;&lt;br /&gt;
| Symmetric&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;K, D&#039;&#039;&#039;&lt;br /&gt;
| Distance&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;K, R&#039;&#039;&#039;&lt;br /&gt;
| Radius&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;K, A&#039;&#039;&#039;&lt;br /&gt;
| Angle&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;K, L&#039;&#039;&#039;&lt;br /&gt;
| Lock&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;K, X&#039;&#039;&#039;&lt;br /&gt;
| Toggle driving / reference&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Ctrl+C / X / V&#039;&#039;&#039;&lt;br /&gt;
| Copy / cut / paste sketch geometry with its constraints&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Everything is remappable: &#039;&#039;&#039;Tools → Customize → Keyboard&#039;&#039;&#039;. If your Fusion muscle memory is strong, remapping &#039;&#039;&#039;E&#039;&#039;&#039; to Pad and &#039;&#039;&#039;Q&#039;&#039;&#039; to Pocket is a popular move.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 16. Add-ons worth having ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tools → Addon Manager.&#039;&#039;&#039; Everything here is free and installs in-place.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Fasteners&#039;&#039;&#039; — a library of ISO/ANSI screws, nuts, washers and heat-set inserts you can drop onto holes. Immediately useful for checking that your M3 socket cap actually clears the counterbore.&lt;br /&gt;
* &#039;&#039;&#039;Curves&#039;&#039;&#039; — advanced surfacing and curve tools. Reach for it when Part Design&#039;s loft isn&#039;t enough.&lt;br /&gt;
* &#039;&#039;&#039;Defeaturing&#039;&#039;&#039; — removes faces and features from imported STEP files. Handy when adapting someone else&#039;s model.&lt;br /&gt;
* &#039;&#039;&#039;Sheet Metal&#039;&#039;&#039; — if you ever bend anything.&lt;br /&gt;
* &#039;&#039;&#039;MeshRemodel&#039;&#039;&#039; — helps convert an imported STL back into editable solid geometry. Imperfect, but the best option available for remixing STLs.&lt;br /&gt;
* &#039;&#039;&#039;Assembly3&#039;&#039;&#039; — an alternative assembly system. You almost certainly don&#039;t need it now that Assembly is built in; mentioned only so you know what people are referring to in old forum posts.&lt;br /&gt;
&lt;br /&gt;
A note on the forum and wiki: the FreeCAD community produces excellent documentation, but a great deal of it predates version 1.0. If a tutorial mentions &amp;quot;Part Design migrate&amp;quot;, the topological naming problem, or tells you to trace over external geometry, it&#039;s describing pre-1.0 behaviour. Check the version before you follow the advice.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 17. Habits to unlearn, habits to build ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Unlearn:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Sketching before creating a container. Body first, always.&lt;br /&gt;
* Leaving sketches under-constrained. It works in Fusion; it will hurt you here.&lt;br /&gt;
* Expecting one command to add or remove depending on direction. Pad and Pocket are different commands.&lt;br /&gt;
* Direct-editing solids by push-pulling faces. Part Design has no equivalent; you go back to the sketch or the feature&#039;s parameters. (The Property editor makes this fast once you&#039;re used to it.)&lt;br /&gt;
* Patterning bodies. You pattern features.&lt;br /&gt;
* Waiting for a cloud save. Ctrl+S writes a real file to a real disk that you own.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Build:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Body → sketch on XY → pad up.&#039;&#039;&#039; Make this reflex.&lt;br /&gt;
* &#039;&#039;&#039;Chase the green.&#039;&#039;&#039; Fully constrain everything before you leave a sketch.&lt;br /&gt;
* &#039;&#039;&#039;Live in the Property editor.&#039;&#039;&#039; It&#039;s faster than reopening dialogs.&lt;br /&gt;
* &#039;&#039;&#039;Start every project with a spreadsheet of print tolerances.&#039;&#039;&#039; Ten minutes, saves hours.&lt;br /&gt;
* &#039;&#039;&#039;Read the Report view when something fails.&#039;&#039;&#039; The answer is nearly always sitting there.&lt;br /&gt;
* &#039;&#039;&#039;Save often, and keep versions.&#039;&#039;&#039; &amp;lt;code&amp;gt;bracket_v3.FCStd&amp;lt;/code&amp;gt; costs you nothing.&lt;br /&gt;
* &#039;&#039;&#039;Fillets and chamfers last.&#039;&#039;&#039; Every time.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== What you actually gained and lost ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Lost:&#039;&#039;&#039; polish, generative tools, integrated CAM and simulation quality, sheet-metal maturity, cloud collaboration, a large ecosystem of tutorials matching your exact version, and Fusion&#039;s forgiving sketcher.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Gained:&#039;&#039;&#039; a &amp;lt;code&amp;gt;.FCStd&amp;lt;/code&amp;gt; file on your own disk that will still open in ten years, no licence terms that can change under you, no export limits or feature paywalls, Python scriptability all the way down, and — once you&#039;ve internalised constraints and the spreadsheet — a parametric workflow that&#039;s arguably more rigorous than the one you left.&lt;br /&gt;
&lt;br /&gt;
For parts destined for a 3D printer, FreeCAD 1.1 is entirely sufficient. Give it two weekends. The first will be frustrating and the second one won&#039;t.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Written for FreeCAD 1.1.3 (released 25 July 2026), default metric install. Version-specific behaviour noted where 1.1 differs from 1.0.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=FreeCad_Tutorial&amp;diff=495</id>
		<title>FreeCad Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=FreeCad_Tutorial&amp;diff=495"/>
		<updated>2026-07-28T09:13:39Z</updated>

		<summary type="html">&lt;p&gt;Damme: Created page with &amp;quot;&amp;lt;!--   FreeCAD 1.1.3 for Fusion 360 Users   MediaWiki source. Requires the accompanying SVG files to be uploaded to this   wiki first (Special:Upload, or maintenance/importImages.php for a batch).   SVG uploads must be enabled in LocalSettings.php:       $wgFileExtensions[] = &amp;#039;svg&amp;#039;;       $wgAllowTitlesInSVG = true;       $wgSVGConverter = &amp;#039;rsvg&amp;#039;;   # or ImageMagick --&amp;gt; &amp;#039;&amp;#039;&amp;#039;A conversion guide for people who only design parts for 3D printing.&amp;#039;&amp;#039;&amp;#039;  Written for a brand-new Fr...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&lt;br /&gt;
  FreeCAD 1.1.3 for Fusion 360 Users&lt;br /&gt;
  MediaWiki source. Requires the accompanying SVG files to be uploaded to this&lt;br /&gt;
  wiki first (Special:Upload, or maintenance/importImages.php for a batch).&lt;br /&gt;
  SVG uploads must be enabled in LocalSettings.php:&lt;br /&gt;
      $wgFileExtensions[] = &#039;svg&#039;;&lt;br /&gt;
      $wgAllowTitlesInSVG = true;&lt;br /&gt;
      $wgSVGConverter = &#039;rsvg&#039;;   # or ImageMagick&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;A conversion guide for people who only design parts for 3D printing.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Written for a brand-new FreeCAD 1.1.3 install, default settings, metric. No CAM, no drawings, no simulation — just getting from an idea to a good STL or 3MF.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
== 1. The five things that will confuse you ==&lt;br /&gt;
&lt;br /&gt;
Read this section twice. Nearly every &amp;quot;FreeCAD is unusable&amp;quot; post comes from one of these five.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1. There is no single modelling environment. There are workbenches.&#039;&#039;&#039;&lt;br /&gt;
Fusion gives you the Design workspace and everything lives in it. FreeCAD splits the same functionality across separate toolsets you switch between with a dropdown. For 3D printing you will live in [[File:FC-WB-PartDesign.svg|24px|link=|alt=Part Design workbench]] &#039;&#039;&#039;Part Design&#039;&#039;&#039; and its child [[File:FC-WB-Sketcher.svg|24px|link=|alt=Sketcher workbench]] &#039;&#039;&#039;Sketcher&#039;&#039;&#039;, and visit [[File:FC-WB-Mesh.svg|24px|link=|alt=Mesh workbench]] &#039;&#039;&#039;Mesh&#039;&#039;&#039; and [[File:FC-WB-Assembly.svg|24px|link=|alt=Assembly workbench]] &#039;&#039;&#039;Assembly&#039;&#039;&#039; occasionally. That&#039;s it. Ignore the other twelve.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2. Everything must live inside a Body.&#039;&#039;&#039;&lt;br /&gt;
In Fusion you can just start sketching. In FreeCAD, a Part Design feature has to belong to a [[File:FC-Body.svg|24px|link=|alt=Create body]] &#039;&#039;&#039;Body&#039;&#039;&#039; — a container that holds one continuous solid and its own origin planes. First action in every new document: create a Body. If you skip this, the Pad button will be greyed out and you&#039;ll wonder why.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3. A Body holds exactly one solid.&#039;&#039;&#039;&lt;br /&gt;
This is the rule Fusion users trip over hardest. Fusion happily lets one component contain several disconnected bodies. FreeCAD&#039;s Part Design will not. If you Pad a sketch that creates a lump floating away from the existing material, you get an error telling you the result is not a single solid. Two disconnected shapes = two Bodies. See [[#11. Multiple bodies, and assemblies for fit checks|section 11]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4. Sketches want to be fully constrained, and FreeCAD nags until they are.&#039;&#039;&#039;&lt;br /&gt;
Fusion tolerates half-constrained sketches indefinitely. FreeCAD technically does too, but a half-constrained sketch is a booby trap: geometry drifts when you edit something upstream. There&#039;s a degrees-of-freedom counter in the status bar, and the sketch turns fully green when it hits zero. Chase the green.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;5. Tools stay active after you use them.&#039;&#039;&#039;&lt;br /&gt;
Draw a line in Fusion and the tool stays armed too — but FreeCAD&#039;s version, called &#039;&#039;continue mode&#039;&#039;, applies to constraints as well, and it catches people out constantly. Press &#039;&#039;&#039;Esc&#039;&#039;&#039; or right-click to drop the current tool. Press &#039;&#039;&#039;Esc&#039;&#039;&#039; again with no tool active and you&#039;ll leave sketch edit mode entirely. There&#039;s a preference to stop that, and you should turn it on (see [[#2.6 Sketcher|2.6]]).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 2. First-run setup — 20 minutes that saves you months ==&lt;br /&gt;
&lt;br /&gt;
FreeCAD&#039;s defaults are conservative and a bit dated. These changes make it behave much more like the tool you&#039;re used to. All of them are in &#039;&#039;&#039;Edit → Preferences&#039;&#039;&#039; unless stated.&lt;br /&gt;
&lt;br /&gt;
=== 2.1 Navigation — make the mouse work like Fusion ===&lt;br /&gt;
&lt;br /&gt;
This is the single highest-value change. FreeCAD ships with &#039;&#039;&#039;CAD navigation&#039;&#039;&#039;, where orbit requires holding the middle button &#039;&#039;and then&#039;&#039; the left button. Fusion uses middle-drag to pan and Shift+middle-drag to orbit. FreeCAD has a preset that matches this exactly, and confusingly it&#039;s called &#039;&#039;&#039;Revit&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → Display → Navigation → 3D Navigation → &amp;lt;code&amp;gt;Revit&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Action&lt;br /&gt;
! Fusion 360&lt;br /&gt;
! FreeCAD &amp;quot;Revit&amp;quot; style&lt;br /&gt;
|-&lt;br /&gt;
| Pan&lt;br /&gt;
| Middle-drag&lt;br /&gt;
| Middle-drag&lt;br /&gt;
|-&lt;br /&gt;
| Orbit&lt;br /&gt;
| Shift + middle-drag&lt;br /&gt;
| Shift + middle-drag&lt;br /&gt;
|-&lt;br /&gt;
| Zoom&lt;br /&gt;
| Scroll wheel&lt;br /&gt;
| Scroll wheel&lt;br /&gt;
|-&lt;br /&gt;
| Select&lt;br /&gt;
| Left-click&lt;br /&gt;
| Left-click&lt;br /&gt;
|-&lt;br /&gt;
| Multi-select&lt;br /&gt;
| Ctrl + click&lt;br /&gt;
| Ctrl + click&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You can also change this any time by clicking the navigation-style button in the bottom-right status bar, or right-clicking empty space in the 3D view → &#039;&#039;&#039;Navigation styles&#039;&#039;&#039;. If you&#039;d rather learn the native CAD style, it&#039;s fine too — but don&#039;t fight two muscle memories at once while you&#039;re also learning the software.&lt;br /&gt;
&lt;br /&gt;
While you&#039;re on that page:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Zoom step&#039;&#039;&#039; — bump to about &amp;lt;code&amp;gt;0.4&amp;lt;/code&amp;gt; if the default feels sluggish.&lt;br /&gt;
* &#039;&#039;&#039;Enable animation&#039;&#039;&#039; — off. The spin-after-release is distracting.&lt;br /&gt;
* &#039;&#039;&#039;Rotation mode&#039;&#039;&#039; — &amp;lt;code&amp;gt;Drag at cursor&amp;lt;/code&amp;gt;. Orbits around whatever&#039;s under the pointer instead of the scene centre. Much closer to Fusion&#039;s feel.&lt;br /&gt;
* &#039;&#039;&#039;Invert zoom&#039;&#039;&#039; — set this if your scroll direction feels backwards.&lt;br /&gt;
&lt;br /&gt;
=== 2.2 Units and precision ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → General → Units&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Unit system&#039;&#039;&#039;: &amp;lt;code&amp;gt;Standard (mm/kg/s/degree)&amp;lt;/code&amp;gt; — already correct on a metric install.&lt;br /&gt;
* &#039;&#039;&#039;Number of decimals&#039;&#039;&#039;: change &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; → &#039;&#039;&#039;&amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt;&#039;&#039;&#039;. This matters. With 2 decimals a 0.125 mm tolerance displays as 0.13 and you&#039;ll chase a phantom error for an hour.&lt;br /&gt;
* &#039;&#039;&#039;Minimum fractional inch&#039;&#039;&#039;: irrelevant, ignore.&lt;br /&gt;
&lt;br /&gt;
=== 2.3 Start behaviour ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → General → General&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Auto load module after start-up&#039;&#039;&#039;: set to &amp;lt;code&amp;gt;Part Design&amp;lt;/code&amp;gt;. Saves a click every session.&lt;br /&gt;
* &#039;&#039;&#039;Enable tiled background&#039;&#039;&#039; / theme: &#039;&#039;&#039;Preferences → General → Themes&#039;&#039;&#039; has a proper theme picker, and 1.1 added a &#039;&#039;&#039;Theme Editor&#039;&#039;&#039; if you want to tune colours. &amp;lt;code&amp;gt;FreeCAD Dark&amp;lt;/code&amp;gt; is a reasonable Fusion-adjacent starting point.&lt;br /&gt;
* &#039;&#039;&#039;Size of recent file list&#039;&#039;&#039;: raise to 10.&lt;br /&gt;
&lt;br /&gt;
=== 2.4 Document and save behaviour ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → General → Document&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Storage → Save thumbnail into project file&#039;&#039;&#039;: on, makes the Start page useful.&lt;br /&gt;
* &#039;&#039;&#039;Run AutoRecovery&#039;&#039;&#039;: on, every &amp;lt;code&amp;gt;300&amp;lt;/code&amp;gt; seconds. FreeCAD is far more stable than its reputation but this is free insurance.&lt;br /&gt;
* &#039;&#039;&#039;Save transactions (Undo/Redo)&#039;&#039;&#039; and &#039;&#039;&#039;Maximum Undo/Redo steps&#039;&#039;&#039;: leave defaults; the undo stack is per-document and generous.&lt;br /&gt;
* &#039;&#039;&#039;Authoring and license&#039;&#039;&#039;: fill in your name once so exported STEP files aren&#039;t authored by &amp;quot;Unknown&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== 2.5 Part Design behaviour ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → Part Design → General&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Automatically refine model after boolean operation&#039;&#039;&#039;: &#039;&#039;&#039;on&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;Automatically refine model after sketch-based operation&#039;&#039;&#039;: &#039;&#039;&#039;on&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Refining removes the redundant seam edges left behind after a Pad or a Boolean. Without it you get invisible splits across flat faces, and then fillets fail on those faces for no visible reason. Turning this on removes a whole category of confusing failure. There&#039;s a small recompute cost; you will not notice it on printable-sized parts.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → Part Design → Shape view&#039;&#039;&#039; (this controls on-screen display quality only):&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Maximum deviation depending on the model bounding box&#039;&#039;&#039;: lower from &amp;lt;code&amp;gt;0.50&amp;lt;/code&amp;gt; to about &#039;&#039;&#039;&amp;lt;code&amp;gt;0.05&amp;lt;/code&amp;gt;&#039;&#039;&#039;. This only affects on-screen smoothness, not exported geometry, but curved surfaces look far better and it costs nothing on parts this size.&lt;br /&gt;
* &#039;&#039;&#039;Maximum angular deflection&#039;&#039;&#039;: lower from &amp;lt;code&amp;gt;28.5°&amp;lt;/code&amp;gt; to about &#039;&#039;&#039;&amp;lt;code&amp;gt;10°&amp;lt;/code&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== 2.6 Sketcher ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → Sketcher → General&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Esc can leave sketch edit mode&#039;&#039;&#039;: &#039;&#039;&#039;uncheck it.&#039;&#039;&#039; With continue mode on, you press Esc constantly to drop tools, and every so often you&#039;ll press it once too often and get dumped out of the sketch. Unchecking this makes Esc only ever cancel the active tool; you leave the sketch with the &#039;&#039;&#039;Close&#039;&#039;&#039; button instead.&lt;br /&gt;
* &#039;&#039;&#039;Dimensioning constraints&#039;&#039;&#039;: leave on &amp;lt;code&amp;gt;Single tool&amp;lt;/code&amp;gt;. This gives you the unified [[File:FC-Sk-Dimension.svg|24px|link=|alt=Dimension constraint]] &#039;&#039;&#039;Dimension&#039;&#039;&#039; tool on &#039;&#039;&#039;D&#039;&#039;&#039;, which behaves like Fusion&#039;s single dimension command — pick geometry and it works out whether you want a length, a radius, an angle or a distance.&lt;br /&gt;
* &#039;&#039;&#039;Unify Coincident and PointOnObject&#039;&#039;&#039;: leave on. One [[File:FC-Sk-Coincident.svg|24px|link=|alt=Coincident constraint]] &#039;&#039;&#039;C&#039;&#039;&#039; key handles coincident, concentric and point-on-edge.&lt;br /&gt;
* &#039;&#039;&#039;Auto tool for Horizontal/Vertical&#039;&#039;&#039;: leave on. One [[File:FC-Sk-HorVer.svg|24px|link=|alt=Horizontal/vertical constraint]] &#039;&#039;&#039;A&#039;&#039;&#039; key applies whichever of horizontal/vertical is closer.&lt;br /&gt;
* &#039;&#039;&#039;On-View-Parameters&#039;&#039;&#039;: set to &#039;&#039;&#039;&amp;lt;code&amp;gt;Dimensional and positional&amp;lt;/code&amp;gt;&#039;&#039;&#039;. This gives you the little input boxes that appear next to the cursor as you draw, so you can type &amp;lt;code&amp;gt;40&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;Tab&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;25&amp;lt;/code&amp;gt; instead of clicking approximately and dimensioning afterwards. It&#039;s very close to how you already sketch in Fusion, and it creates the constraints for you automatically.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → Sketcher → Display&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Show coordinates beside cursor&#039;&#039;&#039;: on.&lt;br /&gt;
* &#039;&#039;&#039;Ask for value after creating a dimensional constraint&#039;&#039;&#039;: on (default). Keeps the type-the-number rhythm.&lt;br /&gt;
* &#039;&#039;&#039;Grid&#039;&#039;&#039; and &#039;&#039;&#039;Snap&#039;&#039;&#039;: personal taste. Snapping does &#039;&#039;not&#039;&#039; create constraints by itself, so don&#039;t rely on it for accuracy.&lt;br /&gt;
&lt;br /&gt;
=== 2.7 Turn on the panels you&#039;ll want ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;View → Panels&#039;&#039;&#039;: enable &#039;&#039;&#039;Report view&#039;&#039;&#039; and &#039;&#039;&#039;Selection view&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;Report view&#039;&#039;&#039; is where FreeCAD tells you &#039;&#039;why&#039;&#039; something failed. When a Pad refuses and the dialog just says &amp;quot;failed&amp;quot;, the real reason is in here. Non-negotiable.&lt;br /&gt;
* The &#039;&#039;&#039;Selection view&#039;&#039;&#039; shows the internal name of whatever you clicked (&amp;lt;code&amp;gt;Body.Face7&amp;lt;/code&amp;gt;). Useful when a fillet complains about a face you can&#039;t identify.&lt;br /&gt;
&lt;br /&gt;
Also set &#039;&#039;&#039;Preferences → General → Report view → Redirect internal Python errors to report view&#039;&#039;&#039;: on, and give warnings a colour.&lt;br /&gt;
&lt;br /&gt;
=== 2.8 Save your setup ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tools → Save preferences to file&#039;&#039;&#039; (or just copy &amp;lt;code&amp;gt;user.cfg&amp;lt;/code&amp;gt; from your FreeCAD config folder). Do it now so a reinstall doesn&#039;t cost you this half hour again.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 3. The interface ==&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Fig-Interface.svg|thumb|center|800px|Annotated FreeCAD 1.1 window with Fusion equivalents]]&lt;br /&gt;
&lt;br /&gt;
The layout is fixed panels rather than Fusion&#039;s floating dialogs. Two things deserve special attention:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The Tasks panel shares a dock with the Model tree.&#039;&#039;&#039; When you start a Pad, the panel switches from Model to Tasks and the tree disappears. That&#039;s normal — it&#039;s not a bug, and the tabs at the top of the panel switch back. This is why you can&#039;t easily click tree items mid-command the way you can in Fusion&#039;s browser.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The Property editor is the thing Fusion doesn&#039;t have.&#039;&#039;&#039; Select any feature in the tree and its full parameter list appears at the bottom-left, live-editable. You do not need to re-open a Pad&#039;s dialog to change its length — click the Pad, click the Length field, type. Once this clicks, it&#039;s faster than Fusion for parametric tweaking. Two tabs at the bottom: &#039;&#039;&#039;Data&#039;&#039;&#039; (the parametric properties) and &#039;&#039;&#039;View&#039;&#039;&#039; (colour, transparency, display mode).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 4. Vocabulary: Fusion → FreeCAD ==&lt;br /&gt;
&lt;br /&gt;
Before the table, the structural difference — Fusion&#039;s Browser and Timeline are one thing in FreeCAD:&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Fig-TreeVsTimeline.svg|thumb|center|760px|Fusion browser and timeline vs the FreeCAD model tree]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Fusion 360&lt;br /&gt;
! FreeCAD 1.1&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Design workspace&lt;br /&gt;
| Part Design workbench&lt;br /&gt;
| Plus Sketcher, which opens automatically&lt;br /&gt;
|-&lt;br /&gt;
| Project / design file&lt;br /&gt;
| Document (&amp;lt;code&amp;gt;.FCStd&amp;lt;/code&amp;gt;)&lt;br /&gt;
| A plain zip file. Local, not cloud. One document can hold many Bodies.&lt;br /&gt;
|-&lt;br /&gt;
| Component&lt;br /&gt;
| [[File:FC-Body.svg|24px|link=|alt=Create body]] Body (or a &#039;&#039;&#039;Part&#039;&#039;&#039; container for grouping)&lt;br /&gt;
| Body = one solid. Part = a folder with its own placement.&lt;br /&gt;
|-&lt;br /&gt;
| Body&lt;br /&gt;
| The solid inside a Body&lt;br /&gt;
| Not the same word. Painful, but true.&lt;br /&gt;
|-&lt;br /&gt;
| Browser&lt;br /&gt;
| Model tree&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Timeline&lt;br /&gt;
| Also the Model tree&lt;br /&gt;
| Order top-to-bottom = history&lt;br /&gt;
|-&lt;br /&gt;
| Timeline marker position&lt;br /&gt;
| &#039;&#039;&#039;Tip&#039;&#039;&#039;&lt;br /&gt;
| Right-click a feature → &#039;&#039;Set tip&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| Suppress feature&lt;br /&gt;
| Right-click → &#039;&#039;&#039;Suppressed&#039;&#039;&#039;&lt;br /&gt;
| Checkbox, added in 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Origin planes&lt;br /&gt;
| &#039;&#039;&#039;Origin&#039;&#039;&#039; group inside each Body&lt;br /&gt;
| XY, XZ, YZ planes plus the three axes&lt;br /&gt;
|-&lt;br /&gt;
| Construction plane / axis / point&lt;br /&gt;
| &#039;&#039;&#039;Datum&#039;&#039;&#039; plane / line / point / coordinate system&lt;br /&gt;
| Rebuilt in 1.1 as core datums&lt;br /&gt;
|-&lt;br /&gt;
| Parameters dialog&lt;br /&gt;
| &#039;&#039;&#039;Spreadsheet&#039;&#039;&#039; workbench + aliases&lt;br /&gt;
| See [[#10. Parameters and expressions|section 10]]&lt;br /&gt;
|-&lt;br /&gt;
| Joint&lt;br /&gt;
| Assembly workbench &#039;&#039;&#039;Joint&#039;&#039;&#039;&lt;br /&gt;
| Only needed for fit checks and print-in-place&lt;br /&gt;
|-&lt;br /&gt;
| Extrude&lt;br /&gt;
| [[File:FC-Pad.svg|24px|link=|alt=Pad]] &#039;&#039;&#039;Pad&#039;&#039;&#039; (adds) / [[File:FC-Pocket.svg|24px|link=|alt=Pocket]] &#039;&#039;&#039;Pocket&#039;&#039;&#039; (removes)&lt;br /&gt;
| Two separate commands, not one with a direction&lt;br /&gt;
|-&lt;br /&gt;
| Revolve&lt;br /&gt;
| [[File:FC-Revolution.svg|24px|link=|alt=Revolution]] &#039;&#039;&#039;Revolution&#039;&#039;&#039; / [[File:FC-Groove.svg|24px|link=|alt=Groove]] &#039;&#039;&#039;Groove&#039;&#039;&#039;&lt;br /&gt;
| Same additive/subtractive split&lt;br /&gt;
|-&lt;br /&gt;
| Sweep&lt;br /&gt;
| [[File:FC-Pipe.svg|24px|link=|alt=Additive pipe]] &#039;&#039;&#039;Additive pipe&#039;&#039;&#039; / Subtractive pipe&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Loft&lt;br /&gt;
| [[File:FC-Loft.svg|24px|link=|alt=Additive loft]] &#039;&#039;&#039;Additive loft&#039;&#039;&#039; / Subtractive loft&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Coil&lt;br /&gt;
| [[File:FC-Helix.svg|24px|link=|alt=Additive helix]] &#039;&#039;&#039;Additive helix&#039;&#039;&#039; / Subtractive helix&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Hole&lt;br /&gt;
| [[File:FC-Hole.svg|24px|link=|alt=Hole]] &#039;&#039;&#039;Hole&#039;&#039;&#039;&lt;br /&gt;
| Sketch circles first, then apply Hole to them&lt;br /&gt;
|-&lt;br /&gt;
| Fillet&lt;br /&gt;
| [[File:FC-Fillet.svg|24px|link=|alt=Fillet]] &#039;&#039;&#039;Fillet&#039;&#039;&#039;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Chamfer&lt;br /&gt;
| [[File:FC-Chamfer.svg|24px|link=|alt=Chamfer]] &#039;&#039;&#039;Chamfer&#039;&#039;&#039;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Shell&lt;br /&gt;
| [[File:FC-Thickness.svg|24px|link=|alt=Thickness]] &#039;&#039;&#039;Thickness&#039;&#039;&#039;&lt;br /&gt;
| Select the face(s) to open, then run it&lt;br /&gt;
|-&lt;br /&gt;
| Draft&lt;br /&gt;
| [[File:FC-Draft.svg|24px|link=|alt=Draft]] &#039;&#039;&#039;Draft&#039;&#039;&#039;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Rectangular pattern&lt;br /&gt;
| [[File:FC-LinearPattern.svg|24px|link=|alt=LinearPattern]] &#039;&#039;&#039;LinearPattern&#039;&#039;&#039;&lt;br /&gt;
| Patterns &#039;&#039;features&#039;&#039;, not faces&lt;br /&gt;
|-&lt;br /&gt;
| Circular pattern&lt;br /&gt;
| [[File:FC-PolarPattern.svg|24px|link=|alt=PolarPattern]] &#039;&#039;&#039;PolarPattern&#039;&#039;&#039;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Mirror&lt;br /&gt;
| [[File:FC-Mirrored.svg|24px|link=|alt=Mirrored]] &#039;&#039;&#039;Mirrored&#039;&#039;&#039;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Combine (cut/join/intersect)&lt;br /&gt;
| [[File:FC-Boolean.svg|24px|link=|alt=Boolean]] &#039;&#039;&#039;Boolean&#039;&#039;&#039; (in Part Design, between Bodies) or the &#039;&#039;&#039;Part&#039;&#039;&#039; workbench booleans&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Move/Copy&lt;br /&gt;
| &#039;&#039;&#039;Transform&#039;&#039;&#039; (overhauled in 1.1 — draggers + numeric input)&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Measure&lt;br /&gt;
| [[File:FC-Std-Measure.svg|24px|link=|alt=Measure]] &#039;&#039;&#039;Measure&#039;&#039;&#039; (Tools menu)&lt;br /&gt;
| Unified tool, works across workbenches&lt;br /&gt;
|-&lt;br /&gt;
| Project geometry&lt;br /&gt;
| [[File:FC-Sk-External.svg|24px|link=|alt=External geometry]] &#039;&#039;&#039;External geometry&#039;&#039;&#039; — in 1.1, &#039;&#039;Projection&#039;&#039; and &#039;&#039;Intersection&#039;&#039;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Construction geometry&lt;br /&gt;
| [[File:FC-Sk-Construction.svg|24px|link=|alt=Construction geometry]] &#039;&#039;&#039;Toggle construction geometry&#039;&#039;&#039;&lt;br /&gt;
| Blue dashed&lt;br /&gt;
|-&lt;br /&gt;
| Capture Position / Ground&lt;br /&gt;
| Constrain the sketch, and attach it properly&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| Export STL&lt;br /&gt;
| [[File:FC-Std-Export.svg|24px|link=|alt=Export]] &#039;&#039;&#039;File → Export&#039;&#039;&#039;, pick &amp;lt;code&amp;gt;.stl&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;.3mf&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 5. The modelling loop ==&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Fig-ModellingLoop.svg|thumb|center|760px|The Part Design modelling loop]]&lt;br /&gt;
&lt;br /&gt;
Concretely, from an empty FreeCAD:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Ctrl+N&#039;&#039;&#039; — new document.&lt;br /&gt;
# Workbench dropdown → &#039;&#039;&#039;Part Design&#039;&#039;&#039;.&lt;br /&gt;
# [[File:FC-Body.svg|24px|link=|alt=Create body]] &#039;&#039;&#039;Create body&#039;&#039;&#039; (the first button on the Part Design toolbar). A Body appears in the tree with an Origin inside it.&lt;br /&gt;
# [[File:FC-NewSketch.svg|24px|link=|alt=Create sketch]] &#039;&#039;&#039;Create sketch&#039;&#039;&#039;. Because nothing is selected, the Tasks panel asks which plane. Pick &#039;&#039;&#039;XY_Plane&#039;&#039;&#039; for a part that sits flat on the print bed — this is the right default answer nearly every time for FDM.&lt;br /&gt;
# Draw and constrain. Close the sketch.&lt;br /&gt;
# With the sketch selected, [[File:FC-Pad.svg|24px|link=|alt=Pad]] &#039;&#039;&#039;Pad&#039;&#039;&#039;. Enter a length. OK.&lt;br /&gt;
# Click a flat face of the result, [[File:FC-NewSketch.svg|24px|link=|alt=Create sketch]] &#039;&#039;&#039;Create sketch&#039;&#039;&#039; again — it lands on that face.&lt;br /&gt;
# Draw, constrain, close, [[File:FC-Pocket.svg|24px|link=|alt=Pocket]] &#039;&#039;&#039;Pocket&#039;&#039;&#039;.&lt;br /&gt;
# Repeat. Add [[File:FC-Fillet.svg|24px|link=|alt=Fillet]] fillets and [[File:FC-Chamfer.svg|24px|link=|alt=Chamfer]] chamfers last.&lt;br /&gt;
# &#039;&#039;&#039;Ctrl+S&#039;&#039;&#039;. Then export.&lt;br /&gt;
&lt;br /&gt;
That&#039;s the whole workflow. Everything else in this document is detail hanging off those ten steps.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;One orientation note specific to printing:&#039;&#039;&#039; decide early which face is the bed. Sketch your footprint on the &#039;&#039;&#039;XY plane&#039;&#039;&#039; and pad upward. FreeCAD&#039;s XY plane is the ground plane in the 3D view, and every slicer will import the part in the same orientation you modelled it. Getting this right means you never have to re-orient in the slicer, which in turn means your overhang and support decisions stay in one place.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 6. Sketching — where the real difference is ==&lt;br /&gt;
&lt;br /&gt;
Fusion&#039;s sketcher is forgiving and quietly fixes things for you. FreeCAD&#039;s is stricter, more explicit, and — once you adapt — more predictable. It is also where you&#039;ll spend most of your first week.&lt;br /&gt;
&lt;br /&gt;
=== 6.1 The rules for a sketch that will actually extrude ===&lt;br /&gt;
&lt;br /&gt;
A profile sketch must be:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Closed.&#039;&#039;&#039; No gaps, however microscopic. A 0.001 mm gap gives you a surface instead of a solid.&lt;br /&gt;
* &#039;&#039;&#039;Non-self-intersecting.&#039;&#039;&#039; No crossing lines.&lt;br /&gt;
* &#039;&#039;&#039;Free of shared edges and T-junctions.&#039;&#039;&#039; More than two edges meeting at a point is not allowed. No duplicate overlapping lines.&lt;br /&gt;
&lt;br /&gt;
Nested closed loops are fine and produce holes — draw a rectangle with a circle inside it and Pad it, and you get a plate with a hole. This is the cheapest way to make holes and often better than the Hole feature.&lt;br /&gt;
&lt;br /&gt;
Anything you don&#039;t want extruded should be [[File:FC-Sk-Construction.svg|24px|link=|alt=Construction geometry]] &#039;&#039;&#039;construction geometry&#039;&#039;&#039; (blue dashed). Construction lines are enormously useful: draw a construction line between two points, constrain it, and hang real geometry off it.&lt;br /&gt;
&lt;br /&gt;
=== 6.2 Constraints, and the DoF counter ===&lt;br /&gt;
&lt;br /&gt;
The status bar shows something like &amp;lt;code&amp;gt;Under-constrained: 4 DoF&amp;lt;/code&amp;gt;. Click that message and FreeCAD selects the elements still free to move. When it reads &#039;&#039;&#039;Fully constrained&#039;&#039;&#039;, the whole sketch turns green and you&#039;re done.&lt;br /&gt;
&lt;br /&gt;
Two rules of thumb:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Geometric constraints first, dimensions second.&#039;&#039;&#039; Get everything horizontal/vertical/tangent/equal, &#039;&#039;then&#039;&#039; add numbers. Doing it in the other order produces sketches that fight you.&lt;br /&gt;
* &#039;&#039;&#039;Anchor to the origin.&#039;&#039;&#039; At least one point in every sketch should be tied to the sketch origin — with a coincident constraint, or a symmetry constraint about an axis. A sketch floating in space is one edit away from sliding sideways.&lt;br /&gt;
&lt;br /&gt;
If your part is symmetric, [[File:FC-Sk-Symmetric.svg|24px|link=|alt=Symmetric constraint]] &#039;&#039;&#039;symmetry about the Y axis&#039;&#039;&#039; is worth two dimensions and makes the whole thing behave when you change widths later.&lt;br /&gt;
&lt;br /&gt;
The constraints you&#039;ll actually use, with their default keys:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Constraint&lt;br /&gt;
! Key&lt;br /&gt;
! Fusion equivalent&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Dimension.svg|24px|link=|alt=Dimension constraint]]&lt;br /&gt;
| Dimension (context-sensitive)&lt;br /&gt;
| &#039;&#039;&#039;D&#039;&#039;&#039;&lt;br /&gt;
| Sketch Dimension&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Coincident.svg|24px|link=|alt=Coincident constraint]]&lt;br /&gt;
| Coincident / concentric / point-on-object&lt;br /&gt;
| &#039;&#039;&#039;C&#039;&#039;&#039;&lt;br /&gt;
| Coincident&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-HorVer.svg|24px|link=|alt=Horizontal/vertical constraint]]&lt;br /&gt;
| Horizontal or vertical (auto)&lt;br /&gt;
| &#039;&#039;&#039;A&#039;&#039;&#039;&lt;br /&gt;
| Horizontal/Vertical&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Equal.svg|24px|link=|alt=Equal constraint]]&lt;br /&gt;
| Equal&lt;br /&gt;
| &#039;&#039;&#039;E&#039;&#039;&#039;&lt;br /&gt;
| Equal&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Tangent.svg|24px|link=|alt=Tangent constraint]]&lt;br /&gt;
| Tangent or collinear&lt;br /&gt;
| &#039;&#039;&#039;T&#039;&#039;&#039;&lt;br /&gt;
| Tangent&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Symmetric.svg|24px|link=|alt=Symmetric constraint]]&lt;br /&gt;
| Symmetric&lt;br /&gt;
| &#039;&#039;&#039;S&#039;&#039;&#039;&lt;br /&gt;
| Symmetry&lt;br /&gt;
|-&lt;br /&gt;
| —&lt;br /&gt;
| Parallel&lt;br /&gt;
| &#039;&#039;&#039;P&#039;&#039;&#039;&lt;br /&gt;
| Parallel&lt;br /&gt;
|-&lt;br /&gt;
| —&lt;br /&gt;
| Perpendicular&lt;br /&gt;
| &#039;&#039;&#039;N&#039;&#039;&#039;&lt;br /&gt;
| Perpendicular&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Lock.svg|24px|link=|alt=Lock constraint]]&lt;br /&gt;
| Lock (X and Y distance to origin)&lt;br /&gt;
| &#039;&#039;&#039;K, L&#039;&#039;&#039;&lt;br /&gt;
| Fix/Unfix&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The unified &#039;&#039;&#039;D&#039;&#039;&#039; key is the workhorse. Select one line → D → length. Select two circles → D → centre distance. Select a circle → D → diameter. Select two lines → D → angle. If it proposes the wrong constraint, press &#039;&#039;&#039;M&#039;&#039;&#039; to cycle through the alternatives before you click to place it.&lt;br /&gt;
&lt;br /&gt;
=== 6.3 Drawing tools ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Tool&lt;br /&gt;
! Key&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Line.svg|24px|link=|alt=Line]]&lt;br /&gt;
| Line&lt;br /&gt;
| &#039;&#039;&#039;G, L&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Polyline.svg|24px|link=|alt=Polyline]]&lt;br /&gt;
| Polyline (line/arc chains)&lt;br /&gt;
| &#039;&#039;&#039;G, M&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Rectangle.svg|24px|link=|alt=Rectangle]]&lt;br /&gt;
| Rectangle&lt;br /&gt;
| &#039;&#039;&#039;G, R&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Circle.svg|24px|link=|alt=Circle]]&lt;br /&gt;
| Circle&lt;br /&gt;
| &#039;&#039;&#039;G, C&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Arc.svg|24px|link=|alt=Arc]]&lt;br /&gt;
| Arc&lt;br /&gt;
| &#039;&#039;&#039;G, A&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Slot.svg|24px|link=|alt=Slot]]&lt;br /&gt;
| Slot&lt;br /&gt;
| &#039;&#039;&#039;G, S&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Fillet.svg|24px|link=|alt=Sketch fillet]]&lt;br /&gt;
| Fillet / chamfer between two edges&lt;br /&gt;
| &#039;&#039;&#039;G, F&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Trim.svg|24px|link=|alt=Trim]]&lt;br /&gt;
| Trim&lt;br /&gt;
| &#039;&#039;&#039;G, T&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Sk-Construction.svg|24px|link=|alt=Construction geometry]]&lt;br /&gt;
| Toggle construction geometry&lt;br /&gt;
| &#039;&#039;&#039;G, N&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Polyline&#039;&#039;&#039; is the tool to learn properly. It&#039;s FreeCAD&#039;s equivalent of Fusion&#039;s line tool with the arc-drag trick: while drawing, press &#039;&#039;&#039;M&#039;&#039;&#039; to cycle between line and several arc modes, so you can lay out a rounded outline in one continuous chain with the tangency constraints already applied.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rectangle&#039;&#039;&#039; in 1.0+ has modes too — press &#039;&#039;&#039;M&#039;&#039;&#039; to switch between corner-to-corner, centred, rounded-corner and offset-copy variants.&lt;br /&gt;
&lt;br /&gt;
=== 6.4 External geometry — and what changed in 1.1 ===&lt;br /&gt;
&lt;br /&gt;
Fusion&#039;s &amp;quot;project geometry&amp;quot; pulls edges of existing solids into your sketch. FreeCAD&#039;s equivalent is [[File:FC-Sk-External.svg|24px|link=|alt=External geometry]] &#039;&#039;&#039;External geometry&#039;&#039;&#039; (&#039;&#039;&#039;G, X&#039;&#039;&#039;), and &#039;&#039;&#039;1.1 changed it in a way that matters&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In 1.0 and earlier, projected external geometry came in as reference-only construction lines — you had to trace over them with real geometry to use them in a profile. &#039;&#039;&#039;In 1.1, projected external geometry is real, defining geometry by default.&#039;&#039;&#039; You can extrude directly against it. You can also toggle it to construction like anything else.&lt;br /&gt;
&lt;br /&gt;
1.1 also split it into two tools:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Projection&#039;&#039;&#039; — projects edges/faces flat onto the sketch plane. This is the Fusion &amp;quot;project&amp;quot; behaviour.&lt;br /&gt;
* &#039;&#039;&#039;Intersection&#039;&#039;&#039; — creates the edges where a solid actually &#039;&#039;crosses&#039;&#039; your sketch plane. There&#039;s no direct Fusion analogue and it&#039;s genuinely useful for cutting a slot through a curved wall.&lt;br /&gt;
&lt;br /&gt;
Both can now be driven by selecting a whole face rather than picking edges one at a time.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Two limitations worth knowing up front:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* You can only reference geometry in the &#039;&#039;&#039;same coordinate system&#039;&#039;&#039; — the same Body, the same Part container, or both at document level. To pull in geometry from a &#039;&#039;different&#039;&#039; Body, add a [[File:FC-SubShapeBinder.svg|24px|link=|alt=SubShapeBinder]] &#039;&#039;&#039;SubShapeBinder&#039;&#039;&#039; first. This is exactly the &amp;quot;make a lid that matches this box&amp;quot; situation.&lt;br /&gt;
* Every external reference creates a dependency on a specific face or edge of the upstream solid, and changing the upstream geometry enough can break it. Links to &#039;&#039;other sketches&#039;&#039; are more robust than links to solid faces, and the FreeCAD docs actively encourage them. Where you can get the same result by referencing an origin plane or a datum, do that instead.&lt;br /&gt;
&lt;br /&gt;
=== 6.5 Editing a sketch afterwards ===&lt;br /&gt;
&lt;br /&gt;
Double-click the sketch in the tree, or select it and press the &#039;&#039;&#039;Edit sketch&#039;&#039;&#039; button. To move a whole sketch to a different plane, select it and use &#039;&#039;&#039;Attach sketch&#039;&#039;&#039; (&amp;lt;code&amp;gt;Sketcher_MapSketch&amp;lt;/code&amp;gt;) — that&#039;s the Fusion &amp;quot;redefine sketch plane&amp;quot; equivalent.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 7. Part Design tools, mapped from Fusion ==&lt;br /&gt;
&lt;br /&gt;
=== 7.1 Additive ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Tool&lt;br /&gt;
! Notes for a Fusion user&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Pad.svg|24px|link=|alt=Pad]]&lt;br /&gt;
| &#039;&#039;&#039;Pad&#039;&#039;&#039;&lt;br /&gt;
| Fusion&#039;s Extrude-Join. Types: &amp;lt;code&amp;gt;Dimension&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;To last&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;To first&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Up to face&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Two dimensions&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Midplane&#039;&#039;&#039; checkbox = Fusion&#039;s symmetric extrude. &#039;&#039;&#039;Reversed&#039;&#039;&#039; flips direction. Set a &#039;&#039;&#039;taper angle&#039;&#039;&#039; here rather than adding a draft feature later.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Revolution.svg|24px|link=|alt=Revolution]]&lt;br /&gt;
| &#039;&#039;&#039;Revolution&#039;&#039;&#039;&lt;br /&gt;
| Needs an axis: a sketch construction line, an origin axis, or a datum line. Sketch must be closed and must not cross the axis.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Loft.svg|24px|link=|alt=Additive loft]]&lt;br /&gt;
| &#039;&#039;&#039;Additive loft&#039;&#039;&#039;&lt;br /&gt;
| Select the first sketch, run the tool, then add the others in the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Pipe.svg|24px|link=|alt=Additive pipe]]&lt;br /&gt;
| &#039;&#039;&#039;Additive pipe&#039;&#039;&#039;&lt;br /&gt;
| Sweep. Profile sketch + path sketch on different planes.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Helix.svg|24px|link=|alt=Additive helix]]&lt;br /&gt;
| &#039;&#039;&#039;Additive helix&#039;&#039;&#039;&lt;br /&gt;
| Coil. This is how you model threads if you want real modelled threads.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Primitive.svg|24px|link=|alt=Additive primitive]]&lt;br /&gt;
| &#039;&#039;&#039;Additive primitives&#039;&#039;&#039;&lt;br /&gt;
| Box, cylinder, sphere, cone, torus, prism, wedge — dropped straight into the Body without a sketch. Genuinely handy for quick blocking-out; Fusion has no clean equivalent inside a timeline.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 7.2 Subtractive ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Tool&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Pocket.svg|24px|link=|alt=Pocket]]&lt;br /&gt;
| &#039;&#039;&#039;Pocket&#039;&#039;&#039;&lt;br /&gt;
| Extrude-Cut. Same type options as Pad, plus &amp;lt;code&amp;gt;Through all&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Hole.svg|24px|link=|alt=Hole]]&lt;br /&gt;
| &#039;&#039;&#039;Hole&#039;&#039;&#039;&lt;br /&gt;
| Draw circles in a sketch, then run Hole. Gives you counterbore, countersink, tapered/straight, and real or cosmetic threads. 1.1 added Whitworth-family threads (BSW, BSF, BSP, NPT) and made modelled threads noticeably faster. &#039;&#039;&#039;For 3D printing, usually skip the thread modelling&#039;&#039;&#039; — print a plain hole and tap it, or print an oversized hole for a heat-set insert.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Groove.svg|24px|link=|alt=Groove]]&lt;br /&gt;
| &#039;&#039;&#039;Groove&#039;&#039;&#039;&lt;br /&gt;
| Revolved cut.&lt;br /&gt;
|-&lt;br /&gt;
| —&lt;br /&gt;
| &#039;&#039;&#039;Subtractive loft / pipe / helix / primitives&#039;&#039;&#039;&lt;br /&gt;
| Mirror images of the additive versions.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 7.3 Dress-up ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Tool&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Fillet.svg|24px|link=|alt=Fillet]]&lt;br /&gt;
| &#039;&#039;&#039;Fillet&#039;&#039;&#039;&lt;br /&gt;
| Select edges or a whole face (fillets every edge of it). 1.1 added interactive draggers so you can pull the radius in the 3D view.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Chamfer.svg|24px|link=|alt=Chamfer]]&lt;br /&gt;
| &#039;&#039;&#039;Chamfer&#039;&#039;&#039;&lt;br /&gt;
| Equal-distance, two-distance, or distance-and-angle. Draggers in 1.1 as well.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Draft.svg|24px|link=|alt=Draft]]&lt;br /&gt;
| &#039;&#039;&#039;Draft&#039;&#039;&#039;&lt;br /&gt;
| Needs a neutral plane, same as Fusion.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Thickness.svg|24px|link=|alt=Thickness]]&lt;br /&gt;
| &#039;&#039;&#039;Thickness&#039;&#039;&#039;&lt;br /&gt;
| Shell. Select the face(s) to remove, then run it. Positive thickness goes outward, negative inward — the opposite of what most people expect, so check the preview.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fillets are the most failure-prone feature in FreeCAD, exactly as in Fusion but slightly more so.&#039;&#039;&#039; Rules that keep you out of trouble:&lt;br /&gt;
&lt;br /&gt;
* Add them &#039;&#039;&#039;last&#039;&#039;&#039;, as the final features in the tree.&lt;br /&gt;
* Group edges that will get the same radius into &#039;&#039;&#039;one&#039;&#039;&#039; fillet feature rather than several — fewer, larger features are more robust than many small ones.&lt;br /&gt;
* Never fillet an edge where three or more fillets will meet at a corner in one go. Do the big ones first as a separate feature, then the small ones.&lt;br /&gt;
* If a fillet fails, halve the radius and try again. If that works, the geometry is too tight, not the software.&lt;br /&gt;
* Turn on the &#039;&#039;&#039;refine&#039;&#039;&#039; preferences from [[#2.5 Part Design behaviour|2.5]] — a surprising number of &amp;quot;impossible&amp;quot; fillets are actually failing on an invisible seam edge.&lt;br /&gt;
* &#039;&#039;&#039;For 3D printing, prefer chamfers on the bottom edge.&#039;&#039;&#039; A 0.6 mm chamfer on the first layer perimeter removes elephant&#039;s foot and prints better than a fillet.&lt;br /&gt;
&lt;br /&gt;
=== 7.4 Transformations ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Tool&lt;br /&gt;
! The important difference&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-LinearPattern.svg|24px|link=|alt=LinearPattern]]&lt;br /&gt;
| &#039;&#039;&#039;LinearPattern&#039;&#039;&#039;&lt;br /&gt;
| Patterns &#039;&#039;&#039;features&#039;&#039;&#039;, not faces or bodies. You select which features from the tree get repeated.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-PolarPattern.svg|24px|link=|alt=PolarPattern]]&lt;br /&gt;
| &#039;&#039;&#039;PolarPattern&#039;&#039;&#039;&lt;br /&gt;
| Same. Needs an axis.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Mirrored.svg|24px|link=|alt=Mirrored]]&lt;br /&gt;
| &#039;&#039;&#039;Mirrored&#039;&#039;&#039;&lt;br /&gt;
| Same. Mirror plane is usually an Origin plane.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-Transform.svg|24px|link=|alt=Transform]]&lt;br /&gt;
| &#039;&#039;&#039;MultiTransform&#039;&#039;&#039;&lt;br /&gt;
| Chains several transforms into one feature — e.g. mirror then pattern. Also the only place to get &#039;&#039;&#039;Scaled&#039;&#039;&#039;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This &amp;quot;patterns operate on features&amp;quot; model is different from Fusion, where you pattern faces or bodies. It&#039;s stricter, but it means the pattern updates correctly when you change the original feature. If you want to pattern something that isn&#039;t a feature — a whole Body, say — use the &#039;&#039;&#039;Draft&#039;&#039;&#039; workbench&#039;s array tools, or the Part workbench.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 8. Reference geometry and attachment ==&lt;br /&gt;
&lt;br /&gt;
Every Body contains an &#039;&#039;&#039;Origin&#039;&#039;&#039; group: XY, XZ, YZ planes and X, Y, Z axes. They&#039;re hidden by default; select one in the tree and press &#039;&#039;&#039;Space&#039;&#039;&#039; to show it. These are your primary references and you should prefer them over faces wherever you can.&lt;br /&gt;
&lt;br /&gt;
When you need more, FreeCAD 1.1 replaced the old Part Design datum tools with &#039;&#039;&#039;core datums&#039;&#039;&#039;, available from the Part Design toolbar and now usable in the Assembly workbench too:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Datum&lt;br /&gt;
! Fusion equivalent&lt;br /&gt;
|-&lt;br /&gt;
| [[File:FC-DatumPlane.svg|24px|link=|alt=Datum plane]]&lt;br /&gt;
| Datum plane&lt;br /&gt;
| Construction plane&lt;br /&gt;
|-&lt;br /&gt;
| —&lt;br /&gt;
| Datum line&lt;br /&gt;
| Construction axis&lt;br /&gt;
|-&lt;br /&gt;
| —&lt;br /&gt;
| Datum point&lt;br /&gt;
| Construction point&lt;br /&gt;
|-&lt;br /&gt;
| —&lt;br /&gt;
| Local coordinate system&lt;br /&gt;
| — (no direct equivalent)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The mechanism behind them is &#039;&#039;&#039;attachment&#039;&#039;&#039;, and it&#039;s more powerful than Fusion&#039;s offset-plane dialog but less obvious. Select the reference geometry first, then create the datum; the &#039;&#039;&#039;Attachment&#039;&#039;&#039; dialog offers modes (&amp;lt;code&amp;gt;FlatFace&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Object&#039;s XY&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Concentric&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Normal to edge&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Plane by 3 points&amp;lt;/code&amp;gt;…) plus numeric offsets in the attachment&#039;s own coordinate system.&lt;br /&gt;
&lt;br /&gt;
Any sketch has the same &#039;&#039;&#039;Attachment&#039;&#039;&#039; properties in the Property editor — an offset sketch plane is just a sketch attached to &amp;lt;code&amp;gt;XY_Plane&amp;lt;/code&amp;gt; with a Z offset, no datum needed. That&#039;s usually the quickest route.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Practical advice:&#039;&#039;&#039; for printed parts, 90% of your sketches should attach to an Origin plane or a flat face, and you&#039;ll rarely need a datum at all. Reach for them for angled features and for revolve axes.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 9. Editing history: the tip, suppression, reordering ==&lt;br /&gt;
&lt;br /&gt;
The tree &#039;&#039;is&#039;&#039; the timeline. Four operations you&#039;ll want:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Roll back — &amp;quot;Set tip&amp;quot;.&#039;&#039;&#039; Right-click a feature → [[File:FC-Std-Tip.svg|24px|link=|alt=Tip]] &#039;&#039;&#039;Set tip&#039;&#039;&#039;. Everything below it is hidden and any new feature you create is inserted at that point. This is Fusion&#039;s drag-the-marker-back. The tip feature is shown in bold. Remember to set the tip back to the last feature when you&#039;re done, or you&#039;ll export an incomplete part.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Suppress.&#039;&#039;&#039; Right-click → &#039;&#039;&#039;Suppressed&#039;&#039;&#039; (checkbox, added in 1.0). Switches a feature off without deleting it. Useful for making a &amp;quot;no holes&amp;quot; variant, or for isolating which feature broke a fillet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reorder.&#039;&#039;&#039; Right-click → &#039;&#039;&#039;Move object after other object&#039;&#039;&#039;. Fusion&#039;s drag-in-timeline. Use it to push fillets to the end where they belong.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Move between bodies.&#039;&#039;&#039; Right-click → &#039;&#039;&#039;Move object to other body&#039;&#039;&#039;. Useful when you realise a feature should have been a separate part.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Edit a feature&#039;s parameters&#039;&#039;&#039; — just click it and use the Property editor. Double-click opens the full dialog if you need the face selections.&lt;br /&gt;
&lt;br /&gt;
One behaviour to know: FreeCAD recomputes eagerly. If a downstream feature can&#039;t rebuild after your edit, it goes red in the tree with a marker. Fix the cause and hit [[File:FC-Std-Refresh.svg|24px|link=|alt=Refresh]] &#039;&#039;&#039;Refresh&#039;&#039;&#039; (Std_Refresh) to force a full recompute. If the tree looks stale, right-click the document → &#039;&#039;&#039;Mark to recompute&#039;&#039;&#039; → then Refresh.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 10. Parameters and expressions ==&lt;br /&gt;
&lt;br /&gt;
Fusion has a Parameters dialog. FreeCAD&#039;s equivalent is a [[File:FC-WB-Spreadsheet.svg|24px|link=|alt=Spreadsheet workbench]] &#039;&#039;&#039;Spreadsheet&#039;&#039;&#039; inside the document, and it&#039;s more capable once set up.&lt;br /&gt;
&lt;br /&gt;
# Workbench dropdown → &#039;&#039;&#039;Spreadsheet&#039;&#039;&#039; → &#039;&#039;&#039;Create spreadsheet&#039;&#039;&#039;.&lt;br /&gt;
# Put a label in column A and the value in column B: &amp;lt;code&amp;gt;wall_thickness&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;2.4&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Click the B cell, and in the &#039;&#039;&#039;Alias&#039;&#039;&#039; box (or right-click → Properties → Alias) type &amp;lt;code&amp;gt;wall_thickness&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Back in Part Design, anywhere you can type a number, click the small &#039;&#039;&#039;fx&#039;&#039;&#039; (blue circle) icon at the right of the field and enter &amp;lt;code&amp;gt;Spreadsheet.wall_thickness&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Now change the spreadsheet and the model follows. You can use full arithmetic in expressions: &amp;lt;code&amp;gt;Spreadsheet.wall_thickness * 2 + 0.4&amp;lt;/code&amp;gt;, and reference other features: &amp;lt;code&amp;gt;Pad.Length / 2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;A printing-specific setup that pays for itself immediately&#039;&#039;&#039; — put these in a spreadsheet at the top of every project:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Alias&lt;br /&gt;
! Typical value&lt;br /&gt;
! Used for&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;nozzle&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;0.4&amp;lt;/code&amp;gt;&lt;br /&gt;
| Making wall thicknesses exact multiples&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;layer&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;0.2&amp;lt;/code&amp;gt;&lt;br /&gt;
| Making heights exact multiples&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;wall&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;=nozzle * 6&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;2.4&amp;lt;/code&amp;gt;&lt;br /&gt;
| Every wall in the part&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clearance_slip&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;0.2&amp;lt;/code&amp;gt;&lt;br /&gt;
| Holes that parts slide into&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clearance_press&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;0.05&amp;lt;/code&amp;gt;&lt;br /&gt;
| Press fits&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clearance_moving&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;0.4&amp;lt;/code&amp;gt;&lt;br /&gt;
| Print-in-place hinges&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Then a hole for a 5 mm rod becomes &amp;lt;code&amp;gt;5 + Spreadsheet.clearance_slip * 2&amp;lt;/code&amp;gt;, and when you switch filament or printer you retune one cell instead of forty dimensions. This is the single biggest quality-of-life win available in FreeCAD for print design, and it&#039;s better than Fusion&#039;s parameters because the spreadsheet can do arithmetic between its own cells.&lt;br /&gt;
&lt;br /&gt;
You can also name individual sketch constraints (there&#039;s a name field in the dimension dialog) and reference them as &amp;lt;code&amp;gt;Sketch.Constraints.hole_dia&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 11. Multiple bodies, and assemblies for fit checks ==&lt;br /&gt;
&lt;br /&gt;
=== 11.1 Two parts in one file ===&lt;br /&gt;
&lt;br /&gt;
Because a Body holds one solid, a two-piece design means two Bodies in the same document. Create the second with [[File:FC-Body.svg|24px|link=|alt=Create body]] &#039;&#039;&#039;Create body&#039;&#039;&#039; — note that this makes it the &#039;&#039;active&#039;&#039; body (shown in bold), and all new features go into it. Double-click a Body in the tree to switch which one is active. Forgetting this is the classic &amp;quot;why did my pocket cut the wrong part&amp;quot; mistake.&lt;br /&gt;
&lt;br /&gt;
To position them relative to each other without a full assembly, select a Body and edit its &#039;&#039;&#039;Placement&#039;&#039;&#039; in the Property editor, or use the 1.1 &#039;&#039;&#039;Transform&#039;&#039;&#039; tool, which now has proper draggers, numeric entry, alignment to any element, and a move-to-target function.&lt;br /&gt;
&lt;br /&gt;
To make a second body reference geometry from the first, use [[File:FC-SubShapeBinder.svg|24px|link=|alt=SubShapeBinder]] &#039;&#039;&#039;SubShapeBinder&#039;&#039;&#039; — it pulls a face or edge across as a reference you can sketch on. This is the correct answer to &amp;quot;how do I make a lid that matches this box&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== 11.2 The Assembly workbench ===&lt;br /&gt;
&lt;br /&gt;
For anything with moving parts, or where you want to check clearances before committing to a 6-hour print, use [[File:FC-WB-Assembly.svg|24px|link=|alt=Assembly workbench]] &#039;&#039;&#039;Assembly&#039;&#039;&#039; (built in since 1.0, improved in 1.1 with &#039;&#039;Insert new part&#039;&#039; and &#039;&#039;Create simulation&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Basic flow: create an Assembly container, insert your Bodies (or link parts from other documents), then add &#039;&#039;&#039;Joints&#039;&#039;&#039; — Fixed, Revolute, Slider, Cylindrical, Ball, Distance. It&#039;s conceptually the same as Fusion&#039;s joints, and the solver is decent.&lt;br /&gt;
&lt;br /&gt;
For print-in-place mechanisms, the assembly is how you verify a hinge actually swings before you print it. 1.1 added kinematic &#039;&#039;&#039;simulation&#039;&#039;&#039; with animation preview, which makes this genuinely quick.&lt;br /&gt;
&lt;br /&gt;
Honest assessment: FreeCAD&#039;s assembly is younger and less polished than Fusion&#039;s. For the scale of thing most 3D printing involves — a handful of parts, a couple of joints — it&#039;s perfectly adequate. Don&#039;t try to build a 200-part machine in it yet.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 12. Exporting for the slicer ==&lt;br /&gt;
&lt;br /&gt;
=== 12.1 The quick way ===&lt;br /&gt;
&lt;br /&gt;
# Select the &#039;&#039;&#039;Body&#039;&#039;&#039; in the tree (the Body, not a feature inside it).&lt;br /&gt;
# &#039;&#039;&#039;File → Export…&#039;&#039;&#039; (&#039;&#039;&#039;Ctrl+E&#039;&#039;&#039;).&lt;br /&gt;
# Choose the file type: &#039;&#039;&#039;&amp;lt;code&amp;gt;STL Mesh (*.stl)&amp;lt;/code&amp;gt;&#039;&#039;&#039; or &#039;&#039;&#039;&amp;lt;code&amp;gt;3MF (*.3mf)&amp;lt;/code&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
# Save.&lt;br /&gt;
&lt;br /&gt;
FreeCAD tessellates the solid on the fly using the settings below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Use 3MF if your slicer supports it&#039;&#039;&#039; (PrusaSlicer, OrcaSlicer, Bambu Studio, Cura all do). It&#039;s a modern container format, it stores units unambiguously, the files are smaller, and it survives multi-body exports better. FreeCAD 1.x imports and exports it. STL remains the safe universal fallback.&lt;br /&gt;
&lt;br /&gt;
Other formats worth knowing:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;STEP&#039;&#039;&#039; (&amp;lt;code&amp;gt;.step&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;.stp&amp;lt;/code&amp;gt;) — exact solid geometry, not a mesh. This is what you send to someone else for CAD work, and what you use to archive. Fusion can import it.&lt;br /&gt;
* &#039;&#039;&#039;OBJ&#039;&#039;&#039;, &#039;&#039;&#039;PLY&#039;&#039;&#039;, &#039;&#039;&#039;AMF&#039;&#039;&#039; — supported, rarely needed for printing.&lt;br /&gt;
&lt;br /&gt;
=== 12.2 Mesh quality — the setting that actually matters ===&lt;br /&gt;
&lt;br /&gt;
Default export settings will give you visibly faceted holes on small parts. Fix it once:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preferences → Import-Export → Mesh formats&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Maximum mesh deviation (surface deviation)&#039;&#039;&#039;: default &amp;lt;code&amp;gt;0.10&amp;lt;/code&amp;gt; mm → set to &#039;&#039;&#039;&amp;lt;code&amp;gt;0.01&amp;lt;/code&amp;gt;&#039;&#039;&#039; mm&lt;br /&gt;
* &#039;&#039;&#039;Maximum angular deviation&#039;&#039;&#039;: default &amp;lt;code&amp;gt;30°&amp;lt;/code&amp;gt; → set to &#039;&#039;&#039;&amp;lt;code&amp;gt;10°&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Mesher&#039;&#039;&#039;: &amp;lt;code&amp;gt;Standard&amp;lt;/code&amp;gt; is fine. &amp;lt;code&amp;gt;Mefisto&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Netgen&amp;lt;/code&amp;gt; exist for special cases.&lt;br /&gt;
* &#039;&#039;&#039;STL format&#039;&#039;&#039;: leave on &#039;&#039;&#039;binary&#039;&#039;&#039; — ASCII STL files are roughly five times larger for no benefit.&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Fig-MeshDeviation.svg|thumb|center|760px|How mesh deviation affects a curved surface]]&lt;br /&gt;
&lt;br /&gt;
The resulting files are bigger — perhaps 2–4 MB instead of 500 KB for a typical part. No slicer or printer built in the last decade will care, and your curved surfaces will be smooth.&lt;br /&gt;
&lt;br /&gt;
=== 12.3 Checking the part before you print it ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Part → Check geometry&#039;&#039;&#039; (also on the Part Design toolbar as [[File:FC-Std-Measure.svg|24px|link=|alt=Measure]] a validation tool) runs an OpenCASCADE geometry check and reports invalid faces, self-intersections and open shells. It&#039;s improved in 1.1 — it now reports valid shapes and skipped objects too, and writes to the Report view.&lt;br /&gt;
&lt;br /&gt;
Run it on any part that took real effort, especially after lots of booleans. A solid that passes here will slice cleanly.&lt;br /&gt;
&lt;br /&gt;
For a visual check, switch the 3D view to &#039;&#039;&#039;View → Draw style → Wireframe&#039;&#039;&#039; or turn on transparency (&#039;&#039;&#039;View&#039;&#039;&#039; tab in the Property editor) to spot internal voids you didn&#039;t intend.&lt;br /&gt;
&lt;br /&gt;
=== 12.4 A note on scale ===&lt;br /&gt;
&lt;br /&gt;
FreeCAD works in millimetres and exports in millimetres. Slicers expect millimetres. Nothing to configure — this just works. If a part arrives in the slicer at 1/25.4 scale, you built it in inches by accident.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 13. Worked example: a parametric wall bracket ==&lt;br /&gt;
&lt;br /&gt;
An L-bracket with a reinforcing rib and mounting holes. Roughly twenty minutes, and it exercises everything above.&lt;br /&gt;
&lt;br /&gt;
=== Setup ===&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Ctrl+N&#039;&#039;&#039;.&lt;br /&gt;
# Switch to &#039;&#039;&#039;Spreadsheet&#039;&#039;&#039;, &#039;&#039;&#039;Create spreadsheet&#039;&#039;&#039;. Enter and alias:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Cell&lt;br /&gt;
! Content&lt;br /&gt;
! Alias&lt;br /&gt;
|-&lt;br /&gt;
| A1&lt;br /&gt;
| &amp;lt;code&amp;gt;thickness&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| B1&lt;br /&gt;
| &amp;lt;code&amp;gt;4&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;thickness&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| A2&lt;br /&gt;
| &amp;lt;code&amp;gt;width&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| B2&lt;br /&gt;
| &amp;lt;code&amp;gt;40&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;width&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| A3&lt;br /&gt;
| &amp;lt;code&amp;gt;arm&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| B3&lt;br /&gt;
| &amp;lt;code&amp;gt;60&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;arm&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| A4&lt;br /&gt;
| &amp;lt;code&amp;gt;bolt_dia&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| B4&lt;br /&gt;
| &amp;lt;code&amp;gt;5.4&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;bolt_dia&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
: (5.4 = M5 clearance plus a little printing allowance.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Switch to &#039;&#039;&#039;Part Design&#039;&#039;&#039; → [[File:FC-Body.svg|24px|link=|alt=Create body]] &#039;&#039;&#039;Create body&#039;&#039;&#039;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The L profile ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;4&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[File:FC-NewSketch.svg|24px|link=|alt=Create sketch]] &#039;&#039;&#039;Create sketch&#039;&#039;&#039; → &#039;&#039;&#039;XZ_Plane&#039;&#039;&#039;. This is the vertical plane facing you, so the L profile is drawn in elevation.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Draw the L with [[File:FC-Sk-Polyline.svg|24px|link=|alt=Polyline]] &#039;&#039;&#039;Polyline&#039;&#039;&#039; (&#039;&#039;&#039;G, M&#039;&#039;&#039;): six segments, roughly L-shaped, closing back on itself. Don&#039;t aim for accuracy — get the shape.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Constrain it:&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;The bottom-left corner point → [[File:FC-Sk-Coincident.svg|24px|link=|alt=Coincident constraint]] &#039;&#039;&#039;C&#039;&#039;&#039; onto the sketch origin.&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Each segment → [[File:FC-Sk-HorVer.svg|24px|link=|alt=Horizontal/vertical constraint]] &#039;&#039;&#039;A&#039;&#039;&#039; for horizontal/vertical (auto-constraints will have caught most already).&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;The vertical arm&#039;s outer edge → &#039;&#039;&#039;D&#039;&#039;&#039;, and in the value box click &#039;&#039;&#039;fx&#039;&#039;&#039; and enter &amp;lt;code&amp;gt;Spreadsheet.arm&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Horizontal arm&#039;s outer edge → &#039;&#039;&#039;D&#039;&#039;&#039; → &amp;lt;code&amp;gt;Spreadsheet.arm&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Both wall thicknesses → &#039;&#039;&#039;D&#039;&#039;&#039; → &amp;lt;code&amp;gt;Spreadsheet.thickness&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Status bar should read &#039;&#039;&#039;Fully constrained&#039;&#039;&#039;, sketch fully green. If not, click the DoF message to see what&#039;s still loose.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Close&#039;&#039;&#039;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The body ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;9&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Select the sketch → [[File:FC-Pad.svg|24px|link=|alt=Pad]] &#039;&#039;&#039;Pad&#039;&#039;&#039;. Length: &#039;&#039;&#039;fx&#039;&#039;&#039; → &amp;lt;code&amp;gt;Spreadsheet.width&amp;lt;/code&amp;gt;. Tick &#039;&#039;&#039;Symmetric to plane&#039;&#039;&#039; so it grows evenly either side of the origin — this makes mirroring behave later. &#039;&#039;&#039;OK&#039;&#039;&#039;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The rib ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;10&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click the inside corner face — or easier, [[File:FC-NewSketch.svg|24px|link=|alt=Create sketch]] &#039;&#039;&#039;Create sketch&#039;&#039;&#039; on &#039;&#039;&#039;XZ_Plane&#039;&#039;&#039; again.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Draw a right triangle in the inner corner with &#039;&#039;&#039;Polyline&#039;&#039;&#039;. Constrain its two straight edges coincident with the projected inner faces (use [[File:FC-Sk-External.svg|24px|link=|alt=External geometry]] &#039;&#039;&#039;External geometry&#039;&#039;&#039;, &#039;&#039;&#039;G, X&#039;&#039;&#039;, to pull those edges in — remember in 1.1 they come in as real geometry you can constrain directly to).&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dimension the two legs to something like &amp;lt;code&amp;gt;arm * 0.5&amp;lt;/code&amp;gt; via expressions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Close → [[File:FC-Pad.svg|24px|link=|alt=Pad]] &#039;&#039;&#039;Pad&#039;&#039;&#039;, symmetric, length &amp;lt;code&amp;gt;Spreadsheet.thickness&amp;lt;/code&amp;gt;. &#039;&#039;&#039;OK&#039;&#039;&#039;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The holes ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;14&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click the outer face of the vertical arm. [[File:FC-NewSketch.svg|24px|link=|alt=Create sketch]] &#039;&#039;&#039;Create sketch&#039;&#039;&#039; — it attaches to that face.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Draw two [[File:FC-Sk-Circle.svg|24px|link=|alt=Circle]] circles (&#039;&#039;&#039;G, C&#039;&#039;&#039;).&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Constrain: [[File:FC-Sk-Symmetric.svg|24px|link=|alt=Symmetric constraint]] &#039;&#039;&#039;S&#039;&#039;&#039; to make them symmetric about the vertical axis, [[File:FC-Sk-Equal.svg|24px|link=|alt=Equal constraint]] &#039;&#039;&#039;E&#039;&#039;&#039; to make them equal diameter, then &#039;&#039;&#039;D&#039;&#039;&#039; on one → &#039;&#039;&#039;fx&#039;&#039;&#039; → &amp;lt;code&amp;gt;Spreadsheet.bolt_dia&amp;lt;/code&amp;gt;. Add a &#039;&#039;&#039;D&#039;&#039;&#039; from the top edge to fix their height.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Close. Select the sketch → [[File:FC-Hole.svg|24px|link=|alt=Hole]] &#039;&#039;&#039;Hole&#039;&#039;&#039;. Set &#039;&#039;&#039;Profile → Diameter&#039;&#039;&#039; to inherit from the sketch, &#039;&#039;&#039;Depth → Through all&#039;&#039;&#039;. If you want countersinks for M5 screws, set &#039;&#039;&#039;Hole cut type → Countersink&#039;&#039;&#039;. &#039;&#039;&#039;OK&#039;&#039;&#039;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Repeat on the horizontal arm.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dress up ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;19&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Select the two outer vertical edges of the bracket → [[File:FC-Fillet.svg|24px|link=|alt=Fillet]] &#039;&#039;&#039;Fillet&#039;&#039;&#039; → 3 mm.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Select the bottom face&#039;s perimeter edges → [[File:FC-Chamfer.svg|24px|link=|alt=Chamfer]] &#039;&#039;&#039;Chamfer&#039;&#039;&#039; → 0.6 mm. This is your elephant&#039;s-foot insurance.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Export ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;21&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Select the &#039;&#039;&#039;Body&#039;&#039;&#039; in the tree.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Ctrl+E&#039;&#039;&#039; → &amp;lt;code&amp;gt;3MF&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;STL&amp;lt;/code&amp;gt;) → save.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Now prove it&#039;s parametric ===&lt;br /&gt;
&lt;br /&gt;
Go back to the spreadsheet and change &amp;lt;code&amp;gt;thickness&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;4&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;6&amp;lt;/code&amp;gt;. Switch to Part Design. The whole bracket — profile, rib, chamfers — thickens, and the holes stay put. That&#039;s the payoff for constraining properly, and it&#039;s the moment FreeCAD usually starts to feel worth it.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 14. When things break ==&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;&amp;quot;Result has multiple solids&amp;quot;&#039;&#039;&#039; on a Pad or Pocket.&lt;br /&gt;
Your feature created material disconnected from the rest of the Body. Either connect it, or put it in its own Body. This is the one-solid-per-Body rule biting.&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;Pad button is greyed out.&#039;&#039;&#039;&lt;br /&gt;
No active Body, or no sketch selected. Double-click a Body in the tree to activate it (it goes bold).&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;&amp;quot;Cannot use this sketch — it is not closed&amp;quot; / you get a surface instead of a solid.&#039;&#039;&#039;&lt;br /&gt;
There&#039;s a gap or a duplicate edge. Close the sketch, select it, and run &#039;&#039;&#039;Sketch → Validate sketch&#039;&#039;&#039; — it will find and optionally repair missing coincidences.&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;Fillet or chamfer fails with no useful message.&#039;&#039;&#039;&lt;br /&gt;
Read the &#039;&#039;&#039;Report view&#039;&#039;&#039; for the real error. Then: reduce the radius; split it into two features; check that the refine preferences from [[#2.5 Part Design behaviour|2.5]] are on; make sure the fillet is the last feature in the tree.&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;A feature turns red after you edit something upstream.&#039;&#039;&#039;&lt;br /&gt;
Usually a broken face or edge reference. Double-click the failing feature, and re-pick the geometry. FreeCAD 1.0 and 1.1 substantially improved the topological naming problem — the classic FreeCAD complaint — and this happens far less than its reputation suggests, but it still happens. Referencing origin planes and datums instead of model faces is the prevention.&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;Everything is grey / you can&#039;t select the thing you want.&#039;&#039;&#039;&lt;br /&gt;
Try the 1.1 &#039;&#039;&#039;Clarify selection&#039;&#039;&#039; tool, which makes nearby geometry temporarily transparent so you can pick the entity underneath. Or hover and press the mouse-over selection cycling.&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;You padded into the wrong body.&#039;&#039;&#039;&lt;br /&gt;
Right-click the feature → &#039;&#039;&#039;Move object to other body&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;The model looks faceted in the 3D view.&#039;&#039;&#039;&lt;br /&gt;
That&#039;s display tessellation only, not your geometry. Fix it in [[#2.5 Part Design behaviour|2.5]]; it does not affect exports (those use the separate mesh-export settings in [[#12.2 Mesh quality — the setting that actually matters|12.2]]).&lt;br /&gt;
&lt;br /&gt;
[[File:FC-Std-Warning.svg|24px|link=|alt=Warning]] &#039;&#039;&#039;Esc dumped you out of the sketch.&#039;&#039;&#039;&lt;br /&gt;
Turn off &#039;&#039;Esc can leave sketch edit mode&#039;&#039; — see [[#2.6 Sketcher|2.6]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 15. Keyboard cheat sheet ==&lt;br /&gt;
&lt;br /&gt;
=== Global ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key&lt;br /&gt;
! Action&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Ctrl+N&#039;&#039;&#039; / &#039;&#039;&#039;Ctrl+O&#039;&#039;&#039; / &#039;&#039;&#039;Ctrl+S&#039;&#039;&#039;&lt;br /&gt;
| New / Open / Save&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Ctrl+E&#039;&#039;&#039;&lt;br /&gt;
| Export&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Ctrl+Z&#039;&#039;&#039; / &#039;&#039;&#039;Ctrl+Shift+Z&#039;&#039;&#039;&lt;br /&gt;
| Undo / Redo&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Space&#039;&#039;&#039;&lt;br /&gt;
| Toggle visibility of selected object&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;1&#039;&#039;&#039;–&#039;&#039;&#039;6&#039;&#039;&#039;&lt;br /&gt;
| Standard views (front, top, right, rear, bottom, left)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;0&#039;&#039;&#039;&lt;br /&gt;
| Isometric / axonometric&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;V, F&#039;&#039;&#039;&lt;br /&gt;
| Fit all (zoom to fit)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sketcher — geometry ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key&lt;br /&gt;
! Tool&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, L&#039;&#039;&#039;&lt;br /&gt;
| Line&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, M&#039;&#039;&#039;&lt;br /&gt;
| Polyline&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, R&#039;&#039;&#039;&lt;br /&gt;
| Rectangle&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, C&#039;&#039;&#039;&lt;br /&gt;
| Circle&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, A&#039;&#039;&#039;&lt;br /&gt;
| Arc&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, S&#039;&#039;&#039;&lt;br /&gt;
| Slot&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, H&#039;&#039;&#039;&lt;br /&gt;
| Regular polygon&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, B&#039;&#039;&#039;&lt;br /&gt;
| B-spline&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, F&#039;&#039;&#039;&lt;br /&gt;
| Fillet / chamfer&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, T&#039;&#039;&#039;&lt;br /&gt;
| Trim&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, Q&#039;&#039;&#039;&lt;br /&gt;
| Extend&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, X&#039;&#039;&#039;&lt;br /&gt;
| External geometry&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;G, N&#039;&#039;&#039;&lt;br /&gt;
| Toggle construction geometry&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;M&#039;&#039;&#039;&lt;br /&gt;
| Cycle the active tool&#039;s mode (while drawing)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Esc&#039;&#039;&#039; / right-click&lt;br /&gt;
| Drop the active tool&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sketcher — constraints ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key&lt;br /&gt;
! Constraint&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;D&#039;&#039;&#039;&lt;br /&gt;
| Dimension (context-sensitive)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;C&#039;&#039;&#039;&lt;br /&gt;
| Coincident / concentric / point-on-object&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;A&#039;&#039;&#039;&lt;br /&gt;
| Horizontal or vertical (auto)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;P&#039;&#039;&#039;&lt;br /&gt;
| Parallel&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;N&#039;&#039;&#039;&lt;br /&gt;
| Perpendicular&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T&#039;&#039;&#039;&lt;br /&gt;
| Tangent / collinear&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;E&#039;&#039;&#039;&lt;br /&gt;
| Equal&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;S&#039;&#039;&#039;&lt;br /&gt;
| Symmetric&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;K, D&#039;&#039;&#039;&lt;br /&gt;
| Distance&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;K, R&#039;&#039;&#039;&lt;br /&gt;
| Radius&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;K, A&#039;&#039;&#039;&lt;br /&gt;
| Angle&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;K, L&#039;&#039;&#039;&lt;br /&gt;
| Lock&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;K, X&#039;&#039;&#039;&lt;br /&gt;
| Toggle driving / reference&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Ctrl+C / X / V&#039;&#039;&#039;&lt;br /&gt;
| Copy / cut / paste sketch geometry with its constraints&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Everything is remappable: &#039;&#039;&#039;Tools → Customize → Keyboard&#039;&#039;&#039;. If your Fusion muscle memory is strong, remapping &#039;&#039;&#039;E&#039;&#039;&#039; to Pad and &#039;&#039;&#039;Q&#039;&#039;&#039; to Pocket is a popular move.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 16. Add-ons worth having ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tools → Addon Manager.&#039;&#039;&#039; Everything here is free and installs in-place.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Fasteners&#039;&#039;&#039; — a library of ISO/ANSI screws, nuts, washers and heat-set inserts you can drop onto holes. Immediately useful for checking that your M3 socket cap actually clears the counterbore.&lt;br /&gt;
* &#039;&#039;&#039;Curves&#039;&#039;&#039; — advanced surfacing and curve tools. Reach for it when Part Design&#039;s loft isn&#039;t enough.&lt;br /&gt;
* &#039;&#039;&#039;Defeaturing&#039;&#039;&#039; — removes faces and features from imported STEP files. Handy when adapting someone else&#039;s model.&lt;br /&gt;
* &#039;&#039;&#039;Sheet Metal&#039;&#039;&#039; — if you ever bend anything.&lt;br /&gt;
* &#039;&#039;&#039;MeshRemodel&#039;&#039;&#039; — helps convert an imported STL back into editable solid geometry. Imperfect, but the best option available for remixing STLs.&lt;br /&gt;
* &#039;&#039;&#039;Assembly3&#039;&#039;&#039; — an alternative assembly system. You almost certainly don&#039;t need it now that Assembly is built in; mentioned only so you know what people are referring to in old forum posts.&lt;br /&gt;
&lt;br /&gt;
A note on the forum and wiki: the FreeCAD community produces excellent documentation, but a great deal of it predates version 1.0. If a tutorial mentions &amp;quot;Part Design migrate&amp;quot;, the topological naming problem, or tells you to trace over external geometry, it&#039;s describing pre-1.0 behaviour. Check the version before you follow the advice.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 17. Habits to unlearn, habits to build ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Unlearn:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Sketching before creating a container. Body first, always.&lt;br /&gt;
* Leaving sketches under-constrained. It works in Fusion; it will hurt you here.&lt;br /&gt;
* Expecting one command to add or remove depending on direction. Pad and Pocket are different commands.&lt;br /&gt;
* Direct-editing solids by push-pulling faces. Part Design has no equivalent; you go back to the sketch or the feature&#039;s parameters. (The Property editor makes this fast once you&#039;re used to it.)&lt;br /&gt;
* Patterning bodies. You pattern features.&lt;br /&gt;
* Waiting for a cloud save. Ctrl+S writes a real file to a real disk that you own.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Build:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Body → sketch on XY → pad up.&#039;&#039;&#039; Make this reflex.&lt;br /&gt;
* &#039;&#039;&#039;Chase the green.&#039;&#039;&#039; Fully constrain everything before you leave a sketch.&lt;br /&gt;
* &#039;&#039;&#039;Live in the Property editor.&#039;&#039;&#039; It&#039;s faster than reopening dialogs.&lt;br /&gt;
* &#039;&#039;&#039;Start every project with a spreadsheet of print tolerances.&#039;&#039;&#039; Ten minutes, saves hours.&lt;br /&gt;
* &#039;&#039;&#039;Read the Report view when something fails.&#039;&#039;&#039; The answer is nearly always sitting there.&lt;br /&gt;
* &#039;&#039;&#039;Save often, and keep versions.&#039;&#039;&#039; &amp;lt;code&amp;gt;bracket_v3.FCStd&amp;lt;/code&amp;gt; costs you nothing.&lt;br /&gt;
* &#039;&#039;&#039;Fillets and chamfers last.&#039;&#039;&#039; Every time.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== What you actually gained and lost ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Lost:&#039;&#039;&#039; polish, generative tools, integrated CAM and simulation quality, sheet-metal maturity, cloud collaboration, a large ecosystem of tutorials matching your exact version, and Fusion&#039;s forgiving sketcher.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Gained:&#039;&#039;&#039; a &amp;lt;code&amp;gt;.FCStd&amp;lt;/code&amp;gt; file on your own disk that will still open in ten years, no licence terms that can change under you, no export limits or feature paywalls, Python scriptability all the way down, and — once you&#039;ve internalised constraints and the spreadsheet — a parametric workflow that&#039;s arguably more rigorous than the one you left.&lt;br /&gt;
&lt;br /&gt;
For parts destined for a 3D printer, FreeCAD 1.1 is entirely sufficient. Give it two weekends. The first will be frustrating and the second one won&#039;t.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Written for FreeCAD 1.1.3 (released 25 July 2026), default metric install. Version-specific behaviour noted where 1.1 differs from 1.0.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Main_Page&amp;diff=494</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Main_Page&amp;diff=494"/>
		<updated>2026-07-28T09:04:10Z</updated>

		<summary type="html">&lt;p&gt;Damme: /* Damme&amp;#039;s stuff */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== World Wide Wiegert Wiki - The best wiki in the world! ==&lt;br /&gt;
 Skapa en sida genom att skapa dig ett konto, editera denna sida och skriv länken inom brackets&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[namn på sidan]]&amp;lt;/nowiki&amp;gt; - spara och klicka på länken så är det bara att skriva vidare!&lt;br /&gt;
&lt;br /&gt;
== Damme&#039;s stuff ==&lt;br /&gt;
[[Daniel Wiegert - About me]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;[[Damme&#039;s linux stuff]]&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Damme&#039;s windows stuff]]&lt;br /&gt;
&lt;br /&gt;
[[Dammes other stuff]]&lt;br /&gt;
&lt;br /&gt;
[[Ubuntu Server LTS]]&lt;br /&gt;
&lt;br /&gt;
[[Hårdvara]]&lt;br /&gt;
&lt;br /&gt;
[[Development]]&lt;br /&gt;
&lt;br /&gt;
[[FreeCad Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[Resor mm]]&lt;br /&gt;
&lt;br /&gt;
[[Hiseeu 5MP PTZ gk7605v100 sc223a]]&lt;br /&gt;
&lt;br /&gt;
== Plupp&#039;s stuff ==&lt;br /&gt;
&lt;br /&gt;
[[Joachim&#039;s research page]]&lt;br /&gt;
&lt;br /&gt;
[[Useful EXWINGS stuff]]&lt;br /&gt;
&lt;br /&gt;
== Thesse&#039;s stuff ==&lt;br /&gt;
&lt;br /&gt;
[[CHANG-ES Interim wiki]] (needs login access)&lt;br /&gt;
&lt;br /&gt;
== Other pages ==&lt;br /&gt;
&lt;br /&gt;
== Wiki ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;[[Cheat sheet]]&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[MediaWiki format help]]&lt;br /&gt;
&lt;br /&gt;
[[Sandbox]] In here you can test wiki language.&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki]&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Daniel_Wiegert_-_About_me&amp;diff=492</id>
		<title>Daniel Wiegert - About me</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Daniel_Wiegert_-_About_me&amp;diff=492"/>
		<updated>2026-06-20T21:25:17Z</updated>

		<summary type="html">&lt;p&gt;Damme: Created page with &amp;quot;TBD ... :)&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TBD ... :)&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_Unicore_GPS&amp;diff=491</id>
		<title>OpenMower Unicore GPS</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_Unicore_GPS&amp;diff=491"/>
		<updated>2026-06-20T21:16:56Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; Only use this wiki if you are running bare metal custom build! Otherwise go to the official wiki, this is just a backup for personal reference!&lt;br /&gt;
&lt;br /&gt;
Several users have chosen alternative GPS RTK modules with chips by &#039;&#039;Unicore&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;UM960&#039;&#039;&lt;br /&gt;
* &#039;&#039;UM980&#039;&#039;&lt;br /&gt;
* &#039;&#039;UM982&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These chips are sold in different variants. Some come with a USB-C socket (so they can be connected directly to the Raspberry Pi). Some have different antenna socket (which need an &#039;&#039;SMA F&#039;&#039; to &#039;&#039;MMCX M90&#039;&#039; cable).&lt;br /&gt;
&lt;br /&gt;
Compared to the &#039;&#039;ArduSimple simpleRTK2B,&#039;&#039; they&#039;re a bit cheaper and support triple-band frequencies.&lt;br /&gt;
&lt;br /&gt;
== Variants how modules can be connected and configured ==&lt;br /&gt;
* Connection&lt;br /&gt;
** Module USB-c -&amp;gt; RPI USB (e.g. with angle connector)&lt;br /&gt;
** Module UART -&amp;gt; MainBoard UART (requires header connectivity)&lt;br /&gt;
&lt;br /&gt;
* Configuration&lt;br /&gt;
** With vendor software (requires Windows PC) - should be done before installing module into mower&lt;br /&gt;
** Over UART bus (only terminal) - should be done when RPI installed and operational&lt;br /&gt;
&lt;br /&gt;
== Step-by step set-up guides ==&lt;br /&gt;
*[[Unicore GPS Setup-CAN| With wiring to mainboard and configuration on UART]]&lt;br /&gt;
* &amp;lt;TODO&amp;gt; add other guides&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
[https://core-electronics.com.au/attachments/localcontent/Unicore_Reference_Commands_Manual_For_N4_High_Precision_Products_V2_EN_R1_1_189543505cb.pdf Command reference]&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
The vendor offers [https://en.unicore.com/products/uprecise.html &#039;&#039;UPrecise&#039;&#039;] to check all status details and configure the receiver. The UI is pleasing and has many features, but also quite some bugs. The download requires creating a free account.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
The following configuration works quite well. COM3 is used when connected via USB.&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
FRESET&lt;br /&gt;
CONFIG COM3 460800&lt;br /&gt;
MODE ROVER UAV&lt;br /&gt;
GPGGA 0.1&lt;br /&gt;
GPGSV 1&lt;br /&gt;
GPRMC 1&lt;br /&gt;
GPGSA 1&lt;br /&gt;
GPVTG 1&lt;br /&gt;
GPGST 1&lt;br /&gt;
SAVECONFIG&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;These lines can be pasted into &#039;&#039;UPrecise&#039;&#039; after connecting to the receiver. Theoretically, you can also connect directly to the receiver&#039;s TTY, but make sure to send CR+LF (&amp;lt;code&amp;gt;\r\n&amp;lt;/code&amp;gt;) line endings, otherwise the commands won&#039;t be recognized.&lt;br /&gt;
&lt;br /&gt;
=== OpenMower (&amp;lt;code&amp;gt;mower_config.txt&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
export OM_GPS_PROTOCOL=&amp;quot;NMEA&amp;quot;&lt;br /&gt;
export OM_GPS_PORT=&amp;quot;/dev/ttyUSB0&amp;quot;&lt;br /&gt;
export OM_GPS_BAUDRATE=&amp;quot;460800&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rebooting ==&lt;br /&gt;
Sometimes the receiver just can&#039;t get a fix. Then it might be helpful to reboot it. There are three buttons in &#039;&#039;UPrecise&#039;&#039;, which execute these commands:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Button&lt;br /&gt;
!Command&lt;br /&gt;
|-&lt;br /&gt;
|Hot Start&lt;br /&gt;
|&amp;lt;code&amp;gt;RESET&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Warm Start&lt;br /&gt;
|&amp;lt;code&amp;gt;RESET EPHEM&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Cold Start&lt;br /&gt;
|&amp;lt;code&amp;gt;RESET EPHEM ALMANAC IONUTC POSITION&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
See also section 8.3 (&amp;quot;Reset&amp;quot;) in the [https://core-electronics.com.au/attachments/localcontent/Unicore_Reference_Commands_Manual_For_N4_High_Precision_Products_V2_EN_R1_1_189543505cb.pdf command reference]. In contrast to the &amp;lt;code&amp;gt;FRESET&amp;lt;/code&amp;gt; command, these command &#039;&#039;&#039;don&#039;t&#039;&#039;&#039; wipe the configuration.&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_Edit_map&amp;diff=490</id>
		<title>OpenMower Edit map</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_Edit_map&amp;diff=490"/>
		<updated>2026-06-20T21:16:47Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; Only use this wiki if you are running bare metal custom build! Otherwise go to the official wiki, this is just a backup for personal reference!&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
This tutorial shows how to use an orthophoto (generated by taking aerial pictures with a drone) and modify the open mower map. In my case I recorded the boundary of my lawn area driving the mower around and later divided the area and added obstacles using the drone footage.&lt;br /&gt;
&lt;br /&gt;
[[File:Openmower map boundary orthophoto.png|none|thumb|openmower map boundary with orthophoto layer]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Generate an orthophoto ===&lt;br /&gt;
I took about 50 pictures with a drone ca. 10m above ground and generated an orthophoto using OpenDroneMap WebODM&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can read about the process here: https://docs.opendronemap.org/tutorials/&lt;br /&gt;
&lt;br /&gt;
OpenDroneMap WebODM runs in a docker container and can be found here: https://www.opendronemap.org/webodm/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can export an orthophoto .tif format there&lt;br /&gt;
&lt;br /&gt;
=== convert map.bag into GPX ===&lt;br /&gt;
Obviously back up your map.bag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I wrote a python script to convert the map area coordinates into utm coordinates. I ran this on the robots raspberry pi. In reads the map.bag from .ros folder and exports a .gpx format file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Following python packages are needed&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip install utm gpxpy&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You need to &amp;lt;code&amp;gt;source /opt/ros/noetic/setup.bash&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Modify the base point coodinates in the script. I use the roof mouned RTK GPS antenna as base coordinates.&lt;br /&gt;
&lt;br /&gt;
Modify the input and output file paths to your needs and run the python script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create a file wit following content: &amp;lt;code&amp;gt;bag_to_gpx_tracks_utm.py&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod +x bag_to_gpx_tracks_utm.py&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
#===========================================&lt;br /&gt;
# Christoph Sobel 11.05.2023&lt;br /&gt;
# script to convert openmower ros map.bag to gpx file&lt;br /&gt;
#===========================================&lt;br /&gt;
&lt;br /&gt;
from codecs import latin_1_decode&lt;br /&gt;
import rosbag&lt;br /&gt;
import utm&lt;br /&gt;
import gpxpy.gpx&lt;br /&gt;
import math&lt;br /&gt;
import os&lt;br /&gt;
from tf.transformations import euler_from_quaternion&lt;br /&gt;
&lt;br /&gt;
bag = rosbag.Bag(&#039;/home/pi/.ros/map.bag&#039;)&lt;br /&gt;
# bag = rosbag.Bag(&#039;output.bag&#039;)&lt;br /&gt;
&lt;br /&gt;
lat0 = 53.00&lt;br /&gt;
lon0 = 8.00&lt;br /&gt;
# lat0 = float(os.getenv(&#039;OM_DATUM_LAT&#039;))&lt;br /&gt;
# lon0 = float(os.getenv(&#039;OM_DATUM_LONG&#039;))&lt;br /&gt;
print(&amp;quot;base_point&amp;quot;, lat0, &amp;quot; &amp;quot;, lon0)&lt;br /&gt;
&lt;br /&gt;
topics = bag.get_type_and_topic_info()[1].keys()&lt;br /&gt;
print(topics)&lt;br /&gt;
&lt;br /&gt;
gpx = gpxpy.gpx.GPX()&lt;br /&gt;
gpx.name = &#039;open_mower_map&#039;&lt;br /&gt;
gpx.description = &#039;Map data from openmower map.bag&#039;&lt;br /&gt;
&lt;br /&gt;
# base point (e.g. gps antenna)&lt;br /&gt;
# base_point = gpxpy.gpx.GPXWaypoint(latitude=lat0, longitude=lon0, name=&amp;quot;base_point&amp;quot;)&lt;br /&gt;
# gpx.waypoints.append(base_point)&lt;br /&gt;
&lt;br /&gt;
x0, y0, zone, ut = utm.from_latlon(lat0, lon0)&lt;br /&gt;
print(&amp;quot;base_point in utm&amp;quot;, x0, &amp;quot; &amp;quot;, y0)&lt;br /&gt;
&lt;br /&gt;
gpx_track = gpxpy.gpx.GPXTrack(name=&amp;quot;base_point&amp;quot;)&lt;br /&gt;
gpx.tracks.append(gpx_track)&lt;br /&gt;
gpx_segment = gpxpy.gpx.GPXTrackSegment()&lt;br /&gt;
gpx_track.segments.append(gpx_segment)&lt;br /&gt;
gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(lat0, lon0, elevation=0))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Loop through areas and obstacles&lt;br /&gt;
area_counter = 0&lt;br /&gt;
&lt;br /&gt;
for area_type in [&#039;mowing_areas&#039;, &#039;navigation_areas&#039;]:&lt;br /&gt;
    for topic, msg, t in bag.read_messages(topics=[area_type]):&lt;br /&gt;
        print(&amp;quot;{}_{}_area&amp;quot;.format(area_type[:-1], area_counter))&lt;br /&gt;
        # Create track in GPX:&lt;br /&gt;
        gpx_track = gpxpy.gpx.GPXTrack(name=&amp;quot;{}_{}_area&amp;quot;.format(area_type[:-1], area_counter))&lt;br /&gt;
        gpx.tracks.append(gpx_track)&lt;br /&gt;
        # Create segment in GPX track:&lt;br /&gt;
        gpx_segment = gpxpy.gpx.GPXTrackSegment()&lt;br /&gt;
        gpx_track.segments.append(gpx_segment)&lt;br /&gt;
&lt;br /&gt;
        # outline&lt;br /&gt;
        for point in msg.area.points:&lt;br /&gt;
            # Create points:&lt;br /&gt;
            lat, lon = utm.to_latlon(x0 + point.x, y0 + point.y, zone, ut)&lt;br /&gt;
            gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(lat, lon, elevation=0))&lt;br /&gt;
&lt;br /&gt;
        # obstacles&lt;br /&gt;
        obstacle_counter = 0&lt;br /&gt;
        for obst in msg.obstacles:&lt;br /&gt;
            print(&amp;quot;{}_{}_obstacle_{}&amp;quot;.format(area_type[:-1], area_counter, obstacle_counter))&lt;br /&gt;
            # Create track in GPX:&lt;br /&gt;
            gpx_track = gpxpy.gpx.GPXTrack(name=&amp;quot;{}_{}_obstacle_{}&amp;quot;.format(area_type[:-1], area_counter, obstacle_counter))&lt;br /&gt;
            gpx.tracks.append(gpx_track)&lt;br /&gt;
            # Create segment in GPX track:&lt;br /&gt;
            gpx_segment = gpxpy.gpx.GPXTrackSegment()&lt;br /&gt;
            gpx_track.segments.append(gpx_segment)&lt;br /&gt;
            for point in obst.points:&lt;br /&gt;
                # Create points:&lt;br /&gt;
                lat, lon = utm.to_latlon(x0 + point.x, y0 + point.y, zone, ut)&lt;br /&gt;
                gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(lat, lon, elevation=0))&lt;br /&gt;
            obstacle_counter += 1&lt;br /&gt;
        area_counter += 1&lt;br /&gt;
&lt;br /&gt;
# docking point&lt;br /&gt;
for topic, msg, t in bag.read_messages(topics=[&#039;docking_point&#039;]):&lt;br /&gt;
    # print(msg)&lt;br /&gt;
    print(&amp;quot;parsing docking point&amp;quot;)&lt;br /&gt;
    quat_list = [msg.orientation.x, msg.orientation.y, msg.orientation.z, msg.orientation.w]&lt;br /&gt;
    (roll, pitch, yaw) = euler_from_quaternion(quat_list)&lt;br /&gt;
    # print((roll, pitch, yaw))&lt;br /&gt;
    x2 = msg.position.x + math.cos(yaw)&lt;br /&gt;
    y2 = msg.position.y + math.sin(yaw)&lt;br /&gt;
&lt;br /&gt;
    lat1, lon1 = utm.to_latlon(x0 + msg.position.x, y0 + msg.position.y, zone, ut)&lt;br /&gt;
    lat2, lon2 = utm.to_latlon(x0 + x2,y0 + y2, zone, ut)&lt;br /&gt;
&lt;br /&gt;
    gpx_track = gpxpy.gpx.GPXTrack(name=&amp;quot;docking_point&amp;quot;)&lt;br /&gt;
    gpx.tracks.append(gpx_track)&lt;br /&gt;
    gpx_segment = gpxpy.gpx.GPXTrackSegment()&lt;br /&gt;
    gpx_track.segments.append(gpx_segment)&lt;br /&gt;
    gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(lat1, lon1, elevation=0))&lt;br /&gt;
    gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(lat2, lon2, elevation=0))&lt;br /&gt;
&lt;br /&gt;
print(&#039;Created GPX file&#039;)&lt;br /&gt;
with open(&amp;quot;map_bag.gpx&amp;quot;, &amp;quot;w&amp;quot;) as f:&lt;br /&gt;
    f.write(gpx.to_xml())&lt;br /&gt;
&lt;br /&gt;
bag.close()&lt;br /&gt;
print(&#039;Done&#039;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== load GPX file into JOSM ===&lt;br /&gt;
Install the Java OpenStreetMap Editor from:&lt;br /&gt;
&lt;br /&gt;
https://josm.openstreetmap.de/wiki/Download&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start JOSM and install the PicLayer Plugin. For this go to &#039;&#039;Edit-&amp;gt;Preferences-&amp;gt;Plugins&#039;&#039; and search for PicLayer and tick the checkbox.&lt;br /&gt;
&lt;br /&gt;
Open your .gpx file, you shoud see the recorded boundaries&lt;br /&gt;
[[File:JOSM imported GPX file.png|none|thumb|Boundaries visible in JOSM from imported GPX file]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Right click on the Layer output.gpx and select &amp;quot;convert to data layer&amp;quot;. Proceed without simplifying. Now every node should be visible.&lt;br /&gt;
&lt;br /&gt;
=== overlay and align with an orthophoto ===&lt;br /&gt;
&lt;br /&gt;
* select &#039;&#039;Imagery-&amp;gt;More...-&amp;gt;New picture layer from file...&#039;&#039; and open your orthophoto .tif file&lt;br /&gt;
* you can now use the PicLayer tools from the toolbar to align you image layer. When all is aligned, right click on the picture layer and save the picture calibration for later use.&lt;br /&gt;
[[File:JOSM with orthophoto.png|none|thumb|mowing area boundaries in JOSM with orthophoto]]&lt;br /&gt;
&lt;br /&gt;
=== modify the boundaries ===&lt;br /&gt;
you can now add/remove/modify/merge/divide:&lt;br /&gt;
&lt;br /&gt;
* mowing or navigation areas&lt;br /&gt;
* obstacles&lt;br /&gt;
* docking point&lt;br /&gt;
&lt;br /&gt;
Using all the nice tools from JOSM.&lt;br /&gt;
&lt;br /&gt;
Following rules for this:&lt;br /&gt;
&lt;br /&gt;
* mowing and navigation areas need to be in counter clockwise direction&lt;br /&gt;
* obstacles need to be in clockwise direction&lt;br /&gt;
&lt;br /&gt;
definition of the feature is in the value of gpx:name tag of each way like this:&lt;br /&gt;
&lt;br /&gt;
* mowing_area_0_area&lt;br /&gt;
* mowing_area_0_obstacle_0&lt;br /&gt;
*mowing_area_0_obstacle_1&lt;br /&gt;
* mowing_area_1_area&lt;br /&gt;
* navigation_area_0_area&lt;br /&gt;
*navigation_area_1_area&lt;br /&gt;
*navigation_area_1_obstacle_0&lt;br /&gt;
* docking_point&lt;br /&gt;
[[File:JOSM gpsname tag information.png|none|thumb|area boundary JOSM gps:name tag information]]&lt;br /&gt;
Here you can see an added obstacle.&lt;br /&gt;
&lt;br /&gt;
=== export as GPX and convert back to openmower map.bag ===&lt;br /&gt;
Right click on the gpx layer and &amp;quot;save as&amp;quot;. Select gpx format.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;source /opt/ros/noetic/setup.bash&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to &amp;lt;code&amp;gt;source ./devel/setup.bash&amp;lt;/code&amp;gt; in your &amp;lt;code&amp;gt;open_mower_ros&amp;lt;/code&amp;gt; folder to get the MapArea custom ros message&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Modify the base point coordinates in the script. I use the roof mounted RTK GPS antenna as base coordinates.&lt;br /&gt;
&lt;br /&gt;
Modify the input and output file paths to your needs in the python script.&lt;br /&gt;
&lt;br /&gt;
Run following python script and put the output_map.bag where your ros.bag was.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create a file wit following content: &amp;lt;code&amp;gt;gpx_to_bag.py&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod +x gpx_to_bag.py&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
#===========================================&lt;br /&gt;
# Christoph Sobel 11.05.2023&lt;br /&gt;
# script to convert gpx files to openmower ros map.bag&lt;br /&gt;
#===========================================&lt;br /&gt;
&lt;br /&gt;
import gpxpy.gpx&lt;br /&gt;
import utm&lt;br /&gt;
import rosbag&lt;br /&gt;
import math&lt;br /&gt;
from geometry_msgs.msg import Polygon, Point32, Pose&lt;br /&gt;
from mower_map.msg import MapArea  # Imports the custom message from its package&lt;br /&gt;
from tf.transformations import quaternion_from_euler&lt;br /&gt;
&lt;br /&gt;
# Base point&lt;br /&gt;
lat0 = 53.00&lt;br /&gt;
lon0 = 8.00&lt;br /&gt;
# lat0 = float(os.getenv(&#039;OM_DATUM_LAT&#039;))&lt;br /&gt;
# lon0 = float(os.getenv(&#039;OM_DATUM_LONG&#039;))&lt;br /&gt;
print(&amp;quot;base_point&amp;quot;, lat0, &amp;quot; &amp;quot;, lon0)&lt;br /&gt;
x0, y0, zone, ut = utm.from_latlon(lat0, lon0)&lt;br /&gt;
print(&amp;quot;base_point in utm&amp;quot;, x0, &amp;quot; &amp;quot;, y0)&lt;br /&gt;
&lt;br /&gt;
gpx_file = open(&#039;map_bag_osm.gpx&#039;, &#039;r&#039;)&lt;br /&gt;
gpx = gpxpy.parse(gpx_file)&lt;br /&gt;
&lt;br /&gt;
mowing_area_dict = {}&lt;br /&gt;
navigation_area_dict = {}&lt;br /&gt;
base_point = []&lt;br /&gt;
docking_points = []&lt;br /&gt;
&lt;br /&gt;
for track in gpx.tracks:&lt;br /&gt;
	print(&amp;quot;reading from gpx: &amp;quot;, track.name)&lt;br /&gt;
	# get points&lt;br /&gt;
	point_list = []&lt;br /&gt;
	for segment in track.segments:&lt;br /&gt;
		print(&amp;quot;Point count:{}&amp;quot;.format(len(segment.points)))&lt;br /&gt;
		for point in segment.points:&lt;br /&gt;
			# print(f&#039;Point at ({point.latitude},{point.longitude}) -&amp;gt; {point.elevation}&#039;)&lt;br /&gt;
			x, y, zone, ut = utm.from_latlon(point.latitude, point.longitude)&lt;br /&gt;
			point_list.append(Point32(x=x-x0, y=y-y0, z=0.0))&lt;br /&gt;
	# store in deciated dict&lt;br /&gt;
	if &amp;quot;mowing&amp;quot; in track.name:&lt;br /&gt;
		mowing_area_dict[track.name] = point_list&lt;br /&gt;
	elif &amp;quot;navigation&amp;quot; in track.name:&lt;br /&gt;
		navigation_area_dict[track.name] = point_list&lt;br /&gt;
	elif &amp;quot;base&amp;quot; in track.name:&lt;br /&gt;
		base_point = point_list&lt;br /&gt;
	elif &amp;quot;docking&amp;quot; in track.name:&lt;br /&gt;
		docking_points  = point_list&lt;br /&gt;
&lt;br /&gt;
docking_pose = Pose()&lt;br /&gt;
if len(docking_points) == 2:&lt;br /&gt;
	yaw = math.atan2(docking_points[1].y - docking_points[0].y, docking_points[1].x - docking_points[0].x)&lt;br /&gt;
	quaternion = quaternion_from_euler(0,0,yaw)&lt;br /&gt;
	&lt;br /&gt;
	docking_pose.position.x = docking_points[0].x&lt;br /&gt;
	docking_pose.position.y = docking_points[0].y&lt;br /&gt;
	# Pose Orientation&lt;br /&gt;
	docking_pose.orientation.x = quaternion[0]&lt;br /&gt;
	docking_pose.orientation.y = quaternion[1]&lt;br /&gt;
	docking_pose.orientation.z = quaternion[2]&lt;br /&gt;
	docking_pose.orientation.w = quaternion[3]&lt;br /&gt;
		&lt;br /&gt;
&lt;br /&gt;
def sort_dict_return_MapAreas(area_dict):&lt;br /&gt;
	areas = {}&lt;br /&gt;
	for track_name, point_list in sorted(area_dict.items()): # store sorted polygons to MapArea&lt;br /&gt;
		map_area = MapArea()&lt;br /&gt;
		print(&amp;quot;converting:&amp;quot;, track_name)&lt;br /&gt;
		area_number = track_name.split(&amp;quot;_&amp;quot;)[2]&lt;br /&gt;
		poly = Polygon(points=point_list)&lt;br /&gt;
		if &amp;quot;area&amp;quot; in track_name[-4:]:&lt;br /&gt;
			map_area.area = poly&lt;br /&gt;
			areas[area_number] = map_area&lt;br /&gt;
		elif &amp;quot;obstacle&amp;quot; in track_name:&lt;br /&gt;
			map_area = areas[area_number]&lt;br /&gt;
			map_area.obstacles.append(poly)&lt;br /&gt;
			areas[area_number] = map_area&lt;br /&gt;
	return areas&lt;br /&gt;
&lt;br /&gt;
mowing_areas_list = sort_dict_return_MapAreas(mowing_area_dict).values()&lt;br /&gt;
navigation_areas_list = sort_dict_return_MapAreas(navigation_area_dict).values()&lt;br /&gt;
&lt;br /&gt;
with rosbag.Bag(&#039;output_map.bag&#039;, &#039;w&#039;) as outbag:&lt;br /&gt;
	print(&#039;writing bag file&#039;)&lt;br /&gt;
	for mowing_area in mowing_areas_list:&lt;br /&gt;
		outbag.write(&amp;quot;mowing_areas&amp;quot;, mowing_area)&lt;br /&gt;
	for navigation_area in navigation_areas_list:	&lt;br /&gt;
		outbag.write(&amp;quot;navigation_areas&amp;quot;, navigation_area)&lt;br /&gt;
	outbag.write(&amp;quot;docking_point&amp;quot;, docking_pose)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_Simulation&amp;diff=489</id>
		<title>OpenMower Simulation</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_Simulation&amp;diff=489"/>
		<updated>2026-06-20T21:16:35Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; Only use this wiki if you are running bare metal custom build! Otherwise go to the official wiki, this is just a backup for personal reference!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
You can test the OpenMower software stack yourself by running a simulation where you can record a map and then have it mowed in a simulation on-screen. &lt;br /&gt;
&lt;br /&gt;
It&#039;s a bit rough around the edges, but it&#039;s a good way to see the software in action without hardware.&lt;br /&gt;
&lt;br /&gt;
This mini-HOWTO is meant to save you a bit of detective work and get you started, not to be a comprehensive guide to the simulation.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
You need the OpenMower software &#039;&#039;&#039;on a platform that has ROS and a graphical interface&#039;&#039;&#039; for rviz to be able to run and show the map. Ubuntu 20 on a desktop is a good choice, possibly on VM, VirtualBox is an excellent choice, if you do not already have a running Ubuntu 20 desktop environment.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Install ROS on Ubuntu&#039;&#039;&#039;: http://wiki.ros.org/noetic/Installation/Ubuntu - use the full install&lt;br /&gt;
** Note: make sure that you have the ROS environment set up in your terminal by &amp;lt;code&amp;gt;echo &amp;quot;source /opt/ros/noetic/setup.bash&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&amp;lt;/code&amp;gt;  and log out and back in.&lt;br /&gt;
* &#039;&#039;&#039;Install the OpenMower software:&#039;&#039;&#039; Use the instructions here: [[Setting up ROS on a Raspberry Pi (intended to be the Rover -- OpenMower)]]&lt;br /&gt;
** Make sure that you have had &amp;lt;code&amp;gt;catkin_make&amp;lt;/code&amp;gt; succeed (may take a few tries, often 4 or more)&lt;br /&gt;
&lt;br /&gt;
You need to have a game controller for controlling the simulated bot.&lt;br /&gt;
&lt;br /&gt;
== Making sure the OpenMower environment is sourced ==&lt;br /&gt;
&#039;&#039;Whenever you are doing anything in a terminal with OpenMower&#039;&#039;, you need to make sure that ROS knows your OpenMower workspace.&lt;br /&gt;
&lt;br /&gt;
In every terminal that you use: &amp;lt;code&amp;gt;source ~/OpenMower/ROS/devel/setup.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Running the simulation ==&lt;br /&gt;
&lt;br /&gt;
=== Recording a map ===&lt;br /&gt;
[[File:VirtualBox enable USB.png|thumb|Enable USB ports on VirtualBox]]&lt;br /&gt;
Attach your joystick to a USB port. If you are on a VirtualBox, make sure that the USB port of your joystick / gamepad is mapped into your Ubuntu environment (see illustration).&lt;br /&gt;
&lt;br /&gt;
Open a terminal and execute&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;roslaunch ~/OpenMower/ROS/src/open_mower_ros/open_mower/launch/sim_mower_logic.launch&amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:Simulation running.png|thumb|OpenMower simulation running]]&lt;br /&gt;
This will launch rviz where you can see the Rover and the map.&lt;br /&gt;
&lt;br /&gt;
Use your joystick to record a map and a base. On my gamepad, the buttons are&lt;br /&gt;
&lt;br /&gt;
* 1 - enable movement&lt;br /&gt;
* 2 - start path recording&lt;br /&gt;
* 4 + ↓ - end path recording&lt;br /&gt;
* 3 - register base&lt;br /&gt;
&lt;br /&gt;
Then exit rviz and the map will be recorded in &amp;lt;code&amp;gt;~/.ros/map.bag&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to record a new map, delete the old one, &amp;lt;code&amp;gt;rm ~/.ros/map.bag&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Running the simulation ===&lt;br /&gt;
&amp;lt;code&amp;gt;roslaunch ~/OpenMower/ROS/src/open_mower_ros/open_mower/launch/sim_mower_logic.launch&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will launch rviz with the map and rqt_reconfigure where you can control various parameters of the simulation.&lt;br /&gt;
&lt;br /&gt;
You will need to press &amp;lt;code&amp;gt;manual_start_mowing&amp;lt;/code&amp;gt; in rqt_reconfigure to start the simulation. You will probably need to zoom out, find your area and then zoom in again on that in rviz.&lt;br /&gt;
&lt;br /&gt;
== Diagnostics / debugging / issues ==&lt;br /&gt;
&lt;br /&gt;
=== Joystick ===&lt;br /&gt;
[[File:Which joystick to use.png|thumb|Which joystick to use]]&lt;br /&gt;
Your joystick needs to be transmitting messages on the topic /joy. To test that it does:&lt;br /&gt;
&lt;br /&gt;
* Run &amp;lt;code&amp;gt;roslaunch ~/OpenMower/ROS/src/open_mower_ros/open_mower/launch/sim_record_area.launch&amp;lt;/code&amp;gt;&lt;br /&gt;
* In a new terminal run &amp;lt;code&amp;gt;rostopic echo /joy&amp;lt;/code&amp;gt;&lt;br /&gt;
You should see messages from the joystick streaming on screen. Test that pressing buttons etc. is reflected in the messages.&lt;br /&gt;
&lt;br /&gt;
If not:&lt;br /&gt;
&lt;br /&gt;
* Check which joysticks your Ubuntu installation knows: &amp;lt;code&amp;gt;ls -l /dev/input/js*&amp;lt;/code&amp;gt;&lt;br /&gt;
* Try to add/adjust which joystick the recorder uses in sim_record_area.launch to use the correct joystick, see illustration here.&lt;br /&gt;
&lt;br /&gt;
===Buttons===&lt;br /&gt;
The control buttons can be edited here:&lt;br /&gt;
*movement activation button&lt;br /&gt;
**File: &amp;lt;code&amp;gt;~/OpenMower/ROS/src/open_mower_ros/open_mower/launch/sim_record_area.launch&amp;lt;/code&amp;gt;&lt;br /&gt;
**Line 17: &amp;lt;code&amp;gt;&amp;lt;param name=&amp;quot;~enable_turbo_button&amp;quot; value=&amp;quot;4&amp;quot;/&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
*area and base recording buttons&lt;br /&gt;
**File: &amp;lt;code&amp;gt;~/OpenMower/ROS/src/open_mower_ros/mower_area_recorder/src/area_recorder.cpp&amp;lt;/code&amp;gt;&lt;br /&gt;
**Lines 61 ff.&lt;br /&gt;
&lt;br /&gt;
==Additional notes / info==&lt;br /&gt;
&lt;br /&gt;
===rviz and OpenMower on different machines ===&lt;br /&gt;
This is all running on one platform - the OpenMower simulation AND the graphical interface, hence the choice of desktop to have a graphical environment. In the real situation, the Rover with the OpenMower software is running on a headless Pi. If you still want to have the ability to see paths and maps (which is possible) in rviz, you need to do that on a separate desktop environment. That is possible. You can use the environment that you set up here, but the Rover and on the Desktop must be on the same network and need a little setup in your &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt; to see each other as being part of the same ROS installation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;On Rover, in &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export ROS_HOSTNAME=192.168.1.126 # replace with your ip for your Rover&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export ROS_MASTER_URI=&amp;lt;nowiki&amp;gt;http://192.168.1.126:11311&amp;lt;/nowiki&amp;gt; # same as above&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;On Desktop, in &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export ROS_HOSTNAME=192.168.1.123 # replace with your ip for your Desktop environment&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export ROS_MASTER_URI=&amp;lt;nowiki&amp;gt;http://192.168.1.126:11311&amp;lt;/nowiki&amp;gt; # eplace with your ip for your Rover&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Note on network visibility and guests on VirtualBox====&lt;br /&gt;
To make your Ubuntu installation running as guest in VirtualBox be able to have an externally accessible ip number and be able to talk to the Rover, you must&lt;br /&gt;
&lt;br /&gt;
#use a cabled network (not Wifi!!) to your computer that acts as host for VirtualBox and your Ubuntu guest OS&lt;br /&gt;
#use a &amp;lt;code&amp;gt;Bridged Adaptor&amp;lt;/code&amp;gt; to the cabled interface for the network setup in VirtualBox for your Ubuntu host.&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_Crosscompiling&amp;diff=488</id>
		<title>OpenMower Crosscompiling</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_Crosscompiling&amp;diff=488"/>
		<updated>2026-06-20T21:16:26Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; Only use this wiki if you are running bare metal custom build! Otherwise go to the official wiki, this is just a backup for personal reference!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 Warning! You are in for a treat! :D - You have been warned. But reward is good, from 3250sec with docker buildx using qemu to 304s on my machine (Clean build)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Instructions =&lt;br /&gt;
These instructions are made for Ubuntu 20.04.6 LTS&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;lt;big&amp;gt;PLEASE DONT RUN ANY SCRIPTS AS SUDO / ROOT! MY SCRIPTS ARE NOT &amp;quot;SAFE&amp;quot;!&amp;lt;/big&amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Instead give yourself write-access to /opt, &amp;lt;code&amp;gt;sudo chmod 777 /opt/&amp;lt;/code&amp;gt; for example.&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
===== INSTALL ROS https://wiki.ros.org/noetic/Installation/Ubuntu =====&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== Update source files ====&lt;br /&gt;
* Add &#039;&#039;&#039;&amp;lt;code&amp;gt;[arch=amd64]&amp;lt;/code&amp;gt;&#039;&#039;&#039; after deb on each line in &amp;lt;code&amp;gt;/etc/apt/sources.list&amp;lt;/code&amp;gt; (This should be changed to your current machines native arch!)&lt;br /&gt;
* Add &#039;&#039;&#039;&amp;lt;code&amp;gt;[arch=amd64,arm64]&amp;lt;/code&amp;gt;&#039;&#039;&#039; after deb in &amp;lt;code&amp;gt;/etc/apt/sources.list.d/ros-latest.list&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Create &amp;lt;code&amp;gt;/etc/apt/sources.list.d/arm-cross-compile-sources.list&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal main restricted&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal-updates main restricted&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal universe&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal-updates universe&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal multiverse&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal-updates multiverse&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal-backports main restricted universe multiverse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Update and install packages ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo dpkg --add-architecture arm64&lt;br /&gt;
&lt;br /&gt;
sudo apt install crossbuild-essential-arm64 parallel&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Clone open_mower_ros repository ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/&lt;br /&gt;
&lt;br /&gt;
git clone https://github.com/ClemensElflein/open_mower_ros&lt;br /&gt;
git submodule update --init --recursive&lt;br /&gt;
cd /opt/open_mower_ros&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Setup sysroot and prepare open_mower_ros ====&lt;br /&gt;
&lt;br /&gt;
We will use CMAKE_SYSROOT /opt/sysroot_arm64 and /opt/sysroot_arm64_download - change these accordingly in the files for your needs. Total size to download is about 200MB and extracted is ~1.1GB. Change the number of download threads as desired.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Create &amp;lt;code&amp;gt;toolchain.cmake&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cmake&amp;quot;&amp;gt;&lt;br /&gt;
set(CMAKE_SYSTEM_NAME Linux)&lt;br /&gt;
set(CMAKE_SYSTEM_VERSION 1)&lt;br /&gt;
set(CMAKE_SYSTEM_PROCESSOR aarch64)&lt;br /&gt;
&lt;br /&gt;
# Specify the cross compiler&lt;br /&gt;
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)&lt;br /&gt;
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)&lt;br /&gt;
&lt;br /&gt;
#set(CMAKE_EXE_LINKER_FLAGS &amp;quot;${CMAKE_EXE_LINKER_FLAGS} -static&amp;quot;)&lt;br /&gt;
#set(CMAKE_SHARED_LINKER_FLAGS &amp;quot;${CMAKE_SHARED_LINKER_FLAGS} -static&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Specify the target system root&lt;br /&gt;
set(CMAKE_SYSROOT /opt/sysroot_arm64)&lt;br /&gt;
&lt;br /&gt;
set(SYSROOT_PATH ${CMAKE_SYSROOT})&lt;br /&gt;
&lt;br /&gt;
unset(CMAKE_SYSTEM_PREFIX_PATH)&lt;br /&gt;
list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${CMAKE_SYSROOT}/opt/ros/noetic)&lt;br /&gt;
&lt;br /&gt;
set(CMAKE_PREFIX_PATH ${CMAKE_SYSROOT}/opt/ros/noetic ${CMAKE_SYSROOT}/opt/ros/noetic/share)&lt;br /&gt;
set(CMAKE_LIBRARY_PATH ${CMAKE_SYSROOT}/opt/ros/noetic/lib)&lt;br /&gt;
set(CMAKE_INCLUDE_PATH ${CMAKE_SYSROOT}/opt/ros/noetic/include)&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})&lt;br /&gt;
&lt;br /&gt;
# Search for programs in the build host directories&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)&lt;br /&gt;
&lt;br /&gt;
# For libraries and headers in the target directories&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)&lt;br /&gt;
&lt;br /&gt;
set(ENV{PKG_CONFIG_PATH} ${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/pkgconfig/)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Create &amp;lt;code&amp;gt;1_setup-sysroot.bash&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
SYSROOT=/opt/sysroot_arm64&lt;br /&gt;
DOWNLOADDIR=/opt/sysroot_downloads&lt;br /&gt;
PARALLELDOWNLOAD=6&lt;br /&gt;
&lt;br /&gt;
#########################&lt;br /&gt;
&lt;br /&gt;
rm -rf $SYSROOT&lt;br /&gt;
mkdir -p $SYSROOT&lt;br /&gt;
mkdir -p $DOWNLOADDIR&lt;br /&gt;
&lt;br /&gt;
# Link might not be needed? Cant remember :D&lt;br /&gt;
ln -s $SYSROOT/usr/lib $SYSROOT/lib&lt;br /&gt;
&lt;br /&gt;
install_package() {&lt;br /&gt;
#  for PKG in &amp;quot;${PACKAGES[@]}&amp;quot;; do&lt;br /&gt;
    PKG=$1&lt;br /&gt;
    URL=$(apt-get download --print-uris $PKG | cut -d\&#039; -f2)&lt;br /&gt;
    if [ -n &amp;quot;$URL&amp;quot; ]; then&lt;br /&gt;
      echo &amp;quot;Downloading $PKG ($URL)&amp;quot;&lt;br /&gt;
      wget -q -nc $URL -P $DOWNLOADDIR &amp;amp;&amp;amp; dpkg -x $DOWNLOADDIR/$(basename $URL) $SYSROOT&lt;br /&gt;
# --show-progress&lt;br /&gt;
#      dpkg -x $DOWNLOADDIR/$(basename $URL) $SYSROOT&lt;br /&gt;
      echo &amp;quot;Done installing $PKG&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      echo &amp;quot;$PKG NOT FOUND!&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
#  done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
export -f install_package&lt;br /&gt;
export DOWNLOADDIR&lt;br /&gt;
export SYSROOT&lt;br /&gt;
&lt;br /&gt;
# read packages.txt into PACKAGES&lt;br /&gt;
while IFS= read -r line; do&lt;br /&gt;
    PACKAGES+=(&amp;quot;$line&amp;quot;)&lt;br /&gt;
done &amp;lt; &amp;quot;packages.txt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
parallel -j $PARALLELDOWNLOAD install_package ::: &amp;quot;${PACKAGES[@]}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Done!&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Download &amp;lt;code&amp;gt;packages.txt&amp;lt;/code&amp;gt; # Focal Ubuntu 20.04.6 LTS! =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://gist.githubusercontent.com/Damme/3161f92ccadf452b4d5f3eee32da097e/raw/8df0172858e95da76091b04f8492705fc0cf0396/packages.txt -O packages.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Create &amp;lt;code&amp;gt;2-fix-links-cmake.bash&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
SYSROOT=/opt/sysroot_arm64&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Linking some missing library links, broken links /hardcoded to /lib/...&amp;quot;&lt;br /&gt;
ln -sfv $SYSROOT/usr/lib/aarch64-linux-gnu/libPocoFoundation.so.62 $SYSROOT/usr/lib/aarch64-linux-gnu/libPocoFoundation.so&lt;br /&gt;
ln -sfv $SYSROOT/usr/lib/aarch64-linux-gnu/blas/libblas.so.3 $SYSROOT/usr/lib/aarch64-linux-gnu/libblas.so.3&lt;br /&gt;
ln -sfv $SYSROOT/usr/lib/aarch64-linux-gnu/lapack/liblapack.so.3 $SYSROOT/usr/lib/aarch64-linux-gnu/liblapack.so.3&lt;br /&gt;
&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/librt.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/librt.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libpthread.so.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libpthread.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libBrokenLocale.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libBrokenLocale.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libanl.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libanl.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libblkid.so.1.1.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libblkid.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libbz2.so.1.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libbz2.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libexpat.so.1.6.11 $SYSROOT/usr/lib/aarch64-linux-gnu/libexpat.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libgpg-error.so.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libgpg-error.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libkeyutils.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libkeyutils.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/liblzma.so.5.2.4 $SYSROOT/usr/lib/aarch64-linux-gnu/liblzma.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libm.so.6 $SYSROOT/usr/lib/aarch64-linux-gnu/libm.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libmount.so.1.1.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libmount.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnsl.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libnsl.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_compat.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_compat.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_dns.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_dns.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_files.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_files.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_hesiod.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_hesiod.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_nis.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_nis.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_nisplus.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_nisplus.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libpcre.so.3 $SYSROOT/usr/lib/aarch64-linux-gnu/libpcre.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libresolv.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libresolv.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libthread_db.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libthread_db.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libutil.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libutil.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libuuid.so.1.3.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libuuid.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libz.so.1.2.11 $SYSROOT/usr/lib/aarch64-linux-gnu/libz.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libdl.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libdl.so&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Fix cmake files with hardcoded paths..&amp;quot;&lt;br /&gt;
find $SYSROOT/opt/ros/noetic/ -name &amp;quot;*.cmake&amp;quot; | xargs -i sh -c &#039;echo {}; sed -i s@/opt/ros/noetic/lib@\${SYSROOT_PATH}/opt/ros/noetic/lib@g {}&#039;&lt;br /&gt;
find $SYSROOT/opt/ros/noetic/ -name &amp;quot;*.cmake&amp;quot; | xargs -i sh -c &#039;echo {}; sed -i s@PREFIX\ /opt/ros/noetic@PREFIX\ \${SYSROOT_PATH}/opt/ros/noetic@g {}&#039;&lt;br /&gt;
find $SYSROOT/opt/ros/noetic/ -name &amp;quot;*.cmake&amp;quot; | xargs -i sh -c &#039;echo {}; sed -i s@\;/usr/@\;\$\{SYSROOT_PATH\}/usr/@g {}&#039;&lt;br /&gt;
find $SYSROOT/opt/ros/noetic/ -name &amp;quot;*.cmake&amp;quot; | xargs -i sh -c &#039;echo {}; sed -i s@\&amp;quot;/usr/@\&amp;quot;\$\{SYSROOT_PATH\}/usr/@g {}&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Create &amp;lt;code&amp;gt;3-patch-openmower-cmake.bash&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
cd src/lib/slic3r_coverage_planner&lt;br /&gt;
&lt;br /&gt;
patch CMakeLists.txt &amp;lt;&amp;lt;&#039;EOF&#039;&lt;br /&gt;
@@ -33,7 +33,9 @@ ExternalProject_Add(&lt;br /&gt;
&lt;br /&gt;
         CMAKE_CACHE_ARGS&lt;br /&gt;
         SOURCE_SUBDIR src&lt;br /&gt;
-        CMAKE_ARGS -DSLIC3R_BUILD_TESTS=OFF&lt;br /&gt;
+        CMAKE_ARGS -DSLIC3R_BUILD_TESTS=OFF -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}&lt;br /&gt;
+               -DCMAKE_EXE_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu&lt;br /&gt;
+               -DCMAKE_SHARED_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu&lt;br /&gt;
         BUILD_COMMAND ${CMAKE_COMMAND} --build &amp;lt;BINARY_DIR&amp;gt; --config Release&lt;br /&gt;
 )&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
cd ../../../&lt;br /&gt;
&lt;br /&gt;
cd src/lib/xbot_driver_gps&lt;br /&gt;
&lt;br /&gt;
patch CMakeLists.txt &amp;lt;&amp;lt;&#039;EOF&#039;&lt;br /&gt;
@@ -32,6 +32,9 @@ ExternalProject_Add(&lt;br /&gt;
         INSTALL_COMMAND cmake -E echo &amp;quot;Skipping install step.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
         CMAKE_CACHE_ARGS&lt;br /&gt;
+        CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}&lt;br /&gt;
+               -DCMAKE_EXE_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu&lt;br /&gt;
+               -DCMAKE_SHARED_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu&lt;br /&gt;
         BUILD_COMMAND ${CMAKE_COMMAND} --build &amp;lt;BINARY_DIR&amp;gt; --config Release&lt;br /&gt;
 )&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
cd ../../../&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Execute scripts ====&lt;br /&gt;
* run the created scripts:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ bash 1-setup_sysroot.bash&lt;br /&gt;
$ bash 2-fix-links-cmake.bash&lt;br /&gt;
$ bash 3-patch-openmower-cmake.bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Compilation  ====&lt;br /&gt;
* build with the following command, change -j1 for number of parallel processes. For some reason catkin_make does not parse toolchain.cmake without forcing it...&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;code&amp;gt;$ catkin_make -DCMAKE_TOOLCHAIN_FILE=/opt/open_mower_ros/toolchain.cmake -j1&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* check the build with&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ find devel/ -type f -executable |xargs file&lt;br /&gt;
devel/_setup_util.py:                                      Python script, ASCII text executable&lt;br /&gt;
devel/env.sh:                                              a /usr/bin/env sh script, ASCII text executable&lt;br /&gt;
devel/lib/mower_utils/planner_test:                        ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_utils/xbot_pose_converter:                 ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xesc_driver/xesc_driver_node:                    ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/libxesc_2040_driver.so:                          ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/ntrip_client/ntrip_ros.py:                       Python script, ASCII text executable&lt;br /&gt;
devel/lib/mower_simulation/mower_simulation:               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/libvesc_driver.so:                               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_comms/mower_comms:                         ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_map/mower_map_service:                     ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/libftc_local_planner.so:                         ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_positioning/xbot_positioning:               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_monitoring/xbot_sensor_example:             ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_monitoring/xbot_monitoring:                 ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_monitoring/heatmap_generator:               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_driver_gps/driver_gps_node:                 ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_logic/mag_calibration:                     ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_logic/monitoring:                          ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_logic/mower_odometry:                      ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_logic/mower_logic:                         ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/libxesc_driver.so:                               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/slic3r_coverage_planner/slic3r_coverage_planner: ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_remote/xbot_remote:                         ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* rsync folder to raspberry pi, note the section below!&lt;br /&gt;
&lt;br /&gt;
==== TODO/Fix me ====&lt;br /&gt;
* Fix &amp;lt;code&amp;gt;[project]/devel/setup.sh&amp;lt;/code&amp;gt; - scripts to use correct paths, maybe have a wrapper for setup.sh that setup some env vars for example CMAKE_PREFIX_PATH to omit sysroot_arm64 path, need to figure out what paths are wrong. Seems &amp;lt;code&amp;gt;_setup_util.py&amp;lt;/code&amp;gt; is the script that setup ros enviroment. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# One temporary fix is to create a link on the RPi:&lt;br /&gt;
$ ln -s / /opt/sysroot_arm64/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* a script to generate packages.txt&lt;br /&gt;
&lt;br /&gt;
Good luck!&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_OLD_Baremetal_installation&amp;diff=487</id>
		<title>OpenMower OLD Baremetal installation</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_OLD_Baremetal_installation&amp;diff=487"/>
		<updated>2026-06-20T21:16:18Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; Only use this wiki if you are running bare metal custom build! Otherwise go to the official wiki, this is just a backup for personal reference!&lt;br /&gt;
&lt;br /&gt;
This page will guide you through the steps to install a basic system image.&lt;br /&gt;
&lt;br /&gt;
On this image you will have the ROS base system, the OpenMower installation, local configuration for your mower and some tools to help you work with the mower.&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
In order to follow this guide, you will need the following:&lt;br /&gt;
&lt;br /&gt;
#A Raspberry Pi 4 (4GB or more recommended, [[System Image#Enable Swap (optional, needed for Pi with &amp;lt;= 2GB RAM)|2GB works with swap, see here]])&lt;br /&gt;
#An SD card&lt;br /&gt;
#A soldered OpenMower mainboard&lt;br /&gt;
&lt;br /&gt;
==Installing the Base System==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;There is also a YouTube video explaining the steps in this section:&#039;&#039;&#039; https://youtu.be/_bImqD-pQSA?t=562&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Flashing Ubuntu to SD Card ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first step is to install the base system. We&#039;re using Ubuntu 20.04 Server for the Raspberry Pi. This is, because this image gives us best support ROS Noetic.&lt;br /&gt;
&lt;br /&gt;
Installing the base image is easy:&lt;br /&gt;
&lt;br /&gt;
#[https://www.raspberrypi.com/software/ Get the Raspberry Pi Imager software]&lt;br /&gt;
#Select the correct operating system:  &#039;&#039;Other-general-purpose OS &amp;gt; Ubuntu &amp;gt; Ubuntu Server 20.04.4 LTS (RPI 3/4/400) 64-bit&#039;&#039;&lt;br /&gt;
#Insert your SD card into your PC and select it in the &#039;&#039;Storage&#039;&#039; part of the software&lt;br /&gt;
#Click &#039;&#039;write&#039;&#039; and wait for the process to finish&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you have successfully flashed your image, remove the SD for your PC &#039;&#039;&#039;and reinsert it again.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Then replace the &amp;lt;code&amp;gt;/boot/config.txt&amp;lt;/code&amp;gt; file with the one provided here: [https://github.com/ClemensElflein/OpenMower/blob/main/configs/RaspberryPiConfig/config.txt]&lt;br /&gt;
&lt;br /&gt;
This will enable all hardware serial ports on the Raspberry Pi.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can theoretically configure networking in this step as well, but I&#039;m not recommending it. This is, because the networking information file gets only copied once and if you have an error it won&#039;t work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;We need an interactive terminal in the next step anyways.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you have done this step, you can eject the SD card and plug it into your Raspberry Pi 4.&lt;br /&gt;
&lt;br /&gt;
=== Opening a Serial Terminal ===&lt;br /&gt;
[[File:SerialRedirect.png|thumb|Serial Terminal: minicom -D /dev/ttyACM0]]&lt;br /&gt;
This step is needed for the following sections. The goal is to have a serial terminal to do basic config (networking etc) easily.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The easiest way of doing so is:&lt;br /&gt;
# Flash the SerialRedirect firmware into your Pico. Get it here: https://github.com/ClemensElflein/OpenMower/tree/main/Firmware/SerialRedirect/bin&lt;br /&gt;
# Provide your mainboard with power&lt;br /&gt;
# Plug your Pico into a computer. A virtual COM port should appear&lt;br /&gt;
# Connect to the COM port (I&#039;m using minicom, see image on the right), then press enter to start the Raspberry Pi.&lt;br /&gt;
#The Pi boots and a serial terminal will appear.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you can login with the default credentials:&lt;br /&gt;
&lt;br /&gt;
username: &amp;lt;code&amp;gt;ubuntu&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
password: &amp;lt;code&amp;gt;ubuntu&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that you will need to change the password immediately.&lt;br /&gt;
&lt;br /&gt;
=== Disable Boot Interrupt ===&lt;br /&gt;
[[File:Image.png|thumb|Commands needed to disable boot interrupt on serial input.]]&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi boot loader will interrupt the boot sequence if data is sent through the main serial port of the Raspberry Pi. Since we&#039;re connecting &amp;quot;nosiy&amp;quot; hardware to the port, this will always interrupt the boot sequence and we need to disable this feature. &lt;br /&gt;
&lt;br /&gt;
In order to do this, reboot the Pi (sudo reboot) and send anything during the count-down in the bootloader (check the YouTube video linked above, if you&#039;re not sure).&lt;br /&gt;
&lt;br /&gt;
Then enter the following commands into the bootloader prompt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
setenv bootdelay -2&lt;br /&gt;
saveenv&lt;br /&gt;
reset&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The Pi should reboot and the count-down should be gone.&lt;br /&gt;
&lt;br /&gt;
=== Some Settings ===&lt;br /&gt;
&lt;br /&gt;
[TODO/WIP]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here are some miscellaneous settings I think are a good idea for an OpenMower install:&lt;br /&gt;
&lt;br /&gt;
* Remove the unnecessary snap system: &amp;lt;code&amp;gt;sudo snap remove --purge lxd &amp;amp;&amp;amp; sudo snap remove --purge core20 &amp;amp;&amp;amp; sudo snap remove --purge snapd &amp;amp;&amp;amp; sudo apt purge --autoremove snapd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Disable unattended upgrades: &amp;lt;code&amp;gt;sudo systemctl stop --force unattended-upgrades &amp;amp;&amp;amp; sudo systemctl disable unattended-upgrades &amp;amp;&amp;amp; sudo systemctl mask unattended-upgrades&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* I like to add the following to &amp;lt;code&amp;gt;cmdline.txt&amp;lt;/code&amp;gt; in order to fsck on boot:  &amp;lt;code&amp;gt;fsck.mode=force fsck.repair=yes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* I prefer to use a static IP (If you use the [[System_Image#Installing_a_WiFi_Hot-Spot_(optional,_but_recommended)|recommend WiFi Hot-Spot]] use &amp;lt;code&amp;gt;sudo nmtui&amp;lt;/code&amp;gt; to configure a static IP)&lt;br /&gt;
&lt;br /&gt;
* If you like to have a terminal wifi scanner/signal monitor just install &amp;lt;code&amp;gt;sudo apt install wavemon&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you like you can change the timezone: &amp;lt;code&amp;gt;sudo timedatectl set-timezone Region/Location&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;sudo dpkg-reconfigure tzdata&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you ever like to plug a keyboard into the Pi don&#039;t forget to change the keymap: &amp;lt;code&amp;gt;sudo dpkg-reconfigure keyboard-configuration&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Enable Swap (optional, needed for Pi with &amp;lt;= 2GB RAM)===&lt;br /&gt;
Compiling the OpenMower software will need more than 2GB of RAM. In order to still do this on a Pi with &amp;lt;= 2GB of RAM, we will add a 2GB swap file to the system by entering the following commands:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Create a new 2GB swap file&lt;br /&gt;
sudo fallocate -l 2G /swapfile&lt;br /&gt;
# Change permissions, so that only root can read and write&lt;br /&gt;
sudo chmod 600 /swapfile&lt;br /&gt;
# Create swap space in the file&lt;br /&gt;
sudo mkswap /swapfile&lt;br /&gt;
# Add it to the fstab&lt;br /&gt;
echo &#039;/swapfile swap swap defaults 0 0&#039; | sudo tee -a /etc/fstab /swapfile swap swap defaults 0 0&lt;br /&gt;
# Reboot to activate&lt;br /&gt;
sudo reboot&lt;br /&gt;
&lt;br /&gt;
# Check if it&#039;s activated&lt;br /&gt;
sudo swapon --show&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Installing a WiFi Hot-Spot (optional, but recommended)===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Since we will be configuring the WiFi interface, make sure that you have connected Ethernet to your Raspberry Pi for this step.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As soon as you have closed your mower&#039;s enclosure, you won&#039;t have physical access to your Raspberry Pi anymore. If for some reason it&#039;s unable to connect to your WiFi (e.g. you have changed your password), you would need to open the case to get access to the SD card or Ethernet port on the Pi to regain access.&lt;br /&gt;
&lt;br /&gt;
To prevent this, we&#039;re going to install a hot-spot software which helps you to connect to WiFi by opening a hot-spot each time the Pi cannot connect to a known WiFi connection.&lt;br /&gt;
&lt;br /&gt;
Now is the best time to do this, because we have a serial terminal anyways and can mess with the network interfaces without shutting us out of the system!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just use the following commands for this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# We need to disable systemd-resolveds caching DNS stub resolver&lt;br /&gt;
# if you want to know why check: https://github.com/pi-hole/docker-pi-hole/#installing-on-ubuntu&lt;br /&gt;
sudo sed -r -i.orig &#039;s/#?DNSStubListener=yes/DNSStubListener=no/g&#039; /etc/systemd/resolved.conf&lt;br /&gt;
sudo systemctl restart systemd-resolved.service&lt;br /&gt;
&lt;br /&gt;
ping ntp.org&lt;br /&gt;
# This will throw an dns error:&lt;br /&gt;
#   ping: ntp.org: Temporary failure in name resolution&lt;br /&gt;
sudo sh -c &#039;rm /etc/resolv.conf &amp;amp;&amp;amp; ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf&#039;&lt;br /&gt;
sudo systemctl restart systemd-resolved.service&lt;br /&gt;
nslookup ntp.org&lt;br /&gt;
# DNS should work now&lt;br /&gt;
&lt;br /&gt;
# Install comitup using the latest version from the projects repo&lt;br /&gt;
wget https://davesteele.github.io/comitup/latest/davesteele-comitup-apt-source_latest.deb&lt;br /&gt;
sudo dpkg -i --force-all davesteele-comitup-apt-source_latest.deb&lt;br /&gt;
rm davesteele-comitup-apt-source_latest.deb&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install comitup --no-install-recommends&lt;br /&gt;
&lt;br /&gt;
sudo systemctl stop comitup&lt;br /&gt;
# Now use network-manager to:&lt;br /&gt;
# - add you wifi network&lt;br /&gt;
# optional:&lt;br /&gt;
# - change your hostname&lt;br /&gt;
# - add a dhcp ethernet connection without any device assigned&lt;br /&gt;
# (if even the hotspot malfunctions you can plug in a usb ethernet adapter)&lt;br /&gt;
sudo nmtui&lt;br /&gt;
&lt;br /&gt;
# Edit comitup.conf to change the wifi name and password (I use OpenMower-&amp;lt;nn&amp;gt;)&lt;br /&gt;
sudo nano /etc/comitup.conf&lt;br /&gt;
sudo systemctl restart comitup&lt;br /&gt;
# reboot - it should work now&lt;br /&gt;
sudo reboot&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Disable Serial Console===&lt;br /&gt;
Now that we have setup the network and can access the Pi even if our WiFi is not in range, we need to disable that serial console so that we can use the serial port for hardware.&lt;br /&gt;
&lt;br /&gt;
To do this, enter: &amp;lt;code&amp;gt;sudo nano /boot/firmware/cmdline.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and remove the &amp;lt;code&amp;gt;console=serial0,115200&amp;lt;/code&amp;gt; part of the line.&lt;br /&gt;
&lt;br /&gt;
Save the file and reboot. You should still see the bootloader output, but no serial output after that.&lt;br /&gt;
&lt;br /&gt;
==Installing Tools==&lt;br /&gt;
If you&#039;re happy with your basic Ubuntu setup, it&#039;s time to install some tools required for the OpenMower&lt;br /&gt;
&lt;br /&gt;
=== General Dependencies ===&lt;br /&gt;
Just install them with apt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install --no-install-recommends build-essential git&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===STR2STR (optional, recommended; only needed if you&#039;re using NTRIP, so probably most of you)===&lt;br /&gt;
We need a newer version than the one available in apt, so install it from source:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install gfortran&lt;br /&gt;
git clone https://github.com/rtklibexplorer/RTKLIB&lt;br /&gt;
cd RTKLIB&lt;br /&gt;
git checkout tags/b34c&lt;br /&gt;
cd app/consapp/&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
sudo make install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;You should now be able to run str2str from anywhere.&lt;br /&gt;
&lt;br /&gt;
=== OpenOCD (optional, recommended; only needed if you want to flash Pico from Raspberry Pi)===&lt;br /&gt;
We need to get the OpenOCD version from the Raspberry Pi foundation, because the &amp;quot;original&amp;quot; one doesn&#039;t have the Pico support built in yet.&lt;br /&gt;
&lt;br /&gt;
Install it from source:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install automake autoconf build-essential libtool libftdi-dev libusb-1.0-0-dev texinfo pkg-config rpi.gpio-common&lt;br /&gt;
git clone https://github.com/raspberrypi/openocd.git --recursive --branch rp2040 --depth=1&lt;br /&gt;
cd openocd&lt;br /&gt;
./bootstrap&lt;br /&gt;
./configure --enable-ftdi --enable-sysfsgpio --enable-bcm2835gpio&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
sudo make install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;You can test if it was a success by running:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
ubuntu@ubuntu:~$ openocd -v&lt;br /&gt;
Open On-Chip Debugger 0.11.0-g610f137-dirty (2022-06-07-00:39)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
	http://openocd.org/doc/doxygen/bugs.html&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Installing ROS and OpenMower==&lt;br /&gt;
We&#039;re using ROS Noetic for the OpenMower project. In this step we will install it, get the OpenMower sources, build the sources and create a basic configuration file for your mower.&lt;br /&gt;
&lt;br /&gt;
===Install ROS Noetic===&lt;br /&gt;
Since we&#039;re running Ubuntu 20.04 installing ROS is as easy as running the following commands:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Get the ROS apt repository&lt;br /&gt;
sudo sh -c &#039;echo &amp;quot;deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main&amp;quot; &amp;gt; /etc/apt/sources.list.d/ros-latest.list&#039;&lt;br /&gt;
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -&lt;br /&gt;
&lt;br /&gt;
# Install the ROS base system&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install --no-install-recommends ros-noetic-ros-base&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;We only need to register the ROS installation in your &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt; file. This will enable you to call ROS specific commands from your terminal:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# If you&#039;re using bash (default on Ubuntu):&lt;br /&gt;
echo &amp;quot;source /opt/ros/noetic/setup.bash&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
source ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
# Else if you&#039;re using zsh&lt;br /&gt;
echo &amp;quot;source /opt/ros/noetic/setup.zsh&amp;quot; &amp;gt;&amp;gt; ~/.zshrc&lt;br /&gt;
source ~/.zshrc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Installing OpenMower Software===&lt;br /&gt;
Now we&#039;re finally able to install the OpenMower software. First, we&#039;re checking out the current version of the sources, then we&#039;re getting the dependencies and finally we&#039;re building the sources:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Clone the GitHub Repository:&lt;br /&gt;
git clone --recursive https://github.com/ClemensElflein/open_mower_ros.git&lt;br /&gt;
&lt;br /&gt;
# Get rosdep, only needed once&lt;br /&gt;
sudo apt install --no-install-recommends python3-rosdep&lt;br /&gt;
sudo rosdep init&lt;br /&gt;
rosdep update&lt;br /&gt;
&lt;br /&gt;
# Get the dependencies using rosdep&lt;br /&gt;
cd ~/open_mower_ros/&lt;br /&gt;
sudo apt-get install --no-install-recommends $(rosdep install --from-paths src --ignore-src --simulate | sed --expression &#039;1d&#039; | sort | tr -d &#039;\n&#039; | sed -e &#039;s/  sudo -H apt-get install//g&#039;)&lt;br /&gt;
&lt;br /&gt;
# Finally, build the sources. This will take a while! &lt;br /&gt;
catkin_make -j1 # on 2GB Pi with SWAP - this takes at least 30min&lt;br /&gt;
# OR&lt;br /&gt;
catkin_make -j2 # on 4/8GB Pi - this takes at least 20min&lt;br /&gt;
&lt;br /&gt;
# Copy the default configuration file to your home directory&lt;br /&gt;
cp ~/open_mower_ros/src/open_mower/config/mower_config.sh.example ~/mower_config.sh&lt;br /&gt;
&lt;br /&gt;
# The next step is to also source the OpenMower ROS install&lt;br /&gt;
# If you&#039;re using bash (default on Ubuntu):&lt;br /&gt;
echo &amp;quot;source ~/open_mower_ros/devel/setup.sh&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
echo &amp;quot;source ~/mower_config.sh&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
source ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
# Else if you&#039;re using zsh&lt;br /&gt;
echo &amp;quot;source ~/open_mower_ros/devel/setup.zsh&amp;quot; &amp;gt;&amp;gt; ~/.zshrc&lt;br /&gt;
echo &amp;quot;source ~/mower_config.sh&amp;quot; &amp;gt;&amp;gt; ~/.zshrc&lt;br /&gt;
source ~/.zshrc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;At this point the OpenMower software is successfully installed! You will need to configure the OpenMower software and then you&#039;re finally ready to mow.&lt;br /&gt;
&lt;br /&gt;
== Some Additional Issues==&lt;br /&gt;
&lt;br /&gt;
===I&#039;m using an external WiFi dongle for better coverage, but sometimes it doesn&#039;t work===&lt;br /&gt;
It seems that the Ubuntu sometimes puts external WiFi dongles to sleep. To prevent this, we create a service which disables powersave:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Enter this to create the service&lt;br /&gt;
sudo systemctl --full --force edit wifi_powersave@.service&lt;br /&gt;
&lt;br /&gt;
# Paste the following:&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Set WiFi power save %i&lt;br /&gt;
After=sys-subsystem-net-devices-wlan1.device&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=oneshot&lt;br /&gt;
RemainAfterExit=yes&lt;br /&gt;
ExecStart=/sbin/iw dev wlan1 set power_save %i&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=sys-subsystem-net-devices-wlan1.device&lt;br /&gt;
&lt;br /&gt;
# Save and exit, then activate using:&lt;br /&gt;
sudo systemctl disable wifi_powersave@on.service&lt;br /&gt;
sudo systemctl enable wifi_powersave@off.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower&amp;diff=486</id>
		<title>OpenMower</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower&amp;diff=486"/>
		<updated>2026-06-20T21:16:13Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; Only use this wiki if you are running bare metal custom build! Otherwise go to the official wiki, this is just a backup for personal reference!&lt;br /&gt;
* [[OpenMower OLD Baremetal installation]]&lt;br /&gt;
* [[OpenMower Crosscompiling]]&lt;br /&gt;
* [[OpenMower Simulation]]&lt;br /&gt;
* [[OpenMower Edit map]]&lt;br /&gt;
* [[OpenMower Unicore GPS]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Subscribers:&lt;br /&gt;
    1. cmd_vel_sub: Subscribes to the cmd_vel topic.&lt;br /&gt;
        ◦ Message Type: geometry_msgs::Twist&lt;br /&gt;
        ◦ Description: Contains the desired linear and angular velocities for the robot.&lt;br /&gt;
        ◦ Contents:&lt;br /&gt;
            ▪ linear.x: Linear velocity in the x-axis direction (m/s).&lt;br /&gt;
            ▪ linear.y: Linear velocity in the y-axis direction (m/s).&lt;br /&gt;
            ▪ linear.z: Linear velocity in the z-axis direction (m/s).&lt;br /&gt;
            ▪ angular.x: Angular velocity around the x-axis (rad/s).&lt;br /&gt;
            ▪ angular.y: Angular velocity around the y-axis (rad/s).&lt;br /&gt;
            ▪ angular.z: Angular velocity around the z-axis (rad/s).&lt;br /&gt;
    2. high_level_status_sub: Subscribes to the /mower_logic/current_state topic.&lt;br /&gt;
        ◦ Message Type: mower_msgs::HighLevelStatus&lt;br /&gt;
        ◦ Description: Receives the high-level state of the mower from the mower logic node. This state includes information about the current operating mode, substate, GPS quality, battery status, charging status, and emergency flag.&lt;br /&gt;
        ◦ Fields:&lt;br /&gt;
            ▪ state: An integer representing the current high-level state of the mower (e.g., idle, autonomous, recording, etc.).&lt;br /&gt;
            ▪ state_name: A string representing the name of the current high-level state (e.g., &amp;quot;IDLE&amp;quot;, &amp;quot;AUTONOMOUS&amp;quot;, &amp;quot;RECORDING&amp;quot;).&lt;br /&gt;
            ▪ sub_state_name: A string representing the name of the current substate (e.g., &amp;quot;SUBSTATE_1&amp;quot;, &amp;quot;SUBSTATE_2&amp;quot;, &amp;quot;SUBSTATE_3&amp;quot;, &amp;quot;SUBSTATE_4&amp;quot;).&lt;br /&gt;
            ▪ gps_quality_percent: A float32 value representing the GPS quality as a percentage, where 0% indicates no GPS signal and 100% indicates a perfect GPS signal.&lt;br /&gt;
            ▪ battery_percent: A float32 value representing the battery charge level as a percentage, where 0% indicates an empty battery and 100% indicates a fully charged battery.&lt;br /&gt;
            ▪ is_charging: A boolean value indicating whether the mower is currently charging or not.&lt;br /&gt;
            ▪ emergency: A boolean value indicating if there is an active emergency situation, such as a collision, detected by the mower.&lt;br /&gt;
        ◦ Callback Function: highLevelStatusReceived&lt;br /&gt;
            ▪ Description: Handles the received high-level state of the mower, updating the internal state representation for the mower communication node.&lt;br /&gt;
Publishers:&lt;br /&gt;
    1. status_pub: Publishes to the /mower/status topic.&lt;br /&gt;
        ◦ Message Type: mower_msgs::Status&lt;br /&gt;
        ◦ Description: Publishes the current status of the mower, including information about the mower&#039;s low-level systems, power status, ultrasonic range measurements, emergency status, battery, and ESC statuses.&lt;br /&gt;
        ◦ Fields:&lt;br /&gt;
            ▪ stamp: A time object representing the timestamp of the message.&lt;br /&gt;
            ▪ mower_status: An integer representing the mower&#039;s status, such as initializing or OK.&lt;br /&gt;
            ▪ raspberry_pi_power: A boolean value indicating if the Raspberry Pi has power.&lt;br /&gt;
            ▪ gps_power: A boolean value indicating if the GPS module has power.&lt;br /&gt;
            ▪ esc_power: A boolean value indicating if the Electronic Speed Controllers (ESCs) have power.&lt;br /&gt;
            ▪ rain_detected: A boolean value indicating if rain is detected.&lt;br /&gt;
            ▪ sound_module_available: A boolean value indicating if the sound module is available.&lt;br /&gt;
            ▪ sound_module_busy: A boolean value indicating if the sound module is busy.&lt;br /&gt;
            ▪ ui_board_available: A boolean value indicating if the UI board is available.&lt;br /&gt;
            ▪ ultrasonic_ranges: An array of 5 float32 values representing the ultrasonic range measurements.&lt;br /&gt;
            ▪ emergency: A boolean value indicating if there is an active emergency situation, such as a collision, detected by the mower.&lt;br /&gt;
            ▪ v_charge: A float32 value representing the charge voltage.&lt;br /&gt;
            ▪ v_battery: A float32 value representing the battery voltage.&lt;br /&gt;
            ▪ charge_current: A float32 value representing the charge current.&lt;br /&gt;
            ▪ left_esc_status: An ESCStatus object containing information about the status of the left ESC.&lt;br /&gt;
            ▪ right_esc_status: An ESCStatus object containing information about the status of the right ESC.&lt;br /&gt;
            ▪ mow_esc_status: An ESCStatus object containing information about the status of the mow ESC.&lt;br /&gt;
    2. wheel_tick_pub: Publishes the mower/wheel_ticks topic.&lt;br /&gt;
        ◦ Message Type: xbot_msgs::WheelTick&lt;br /&gt;
        ◦ Description: Publishes the wheel tick information for the left and right wheels of the mower, which is used to calculate odometry.&lt;br /&gt;
        ◦ Fields:&lt;br /&gt;
            ▪ header: Standard ROS message header containing a timestamp and frame_id.&lt;br /&gt;
            ▪ left_ticks: The number of ticks for the left wheel since the last message.&lt;br /&gt;
            ▪ right_ticks: The number of ticks for the right wheel since the last message.&lt;br /&gt;
            ▪ interval: The time interval in seconds between the current and previous wheel tick message.&lt;br /&gt;
    3. sensor_imu_pub: Publishes to the imu/data_raw topic.&lt;br /&gt;
        ◦ Message Type: sensor_msgs::Imu&lt;br /&gt;
        ◦ Description: Provides raw IMU data, including linear acceleration and angular velocity.&lt;br /&gt;
        ◦ Contents:&lt;br /&gt;
            ▪ header: Message header, containing timestamp and frame ID.&lt;br /&gt;
            ▪ orientation: Orientation as a quaternion (x, y, z, w).&lt;br /&gt;
            ▪ orientation_covariance: Orientation covariance matrix (3x3).&lt;br /&gt;
            ▪ angular_velocity: Angular velocity vector (x, y, z) in rad/s.&lt;br /&gt;
            ▪ angular_velocity_covariance: Angular velocity covariance matrix (3x3).&lt;br /&gt;
            ▪ linear_acceleration: Linear acceleration vector (x, y, z) in m/s^2.&lt;br /&gt;
            ▪ linear_acceleration_covariance: Linear acceleration covariance matrix (3x3).&lt;br /&gt;
    4. sensor_mag_pub: Publishes to the imu/mag topic.&lt;br /&gt;
        ◦ Message Type: sensor_msgs::MagneticField&lt;br /&gt;
        ◦ Description: Provides magnetic field data from the IMU.&lt;br /&gt;
        ◦ Contents:&lt;br /&gt;
            ▪ header: Message header, containing timestamp and frame ID.&lt;br /&gt;
            ▪ magnetic_field: Magnetic field vector (x, y, z) in Tesla.&lt;br /&gt;
            ▪ magnetic_field_covariance: Magnetic field covariance matrix (3x3).&lt;br /&gt;
Services:&lt;br /&gt;
    1. mow_service: Advertises the mower_service/mow_enabled service.&lt;br /&gt;
        ◦ Service Type: std_srvs::SetBool&lt;br /&gt;
        ◦ Description: Allows enabling or disabling the mower&#039;s mowing functionality.&lt;br /&gt;
        ◦ Request Fields:&lt;br /&gt;
            ▪ data: A boolean value representing the desired state of the mower&#039;s mowing functionality. True for enabling and False for disabling.&lt;br /&gt;
        ◦ Response Fields:&lt;br /&gt;
            ▪ success: A boolean value indicating if the requested operation was successful.&lt;br /&gt;
            ▪ message: A string providing additional information about the outcome of the operation.&lt;br /&gt;
    2. emergency_service: Advertises the mower_service/emergency service.&lt;br /&gt;
        ◦ Service Type: std_srvs::Trigger&lt;br /&gt;
        ◦ Description: Triggers an emergency stop for the mower.&lt;br /&gt;
        ◦ Request Fields: No fields required.&lt;br /&gt;
        ◦ Response Fields:&lt;br /&gt;
            ▪ success: A boolean value indicating if the emergency stop was successfully triggered.&lt;br /&gt;
            ▪ message: A string providing additional information about the outcome of the operation.&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_Simulation&amp;diff=485</id>
		<title>OpenMower Simulation</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_Simulation&amp;diff=485"/>
		<updated>2026-06-20T21:15:49Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; Only use these is you are running bare metal custom build! Otherwise go to the official wiki, this is just a backup for personal reference!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
You can test the OpenMower software stack yourself by running a simulation where you can record a map and then have it mowed in a simulation on-screen. &lt;br /&gt;
&lt;br /&gt;
It&#039;s a bit rough around the edges, but it&#039;s a good way to see the software in action without hardware.&lt;br /&gt;
&lt;br /&gt;
This mini-HOWTO is meant to save you a bit of detective work and get you started, not to be a comprehensive guide to the simulation.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
You need the OpenMower software &#039;&#039;&#039;on a platform that has ROS and a graphical interface&#039;&#039;&#039; for rviz to be able to run and show the map. Ubuntu 20 on a desktop is a good choice, possibly on VM, VirtualBox is an excellent choice, if you do not already have a running Ubuntu 20 desktop environment.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Install ROS on Ubuntu&#039;&#039;&#039;: http://wiki.ros.org/noetic/Installation/Ubuntu - use the full install&lt;br /&gt;
** Note: make sure that you have the ROS environment set up in your terminal by &amp;lt;code&amp;gt;echo &amp;quot;source /opt/ros/noetic/setup.bash&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&amp;lt;/code&amp;gt;  and log out and back in.&lt;br /&gt;
* &#039;&#039;&#039;Install the OpenMower software:&#039;&#039;&#039; Use the instructions here: [[Setting up ROS on a Raspberry Pi (intended to be the Rover -- OpenMower)]]&lt;br /&gt;
** Make sure that you have had &amp;lt;code&amp;gt;catkin_make&amp;lt;/code&amp;gt; succeed (may take a few tries, often 4 or more)&lt;br /&gt;
&lt;br /&gt;
You need to have a game controller for controlling the simulated bot.&lt;br /&gt;
&lt;br /&gt;
== Making sure the OpenMower environment is sourced ==&lt;br /&gt;
&#039;&#039;Whenever you are doing anything in a terminal with OpenMower&#039;&#039;, you need to make sure that ROS knows your OpenMower workspace.&lt;br /&gt;
&lt;br /&gt;
In every terminal that you use: &amp;lt;code&amp;gt;source ~/OpenMower/ROS/devel/setup.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Running the simulation ==&lt;br /&gt;
&lt;br /&gt;
=== Recording a map ===&lt;br /&gt;
[[File:VirtualBox enable USB.png|thumb|Enable USB ports on VirtualBox]]&lt;br /&gt;
Attach your joystick to a USB port. If you are on a VirtualBox, make sure that the USB port of your joystick / gamepad is mapped into your Ubuntu environment (see illustration).&lt;br /&gt;
&lt;br /&gt;
Open a terminal and execute&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;roslaunch ~/OpenMower/ROS/src/open_mower_ros/open_mower/launch/sim_mower_logic.launch&amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:Simulation running.png|thumb|OpenMower simulation running]]&lt;br /&gt;
This will launch rviz where you can see the Rover and the map.&lt;br /&gt;
&lt;br /&gt;
Use your joystick to record a map and a base. On my gamepad, the buttons are&lt;br /&gt;
&lt;br /&gt;
* 1 - enable movement&lt;br /&gt;
* 2 - start path recording&lt;br /&gt;
* 4 + ↓ - end path recording&lt;br /&gt;
* 3 - register base&lt;br /&gt;
&lt;br /&gt;
Then exit rviz and the map will be recorded in &amp;lt;code&amp;gt;~/.ros/map.bag&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to record a new map, delete the old one, &amp;lt;code&amp;gt;rm ~/.ros/map.bag&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Running the simulation ===&lt;br /&gt;
&amp;lt;code&amp;gt;roslaunch ~/OpenMower/ROS/src/open_mower_ros/open_mower/launch/sim_mower_logic.launch&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will launch rviz with the map and rqt_reconfigure where you can control various parameters of the simulation.&lt;br /&gt;
&lt;br /&gt;
You will need to press &amp;lt;code&amp;gt;manual_start_mowing&amp;lt;/code&amp;gt; in rqt_reconfigure to start the simulation. You will probably need to zoom out, find your area and then zoom in again on that in rviz.&lt;br /&gt;
&lt;br /&gt;
== Diagnostics / debugging / issues ==&lt;br /&gt;
&lt;br /&gt;
=== Joystick ===&lt;br /&gt;
[[File:Which joystick to use.png|thumb|Which joystick to use]]&lt;br /&gt;
Your joystick needs to be transmitting messages on the topic /joy. To test that it does:&lt;br /&gt;
&lt;br /&gt;
* Run &amp;lt;code&amp;gt;roslaunch ~/OpenMower/ROS/src/open_mower_ros/open_mower/launch/sim_record_area.launch&amp;lt;/code&amp;gt;&lt;br /&gt;
* In a new terminal run &amp;lt;code&amp;gt;rostopic echo /joy&amp;lt;/code&amp;gt;&lt;br /&gt;
You should see messages from the joystick streaming on screen. Test that pressing buttons etc. is reflected in the messages.&lt;br /&gt;
&lt;br /&gt;
If not:&lt;br /&gt;
&lt;br /&gt;
* Check which joysticks your Ubuntu installation knows: &amp;lt;code&amp;gt;ls -l /dev/input/js*&amp;lt;/code&amp;gt;&lt;br /&gt;
* Try to add/adjust which joystick the recorder uses in sim_record_area.launch to use the correct joystick, see illustration here.&lt;br /&gt;
&lt;br /&gt;
===Buttons===&lt;br /&gt;
The control buttons can be edited here:&lt;br /&gt;
*movement activation button&lt;br /&gt;
**File: &amp;lt;code&amp;gt;~/OpenMower/ROS/src/open_mower_ros/open_mower/launch/sim_record_area.launch&amp;lt;/code&amp;gt;&lt;br /&gt;
**Line 17: &amp;lt;code&amp;gt;&amp;lt;param name=&amp;quot;~enable_turbo_button&amp;quot; value=&amp;quot;4&amp;quot;/&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
*area and base recording buttons&lt;br /&gt;
**File: &amp;lt;code&amp;gt;~/OpenMower/ROS/src/open_mower_ros/mower_area_recorder/src/area_recorder.cpp&amp;lt;/code&amp;gt;&lt;br /&gt;
**Lines 61 ff.&lt;br /&gt;
&lt;br /&gt;
==Additional notes / info==&lt;br /&gt;
&lt;br /&gt;
===rviz and OpenMower on different machines ===&lt;br /&gt;
This is all running on one platform - the OpenMower simulation AND the graphical interface, hence the choice of desktop to have a graphical environment. In the real situation, the Rover with the OpenMower software is running on a headless Pi. If you still want to have the ability to see paths and maps (which is possible) in rviz, you need to do that on a separate desktop environment. That is possible. You can use the environment that you set up here, but the Rover and on the Desktop must be on the same network and need a little setup in your &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt; to see each other as being part of the same ROS installation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;On Rover, in &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export ROS_HOSTNAME=192.168.1.126 # replace with your ip for your Rover&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export ROS_MASTER_URI=&amp;lt;nowiki&amp;gt;http://192.168.1.126:11311&amp;lt;/nowiki&amp;gt; # same as above&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;On Desktop, in &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export ROS_HOSTNAME=192.168.1.123 # replace with your ip for your Desktop environment&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export ROS_MASTER_URI=&amp;lt;nowiki&amp;gt;http://192.168.1.126:11311&amp;lt;/nowiki&amp;gt; # eplace with your ip for your Rover&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Note on network visibility and guests on VirtualBox====&lt;br /&gt;
To make your Ubuntu installation running as guest in VirtualBox be able to have an externally accessible ip number and be able to talk to the Rover, you must&lt;br /&gt;
&lt;br /&gt;
#use a cabled network (not Wifi!!) to your computer that acts as host for VirtualBox and your Ubuntu guest OS&lt;br /&gt;
#use a &amp;lt;code&amp;gt;Bridged Adaptor&amp;lt;/code&amp;gt; to the cabled interface for the network setup in VirtualBox for your Ubuntu host.&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_Crosscompiling&amp;diff=484</id>
		<title>OpenMower Crosscompiling</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_Crosscompiling&amp;diff=484"/>
		<updated>2026-06-20T21:15:39Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; Only use these is you are running bare metal custom build! Otherwise go to the official wiki, this is just a backup for personal reference!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 Warning! You are in for a treat! :D - You have been warned. But reward is good, from 3250sec with docker buildx using qemu to 304s on my machine (Clean build)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Instructions =&lt;br /&gt;
These instructions are made for Ubuntu 20.04.6 LTS&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;lt;big&amp;gt;PLEASE DONT RUN ANY SCRIPTS AS SUDO / ROOT! MY SCRIPTS ARE NOT &amp;quot;SAFE&amp;quot;!&amp;lt;/big&amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Instead give yourself write-access to /opt, &amp;lt;code&amp;gt;sudo chmod 777 /opt/&amp;lt;/code&amp;gt; for example.&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
===== INSTALL ROS https://wiki.ros.org/noetic/Installation/Ubuntu =====&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== Update source files ====&lt;br /&gt;
* Add &#039;&#039;&#039;&amp;lt;code&amp;gt;[arch=amd64]&amp;lt;/code&amp;gt;&#039;&#039;&#039; after deb on each line in &amp;lt;code&amp;gt;/etc/apt/sources.list&amp;lt;/code&amp;gt; (This should be changed to your current machines native arch!)&lt;br /&gt;
* Add &#039;&#039;&#039;&amp;lt;code&amp;gt;[arch=amd64,arm64]&amp;lt;/code&amp;gt;&#039;&#039;&#039; after deb in &amp;lt;code&amp;gt;/etc/apt/sources.list.d/ros-latest.list&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Create &amp;lt;code&amp;gt;/etc/apt/sources.list.d/arm-cross-compile-sources.list&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal main restricted&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal-updates main restricted&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal universe&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal-updates universe&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal multiverse&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal-updates multiverse&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal-backports main restricted universe multiverse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Update and install packages ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo dpkg --add-architecture arm64&lt;br /&gt;
&lt;br /&gt;
sudo apt install crossbuild-essential-arm64 parallel&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Clone open_mower_ros repository ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/&lt;br /&gt;
&lt;br /&gt;
git clone https://github.com/ClemensElflein/open_mower_ros&lt;br /&gt;
git submodule update --init --recursive&lt;br /&gt;
cd /opt/open_mower_ros&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Setup sysroot and prepare open_mower_ros ====&lt;br /&gt;
&lt;br /&gt;
We will use CMAKE_SYSROOT /opt/sysroot_arm64 and /opt/sysroot_arm64_download - change these accordingly in the files for your needs. Total size to download is about 200MB and extracted is ~1.1GB. Change the number of download threads as desired.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Create &amp;lt;code&amp;gt;toolchain.cmake&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cmake&amp;quot;&amp;gt;&lt;br /&gt;
set(CMAKE_SYSTEM_NAME Linux)&lt;br /&gt;
set(CMAKE_SYSTEM_VERSION 1)&lt;br /&gt;
set(CMAKE_SYSTEM_PROCESSOR aarch64)&lt;br /&gt;
&lt;br /&gt;
# Specify the cross compiler&lt;br /&gt;
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)&lt;br /&gt;
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)&lt;br /&gt;
&lt;br /&gt;
#set(CMAKE_EXE_LINKER_FLAGS &amp;quot;${CMAKE_EXE_LINKER_FLAGS} -static&amp;quot;)&lt;br /&gt;
#set(CMAKE_SHARED_LINKER_FLAGS &amp;quot;${CMAKE_SHARED_LINKER_FLAGS} -static&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Specify the target system root&lt;br /&gt;
set(CMAKE_SYSROOT /opt/sysroot_arm64)&lt;br /&gt;
&lt;br /&gt;
set(SYSROOT_PATH ${CMAKE_SYSROOT})&lt;br /&gt;
&lt;br /&gt;
unset(CMAKE_SYSTEM_PREFIX_PATH)&lt;br /&gt;
list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${CMAKE_SYSROOT}/opt/ros/noetic)&lt;br /&gt;
&lt;br /&gt;
set(CMAKE_PREFIX_PATH ${CMAKE_SYSROOT}/opt/ros/noetic ${CMAKE_SYSROOT}/opt/ros/noetic/share)&lt;br /&gt;
set(CMAKE_LIBRARY_PATH ${CMAKE_SYSROOT}/opt/ros/noetic/lib)&lt;br /&gt;
set(CMAKE_INCLUDE_PATH ${CMAKE_SYSROOT}/opt/ros/noetic/include)&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})&lt;br /&gt;
&lt;br /&gt;
# Search for programs in the build host directories&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)&lt;br /&gt;
&lt;br /&gt;
# For libraries and headers in the target directories&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)&lt;br /&gt;
&lt;br /&gt;
set(ENV{PKG_CONFIG_PATH} ${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/pkgconfig/)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Create &amp;lt;code&amp;gt;1_setup-sysroot.bash&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
SYSROOT=/opt/sysroot_arm64&lt;br /&gt;
DOWNLOADDIR=/opt/sysroot_downloads&lt;br /&gt;
PARALLELDOWNLOAD=6&lt;br /&gt;
&lt;br /&gt;
#########################&lt;br /&gt;
&lt;br /&gt;
rm -rf $SYSROOT&lt;br /&gt;
mkdir -p $SYSROOT&lt;br /&gt;
mkdir -p $DOWNLOADDIR&lt;br /&gt;
&lt;br /&gt;
# Link might not be needed? Cant remember :D&lt;br /&gt;
ln -s $SYSROOT/usr/lib $SYSROOT/lib&lt;br /&gt;
&lt;br /&gt;
install_package() {&lt;br /&gt;
#  for PKG in &amp;quot;${PACKAGES[@]}&amp;quot;; do&lt;br /&gt;
    PKG=$1&lt;br /&gt;
    URL=$(apt-get download --print-uris $PKG | cut -d\&#039; -f2)&lt;br /&gt;
    if [ -n &amp;quot;$URL&amp;quot; ]; then&lt;br /&gt;
      echo &amp;quot;Downloading $PKG ($URL)&amp;quot;&lt;br /&gt;
      wget -q -nc $URL -P $DOWNLOADDIR &amp;amp;&amp;amp; dpkg -x $DOWNLOADDIR/$(basename $URL) $SYSROOT&lt;br /&gt;
# --show-progress&lt;br /&gt;
#      dpkg -x $DOWNLOADDIR/$(basename $URL) $SYSROOT&lt;br /&gt;
      echo &amp;quot;Done installing $PKG&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      echo &amp;quot;$PKG NOT FOUND!&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
#  done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
export -f install_package&lt;br /&gt;
export DOWNLOADDIR&lt;br /&gt;
export SYSROOT&lt;br /&gt;
&lt;br /&gt;
# read packages.txt into PACKAGES&lt;br /&gt;
while IFS= read -r line; do&lt;br /&gt;
    PACKAGES+=(&amp;quot;$line&amp;quot;)&lt;br /&gt;
done &amp;lt; &amp;quot;packages.txt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
parallel -j $PARALLELDOWNLOAD install_package ::: &amp;quot;${PACKAGES[@]}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Done!&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Download &amp;lt;code&amp;gt;packages.txt&amp;lt;/code&amp;gt; # Focal Ubuntu 20.04.6 LTS! =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://gist.githubusercontent.com/Damme/3161f92ccadf452b4d5f3eee32da097e/raw/8df0172858e95da76091b04f8492705fc0cf0396/packages.txt -O packages.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Create &amp;lt;code&amp;gt;2-fix-links-cmake.bash&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
SYSROOT=/opt/sysroot_arm64&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Linking some missing library links, broken links /hardcoded to /lib/...&amp;quot;&lt;br /&gt;
ln -sfv $SYSROOT/usr/lib/aarch64-linux-gnu/libPocoFoundation.so.62 $SYSROOT/usr/lib/aarch64-linux-gnu/libPocoFoundation.so&lt;br /&gt;
ln -sfv $SYSROOT/usr/lib/aarch64-linux-gnu/blas/libblas.so.3 $SYSROOT/usr/lib/aarch64-linux-gnu/libblas.so.3&lt;br /&gt;
ln -sfv $SYSROOT/usr/lib/aarch64-linux-gnu/lapack/liblapack.so.3 $SYSROOT/usr/lib/aarch64-linux-gnu/liblapack.so.3&lt;br /&gt;
&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/librt.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/librt.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libpthread.so.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libpthread.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libBrokenLocale.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libBrokenLocale.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libanl.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libanl.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libblkid.so.1.1.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libblkid.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libbz2.so.1.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libbz2.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libexpat.so.1.6.11 $SYSROOT/usr/lib/aarch64-linux-gnu/libexpat.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libgpg-error.so.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libgpg-error.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libkeyutils.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libkeyutils.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/liblzma.so.5.2.4 $SYSROOT/usr/lib/aarch64-linux-gnu/liblzma.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libm.so.6 $SYSROOT/usr/lib/aarch64-linux-gnu/libm.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libmount.so.1.1.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libmount.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnsl.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libnsl.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_compat.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_compat.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_dns.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_dns.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_files.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_files.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_hesiod.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_hesiod.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_nis.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_nis.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_nisplus.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_nisplus.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libpcre.so.3 $SYSROOT/usr/lib/aarch64-linux-gnu/libpcre.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libresolv.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libresolv.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libthread_db.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libthread_db.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libutil.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libutil.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libuuid.so.1.3.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libuuid.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libz.so.1.2.11 $SYSROOT/usr/lib/aarch64-linux-gnu/libz.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libdl.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libdl.so&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Fix cmake files with hardcoded paths..&amp;quot;&lt;br /&gt;
find $SYSROOT/opt/ros/noetic/ -name &amp;quot;*.cmake&amp;quot; | xargs -i sh -c &#039;echo {}; sed -i s@/opt/ros/noetic/lib@\${SYSROOT_PATH}/opt/ros/noetic/lib@g {}&#039;&lt;br /&gt;
find $SYSROOT/opt/ros/noetic/ -name &amp;quot;*.cmake&amp;quot; | xargs -i sh -c &#039;echo {}; sed -i s@PREFIX\ /opt/ros/noetic@PREFIX\ \${SYSROOT_PATH}/opt/ros/noetic@g {}&#039;&lt;br /&gt;
find $SYSROOT/opt/ros/noetic/ -name &amp;quot;*.cmake&amp;quot; | xargs -i sh -c &#039;echo {}; sed -i s@\;/usr/@\;\$\{SYSROOT_PATH\}/usr/@g {}&#039;&lt;br /&gt;
find $SYSROOT/opt/ros/noetic/ -name &amp;quot;*.cmake&amp;quot; | xargs -i sh -c &#039;echo {}; sed -i s@\&amp;quot;/usr/@\&amp;quot;\$\{SYSROOT_PATH\}/usr/@g {}&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Create &amp;lt;code&amp;gt;3-patch-openmower-cmake.bash&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
cd src/lib/slic3r_coverage_planner&lt;br /&gt;
&lt;br /&gt;
patch CMakeLists.txt &amp;lt;&amp;lt;&#039;EOF&#039;&lt;br /&gt;
@@ -33,7 +33,9 @@ ExternalProject_Add(&lt;br /&gt;
&lt;br /&gt;
         CMAKE_CACHE_ARGS&lt;br /&gt;
         SOURCE_SUBDIR src&lt;br /&gt;
-        CMAKE_ARGS -DSLIC3R_BUILD_TESTS=OFF&lt;br /&gt;
+        CMAKE_ARGS -DSLIC3R_BUILD_TESTS=OFF -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}&lt;br /&gt;
+               -DCMAKE_EXE_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu&lt;br /&gt;
+               -DCMAKE_SHARED_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu&lt;br /&gt;
         BUILD_COMMAND ${CMAKE_COMMAND} --build &amp;lt;BINARY_DIR&amp;gt; --config Release&lt;br /&gt;
 )&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
cd ../../../&lt;br /&gt;
&lt;br /&gt;
cd src/lib/xbot_driver_gps&lt;br /&gt;
&lt;br /&gt;
patch CMakeLists.txt &amp;lt;&amp;lt;&#039;EOF&#039;&lt;br /&gt;
@@ -32,6 +32,9 @@ ExternalProject_Add(&lt;br /&gt;
         INSTALL_COMMAND cmake -E echo &amp;quot;Skipping install step.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
         CMAKE_CACHE_ARGS&lt;br /&gt;
+        CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}&lt;br /&gt;
+               -DCMAKE_EXE_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu&lt;br /&gt;
+               -DCMAKE_SHARED_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu&lt;br /&gt;
         BUILD_COMMAND ${CMAKE_COMMAND} --build &amp;lt;BINARY_DIR&amp;gt; --config Release&lt;br /&gt;
 )&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
cd ../../../&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Execute scripts ====&lt;br /&gt;
* run the created scripts:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ bash 1-setup_sysroot.bash&lt;br /&gt;
$ bash 2-fix-links-cmake.bash&lt;br /&gt;
$ bash 3-patch-openmower-cmake.bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Compilation  ====&lt;br /&gt;
* build with the following command, change -j1 for number of parallel processes. For some reason catkin_make does not parse toolchain.cmake without forcing it...&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;code&amp;gt;$ catkin_make -DCMAKE_TOOLCHAIN_FILE=/opt/open_mower_ros/toolchain.cmake -j1&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* check the build with&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ find devel/ -type f -executable |xargs file&lt;br /&gt;
devel/_setup_util.py:                                      Python script, ASCII text executable&lt;br /&gt;
devel/env.sh:                                              a /usr/bin/env sh script, ASCII text executable&lt;br /&gt;
devel/lib/mower_utils/planner_test:                        ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_utils/xbot_pose_converter:                 ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xesc_driver/xesc_driver_node:                    ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/libxesc_2040_driver.so:                          ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/ntrip_client/ntrip_ros.py:                       Python script, ASCII text executable&lt;br /&gt;
devel/lib/mower_simulation/mower_simulation:               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/libvesc_driver.so:                               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_comms/mower_comms:                         ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_map/mower_map_service:                     ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/libftc_local_planner.so:                         ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_positioning/xbot_positioning:               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_monitoring/xbot_sensor_example:             ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_monitoring/xbot_monitoring:                 ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_monitoring/heatmap_generator:               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_driver_gps/driver_gps_node:                 ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_logic/mag_calibration:                     ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_logic/monitoring:                          ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_logic/mower_odometry:                      ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_logic/mower_logic:                         ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/libxesc_driver.so:                               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/slic3r_coverage_planner/slic3r_coverage_planner: ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_remote/xbot_remote:                         ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* rsync folder to raspberry pi, note the section below!&lt;br /&gt;
&lt;br /&gt;
==== TODO/Fix me ====&lt;br /&gt;
* Fix &amp;lt;code&amp;gt;[project]/devel/setup.sh&amp;lt;/code&amp;gt; - scripts to use correct paths, maybe have a wrapper for setup.sh that setup some env vars for example CMAKE_PREFIX_PATH to omit sysroot_arm64 path, need to figure out what paths are wrong. Seems &amp;lt;code&amp;gt;_setup_util.py&amp;lt;/code&amp;gt; is the script that setup ros enviroment. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# One temporary fix is to create a link on the RPi:&lt;br /&gt;
$ ln -s / /opt/sysroot_arm64/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* a script to generate packages.txt&lt;br /&gt;
&lt;br /&gt;
Good luck!&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_OLD_Baremetal_installation&amp;diff=483</id>
		<title>OpenMower OLD Baremetal installation</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_OLD_Baremetal_installation&amp;diff=483"/>
		<updated>2026-06-20T21:15:27Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; Only use these is you are running bare metal custom build! Otherwise go to the official wiki, this is just a backup for personal reference!&lt;br /&gt;
&lt;br /&gt;
This page will guide you through the steps to install a basic system image.&lt;br /&gt;
&lt;br /&gt;
On this image you will have the ROS base system, the OpenMower installation, local configuration for your mower and some tools to help you work with the mower.&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
In order to follow this guide, you will need the following:&lt;br /&gt;
&lt;br /&gt;
#A Raspberry Pi 4 (4GB or more recommended, [[System Image#Enable Swap (optional, needed for Pi with &amp;lt;= 2GB RAM)|2GB works with swap, see here]])&lt;br /&gt;
#An SD card&lt;br /&gt;
#A soldered OpenMower mainboard&lt;br /&gt;
&lt;br /&gt;
==Installing the Base System==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;There is also a YouTube video explaining the steps in this section:&#039;&#039;&#039; https://youtu.be/_bImqD-pQSA?t=562&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Flashing Ubuntu to SD Card ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first step is to install the base system. We&#039;re using Ubuntu 20.04 Server for the Raspberry Pi. This is, because this image gives us best support ROS Noetic.&lt;br /&gt;
&lt;br /&gt;
Installing the base image is easy:&lt;br /&gt;
&lt;br /&gt;
#[https://www.raspberrypi.com/software/ Get the Raspberry Pi Imager software]&lt;br /&gt;
#Select the correct operating system:  &#039;&#039;Other-general-purpose OS &amp;gt; Ubuntu &amp;gt; Ubuntu Server 20.04.4 LTS (RPI 3/4/400) 64-bit&#039;&#039;&lt;br /&gt;
#Insert your SD card into your PC and select it in the &#039;&#039;Storage&#039;&#039; part of the software&lt;br /&gt;
#Click &#039;&#039;write&#039;&#039; and wait for the process to finish&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you have successfully flashed your image, remove the SD for your PC &#039;&#039;&#039;and reinsert it again.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Then replace the &amp;lt;code&amp;gt;/boot/config.txt&amp;lt;/code&amp;gt; file with the one provided here: [https://github.com/ClemensElflein/OpenMower/blob/main/configs/RaspberryPiConfig/config.txt]&lt;br /&gt;
&lt;br /&gt;
This will enable all hardware serial ports on the Raspberry Pi.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can theoretically configure networking in this step as well, but I&#039;m not recommending it. This is, because the networking information file gets only copied once and if you have an error it won&#039;t work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;We need an interactive terminal in the next step anyways.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you have done this step, you can eject the SD card and plug it into your Raspberry Pi 4.&lt;br /&gt;
&lt;br /&gt;
=== Opening a Serial Terminal ===&lt;br /&gt;
[[File:SerialRedirect.png|thumb|Serial Terminal: minicom -D /dev/ttyACM0]]&lt;br /&gt;
This step is needed for the following sections. The goal is to have a serial terminal to do basic config (networking etc) easily.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The easiest way of doing so is:&lt;br /&gt;
# Flash the SerialRedirect firmware into your Pico. Get it here: https://github.com/ClemensElflein/OpenMower/tree/main/Firmware/SerialRedirect/bin&lt;br /&gt;
# Provide your mainboard with power&lt;br /&gt;
# Plug your Pico into a computer. A virtual COM port should appear&lt;br /&gt;
# Connect to the COM port (I&#039;m using minicom, see image on the right), then press enter to start the Raspberry Pi.&lt;br /&gt;
#The Pi boots and a serial terminal will appear.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you can login with the default credentials:&lt;br /&gt;
&lt;br /&gt;
username: &amp;lt;code&amp;gt;ubuntu&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
password: &amp;lt;code&amp;gt;ubuntu&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that you will need to change the password immediately.&lt;br /&gt;
&lt;br /&gt;
=== Disable Boot Interrupt ===&lt;br /&gt;
[[File:Image.png|thumb|Commands needed to disable boot interrupt on serial input.]]&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi boot loader will interrupt the boot sequence if data is sent through the main serial port of the Raspberry Pi. Since we&#039;re connecting &amp;quot;nosiy&amp;quot; hardware to the port, this will always interrupt the boot sequence and we need to disable this feature. &lt;br /&gt;
&lt;br /&gt;
In order to do this, reboot the Pi (sudo reboot) and send anything during the count-down in the bootloader (check the YouTube video linked above, if you&#039;re not sure).&lt;br /&gt;
&lt;br /&gt;
Then enter the following commands into the bootloader prompt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
setenv bootdelay -2&lt;br /&gt;
saveenv&lt;br /&gt;
reset&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The Pi should reboot and the count-down should be gone.&lt;br /&gt;
&lt;br /&gt;
=== Some Settings ===&lt;br /&gt;
&lt;br /&gt;
[TODO/WIP]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here are some miscellaneous settings I think are a good idea for an OpenMower install:&lt;br /&gt;
&lt;br /&gt;
* Remove the unnecessary snap system: &amp;lt;code&amp;gt;sudo snap remove --purge lxd &amp;amp;&amp;amp; sudo snap remove --purge core20 &amp;amp;&amp;amp; sudo snap remove --purge snapd &amp;amp;&amp;amp; sudo apt purge --autoremove snapd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Disable unattended upgrades: &amp;lt;code&amp;gt;sudo systemctl stop --force unattended-upgrades &amp;amp;&amp;amp; sudo systemctl disable unattended-upgrades &amp;amp;&amp;amp; sudo systemctl mask unattended-upgrades&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* I like to add the following to &amp;lt;code&amp;gt;cmdline.txt&amp;lt;/code&amp;gt; in order to fsck on boot:  &amp;lt;code&amp;gt;fsck.mode=force fsck.repair=yes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* I prefer to use a static IP (If you use the [[System_Image#Installing_a_WiFi_Hot-Spot_(optional,_but_recommended)|recommend WiFi Hot-Spot]] use &amp;lt;code&amp;gt;sudo nmtui&amp;lt;/code&amp;gt; to configure a static IP)&lt;br /&gt;
&lt;br /&gt;
* If you like to have a terminal wifi scanner/signal monitor just install &amp;lt;code&amp;gt;sudo apt install wavemon&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you like you can change the timezone: &amp;lt;code&amp;gt;sudo timedatectl set-timezone Region/Location&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;sudo dpkg-reconfigure tzdata&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you ever like to plug a keyboard into the Pi don&#039;t forget to change the keymap: &amp;lt;code&amp;gt;sudo dpkg-reconfigure keyboard-configuration&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Enable Swap (optional, needed for Pi with &amp;lt;= 2GB RAM)===&lt;br /&gt;
Compiling the OpenMower software will need more than 2GB of RAM. In order to still do this on a Pi with &amp;lt;= 2GB of RAM, we will add a 2GB swap file to the system by entering the following commands:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Create a new 2GB swap file&lt;br /&gt;
sudo fallocate -l 2G /swapfile&lt;br /&gt;
# Change permissions, so that only root can read and write&lt;br /&gt;
sudo chmod 600 /swapfile&lt;br /&gt;
# Create swap space in the file&lt;br /&gt;
sudo mkswap /swapfile&lt;br /&gt;
# Add it to the fstab&lt;br /&gt;
echo &#039;/swapfile swap swap defaults 0 0&#039; | sudo tee -a /etc/fstab /swapfile swap swap defaults 0 0&lt;br /&gt;
# Reboot to activate&lt;br /&gt;
sudo reboot&lt;br /&gt;
&lt;br /&gt;
# Check if it&#039;s activated&lt;br /&gt;
sudo swapon --show&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Installing a WiFi Hot-Spot (optional, but recommended)===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Since we will be configuring the WiFi interface, make sure that you have connected Ethernet to your Raspberry Pi for this step.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As soon as you have closed your mower&#039;s enclosure, you won&#039;t have physical access to your Raspberry Pi anymore. If for some reason it&#039;s unable to connect to your WiFi (e.g. you have changed your password), you would need to open the case to get access to the SD card or Ethernet port on the Pi to regain access.&lt;br /&gt;
&lt;br /&gt;
To prevent this, we&#039;re going to install a hot-spot software which helps you to connect to WiFi by opening a hot-spot each time the Pi cannot connect to a known WiFi connection.&lt;br /&gt;
&lt;br /&gt;
Now is the best time to do this, because we have a serial terminal anyways and can mess with the network interfaces without shutting us out of the system!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just use the following commands for this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# We need to disable systemd-resolveds caching DNS stub resolver&lt;br /&gt;
# if you want to know why check: https://github.com/pi-hole/docker-pi-hole/#installing-on-ubuntu&lt;br /&gt;
sudo sed -r -i.orig &#039;s/#?DNSStubListener=yes/DNSStubListener=no/g&#039; /etc/systemd/resolved.conf&lt;br /&gt;
sudo systemctl restart systemd-resolved.service&lt;br /&gt;
&lt;br /&gt;
ping ntp.org&lt;br /&gt;
# This will throw an dns error:&lt;br /&gt;
#   ping: ntp.org: Temporary failure in name resolution&lt;br /&gt;
sudo sh -c &#039;rm /etc/resolv.conf &amp;amp;&amp;amp; ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf&#039;&lt;br /&gt;
sudo systemctl restart systemd-resolved.service&lt;br /&gt;
nslookup ntp.org&lt;br /&gt;
# DNS should work now&lt;br /&gt;
&lt;br /&gt;
# Install comitup using the latest version from the projects repo&lt;br /&gt;
wget https://davesteele.github.io/comitup/latest/davesteele-comitup-apt-source_latest.deb&lt;br /&gt;
sudo dpkg -i --force-all davesteele-comitup-apt-source_latest.deb&lt;br /&gt;
rm davesteele-comitup-apt-source_latest.deb&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install comitup --no-install-recommends&lt;br /&gt;
&lt;br /&gt;
sudo systemctl stop comitup&lt;br /&gt;
# Now use network-manager to:&lt;br /&gt;
# - add you wifi network&lt;br /&gt;
# optional:&lt;br /&gt;
# - change your hostname&lt;br /&gt;
# - add a dhcp ethernet connection without any device assigned&lt;br /&gt;
# (if even the hotspot malfunctions you can plug in a usb ethernet adapter)&lt;br /&gt;
sudo nmtui&lt;br /&gt;
&lt;br /&gt;
# Edit comitup.conf to change the wifi name and password (I use OpenMower-&amp;lt;nn&amp;gt;)&lt;br /&gt;
sudo nano /etc/comitup.conf&lt;br /&gt;
sudo systemctl restart comitup&lt;br /&gt;
# reboot - it should work now&lt;br /&gt;
sudo reboot&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Disable Serial Console===&lt;br /&gt;
Now that we have setup the network and can access the Pi even if our WiFi is not in range, we need to disable that serial console so that we can use the serial port for hardware.&lt;br /&gt;
&lt;br /&gt;
To do this, enter: &amp;lt;code&amp;gt;sudo nano /boot/firmware/cmdline.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and remove the &amp;lt;code&amp;gt;console=serial0,115200&amp;lt;/code&amp;gt; part of the line.&lt;br /&gt;
&lt;br /&gt;
Save the file and reboot. You should still see the bootloader output, but no serial output after that.&lt;br /&gt;
&lt;br /&gt;
==Installing Tools==&lt;br /&gt;
If you&#039;re happy with your basic Ubuntu setup, it&#039;s time to install some tools required for the OpenMower&lt;br /&gt;
&lt;br /&gt;
=== General Dependencies ===&lt;br /&gt;
Just install them with apt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install --no-install-recommends build-essential git&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===STR2STR (optional, recommended; only needed if you&#039;re using NTRIP, so probably most of you)===&lt;br /&gt;
We need a newer version than the one available in apt, so install it from source:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install gfortran&lt;br /&gt;
git clone https://github.com/rtklibexplorer/RTKLIB&lt;br /&gt;
cd RTKLIB&lt;br /&gt;
git checkout tags/b34c&lt;br /&gt;
cd app/consapp/&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
sudo make install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;You should now be able to run str2str from anywhere.&lt;br /&gt;
&lt;br /&gt;
=== OpenOCD (optional, recommended; only needed if you want to flash Pico from Raspberry Pi)===&lt;br /&gt;
We need to get the OpenOCD version from the Raspberry Pi foundation, because the &amp;quot;original&amp;quot; one doesn&#039;t have the Pico support built in yet.&lt;br /&gt;
&lt;br /&gt;
Install it from source:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install automake autoconf build-essential libtool libftdi-dev libusb-1.0-0-dev texinfo pkg-config rpi.gpio-common&lt;br /&gt;
git clone https://github.com/raspberrypi/openocd.git --recursive --branch rp2040 --depth=1&lt;br /&gt;
cd openocd&lt;br /&gt;
./bootstrap&lt;br /&gt;
./configure --enable-ftdi --enable-sysfsgpio --enable-bcm2835gpio&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
sudo make install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;You can test if it was a success by running:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
ubuntu@ubuntu:~$ openocd -v&lt;br /&gt;
Open On-Chip Debugger 0.11.0-g610f137-dirty (2022-06-07-00:39)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
	http://openocd.org/doc/doxygen/bugs.html&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Installing ROS and OpenMower==&lt;br /&gt;
We&#039;re using ROS Noetic for the OpenMower project. In this step we will install it, get the OpenMower sources, build the sources and create a basic configuration file for your mower.&lt;br /&gt;
&lt;br /&gt;
===Install ROS Noetic===&lt;br /&gt;
Since we&#039;re running Ubuntu 20.04 installing ROS is as easy as running the following commands:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Get the ROS apt repository&lt;br /&gt;
sudo sh -c &#039;echo &amp;quot;deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main&amp;quot; &amp;gt; /etc/apt/sources.list.d/ros-latest.list&#039;&lt;br /&gt;
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -&lt;br /&gt;
&lt;br /&gt;
# Install the ROS base system&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install --no-install-recommends ros-noetic-ros-base&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;We only need to register the ROS installation in your &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt; file. This will enable you to call ROS specific commands from your terminal:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# If you&#039;re using bash (default on Ubuntu):&lt;br /&gt;
echo &amp;quot;source /opt/ros/noetic/setup.bash&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
source ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
# Else if you&#039;re using zsh&lt;br /&gt;
echo &amp;quot;source /opt/ros/noetic/setup.zsh&amp;quot; &amp;gt;&amp;gt; ~/.zshrc&lt;br /&gt;
source ~/.zshrc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Installing OpenMower Software===&lt;br /&gt;
Now we&#039;re finally able to install the OpenMower software. First, we&#039;re checking out the current version of the sources, then we&#039;re getting the dependencies and finally we&#039;re building the sources:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Clone the GitHub Repository:&lt;br /&gt;
git clone --recursive https://github.com/ClemensElflein/open_mower_ros.git&lt;br /&gt;
&lt;br /&gt;
# Get rosdep, only needed once&lt;br /&gt;
sudo apt install --no-install-recommends python3-rosdep&lt;br /&gt;
sudo rosdep init&lt;br /&gt;
rosdep update&lt;br /&gt;
&lt;br /&gt;
# Get the dependencies using rosdep&lt;br /&gt;
cd ~/open_mower_ros/&lt;br /&gt;
sudo apt-get install --no-install-recommends $(rosdep install --from-paths src --ignore-src --simulate | sed --expression &#039;1d&#039; | sort | tr -d &#039;\n&#039; | sed -e &#039;s/  sudo -H apt-get install//g&#039;)&lt;br /&gt;
&lt;br /&gt;
# Finally, build the sources. This will take a while! &lt;br /&gt;
catkin_make -j1 # on 2GB Pi with SWAP - this takes at least 30min&lt;br /&gt;
# OR&lt;br /&gt;
catkin_make -j2 # on 4/8GB Pi - this takes at least 20min&lt;br /&gt;
&lt;br /&gt;
# Copy the default configuration file to your home directory&lt;br /&gt;
cp ~/open_mower_ros/src/open_mower/config/mower_config.sh.example ~/mower_config.sh&lt;br /&gt;
&lt;br /&gt;
# The next step is to also source the OpenMower ROS install&lt;br /&gt;
# If you&#039;re using bash (default on Ubuntu):&lt;br /&gt;
echo &amp;quot;source ~/open_mower_ros/devel/setup.sh&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
echo &amp;quot;source ~/mower_config.sh&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
source ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
# Else if you&#039;re using zsh&lt;br /&gt;
echo &amp;quot;source ~/open_mower_ros/devel/setup.zsh&amp;quot; &amp;gt;&amp;gt; ~/.zshrc&lt;br /&gt;
echo &amp;quot;source ~/mower_config.sh&amp;quot; &amp;gt;&amp;gt; ~/.zshrc&lt;br /&gt;
source ~/.zshrc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;At this point the OpenMower software is successfully installed! You will need to configure the OpenMower software and then you&#039;re finally ready to mow.&lt;br /&gt;
&lt;br /&gt;
== Some Additional Issues==&lt;br /&gt;
&lt;br /&gt;
===I&#039;m using an external WiFi dongle for better coverage, but sometimes it doesn&#039;t work===&lt;br /&gt;
It seems that the Ubuntu sometimes puts external WiFi dongles to sleep. To prevent this, we create a service which disables powersave:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Enter this to create the service&lt;br /&gt;
sudo systemctl --full --force edit wifi_powersave@.service&lt;br /&gt;
&lt;br /&gt;
# Paste the following:&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Set WiFi power save %i&lt;br /&gt;
After=sys-subsystem-net-devices-wlan1.device&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=oneshot&lt;br /&gt;
RemainAfterExit=yes&lt;br /&gt;
ExecStart=/sbin/iw dev wlan1 set power_save %i&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=sys-subsystem-net-devices-wlan1.device&lt;br /&gt;
&lt;br /&gt;
# Save and exit, then activate using:&lt;br /&gt;
sudo systemctl disable wifi_powersave@on.service&lt;br /&gt;
sudo systemctl enable wifi_powersave@off.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower&amp;diff=482</id>
		<title>OpenMower</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower&amp;diff=482"/>
		<updated>2026-06-20T21:15:11Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; Only use these is you are running bare metal custom build! Otherwise go to the official wiki, this is just a backup for personal reference!&lt;br /&gt;
* [[OpenMower OLD Baremetal installation]]&lt;br /&gt;
* [[OpenMower Crosscompiling]]&lt;br /&gt;
* [[OpenMower Simulation]]&lt;br /&gt;
* [[OpenMower Edit map]]&lt;br /&gt;
* [[OpenMower Unicore GPS]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Subscribers:&lt;br /&gt;
    1. cmd_vel_sub: Subscribes to the cmd_vel topic.&lt;br /&gt;
        ◦ Message Type: geometry_msgs::Twist&lt;br /&gt;
        ◦ Description: Contains the desired linear and angular velocities for the robot.&lt;br /&gt;
        ◦ Contents:&lt;br /&gt;
            ▪ linear.x: Linear velocity in the x-axis direction (m/s).&lt;br /&gt;
            ▪ linear.y: Linear velocity in the y-axis direction (m/s).&lt;br /&gt;
            ▪ linear.z: Linear velocity in the z-axis direction (m/s).&lt;br /&gt;
            ▪ angular.x: Angular velocity around the x-axis (rad/s).&lt;br /&gt;
            ▪ angular.y: Angular velocity around the y-axis (rad/s).&lt;br /&gt;
            ▪ angular.z: Angular velocity around the z-axis (rad/s).&lt;br /&gt;
    2. high_level_status_sub: Subscribes to the /mower_logic/current_state topic.&lt;br /&gt;
        ◦ Message Type: mower_msgs::HighLevelStatus&lt;br /&gt;
        ◦ Description: Receives the high-level state of the mower from the mower logic node. This state includes information about the current operating mode, substate, GPS quality, battery status, charging status, and emergency flag.&lt;br /&gt;
        ◦ Fields:&lt;br /&gt;
            ▪ state: An integer representing the current high-level state of the mower (e.g., idle, autonomous, recording, etc.).&lt;br /&gt;
            ▪ state_name: A string representing the name of the current high-level state (e.g., &amp;quot;IDLE&amp;quot;, &amp;quot;AUTONOMOUS&amp;quot;, &amp;quot;RECORDING&amp;quot;).&lt;br /&gt;
            ▪ sub_state_name: A string representing the name of the current substate (e.g., &amp;quot;SUBSTATE_1&amp;quot;, &amp;quot;SUBSTATE_2&amp;quot;, &amp;quot;SUBSTATE_3&amp;quot;, &amp;quot;SUBSTATE_4&amp;quot;).&lt;br /&gt;
            ▪ gps_quality_percent: A float32 value representing the GPS quality as a percentage, where 0% indicates no GPS signal and 100% indicates a perfect GPS signal.&lt;br /&gt;
            ▪ battery_percent: A float32 value representing the battery charge level as a percentage, where 0% indicates an empty battery and 100% indicates a fully charged battery.&lt;br /&gt;
            ▪ is_charging: A boolean value indicating whether the mower is currently charging or not.&lt;br /&gt;
            ▪ emergency: A boolean value indicating if there is an active emergency situation, such as a collision, detected by the mower.&lt;br /&gt;
        ◦ Callback Function: highLevelStatusReceived&lt;br /&gt;
            ▪ Description: Handles the received high-level state of the mower, updating the internal state representation for the mower communication node.&lt;br /&gt;
Publishers:&lt;br /&gt;
    1. status_pub: Publishes to the /mower/status topic.&lt;br /&gt;
        ◦ Message Type: mower_msgs::Status&lt;br /&gt;
        ◦ Description: Publishes the current status of the mower, including information about the mower&#039;s low-level systems, power status, ultrasonic range measurements, emergency status, battery, and ESC statuses.&lt;br /&gt;
        ◦ Fields:&lt;br /&gt;
            ▪ stamp: A time object representing the timestamp of the message.&lt;br /&gt;
            ▪ mower_status: An integer representing the mower&#039;s status, such as initializing or OK.&lt;br /&gt;
            ▪ raspberry_pi_power: A boolean value indicating if the Raspberry Pi has power.&lt;br /&gt;
            ▪ gps_power: A boolean value indicating if the GPS module has power.&lt;br /&gt;
            ▪ esc_power: A boolean value indicating if the Electronic Speed Controllers (ESCs) have power.&lt;br /&gt;
            ▪ rain_detected: A boolean value indicating if rain is detected.&lt;br /&gt;
            ▪ sound_module_available: A boolean value indicating if the sound module is available.&lt;br /&gt;
            ▪ sound_module_busy: A boolean value indicating if the sound module is busy.&lt;br /&gt;
            ▪ ui_board_available: A boolean value indicating if the UI board is available.&lt;br /&gt;
            ▪ ultrasonic_ranges: An array of 5 float32 values representing the ultrasonic range measurements.&lt;br /&gt;
            ▪ emergency: A boolean value indicating if there is an active emergency situation, such as a collision, detected by the mower.&lt;br /&gt;
            ▪ v_charge: A float32 value representing the charge voltage.&lt;br /&gt;
            ▪ v_battery: A float32 value representing the battery voltage.&lt;br /&gt;
            ▪ charge_current: A float32 value representing the charge current.&lt;br /&gt;
            ▪ left_esc_status: An ESCStatus object containing information about the status of the left ESC.&lt;br /&gt;
            ▪ right_esc_status: An ESCStatus object containing information about the status of the right ESC.&lt;br /&gt;
            ▪ mow_esc_status: An ESCStatus object containing information about the status of the mow ESC.&lt;br /&gt;
    2. wheel_tick_pub: Publishes the mower/wheel_ticks topic.&lt;br /&gt;
        ◦ Message Type: xbot_msgs::WheelTick&lt;br /&gt;
        ◦ Description: Publishes the wheel tick information for the left and right wheels of the mower, which is used to calculate odometry.&lt;br /&gt;
        ◦ Fields:&lt;br /&gt;
            ▪ header: Standard ROS message header containing a timestamp and frame_id.&lt;br /&gt;
            ▪ left_ticks: The number of ticks for the left wheel since the last message.&lt;br /&gt;
            ▪ right_ticks: The number of ticks for the right wheel since the last message.&lt;br /&gt;
            ▪ interval: The time interval in seconds between the current and previous wheel tick message.&lt;br /&gt;
    3. sensor_imu_pub: Publishes to the imu/data_raw topic.&lt;br /&gt;
        ◦ Message Type: sensor_msgs::Imu&lt;br /&gt;
        ◦ Description: Provides raw IMU data, including linear acceleration and angular velocity.&lt;br /&gt;
        ◦ Contents:&lt;br /&gt;
            ▪ header: Message header, containing timestamp and frame ID.&lt;br /&gt;
            ▪ orientation: Orientation as a quaternion (x, y, z, w).&lt;br /&gt;
            ▪ orientation_covariance: Orientation covariance matrix (3x3).&lt;br /&gt;
            ▪ angular_velocity: Angular velocity vector (x, y, z) in rad/s.&lt;br /&gt;
            ▪ angular_velocity_covariance: Angular velocity covariance matrix (3x3).&lt;br /&gt;
            ▪ linear_acceleration: Linear acceleration vector (x, y, z) in m/s^2.&lt;br /&gt;
            ▪ linear_acceleration_covariance: Linear acceleration covariance matrix (3x3).&lt;br /&gt;
    4. sensor_mag_pub: Publishes to the imu/mag topic.&lt;br /&gt;
        ◦ Message Type: sensor_msgs::MagneticField&lt;br /&gt;
        ◦ Description: Provides magnetic field data from the IMU.&lt;br /&gt;
        ◦ Contents:&lt;br /&gt;
            ▪ header: Message header, containing timestamp and frame ID.&lt;br /&gt;
            ▪ magnetic_field: Magnetic field vector (x, y, z) in Tesla.&lt;br /&gt;
            ▪ magnetic_field_covariance: Magnetic field covariance matrix (3x3).&lt;br /&gt;
Services:&lt;br /&gt;
    1. mow_service: Advertises the mower_service/mow_enabled service.&lt;br /&gt;
        ◦ Service Type: std_srvs::SetBool&lt;br /&gt;
        ◦ Description: Allows enabling or disabling the mower&#039;s mowing functionality.&lt;br /&gt;
        ◦ Request Fields:&lt;br /&gt;
            ▪ data: A boolean value representing the desired state of the mower&#039;s mowing functionality. True for enabling and False for disabling.&lt;br /&gt;
        ◦ Response Fields:&lt;br /&gt;
            ▪ success: A boolean value indicating if the requested operation was successful.&lt;br /&gt;
            ▪ message: A string providing additional information about the outcome of the operation.&lt;br /&gt;
    2. emergency_service: Advertises the mower_service/emergency service.&lt;br /&gt;
        ◦ Service Type: std_srvs::Trigger&lt;br /&gt;
        ◦ Description: Triggers an emergency stop for the mower.&lt;br /&gt;
        ◦ Request Fields: No fields required.&lt;br /&gt;
        ◦ Response Fields:&lt;br /&gt;
            ▪ success: A boolean value indicating if the emergency stop was successfully triggered.&lt;br /&gt;
            ▪ message: A string providing additional information about the outcome of the operation.&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_Unicore_GPS&amp;diff=481</id>
		<title>OpenMower Unicore GPS</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_Unicore_GPS&amp;diff=481"/>
		<updated>2026-06-20T21:03:18Z</updated>

		<summary type="html">&lt;p&gt;Damme: Created page with &amp;quot;Several users have chosen alternative GPS RTK modules with chips by &amp;#039;&amp;#039;Unicore&amp;#039;&amp;#039;:  * &amp;#039;&amp;#039;UM960&amp;#039;&amp;#039; * &amp;#039;&amp;#039;UM980&amp;#039;&amp;#039; * &amp;#039;&amp;#039;UM982&amp;#039;&amp;#039;  These chips are sold in different variants. Some come with a USB-C socket (so they can be connected directly to the Raspberry Pi). Some have different antenna socket (which need an &amp;#039;&amp;#039;SMA F&amp;#039;&amp;#039; to &amp;#039;&amp;#039;MMCX M90&amp;#039;&amp;#039; cable).  Compared to the &amp;#039;&amp;#039;ArduSimple simpleRTK2B,&amp;#039;&amp;#039; they&amp;#039;re a bit cheaper and support triple-band frequencies.  == Variants how modules can be conne...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Several users have chosen alternative GPS RTK modules with chips by &#039;&#039;Unicore&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;UM960&#039;&#039;&lt;br /&gt;
* &#039;&#039;UM980&#039;&#039;&lt;br /&gt;
* &#039;&#039;UM982&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These chips are sold in different variants. Some come with a USB-C socket (so they can be connected directly to the Raspberry Pi). Some have different antenna socket (which need an &#039;&#039;SMA F&#039;&#039; to &#039;&#039;MMCX M90&#039;&#039; cable).&lt;br /&gt;
&lt;br /&gt;
Compared to the &#039;&#039;ArduSimple simpleRTK2B,&#039;&#039; they&#039;re a bit cheaper and support triple-band frequencies.&lt;br /&gt;
&lt;br /&gt;
== Variants how modules can be connected and configured ==&lt;br /&gt;
* Connection&lt;br /&gt;
** Module USB-c -&amp;gt; RPI USB (e.g. with angle connector)&lt;br /&gt;
** Module UART -&amp;gt; MainBoard UART (requires header connectivity)&lt;br /&gt;
&lt;br /&gt;
* Configuration&lt;br /&gt;
** With vendor software (requires Windows PC) - should be done before installing module into mower&lt;br /&gt;
** Over UART bus (only terminal) - should be done when RPI installed and operational&lt;br /&gt;
&lt;br /&gt;
== Step-by step set-up guides ==&lt;br /&gt;
*[[Unicore GPS Setup-CAN| With wiring to mainboard and configuration on UART]]&lt;br /&gt;
* &amp;lt;TODO&amp;gt; add other guides&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
[https://core-electronics.com.au/attachments/localcontent/Unicore_Reference_Commands_Manual_For_N4_High_Precision_Products_V2_EN_R1_1_189543505cb.pdf Command reference]&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
The vendor offers [https://en.unicore.com/products/uprecise.html &#039;&#039;UPrecise&#039;&#039;] to check all status details and configure the receiver. The UI is pleasing and has many features, but also quite some bugs. The download requires creating a free account.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
The following configuration works quite well. COM3 is used when connected via USB.&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
FRESET&lt;br /&gt;
CONFIG COM3 460800&lt;br /&gt;
MODE ROVER UAV&lt;br /&gt;
GPGGA 0.1&lt;br /&gt;
GPGSV 1&lt;br /&gt;
GPRMC 1&lt;br /&gt;
GPGSA 1&lt;br /&gt;
GPVTG 1&lt;br /&gt;
GPGST 1&lt;br /&gt;
SAVECONFIG&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;These lines can be pasted into &#039;&#039;UPrecise&#039;&#039; after connecting to the receiver. Theoretically, you can also connect directly to the receiver&#039;s TTY, but make sure to send CR+LF (&amp;lt;code&amp;gt;\r\n&amp;lt;/code&amp;gt;) line endings, otherwise the commands won&#039;t be recognized.&lt;br /&gt;
&lt;br /&gt;
=== OpenMower (&amp;lt;code&amp;gt;mower_config.txt&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
export OM_GPS_PROTOCOL=&amp;quot;NMEA&amp;quot;&lt;br /&gt;
export OM_GPS_PORT=&amp;quot;/dev/ttyUSB0&amp;quot;&lt;br /&gt;
export OM_GPS_BAUDRATE=&amp;quot;460800&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rebooting ==&lt;br /&gt;
Sometimes the receiver just can&#039;t get a fix. Then it might be helpful to reboot it. There are three buttons in &#039;&#039;UPrecise&#039;&#039;, which execute these commands:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Button&lt;br /&gt;
!Command&lt;br /&gt;
|-&lt;br /&gt;
|Hot Start&lt;br /&gt;
|&amp;lt;code&amp;gt;RESET&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Warm Start&lt;br /&gt;
|&amp;lt;code&amp;gt;RESET EPHEM&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Cold Start&lt;br /&gt;
|&amp;lt;code&amp;gt;RESET EPHEM ALMANAC IONUTC POSITION&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
See also section 8.3 (&amp;quot;Reset&amp;quot;) in the [https://core-electronics.com.au/attachments/localcontent/Unicore_Reference_Commands_Manual_For_N4_High_Precision_Products_V2_EN_R1_1_189543505cb.pdf command reference]. In contrast to the &amp;lt;code&amp;gt;FRESET&amp;lt;/code&amp;gt; command, these command &#039;&#039;&#039;don&#039;t&#039;&#039;&#039; wipe the configuration.&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower&amp;diff=480</id>
		<title>OpenMower</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower&amp;diff=480"/>
		<updated>2026-06-20T21:03:15Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[OpenMower OLD Baremetal installation]]&lt;br /&gt;
* [[OpenMower Crosscompiling]]&lt;br /&gt;
* [[OpenMower Simulation]]&lt;br /&gt;
* [[OpenMower Edit map]]&lt;br /&gt;
* [[OpenMower Unicore GPS]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Subscribers:&lt;br /&gt;
    1. cmd_vel_sub: Subscribes to the cmd_vel topic.&lt;br /&gt;
        ◦ Message Type: geometry_msgs::Twist&lt;br /&gt;
        ◦ Description: Contains the desired linear and angular velocities for the robot.&lt;br /&gt;
        ◦ Contents:&lt;br /&gt;
            ▪ linear.x: Linear velocity in the x-axis direction (m/s).&lt;br /&gt;
            ▪ linear.y: Linear velocity in the y-axis direction (m/s).&lt;br /&gt;
            ▪ linear.z: Linear velocity in the z-axis direction (m/s).&lt;br /&gt;
            ▪ angular.x: Angular velocity around the x-axis (rad/s).&lt;br /&gt;
            ▪ angular.y: Angular velocity around the y-axis (rad/s).&lt;br /&gt;
            ▪ angular.z: Angular velocity around the z-axis (rad/s).&lt;br /&gt;
    2. high_level_status_sub: Subscribes to the /mower_logic/current_state topic.&lt;br /&gt;
        ◦ Message Type: mower_msgs::HighLevelStatus&lt;br /&gt;
        ◦ Description: Receives the high-level state of the mower from the mower logic node. This state includes information about the current operating mode, substate, GPS quality, battery status, charging status, and emergency flag.&lt;br /&gt;
        ◦ Fields:&lt;br /&gt;
            ▪ state: An integer representing the current high-level state of the mower (e.g., idle, autonomous, recording, etc.).&lt;br /&gt;
            ▪ state_name: A string representing the name of the current high-level state (e.g., &amp;quot;IDLE&amp;quot;, &amp;quot;AUTONOMOUS&amp;quot;, &amp;quot;RECORDING&amp;quot;).&lt;br /&gt;
            ▪ sub_state_name: A string representing the name of the current substate (e.g., &amp;quot;SUBSTATE_1&amp;quot;, &amp;quot;SUBSTATE_2&amp;quot;, &amp;quot;SUBSTATE_3&amp;quot;, &amp;quot;SUBSTATE_4&amp;quot;).&lt;br /&gt;
            ▪ gps_quality_percent: A float32 value representing the GPS quality as a percentage, where 0% indicates no GPS signal and 100% indicates a perfect GPS signal.&lt;br /&gt;
            ▪ battery_percent: A float32 value representing the battery charge level as a percentage, where 0% indicates an empty battery and 100% indicates a fully charged battery.&lt;br /&gt;
            ▪ is_charging: A boolean value indicating whether the mower is currently charging or not.&lt;br /&gt;
            ▪ emergency: A boolean value indicating if there is an active emergency situation, such as a collision, detected by the mower.&lt;br /&gt;
        ◦ Callback Function: highLevelStatusReceived&lt;br /&gt;
            ▪ Description: Handles the received high-level state of the mower, updating the internal state representation for the mower communication node.&lt;br /&gt;
Publishers:&lt;br /&gt;
    1. status_pub: Publishes to the /mower/status topic.&lt;br /&gt;
        ◦ Message Type: mower_msgs::Status&lt;br /&gt;
        ◦ Description: Publishes the current status of the mower, including information about the mower&#039;s low-level systems, power status, ultrasonic range measurements, emergency status, battery, and ESC statuses.&lt;br /&gt;
        ◦ Fields:&lt;br /&gt;
            ▪ stamp: A time object representing the timestamp of the message.&lt;br /&gt;
            ▪ mower_status: An integer representing the mower&#039;s status, such as initializing or OK.&lt;br /&gt;
            ▪ raspberry_pi_power: A boolean value indicating if the Raspberry Pi has power.&lt;br /&gt;
            ▪ gps_power: A boolean value indicating if the GPS module has power.&lt;br /&gt;
            ▪ esc_power: A boolean value indicating if the Electronic Speed Controllers (ESCs) have power.&lt;br /&gt;
            ▪ rain_detected: A boolean value indicating if rain is detected.&lt;br /&gt;
            ▪ sound_module_available: A boolean value indicating if the sound module is available.&lt;br /&gt;
            ▪ sound_module_busy: A boolean value indicating if the sound module is busy.&lt;br /&gt;
            ▪ ui_board_available: A boolean value indicating if the UI board is available.&lt;br /&gt;
            ▪ ultrasonic_ranges: An array of 5 float32 values representing the ultrasonic range measurements.&lt;br /&gt;
            ▪ emergency: A boolean value indicating if there is an active emergency situation, such as a collision, detected by the mower.&lt;br /&gt;
            ▪ v_charge: A float32 value representing the charge voltage.&lt;br /&gt;
            ▪ v_battery: A float32 value representing the battery voltage.&lt;br /&gt;
            ▪ charge_current: A float32 value representing the charge current.&lt;br /&gt;
            ▪ left_esc_status: An ESCStatus object containing information about the status of the left ESC.&lt;br /&gt;
            ▪ right_esc_status: An ESCStatus object containing information about the status of the right ESC.&lt;br /&gt;
            ▪ mow_esc_status: An ESCStatus object containing information about the status of the mow ESC.&lt;br /&gt;
    2. wheel_tick_pub: Publishes the mower/wheel_ticks topic.&lt;br /&gt;
        ◦ Message Type: xbot_msgs::WheelTick&lt;br /&gt;
        ◦ Description: Publishes the wheel tick information for the left and right wheels of the mower, which is used to calculate odometry.&lt;br /&gt;
        ◦ Fields:&lt;br /&gt;
            ▪ header: Standard ROS message header containing a timestamp and frame_id.&lt;br /&gt;
            ▪ left_ticks: The number of ticks for the left wheel since the last message.&lt;br /&gt;
            ▪ right_ticks: The number of ticks for the right wheel since the last message.&lt;br /&gt;
            ▪ interval: The time interval in seconds between the current and previous wheel tick message.&lt;br /&gt;
    3. sensor_imu_pub: Publishes to the imu/data_raw topic.&lt;br /&gt;
        ◦ Message Type: sensor_msgs::Imu&lt;br /&gt;
        ◦ Description: Provides raw IMU data, including linear acceleration and angular velocity.&lt;br /&gt;
        ◦ Contents:&lt;br /&gt;
            ▪ header: Message header, containing timestamp and frame ID.&lt;br /&gt;
            ▪ orientation: Orientation as a quaternion (x, y, z, w).&lt;br /&gt;
            ▪ orientation_covariance: Orientation covariance matrix (3x3).&lt;br /&gt;
            ▪ angular_velocity: Angular velocity vector (x, y, z) in rad/s.&lt;br /&gt;
            ▪ angular_velocity_covariance: Angular velocity covariance matrix (3x3).&lt;br /&gt;
            ▪ linear_acceleration: Linear acceleration vector (x, y, z) in m/s^2.&lt;br /&gt;
            ▪ linear_acceleration_covariance: Linear acceleration covariance matrix (3x3).&lt;br /&gt;
    4. sensor_mag_pub: Publishes to the imu/mag topic.&lt;br /&gt;
        ◦ Message Type: sensor_msgs::MagneticField&lt;br /&gt;
        ◦ Description: Provides magnetic field data from the IMU.&lt;br /&gt;
        ◦ Contents:&lt;br /&gt;
            ▪ header: Message header, containing timestamp and frame ID.&lt;br /&gt;
            ▪ magnetic_field: Magnetic field vector (x, y, z) in Tesla.&lt;br /&gt;
            ▪ magnetic_field_covariance: Magnetic field covariance matrix (3x3).&lt;br /&gt;
Services:&lt;br /&gt;
    1. mow_service: Advertises the mower_service/mow_enabled service.&lt;br /&gt;
        ◦ Service Type: std_srvs::SetBool&lt;br /&gt;
        ◦ Description: Allows enabling or disabling the mower&#039;s mowing functionality.&lt;br /&gt;
        ◦ Request Fields:&lt;br /&gt;
            ▪ data: A boolean value representing the desired state of the mower&#039;s mowing functionality. True for enabling and False for disabling.&lt;br /&gt;
        ◦ Response Fields:&lt;br /&gt;
            ▪ success: A boolean value indicating if the requested operation was successful.&lt;br /&gt;
            ▪ message: A string providing additional information about the outcome of the operation.&lt;br /&gt;
    2. emergency_service: Advertises the mower_service/emergency service.&lt;br /&gt;
        ◦ Service Type: std_srvs::Trigger&lt;br /&gt;
        ◦ Description: Triggers an emergency stop for the mower.&lt;br /&gt;
        ◦ Request Fields: No fields required.&lt;br /&gt;
        ◦ Response Fields:&lt;br /&gt;
            ▪ success: A boolean value indicating if the emergency stop was successfully triggered.&lt;br /&gt;
            ▪ message: A string providing additional information about the outcome of the operation.&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower&amp;diff=479</id>
		<title>OpenMower</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower&amp;diff=479"/>
		<updated>2026-06-20T21:01:54Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[OpenMower OLD Baremetal installation]]&lt;br /&gt;
* [[OpenMower Crosscompiling]]&lt;br /&gt;
* [[OpenMower Simulation]]&lt;br /&gt;
* [[OpenMower Edit map]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Subscribers:&lt;br /&gt;
    1. cmd_vel_sub: Subscribes to the cmd_vel topic.&lt;br /&gt;
        ◦ Message Type: geometry_msgs::Twist&lt;br /&gt;
        ◦ Description: Contains the desired linear and angular velocities for the robot.&lt;br /&gt;
        ◦ Contents:&lt;br /&gt;
            ▪ linear.x: Linear velocity in the x-axis direction (m/s).&lt;br /&gt;
            ▪ linear.y: Linear velocity in the y-axis direction (m/s).&lt;br /&gt;
            ▪ linear.z: Linear velocity in the z-axis direction (m/s).&lt;br /&gt;
            ▪ angular.x: Angular velocity around the x-axis (rad/s).&lt;br /&gt;
            ▪ angular.y: Angular velocity around the y-axis (rad/s).&lt;br /&gt;
            ▪ angular.z: Angular velocity around the z-axis (rad/s).&lt;br /&gt;
    2. high_level_status_sub: Subscribes to the /mower_logic/current_state topic.&lt;br /&gt;
        ◦ Message Type: mower_msgs::HighLevelStatus&lt;br /&gt;
        ◦ Description: Receives the high-level state of the mower from the mower logic node. This state includes information about the current operating mode, substate, GPS quality, battery status, charging status, and emergency flag.&lt;br /&gt;
        ◦ Fields:&lt;br /&gt;
            ▪ state: An integer representing the current high-level state of the mower (e.g., idle, autonomous, recording, etc.).&lt;br /&gt;
            ▪ state_name: A string representing the name of the current high-level state (e.g., &amp;quot;IDLE&amp;quot;, &amp;quot;AUTONOMOUS&amp;quot;, &amp;quot;RECORDING&amp;quot;).&lt;br /&gt;
            ▪ sub_state_name: A string representing the name of the current substate (e.g., &amp;quot;SUBSTATE_1&amp;quot;, &amp;quot;SUBSTATE_2&amp;quot;, &amp;quot;SUBSTATE_3&amp;quot;, &amp;quot;SUBSTATE_4&amp;quot;).&lt;br /&gt;
            ▪ gps_quality_percent: A float32 value representing the GPS quality as a percentage, where 0% indicates no GPS signal and 100% indicates a perfect GPS signal.&lt;br /&gt;
            ▪ battery_percent: A float32 value representing the battery charge level as a percentage, where 0% indicates an empty battery and 100% indicates a fully charged battery.&lt;br /&gt;
            ▪ is_charging: A boolean value indicating whether the mower is currently charging or not.&lt;br /&gt;
            ▪ emergency: A boolean value indicating if there is an active emergency situation, such as a collision, detected by the mower.&lt;br /&gt;
        ◦ Callback Function: highLevelStatusReceived&lt;br /&gt;
            ▪ Description: Handles the received high-level state of the mower, updating the internal state representation for the mower communication node.&lt;br /&gt;
Publishers:&lt;br /&gt;
    1. status_pub: Publishes to the /mower/status topic.&lt;br /&gt;
        ◦ Message Type: mower_msgs::Status&lt;br /&gt;
        ◦ Description: Publishes the current status of the mower, including information about the mower&#039;s low-level systems, power status, ultrasonic range measurements, emergency status, battery, and ESC statuses.&lt;br /&gt;
        ◦ Fields:&lt;br /&gt;
            ▪ stamp: A time object representing the timestamp of the message.&lt;br /&gt;
            ▪ mower_status: An integer representing the mower&#039;s status, such as initializing or OK.&lt;br /&gt;
            ▪ raspberry_pi_power: A boolean value indicating if the Raspberry Pi has power.&lt;br /&gt;
            ▪ gps_power: A boolean value indicating if the GPS module has power.&lt;br /&gt;
            ▪ esc_power: A boolean value indicating if the Electronic Speed Controllers (ESCs) have power.&lt;br /&gt;
            ▪ rain_detected: A boolean value indicating if rain is detected.&lt;br /&gt;
            ▪ sound_module_available: A boolean value indicating if the sound module is available.&lt;br /&gt;
            ▪ sound_module_busy: A boolean value indicating if the sound module is busy.&lt;br /&gt;
            ▪ ui_board_available: A boolean value indicating if the UI board is available.&lt;br /&gt;
            ▪ ultrasonic_ranges: An array of 5 float32 values representing the ultrasonic range measurements.&lt;br /&gt;
            ▪ emergency: A boolean value indicating if there is an active emergency situation, such as a collision, detected by the mower.&lt;br /&gt;
            ▪ v_charge: A float32 value representing the charge voltage.&lt;br /&gt;
            ▪ v_battery: A float32 value representing the battery voltage.&lt;br /&gt;
            ▪ charge_current: A float32 value representing the charge current.&lt;br /&gt;
            ▪ left_esc_status: An ESCStatus object containing information about the status of the left ESC.&lt;br /&gt;
            ▪ right_esc_status: An ESCStatus object containing information about the status of the right ESC.&lt;br /&gt;
            ▪ mow_esc_status: An ESCStatus object containing information about the status of the mow ESC.&lt;br /&gt;
    2. wheel_tick_pub: Publishes the mower/wheel_ticks topic.&lt;br /&gt;
        ◦ Message Type: xbot_msgs::WheelTick&lt;br /&gt;
        ◦ Description: Publishes the wheel tick information for the left and right wheels of the mower, which is used to calculate odometry.&lt;br /&gt;
        ◦ Fields:&lt;br /&gt;
            ▪ header: Standard ROS message header containing a timestamp and frame_id.&lt;br /&gt;
            ▪ left_ticks: The number of ticks for the left wheel since the last message.&lt;br /&gt;
            ▪ right_ticks: The number of ticks for the right wheel since the last message.&lt;br /&gt;
            ▪ interval: The time interval in seconds between the current and previous wheel tick message.&lt;br /&gt;
    3. sensor_imu_pub: Publishes to the imu/data_raw topic.&lt;br /&gt;
        ◦ Message Type: sensor_msgs::Imu&lt;br /&gt;
        ◦ Description: Provides raw IMU data, including linear acceleration and angular velocity.&lt;br /&gt;
        ◦ Contents:&lt;br /&gt;
            ▪ header: Message header, containing timestamp and frame ID.&lt;br /&gt;
            ▪ orientation: Orientation as a quaternion (x, y, z, w).&lt;br /&gt;
            ▪ orientation_covariance: Orientation covariance matrix (3x3).&lt;br /&gt;
            ▪ angular_velocity: Angular velocity vector (x, y, z) in rad/s.&lt;br /&gt;
            ▪ angular_velocity_covariance: Angular velocity covariance matrix (3x3).&lt;br /&gt;
            ▪ linear_acceleration: Linear acceleration vector (x, y, z) in m/s^2.&lt;br /&gt;
            ▪ linear_acceleration_covariance: Linear acceleration covariance matrix (3x3).&lt;br /&gt;
    4. sensor_mag_pub: Publishes to the imu/mag topic.&lt;br /&gt;
        ◦ Message Type: sensor_msgs::MagneticField&lt;br /&gt;
        ◦ Description: Provides magnetic field data from the IMU.&lt;br /&gt;
        ◦ Contents:&lt;br /&gt;
            ▪ header: Message header, containing timestamp and frame ID.&lt;br /&gt;
            ▪ magnetic_field: Magnetic field vector (x, y, z) in Tesla.&lt;br /&gt;
            ▪ magnetic_field_covariance: Magnetic field covariance matrix (3x3).&lt;br /&gt;
Services:&lt;br /&gt;
    1. mow_service: Advertises the mower_service/mow_enabled service.&lt;br /&gt;
        ◦ Service Type: std_srvs::SetBool&lt;br /&gt;
        ◦ Description: Allows enabling or disabling the mower&#039;s mowing functionality.&lt;br /&gt;
        ◦ Request Fields:&lt;br /&gt;
            ▪ data: A boolean value representing the desired state of the mower&#039;s mowing functionality. True for enabling and False for disabling.&lt;br /&gt;
        ◦ Response Fields:&lt;br /&gt;
            ▪ success: A boolean value indicating if the requested operation was successful.&lt;br /&gt;
            ▪ message: A string providing additional information about the outcome of the operation.&lt;br /&gt;
    2. emergency_service: Advertises the mower_service/emergency service.&lt;br /&gt;
        ◦ Service Type: std_srvs::Trigger&lt;br /&gt;
        ◦ Description: Triggers an emergency stop for the mower.&lt;br /&gt;
        ◦ Request Fields: No fields required.&lt;br /&gt;
        ◦ Response Fields:&lt;br /&gt;
            ▪ success: A boolean value indicating if the emergency stop was successfully triggered.&lt;br /&gt;
            ▪ message: A string providing additional information about the outcome of the operation.&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Development&amp;diff=478</id>
		<title>Development</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Development&amp;diff=478"/>
		<updated>2026-06-20T21:01:48Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[OpenMower]]&lt;br /&gt;
&lt;br /&gt;
* https://twitter.com/perborgen/status/1580930648797483010 CSS Grid&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_Simulation&amp;diff=477</id>
		<title>OpenMower Simulation</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_Simulation&amp;diff=477"/>
		<updated>2026-06-20T21:01:39Z</updated>

		<summary type="html">&lt;p&gt;Damme: Created page with &amp;quot;== Introduction == You can test the OpenMower software stack yourself by running a simulation where you can record a map and then have it mowed in a simulation on-screen.   It&amp;#039;s a bit rough around the edges, but it&amp;#039;s a good way to see the software in action without hardware.  This mini-HOWTO is meant to save you a bit of detective work and get you started, not to be a comprehensive guide to the simulation.  == Prerequisites == You need the OpenMower software &amp;#039;&amp;#039;&amp;#039;on a plat...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
You can test the OpenMower software stack yourself by running a simulation where you can record a map and then have it mowed in a simulation on-screen. &lt;br /&gt;
&lt;br /&gt;
It&#039;s a bit rough around the edges, but it&#039;s a good way to see the software in action without hardware.&lt;br /&gt;
&lt;br /&gt;
This mini-HOWTO is meant to save you a bit of detective work and get you started, not to be a comprehensive guide to the simulation.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
You need the OpenMower software &#039;&#039;&#039;on a platform that has ROS and a graphical interface&#039;&#039;&#039; for rviz to be able to run and show the map. Ubuntu 20 on a desktop is a good choice, possibly on VM, VirtualBox is an excellent choice, if you do not already have a running Ubuntu 20 desktop environment.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Install ROS on Ubuntu&#039;&#039;&#039;: http://wiki.ros.org/noetic/Installation/Ubuntu - use the full install&lt;br /&gt;
** Note: make sure that you have the ROS environment set up in your terminal by &amp;lt;code&amp;gt;echo &amp;quot;source /opt/ros/noetic/setup.bash&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&amp;lt;/code&amp;gt;  and log out and back in.&lt;br /&gt;
* &#039;&#039;&#039;Install the OpenMower software:&#039;&#039;&#039; Use the instructions here: [[Setting up ROS on a Raspberry Pi (intended to be the Rover -- OpenMower)]]&lt;br /&gt;
** Make sure that you have had &amp;lt;code&amp;gt;catkin_make&amp;lt;/code&amp;gt; succeed (may take a few tries, often 4 or more)&lt;br /&gt;
&lt;br /&gt;
You need to have a game controller for controlling the simulated bot.&lt;br /&gt;
&lt;br /&gt;
== Making sure the OpenMower environment is sourced ==&lt;br /&gt;
&#039;&#039;Whenever you are doing anything in a terminal with OpenMower&#039;&#039;, you need to make sure that ROS knows your OpenMower workspace.&lt;br /&gt;
&lt;br /&gt;
In every terminal that you use: &amp;lt;code&amp;gt;source ~/OpenMower/ROS/devel/setup.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Running the simulation ==&lt;br /&gt;
&lt;br /&gt;
=== Recording a map ===&lt;br /&gt;
[[File:VirtualBox enable USB.png|thumb|Enable USB ports on VirtualBox]]&lt;br /&gt;
Attach your joystick to a USB port. If you are on a VirtualBox, make sure that the USB port of your joystick / gamepad is mapped into your Ubuntu environment (see illustration).&lt;br /&gt;
&lt;br /&gt;
Open a terminal and execute&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;roslaunch ~/OpenMower/ROS/src/open_mower_ros/open_mower/launch/sim_mower_logic.launch&amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:Simulation running.png|thumb|OpenMower simulation running]]&lt;br /&gt;
This will launch rviz where you can see the Rover and the map.&lt;br /&gt;
&lt;br /&gt;
Use your joystick to record a map and a base. On my gamepad, the buttons are&lt;br /&gt;
&lt;br /&gt;
* 1 - enable movement&lt;br /&gt;
* 2 - start path recording&lt;br /&gt;
* 4 + ↓ - end path recording&lt;br /&gt;
* 3 - register base&lt;br /&gt;
&lt;br /&gt;
Then exit rviz and the map will be recorded in &amp;lt;code&amp;gt;~/.ros/map.bag&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to record a new map, delete the old one, &amp;lt;code&amp;gt;rm ~/.ros/map.bag&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Running the simulation ===&lt;br /&gt;
&amp;lt;code&amp;gt;roslaunch ~/OpenMower/ROS/src/open_mower_ros/open_mower/launch/sim_mower_logic.launch&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will launch rviz with the map and rqt_reconfigure where you can control various parameters of the simulation.&lt;br /&gt;
&lt;br /&gt;
You will need to press &amp;lt;code&amp;gt;manual_start_mowing&amp;lt;/code&amp;gt; in rqt_reconfigure to start the simulation. You will probably need to zoom out, find your area and then zoom in again on that in rviz.&lt;br /&gt;
&lt;br /&gt;
== Diagnostics / debugging / issues ==&lt;br /&gt;
&lt;br /&gt;
=== Joystick ===&lt;br /&gt;
[[File:Which joystick to use.png|thumb|Which joystick to use]]&lt;br /&gt;
Your joystick needs to be transmitting messages on the topic /joy. To test that it does:&lt;br /&gt;
&lt;br /&gt;
* Run &amp;lt;code&amp;gt;roslaunch ~/OpenMower/ROS/src/open_mower_ros/open_mower/launch/sim_record_area.launch&amp;lt;/code&amp;gt;&lt;br /&gt;
* In a new terminal run &amp;lt;code&amp;gt;rostopic echo /joy&amp;lt;/code&amp;gt;&lt;br /&gt;
You should see messages from the joystick streaming on screen. Test that pressing buttons etc. is reflected in the messages.&lt;br /&gt;
&lt;br /&gt;
If not:&lt;br /&gt;
&lt;br /&gt;
* Check which joysticks your Ubuntu installation knows: &amp;lt;code&amp;gt;ls -l /dev/input/js*&amp;lt;/code&amp;gt;&lt;br /&gt;
* Try to add/adjust which joystick the recorder uses in sim_record_area.launch to use the correct joystick, see illustration here.&lt;br /&gt;
&lt;br /&gt;
===Buttons===&lt;br /&gt;
The control buttons can be edited here:&lt;br /&gt;
*movement activation button&lt;br /&gt;
**File: &amp;lt;code&amp;gt;~/OpenMower/ROS/src/open_mower_ros/open_mower/launch/sim_record_area.launch&amp;lt;/code&amp;gt;&lt;br /&gt;
**Line 17: &amp;lt;code&amp;gt;&amp;lt;param name=&amp;quot;~enable_turbo_button&amp;quot; value=&amp;quot;4&amp;quot;/&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
*area and base recording buttons&lt;br /&gt;
**File: &amp;lt;code&amp;gt;~/OpenMower/ROS/src/open_mower_ros/mower_area_recorder/src/area_recorder.cpp&amp;lt;/code&amp;gt;&lt;br /&gt;
**Lines 61 ff.&lt;br /&gt;
&lt;br /&gt;
==Additional notes / info==&lt;br /&gt;
&lt;br /&gt;
===rviz and OpenMower on different machines ===&lt;br /&gt;
This is all running on one platform - the OpenMower simulation AND the graphical interface, hence the choice of desktop to have a graphical environment. In the real situation, the Rover with the OpenMower software is running on a headless Pi. If you still want to have the ability to see paths and maps (which is possible) in rviz, you need to do that on a separate desktop environment. That is possible. You can use the environment that you set up here, but the Rover and on the Desktop must be on the same network and need a little setup in your &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt; to see each other as being part of the same ROS installation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;On Rover, in &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export ROS_HOSTNAME=192.168.1.126 # replace with your ip for your Rover&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export ROS_MASTER_URI=&amp;lt;nowiki&amp;gt;http://192.168.1.126:11311&amp;lt;/nowiki&amp;gt; # same as above&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;On Desktop, in &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export ROS_HOSTNAME=192.168.1.123 # replace with your ip for your Desktop environment&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export ROS_MASTER_URI=&amp;lt;nowiki&amp;gt;http://192.168.1.126:11311&amp;lt;/nowiki&amp;gt; # eplace with your ip for your Rover&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Note on network visibility and guests on VirtualBox====&lt;br /&gt;
To make your Ubuntu installation running as guest in VirtualBox be able to have an externally accessible ip number and be able to talk to the Rover, you must&lt;br /&gt;
&lt;br /&gt;
#use a cabled network (not Wifi!!) to your computer that acts as host for VirtualBox and your Ubuntu guest OS&lt;br /&gt;
#use a &amp;lt;code&amp;gt;Bridged Adaptor&amp;lt;/code&amp;gt; to the cabled interface for the network setup in VirtualBox for your Ubuntu host.&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Development&amp;diff=476</id>
		<title>Development</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Development&amp;diff=476"/>
		<updated>2026-06-20T21:01:36Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[OpenMower]]&lt;br /&gt;
* [[OpenMower OLD Baremetal installation]]&lt;br /&gt;
* [[OpenMower Crosscompiling]]&lt;br /&gt;
* [[OpenMower Simulation]]&lt;br /&gt;
* [[OpenMower Edit map]]&lt;br /&gt;
* https://twitter.com/perborgen/status/1580930648797483010 CSS Grid&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_Edit_map&amp;diff=475</id>
		<title>OpenMower Edit map</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_Edit_map&amp;diff=475"/>
		<updated>2026-06-20T20:59:51Z</updated>

		<summary type="html">&lt;p&gt;Damme: Created page with &amp;quot;=== Introduction === This tutorial shows how to use an orthophoto (generated by taking aerial pictures with a drone) and modify the open mower map. In my case I recorded the boundary of my lawn area driving the mower around and later divided the area and added obstacles using the drone footage.  openmower map boundary with orthophoto layer   === Generate an orthophoto === I took about 50 pictures with a drone ca....&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Introduction ===&lt;br /&gt;
This tutorial shows how to use an orthophoto (generated by taking aerial pictures with a drone) and modify the open mower map. In my case I recorded the boundary of my lawn area driving the mower around and later divided the area and added obstacles using the drone footage.&lt;br /&gt;
&lt;br /&gt;
[[File:Openmower map boundary orthophoto.png|none|thumb|openmower map boundary with orthophoto layer]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Generate an orthophoto ===&lt;br /&gt;
I took about 50 pictures with a drone ca. 10m above ground and generated an orthophoto using OpenDroneMap WebODM&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can read about the process here: https://docs.opendronemap.org/tutorials/&lt;br /&gt;
&lt;br /&gt;
OpenDroneMap WebODM runs in a docker container and can be found here: https://www.opendronemap.org/webodm/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can export an orthophoto .tif format there&lt;br /&gt;
&lt;br /&gt;
=== convert map.bag into GPX ===&lt;br /&gt;
Obviously back up your map.bag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I wrote a python script to convert the map area coordinates into utm coordinates. I ran this on the robots raspberry pi. In reads the map.bag from .ros folder and exports a .gpx format file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Following python packages are needed&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip install utm gpxpy&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You need to &amp;lt;code&amp;gt;source /opt/ros/noetic/setup.bash&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Modify the base point coodinates in the script. I use the roof mouned RTK GPS antenna as base coordinates.&lt;br /&gt;
&lt;br /&gt;
Modify the input and output file paths to your needs and run the python script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create a file wit following content: &amp;lt;code&amp;gt;bag_to_gpx_tracks_utm.py&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod +x bag_to_gpx_tracks_utm.py&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
#===========================================&lt;br /&gt;
# Christoph Sobel 11.05.2023&lt;br /&gt;
# script to convert openmower ros map.bag to gpx file&lt;br /&gt;
#===========================================&lt;br /&gt;
&lt;br /&gt;
from codecs import latin_1_decode&lt;br /&gt;
import rosbag&lt;br /&gt;
import utm&lt;br /&gt;
import gpxpy.gpx&lt;br /&gt;
import math&lt;br /&gt;
import os&lt;br /&gt;
from tf.transformations import euler_from_quaternion&lt;br /&gt;
&lt;br /&gt;
bag = rosbag.Bag(&#039;/home/pi/.ros/map.bag&#039;)&lt;br /&gt;
# bag = rosbag.Bag(&#039;output.bag&#039;)&lt;br /&gt;
&lt;br /&gt;
lat0 = 53.00&lt;br /&gt;
lon0 = 8.00&lt;br /&gt;
# lat0 = float(os.getenv(&#039;OM_DATUM_LAT&#039;))&lt;br /&gt;
# lon0 = float(os.getenv(&#039;OM_DATUM_LONG&#039;))&lt;br /&gt;
print(&amp;quot;base_point&amp;quot;, lat0, &amp;quot; &amp;quot;, lon0)&lt;br /&gt;
&lt;br /&gt;
topics = bag.get_type_and_topic_info()[1].keys()&lt;br /&gt;
print(topics)&lt;br /&gt;
&lt;br /&gt;
gpx = gpxpy.gpx.GPX()&lt;br /&gt;
gpx.name = &#039;open_mower_map&#039;&lt;br /&gt;
gpx.description = &#039;Map data from openmower map.bag&#039;&lt;br /&gt;
&lt;br /&gt;
# base point (e.g. gps antenna)&lt;br /&gt;
# base_point = gpxpy.gpx.GPXWaypoint(latitude=lat0, longitude=lon0, name=&amp;quot;base_point&amp;quot;)&lt;br /&gt;
# gpx.waypoints.append(base_point)&lt;br /&gt;
&lt;br /&gt;
x0, y0, zone, ut = utm.from_latlon(lat0, lon0)&lt;br /&gt;
print(&amp;quot;base_point in utm&amp;quot;, x0, &amp;quot; &amp;quot;, y0)&lt;br /&gt;
&lt;br /&gt;
gpx_track = gpxpy.gpx.GPXTrack(name=&amp;quot;base_point&amp;quot;)&lt;br /&gt;
gpx.tracks.append(gpx_track)&lt;br /&gt;
gpx_segment = gpxpy.gpx.GPXTrackSegment()&lt;br /&gt;
gpx_track.segments.append(gpx_segment)&lt;br /&gt;
gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(lat0, lon0, elevation=0))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Loop through areas and obstacles&lt;br /&gt;
area_counter = 0&lt;br /&gt;
&lt;br /&gt;
for area_type in [&#039;mowing_areas&#039;, &#039;navigation_areas&#039;]:&lt;br /&gt;
    for topic, msg, t in bag.read_messages(topics=[area_type]):&lt;br /&gt;
        print(&amp;quot;{}_{}_area&amp;quot;.format(area_type[:-1], area_counter))&lt;br /&gt;
        # Create track in GPX:&lt;br /&gt;
        gpx_track = gpxpy.gpx.GPXTrack(name=&amp;quot;{}_{}_area&amp;quot;.format(area_type[:-1], area_counter))&lt;br /&gt;
        gpx.tracks.append(gpx_track)&lt;br /&gt;
        # Create segment in GPX track:&lt;br /&gt;
        gpx_segment = gpxpy.gpx.GPXTrackSegment()&lt;br /&gt;
        gpx_track.segments.append(gpx_segment)&lt;br /&gt;
&lt;br /&gt;
        # outline&lt;br /&gt;
        for point in msg.area.points:&lt;br /&gt;
            # Create points:&lt;br /&gt;
            lat, lon = utm.to_latlon(x0 + point.x, y0 + point.y, zone, ut)&lt;br /&gt;
            gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(lat, lon, elevation=0))&lt;br /&gt;
&lt;br /&gt;
        # obstacles&lt;br /&gt;
        obstacle_counter = 0&lt;br /&gt;
        for obst in msg.obstacles:&lt;br /&gt;
            print(&amp;quot;{}_{}_obstacle_{}&amp;quot;.format(area_type[:-1], area_counter, obstacle_counter))&lt;br /&gt;
            # Create track in GPX:&lt;br /&gt;
            gpx_track = gpxpy.gpx.GPXTrack(name=&amp;quot;{}_{}_obstacle_{}&amp;quot;.format(area_type[:-1], area_counter, obstacle_counter))&lt;br /&gt;
            gpx.tracks.append(gpx_track)&lt;br /&gt;
            # Create segment in GPX track:&lt;br /&gt;
            gpx_segment = gpxpy.gpx.GPXTrackSegment()&lt;br /&gt;
            gpx_track.segments.append(gpx_segment)&lt;br /&gt;
            for point in obst.points:&lt;br /&gt;
                # Create points:&lt;br /&gt;
                lat, lon = utm.to_latlon(x0 + point.x, y0 + point.y, zone, ut)&lt;br /&gt;
                gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(lat, lon, elevation=0))&lt;br /&gt;
            obstacle_counter += 1&lt;br /&gt;
        area_counter += 1&lt;br /&gt;
&lt;br /&gt;
# docking point&lt;br /&gt;
for topic, msg, t in bag.read_messages(topics=[&#039;docking_point&#039;]):&lt;br /&gt;
    # print(msg)&lt;br /&gt;
    print(&amp;quot;parsing docking point&amp;quot;)&lt;br /&gt;
    quat_list = [msg.orientation.x, msg.orientation.y, msg.orientation.z, msg.orientation.w]&lt;br /&gt;
    (roll, pitch, yaw) = euler_from_quaternion(quat_list)&lt;br /&gt;
    # print((roll, pitch, yaw))&lt;br /&gt;
    x2 = msg.position.x + math.cos(yaw)&lt;br /&gt;
    y2 = msg.position.y + math.sin(yaw)&lt;br /&gt;
&lt;br /&gt;
    lat1, lon1 = utm.to_latlon(x0 + msg.position.x, y0 + msg.position.y, zone, ut)&lt;br /&gt;
    lat2, lon2 = utm.to_latlon(x0 + x2,y0 + y2, zone, ut)&lt;br /&gt;
&lt;br /&gt;
    gpx_track = gpxpy.gpx.GPXTrack(name=&amp;quot;docking_point&amp;quot;)&lt;br /&gt;
    gpx.tracks.append(gpx_track)&lt;br /&gt;
    gpx_segment = gpxpy.gpx.GPXTrackSegment()&lt;br /&gt;
    gpx_track.segments.append(gpx_segment)&lt;br /&gt;
    gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(lat1, lon1, elevation=0))&lt;br /&gt;
    gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(lat2, lon2, elevation=0))&lt;br /&gt;
&lt;br /&gt;
print(&#039;Created GPX file&#039;)&lt;br /&gt;
with open(&amp;quot;map_bag.gpx&amp;quot;, &amp;quot;w&amp;quot;) as f:&lt;br /&gt;
    f.write(gpx.to_xml())&lt;br /&gt;
&lt;br /&gt;
bag.close()&lt;br /&gt;
print(&#039;Done&#039;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== load GPX file into JOSM ===&lt;br /&gt;
Install the Java OpenStreetMap Editor from:&lt;br /&gt;
&lt;br /&gt;
https://josm.openstreetmap.de/wiki/Download&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start JOSM and install the PicLayer Plugin. For this go to &#039;&#039;Edit-&amp;gt;Preferences-&amp;gt;Plugins&#039;&#039; and search for PicLayer and tick the checkbox.&lt;br /&gt;
&lt;br /&gt;
Open your .gpx file, you shoud see the recorded boundaries&lt;br /&gt;
[[File:JOSM imported GPX file.png|none|thumb|Boundaries visible in JOSM from imported GPX file]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Right click on the Layer output.gpx and select &amp;quot;convert to data layer&amp;quot;. Proceed without simplifying. Now every node should be visible.&lt;br /&gt;
&lt;br /&gt;
=== overlay and align with an orthophoto ===&lt;br /&gt;
&lt;br /&gt;
* select &#039;&#039;Imagery-&amp;gt;More...-&amp;gt;New picture layer from file...&#039;&#039; and open your orthophoto .tif file&lt;br /&gt;
* you can now use the PicLayer tools from the toolbar to align you image layer. When all is aligned, right click on the picture layer and save the picture calibration for later use.&lt;br /&gt;
[[File:JOSM with orthophoto.png|none|thumb|mowing area boundaries in JOSM with orthophoto]]&lt;br /&gt;
&lt;br /&gt;
=== modify the boundaries ===&lt;br /&gt;
you can now add/remove/modify/merge/divide:&lt;br /&gt;
&lt;br /&gt;
* mowing or navigation areas&lt;br /&gt;
* obstacles&lt;br /&gt;
* docking point&lt;br /&gt;
&lt;br /&gt;
Using all the nice tools from JOSM.&lt;br /&gt;
&lt;br /&gt;
Following rules for this:&lt;br /&gt;
&lt;br /&gt;
* mowing and navigation areas need to be in counter clockwise direction&lt;br /&gt;
* obstacles need to be in clockwise direction&lt;br /&gt;
&lt;br /&gt;
definition of the feature is in the value of gpx:name tag of each way like this:&lt;br /&gt;
&lt;br /&gt;
* mowing_area_0_area&lt;br /&gt;
* mowing_area_0_obstacle_0&lt;br /&gt;
*mowing_area_0_obstacle_1&lt;br /&gt;
* mowing_area_1_area&lt;br /&gt;
* navigation_area_0_area&lt;br /&gt;
*navigation_area_1_area&lt;br /&gt;
*navigation_area_1_obstacle_0&lt;br /&gt;
* docking_point&lt;br /&gt;
[[File:JOSM gpsname tag information.png|none|thumb|area boundary JOSM gps:name tag information]]&lt;br /&gt;
Here you can see an added obstacle.&lt;br /&gt;
&lt;br /&gt;
=== export as GPX and convert back to openmower map.bag ===&lt;br /&gt;
Right click on the gpx layer and &amp;quot;save as&amp;quot;. Select gpx format.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;source /opt/ros/noetic/setup.bash&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to &amp;lt;code&amp;gt;source ./devel/setup.bash&amp;lt;/code&amp;gt; in your &amp;lt;code&amp;gt;open_mower_ros&amp;lt;/code&amp;gt; folder to get the MapArea custom ros message&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Modify the base point coordinates in the script. I use the roof mounted RTK GPS antenna as base coordinates.&lt;br /&gt;
&lt;br /&gt;
Modify the input and output file paths to your needs in the python script.&lt;br /&gt;
&lt;br /&gt;
Run following python script and put the output_map.bag where your ros.bag was.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create a file wit following content: &amp;lt;code&amp;gt;gpx_to_bag.py&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod +x gpx_to_bag.py&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
#===========================================&lt;br /&gt;
# Christoph Sobel 11.05.2023&lt;br /&gt;
# script to convert gpx files to openmower ros map.bag&lt;br /&gt;
#===========================================&lt;br /&gt;
&lt;br /&gt;
import gpxpy.gpx&lt;br /&gt;
import utm&lt;br /&gt;
import rosbag&lt;br /&gt;
import math&lt;br /&gt;
from geometry_msgs.msg import Polygon, Point32, Pose&lt;br /&gt;
from mower_map.msg import MapArea  # Imports the custom message from its package&lt;br /&gt;
from tf.transformations import quaternion_from_euler&lt;br /&gt;
&lt;br /&gt;
# Base point&lt;br /&gt;
lat0 = 53.00&lt;br /&gt;
lon0 = 8.00&lt;br /&gt;
# lat0 = float(os.getenv(&#039;OM_DATUM_LAT&#039;))&lt;br /&gt;
# lon0 = float(os.getenv(&#039;OM_DATUM_LONG&#039;))&lt;br /&gt;
print(&amp;quot;base_point&amp;quot;, lat0, &amp;quot; &amp;quot;, lon0)&lt;br /&gt;
x0, y0, zone, ut = utm.from_latlon(lat0, lon0)&lt;br /&gt;
print(&amp;quot;base_point in utm&amp;quot;, x0, &amp;quot; &amp;quot;, y0)&lt;br /&gt;
&lt;br /&gt;
gpx_file = open(&#039;map_bag_osm.gpx&#039;, &#039;r&#039;)&lt;br /&gt;
gpx = gpxpy.parse(gpx_file)&lt;br /&gt;
&lt;br /&gt;
mowing_area_dict = {}&lt;br /&gt;
navigation_area_dict = {}&lt;br /&gt;
base_point = []&lt;br /&gt;
docking_points = []&lt;br /&gt;
&lt;br /&gt;
for track in gpx.tracks:&lt;br /&gt;
	print(&amp;quot;reading from gpx: &amp;quot;, track.name)&lt;br /&gt;
	# get points&lt;br /&gt;
	point_list = []&lt;br /&gt;
	for segment in track.segments:&lt;br /&gt;
		print(&amp;quot;Point count:{}&amp;quot;.format(len(segment.points)))&lt;br /&gt;
		for point in segment.points:&lt;br /&gt;
			# print(f&#039;Point at ({point.latitude},{point.longitude}) -&amp;gt; {point.elevation}&#039;)&lt;br /&gt;
			x, y, zone, ut = utm.from_latlon(point.latitude, point.longitude)&lt;br /&gt;
			point_list.append(Point32(x=x-x0, y=y-y0, z=0.0))&lt;br /&gt;
	# store in deciated dict&lt;br /&gt;
	if &amp;quot;mowing&amp;quot; in track.name:&lt;br /&gt;
		mowing_area_dict[track.name] = point_list&lt;br /&gt;
	elif &amp;quot;navigation&amp;quot; in track.name:&lt;br /&gt;
		navigation_area_dict[track.name] = point_list&lt;br /&gt;
	elif &amp;quot;base&amp;quot; in track.name:&lt;br /&gt;
		base_point = point_list&lt;br /&gt;
	elif &amp;quot;docking&amp;quot; in track.name:&lt;br /&gt;
		docking_points  = point_list&lt;br /&gt;
&lt;br /&gt;
docking_pose = Pose()&lt;br /&gt;
if len(docking_points) == 2:&lt;br /&gt;
	yaw = math.atan2(docking_points[1].y - docking_points[0].y, docking_points[1].x - docking_points[0].x)&lt;br /&gt;
	quaternion = quaternion_from_euler(0,0,yaw)&lt;br /&gt;
	&lt;br /&gt;
	docking_pose.position.x = docking_points[0].x&lt;br /&gt;
	docking_pose.position.y = docking_points[0].y&lt;br /&gt;
	# Pose Orientation&lt;br /&gt;
	docking_pose.orientation.x = quaternion[0]&lt;br /&gt;
	docking_pose.orientation.y = quaternion[1]&lt;br /&gt;
	docking_pose.orientation.z = quaternion[2]&lt;br /&gt;
	docking_pose.orientation.w = quaternion[3]&lt;br /&gt;
		&lt;br /&gt;
&lt;br /&gt;
def sort_dict_return_MapAreas(area_dict):&lt;br /&gt;
	areas = {}&lt;br /&gt;
	for track_name, point_list in sorted(area_dict.items()): # store sorted polygons to MapArea&lt;br /&gt;
		map_area = MapArea()&lt;br /&gt;
		print(&amp;quot;converting:&amp;quot;, track_name)&lt;br /&gt;
		area_number = track_name.split(&amp;quot;_&amp;quot;)[2]&lt;br /&gt;
		poly = Polygon(points=point_list)&lt;br /&gt;
		if &amp;quot;area&amp;quot; in track_name[-4:]:&lt;br /&gt;
			map_area.area = poly&lt;br /&gt;
			areas[area_number] = map_area&lt;br /&gt;
		elif &amp;quot;obstacle&amp;quot; in track_name:&lt;br /&gt;
			map_area = areas[area_number]&lt;br /&gt;
			map_area.obstacles.append(poly)&lt;br /&gt;
			areas[area_number] = map_area&lt;br /&gt;
	return areas&lt;br /&gt;
&lt;br /&gt;
mowing_areas_list = sort_dict_return_MapAreas(mowing_area_dict).values()&lt;br /&gt;
navigation_areas_list = sort_dict_return_MapAreas(navigation_area_dict).values()&lt;br /&gt;
&lt;br /&gt;
with rosbag.Bag(&#039;output_map.bag&#039;, &#039;w&#039;) as outbag:&lt;br /&gt;
	print(&#039;writing bag file&#039;)&lt;br /&gt;
	for mowing_area in mowing_areas_list:&lt;br /&gt;
		outbag.write(&amp;quot;mowing_areas&amp;quot;, mowing_area)&lt;br /&gt;
	for navigation_area in navigation_areas_list:	&lt;br /&gt;
		outbag.write(&amp;quot;navigation_areas&amp;quot;, navigation_area)&lt;br /&gt;
	outbag.write(&amp;quot;docking_point&amp;quot;, docking_pose)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Development&amp;diff=474</id>
		<title>Development</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Development&amp;diff=474"/>
		<updated>2026-06-20T20:59:46Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[OpenMower]]&lt;br /&gt;
* [[OpenMower OLD Baremetal installation]]&lt;br /&gt;
* [[OpenMower Crosscompiling]]&lt;br /&gt;
* [[OpenMower Edit map]]&lt;br /&gt;
* https://twitter.com/perborgen/status/1580930648797483010 CSS Grid&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Development&amp;diff=473</id>
		<title>Development</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Development&amp;diff=473"/>
		<updated>2026-06-20T20:53:22Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[OpenMower]]&lt;br /&gt;
* [[OpenMower OLD Baremetal installation]]&lt;br /&gt;
* [[OpenMower Crosscompiling]]&lt;br /&gt;
* https://twitter.com/perborgen/status/1580930648797483010 CSS Grid&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_OLD_Barmetal_installation&amp;diff=472</id>
		<title>OpenMower OLD Barmetal installation</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_OLD_Barmetal_installation&amp;diff=472"/>
		<updated>2026-06-20T20:53:04Z</updated>

		<summary type="html">&lt;p&gt;Damme: Damme moved page OpenMower OLD Barmetal installation to OpenMower OLD Baremetal installation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[OpenMower OLD Baremetal installation]]&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_OLD_Baremetal_installation&amp;diff=471</id>
		<title>OpenMower OLD Baremetal installation</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_OLD_Baremetal_installation&amp;diff=471"/>
		<updated>2026-06-20T20:53:04Z</updated>

		<summary type="html">&lt;p&gt;Damme: Damme moved page OpenMower OLD Barmetal installation to OpenMower OLD Baremetal installation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will guide you through the steps to install a basic system image.&lt;br /&gt;
&lt;br /&gt;
On this image you will have the ROS base system, the OpenMower installation, local configuration for your mower and some tools to help you work with the mower.&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
In order to follow this guide, you will need the following:&lt;br /&gt;
&lt;br /&gt;
#A Raspberry Pi 4 (4GB or more recommended, [[System Image#Enable Swap (optional, needed for Pi with &amp;lt;= 2GB RAM)|2GB works with swap, see here]])&lt;br /&gt;
#An SD card&lt;br /&gt;
#A soldered OpenMower mainboard&lt;br /&gt;
&lt;br /&gt;
==Installing the Base System==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;There is also a YouTube video explaining the steps in this section:&#039;&#039;&#039; https://youtu.be/_bImqD-pQSA?t=562&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Flashing Ubuntu to SD Card ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first step is to install the base system. We&#039;re using Ubuntu 20.04 Server for the Raspberry Pi. This is, because this image gives us best support ROS Noetic.&lt;br /&gt;
&lt;br /&gt;
Installing the base image is easy:&lt;br /&gt;
&lt;br /&gt;
#[https://www.raspberrypi.com/software/ Get the Raspberry Pi Imager software]&lt;br /&gt;
#Select the correct operating system:  &#039;&#039;Other-general-purpose OS &amp;gt; Ubuntu &amp;gt; Ubuntu Server 20.04.4 LTS (RPI 3/4/400) 64-bit&#039;&#039;&lt;br /&gt;
#Insert your SD card into your PC and select it in the &#039;&#039;Storage&#039;&#039; part of the software&lt;br /&gt;
#Click &#039;&#039;write&#039;&#039; and wait for the process to finish&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you have successfully flashed your image, remove the SD for your PC &#039;&#039;&#039;and reinsert it again.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Then replace the &amp;lt;code&amp;gt;/boot/config.txt&amp;lt;/code&amp;gt; file with the one provided here: [https://github.com/ClemensElflein/OpenMower/blob/main/configs/RaspberryPiConfig/config.txt]&lt;br /&gt;
&lt;br /&gt;
This will enable all hardware serial ports on the Raspberry Pi.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can theoretically configure networking in this step as well, but I&#039;m not recommending it. This is, because the networking information file gets only copied once and if you have an error it won&#039;t work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;We need an interactive terminal in the next step anyways.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you have done this step, you can eject the SD card and plug it into your Raspberry Pi 4.&lt;br /&gt;
&lt;br /&gt;
=== Opening a Serial Terminal ===&lt;br /&gt;
[[File:SerialRedirect.png|thumb|Serial Terminal: minicom -D /dev/ttyACM0]]&lt;br /&gt;
This step is needed for the following sections. The goal is to have a serial terminal to do basic config (networking etc) easily.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The easiest way of doing so is:&lt;br /&gt;
# Flash the SerialRedirect firmware into your Pico. Get it here: https://github.com/ClemensElflein/OpenMower/tree/main/Firmware/SerialRedirect/bin&lt;br /&gt;
# Provide your mainboard with power&lt;br /&gt;
# Plug your Pico into a computer. A virtual COM port should appear&lt;br /&gt;
# Connect to the COM port (I&#039;m using minicom, see image on the right), then press enter to start the Raspberry Pi.&lt;br /&gt;
#The Pi boots and a serial terminal will appear.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you can login with the default credentials:&lt;br /&gt;
&lt;br /&gt;
username: &amp;lt;code&amp;gt;ubuntu&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
password: &amp;lt;code&amp;gt;ubuntu&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that you will need to change the password immediately.&lt;br /&gt;
&lt;br /&gt;
=== Disable Boot Interrupt ===&lt;br /&gt;
[[File:Image.png|thumb|Commands needed to disable boot interrupt on serial input.]]&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi boot loader will interrupt the boot sequence if data is sent through the main serial port of the Raspberry Pi. Since we&#039;re connecting &amp;quot;nosiy&amp;quot; hardware to the port, this will always interrupt the boot sequence and we need to disable this feature. &lt;br /&gt;
&lt;br /&gt;
In order to do this, reboot the Pi (sudo reboot) and send anything during the count-down in the bootloader (check the YouTube video linked above, if you&#039;re not sure).&lt;br /&gt;
&lt;br /&gt;
Then enter the following commands into the bootloader prompt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
setenv bootdelay -2&lt;br /&gt;
saveenv&lt;br /&gt;
reset&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The Pi should reboot and the count-down should be gone.&lt;br /&gt;
&lt;br /&gt;
=== Some Settings ===&lt;br /&gt;
&lt;br /&gt;
[TODO/WIP]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here are some miscellaneous settings I think are a good idea for an OpenMower install:&lt;br /&gt;
&lt;br /&gt;
* Remove the unnecessary snap system: &amp;lt;code&amp;gt;sudo snap remove --purge lxd &amp;amp;&amp;amp; sudo snap remove --purge core20 &amp;amp;&amp;amp; sudo snap remove --purge snapd &amp;amp;&amp;amp; sudo apt purge --autoremove snapd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Disable unattended upgrades: &amp;lt;code&amp;gt;sudo systemctl stop --force unattended-upgrades &amp;amp;&amp;amp; sudo systemctl disable unattended-upgrades &amp;amp;&amp;amp; sudo systemctl mask unattended-upgrades&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* I like to add the following to &amp;lt;code&amp;gt;cmdline.txt&amp;lt;/code&amp;gt; in order to fsck on boot:  &amp;lt;code&amp;gt;fsck.mode=force fsck.repair=yes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* I prefer to use a static IP (If you use the [[System_Image#Installing_a_WiFi_Hot-Spot_(optional,_but_recommended)|recommend WiFi Hot-Spot]] use &amp;lt;code&amp;gt;sudo nmtui&amp;lt;/code&amp;gt; to configure a static IP)&lt;br /&gt;
&lt;br /&gt;
* If you like to have a terminal wifi scanner/signal monitor just install &amp;lt;code&amp;gt;sudo apt install wavemon&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you like you can change the timezone: &amp;lt;code&amp;gt;sudo timedatectl set-timezone Region/Location&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;sudo dpkg-reconfigure tzdata&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you ever like to plug a keyboard into the Pi don&#039;t forget to change the keymap: &amp;lt;code&amp;gt;sudo dpkg-reconfigure keyboard-configuration&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Enable Swap (optional, needed for Pi with &amp;lt;= 2GB RAM)===&lt;br /&gt;
Compiling the OpenMower software will need more than 2GB of RAM. In order to still do this on a Pi with &amp;lt;= 2GB of RAM, we will add a 2GB swap file to the system by entering the following commands:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Create a new 2GB swap file&lt;br /&gt;
sudo fallocate -l 2G /swapfile&lt;br /&gt;
# Change permissions, so that only root can read and write&lt;br /&gt;
sudo chmod 600 /swapfile&lt;br /&gt;
# Create swap space in the file&lt;br /&gt;
sudo mkswap /swapfile&lt;br /&gt;
# Add it to the fstab&lt;br /&gt;
echo &#039;/swapfile swap swap defaults 0 0&#039; | sudo tee -a /etc/fstab /swapfile swap swap defaults 0 0&lt;br /&gt;
# Reboot to activate&lt;br /&gt;
sudo reboot&lt;br /&gt;
&lt;br /&gt;
# Check if it&#039;s activated&lt;br /&gt;
sudo swapon --show&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Installing a WiFi Hot-Spot (optional, but recommended)===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Since we will be configuring the WiFi interface, make sure that you have connected Ethernet to your Raspberry Pi for this step.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As soon as you have closed your mower&#039;s enclosure, you won&#039;t have physical access to your Raspberry Pi anymore. If for some reason it&#039;s unable to connect to your WiFi (e.g. you have changed your password), you would need to open the case to get access to the SD card or Ethernet port on the Pi to regain access.&lt;br /&gt;
&lt;br /&gt;
To prevent this, we&#039;re going to install a hot-spot software which helps you to connect to WiFi by opening a hot-spot each time the Pi cannot connect to a known WiFi connection.&lt;br /&gt;
&lt;br /&gt;
Now is the best time to do this, because we have a serial terminal anyways and can mess with the network interfaces without shutting us out of the system!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just use the following commands for this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# We need to disable systemd-resolveds caching DNS stub resolver&lt;br /&gt;
# if you want to know why check: https://github.com/pi-hole/docker-pi-hole/#installing-on-ubuntu&lt;br /&gt;
sudo sed -r -i.orig &#039;s/#?DNSStubListener=yes/DNSStubListener=no/g&#039; /etc/systemd/resolved.conf&lt;br /&gt;
sudo systemctl restart systemd-resolved.service&lt;br /&gt;
&lt;br /&gt;
ping ntp.org&lt;br /&gt;
# This will throw an dns error:&lt;br /&gt;
#   ping: ntp.org: Temporary failure in name resolution&lt;br /&gt;
sudo sh -c &#039;rm /etc/resolv.conf &amp;amp;&amp;amp; ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf&#039;&lt;br /&gt;
sudo systemctl restart systemd-resolved.service&lt;br /&gt;
nslookup ntp.org&lt;br /&gt;
# DNS should work now&lt;br /&gt;
&lt;br /&gt;
# Install comitup using the latest version from the projects repo&lt;br /&gt;
wget https://davesteele.github.io/comitup/latest/davesteele-comitup-apt-source_latest.deb&lt;br /&gt;
sudo dpkg -i --force-all davesteele-comitup-apt-source_latest.deb&lt;br /&gt;
rm davesteele-comitup-apt-source_latest.deb&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install comitup --no-install-recommends&lt;br /&gt;
&lt;br /&gt;
sudo systemctl stop comitup&lt;br /&gt;
# Now use network-manager to:&lt;br /&gt;
# - add you wifi network&lt;br /&gt;
# optional:&lt;br /&gt;
# - change your hostname&lt;br /&gt;
# - add a dhcp ethernet connection without any device assigned&lt;br /&gt;
# (if even the hotspot malfunctions you can plug in a usb ethernet adapter)&lt;br /&gt;
sudo nmtui&lt;br /&gt;
&lt;br /&gt;
# Edit comitup.conf to change the wifi name and password (I use OpenMower-&amp;lt;nn&amp;gt;)&lt;br /&gt;
sudo nano /etc/comitup.conf&lt;br /&gt;
sudo systemctl restart comitup&lt;br /&gt;
# reboot - it should work now&lt;br /&gt;
sudo reboot&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Disable Serial Console===&lt;br /&gt;
Now that we have setup the network and can access the Pi even if our WiFi is not in range, we need to disable that serial console so that we can use the serial port for hardware.&lt;br /&gt;
&lt;br /&gt;
To do this, enter: &amp;lt;code&amp;gt;sudo nano /boot/firmware/cmdline.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and remove the &amp;lt;code&amp;gt;console=serial0,115200&amp;lt;/code&amp;gt; part of the line.&lt;br /&gt;
&lt;br /&gt;
Save the file and reboot. You should still see the bootloader output, but no serial output after that.&lt;br /&gt;
&lt;br /&gt;
==Installing Tools==&lt;br /&gt;
If you&#039;re happy with your basic Ubuntu setup, it&#039;s time to install some tools required for the OpenMower&lt;br /&gt;
&lt;br /&gt;
=== General Dependencies ===&lt;br /&gt;
Just install them with apt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install --no-install-recommends build-essential git&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===STR2STR (optional, recommended; only needed if you&#039;re using NTRIP, so probably most of you)===&lt;br /&gt;
We need a newer version than the one available in apt, so install it from source:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install gfortran&lt;br /&gt;
git clone https://github.com/rtklibexplorer/RTKLIB&lt;br /&gt;
cd RTKLIB&lt;br /&gt;
git checkout tags/b34c&lt;br /&gt;
cd app/consapp/&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
sudo make install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;You should now be able to run str2str from anywhere.&lt;br /&gt;
&lt;br /&gt;
=== OpenOCD (optional, recommended; only needed if you want to flash Pico from Raspberry Pi)===&lt;br /&gt;
We need to get the OpenOCD version from the Raspberry Pi foundation, because the &amp;quot;original&amp;quot; one doesn&#039;t have the Pico support built in yet.&lt;br /&gt;
&lt;br /&gt;
Install it from source:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install automake autoconf build-essential libtool libftdi-dev libusb-1.0-0-dev texinfo pkg-config rpi.gpio-common&lt;br /&gt;
git clone https://github.com/raspberrypi/openocd.git --recursive --branch rp2040 --depth=1&lt;br /&gt;
cd openocd&lt;br /&gt;
./bootstrap&lt;br /&gt;
./configure --enable-ftdi --enable-sysfsgpio --enable-bcm2835gpio&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
sudo make install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;You can test if it was a success by running:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
ubuntu@ubuntu:~$ openocd -v&lt;br /&gt;
Open On-Chip Debugger 0.11.0-g610f137-dirty (2022-06-07-00:39)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
	http://openocd.org/doc/doxygen/bugs.html&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Installing ROS and OpenMower==&lt;br /&gt;
We&#039;re using ROS Noetic for the OpenMower project. In this step we will install it, get the OpenMower sources, build the sources and create a basic configuration file for your mower.&lt;br /&gt;
&lt;br /&gt;
===Install ROS Noetic===&lt;br /&gt;
Since we&#039;re running Ubuntu 20.04 installing ROS is as easy as running the following commands:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Get the ROS apt repository&lt;br /&gt;
sudo sh -c &#039;echo &amp;quot;deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main&amp;quot; &amp;gt; /etc/apt/sources.list.d/ros-latest.list&#039;&lt;br /&gt;
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -&lt;br /&gt;
&lt;br /&gt;
# Install the ROS base system&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install --no-install-recommends ros-noetic-ros-base&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;We only need to register the ROS installation in your &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt; file. This will enable you to call ROS specific commands from your terminal:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# If you&#039;re using bash (default on Ubuntu):&lt;br /&gt;
echo &amp;quot;source /opt/ros/noetic/setup.bash&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
source ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
# Else if you&#039;re using zsh&lt;br /&gt;
echo &amp;quot;source /opt/ros/noetic/setup.zsh&amp;quot; &amp;gt;&amp;gt; ~/.zshrc&lt;br /&gt;
source ~/.zshrc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Installing OpenMower Software===&lt;br /&gt;
Now we&#039;re finally able to install the OpenMower software. First, we&#039;re checking out the current version of the sources, then we&#039;re getting the dependencies and finally we&#039;re building the sources:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Clone the GitHub Repository:&lt;br /&gt;
git clone --recursive https://github.com/ClemensElflein/open_mower_ros.git&lt;br /&gt;
&lt;br /&gt;
# Get rosdep, only needed once&lt;br /&gt;
sudo apt install --no-install-recommends python3-rosdep&lt;br /&gt;
sudo rosdep init&lt;br /&gt;
rosdep update&lt;br /&gt;
&lt;br /&gt;
# Get the dependencies using rosdep&lt;br /&gt;
cd ~/open_mower_ros/&lt;br /&gt;
sudo apt-get install --no-install-recommends $(rosdep install --from-paths src --ignore-src --simulate | sed --expression &#039;1d&#039; | sort | tr -d &#039;\n&#039; | sed -e &#039;s/  sudo -H apt-get install//g&#039;)&lt;br /&gt;
&lt;br /&gt;
# Finally, build the sources. This will take a while! &lt;br /&gt;
catkin_make -j1 # on 2GB Pi with SWAP - this takes at least 30min&lt;br /&gt;
# OR&lt;br /&gt;
catkin_make -j2 # on 4/8GB Pi - this takes at least 20min&lt;br /&gt;
&lt;br /&gt;
# Copy the default configuration file to your home directory&lt;br /&gt;
cp ~/open_mower_ros/src/open_mower/config/mower_config.sh.example ~/mower_config.sh&lt;br /&gt;
&lt;br /&gt;
# The next step is to also source the OpenMower ROS install&lt;br /&gt;
# If you&#039;re using bash (default on Ubuntu):&lt;br /&gt;
echo &amp;quot;source ~/open_mower_ros/devel/setup.sh&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
echo &amp;quot;source ~/mower_config.sh&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
source ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
# Else if you&#039;re using zsh&lt;br /&gt;
echo &amp;quot;source ~/open_mower_ros/devel/setup.zsh&amp;quot; &amp;gt;&amp;gt; ~/.zshrc&lt;br /&gt;
echo &amp;quot;source ~/mower_config.sh&amp;quot; &amp;gt;&amp;gt; ~/.zshrc&lt;br /&gt;
source ~/.zshrc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;At this point the OpenMower software is successfully installed! You will need to configure the OpenMower software and then you&#039;re finally ready to mow.&lt;br /&gt;
&lt;br /&gt;
== Some Additional Issues==&lt;br /&gt;
&lt;br /&gt;
===I&#039;m using an external WiFi dongle for better coverage, but sometimes it doesn&#039;t work===&lt;br /&gt;
It seems that the Ubuntu sometimes puts external WiFi dongles to sleep. To prevent this, we create a service which disables powersave:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Enter this to create the service&lt;br /&gt;
sudo systemctl --full --force edit wifi_powersave@.service&lt;br /&gt;
&lt;br /&gt;
# Paste the following:&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Set WiFi power save %i&lt;br /&gt;
After=sys-subsystem-net-devices-wlan1.device&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=oneshot&lt;br /&gt;
RemainAfterExit=yes&lt;br /&gt;
ExecStart=/sbin/iw dev wlan1 set power_save %i&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=sys-subsystem-net-devices-wlan1.device&lt;br /&gt;
&lt;br /&gt;
# Save and exit, then activate using:&lt;br /&gt;
sudo systemctl disable wifi_powersave@on.service&lt;br /&gt;
sudo systemctl enable wifi_powersave@off.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Development&amp;diff=470</id>
		<title>Development</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Development&amp;diff=470"/>
		<updated>2026-06-20T20:47:51Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[OpenMower]]&lt;br /&gt;
* [[OpenMower OLD Barmetal installation]]&lt;br /&gt;
* [[OpenMower Crosscompiling]]&lt;br /&gt;
* https://twitter.com/perborgen/status/1580930648797483010 CSS Grid&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_OLD_Baremetal_installation&amp;diff=469</id>
		<title>OpenMower OLD Baremetal installation</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_OLD_Baremetal_installation&amp;diff=469"/>
		<updated>2026-06-20T20:47:40Z</updated>

		<summary type="html">&lt;p&gt;Damme: Created page with &amp;quot;This page will guide you through the steps to install a basic system image.  On this image you will have the ROS base system, the OpenMower installation, local configuration for your mower and some tools to help you work with the mower.  ==Prerequisites== In order to follow this guide, you will need the following:  #A Raspberry Pi 4 (4GB or more recommended, 2GB works with swap, see here) #An SD card...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will guide you through the steps to install a basic system image.&lt;br /&gt;
&lt;br /&gt;
On this image you will have the ROS base system, the OpenMower installation, local configuration for your mower and some tools to help you work with the mower.&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
In order to follow this guide, you will need the following:&lt;br /&gt;
&lt;br /&gt;
#A Raspberry Pi 4 (4GB or more recommended, [[System Image#Enable Swap (optional, needed for Pi with &amp;lt;= 2GB RAM)|2GB works with swap, see here]])&lt;br /&gt;
#An SD card&lt;br /&gt;
#A soldered OpenMower mainboard&lt;br /&gt;
&lt;br /&gt;
==Installing the Base System==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&#039;&#039;&#039;There is also a YouTube video explaining the steps in this section:&#039;&#039;&#039; https://youtu.be/_bImqD-pQSA?t=562&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Flashing Ubuntu to SD Card ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first step is to install the base system. We&#039;re using Ubuntu 20.04 Server for the Raspberry Pi. This is, because this image gives us best support ROS Noetic.&lt;br /&gt;
&lt;br /&gt;
Installing the base image is easy:&lt;br /&gt;
&lt;br /&gt;
#[https://www.raspberrypi.com/software/ Get the Raspberry Pi Imager software]&lt;br /&gt;
#Select the correct operating system:  &#039;&#039;Other-general-purpose OS &amp;gt; Ubuntu &amp;gt; Ubuntu Server 20.04.4 LTS (RPI 3/4/400) 64-bit&#039;&#039;&lt;br /&gt;
#Insert your SD card into your PC and select it in the &#039;&#039;Storage&#039;&#039; part of the software&lt;br /&gt;
#Click &#039;&#039;write&#039;&#039; and wait for the process to finish&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you have successfully flashed your image, remove the SD for your PC &#039;&#039;&#039;and reinsert it again.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Then replace the &amp;lt;code&amp;gt;/boot/config.txt&amp;lt;/code&amp;gt; file with the one provided here: [https://github.com/ClemensElflein/OpenMower/blob/main/configs/RaspberryPiConfig/config.txt]&lt;br /&gt;
&lt;br /&gt;
This will enable all hardware serial ports on the Raspberry Pi.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can theoretically configure networking in this step as well, but I&#039;m not recommending it. This is, because the networking information file gets only copied once and if you have an error it won&#039;t work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;We need an interactive terminal in the next step anyways.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you have done this step, you can eject the SD card and plug it into your Raspberry Pi 4.&lt;br /&gt;
&lt;br /&gt;
=== Opening a Serial Terminal ===&lt;br /&gt;
[[File:SerialRedirect.png|thumb|Serial Terminal: minicom -D /dev/ttyACM0]]&lt;br /&gt;
This step is needed for the following sections. The goal is to have a serial terminal to do basic config (networking etc) easily.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The easiest way of doing so is:&lt;br /&gt;
# Flash the SerialRedirect firmware into your Pico. Get it here: https://github.com/ClemensElflein/OpenMower/tree/main/Firmware/SerialRedirect/bin&lt;br /&gt;
# Provide your mainboard with power&lt;br /&gt;
# Plug your Pico into a computer. A virtual COM port should appear&lt;br /&gt;
# Connect to the COM port (I&#039;m using minicom, see image on the right), then press enter to start the Raspberry Pi.&lt;br /&gt;
#The Pi boots and a serial terminal will appear.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you can login with the default credentials:&lt;br /&gt;
&lt;br /&gt;
username: &amp;lt;code&amp;gt;ubuntu&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
password: &amp;lt;code&amp;gt;ubuntu&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that you will need to change the password immediately.&lt;br /&gt;
&lt;br /&gt;
=== Disable Boot Interrupt ===&lt;br /&gt;
[[File:Image.png|thumb|Commands needed to disable boot interrupt on serial input.]]&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi boot loader will interrupt the boot sequence if data is sent through the main serial port of the Raspberry Pi. Since we&#039;re connecting &amp;quot;nosiy&amp;quot; hardware to the port, this will always interrupt the boot sequence and we need to disable this feature. &lt;br /&gt;
&lt;br /&gt;
In order to do this, reboot the Pi (sudo reboot) and send anything during the count-down in the bootloader (check the YouTube video linked above, if you&#039;re not sure).&lt;br /&gt;
&lt;br /&gt;
Then enter the following commands into the bootloader prompt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
setenv bootdelay -2&lt;br /&gt;
saveenv&lt;br /&gt;
reset&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The Pi should reboot and the count-down should be gone.&lt;br /&gt;
&lt;br /&gt;
=== Some Settings ===&lt;br /&gt;
&lt;br /&gt;
[TODO/WIP]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here are some miscellaneous settings I think are a good idea for an OpenMower install:&lt;br /&gt;
&lt;br /&gt;
* Remove the unnecessary snap system: &amp;lt;code&amp;gt;sudo snap remove --purge lxd &amp;amp;&amp;amp; sudo snap remove --purge core20 &amp;amp;&amp;amp; sudo snap remove --purge snapd &amp;amp;&amp;amp; sudo apt purge --autoremove snapd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Disable unattended upgrades: &amp;lt;code&amp;gt;sudo systemctl stop --force unattended-upgrades &amp;amp;&amp;amp; sudo systemctl disable unattended-upgrades &amp;amp;&amp;amp; sudo systemctl mask unattended-upgrades&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* I like to add the following to &amp;lt;code&amp;gt;cmdline.txt&amp;lt;/code&amp;gt; in order to fsck on boot:  &amp;lt;code&amp;gt;fsck.mode=force fsck.repair=yes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* I prefer to use a static IP (If you use the [[System_Image#Installing_a_WiFi_Hot-Spot_(optional,_but_recommended)|recommend WiFi Hot-Spot]] use &amp;lt;code&amp;gt;sudo nmtui&amp;lt;/code&amp;gt; to configure a static IP)&lt;br /&gt;
&lt;br /&gt;
* If you like to have a terminal wifi scanner/signal monitor just install &amp;lt;code&amp;gt;sudo apt install wavemon&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you like you can change the timezone: &amp;lt;code&amp;gt;sudo timedatectl set-timezone Region/Location&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;sudo dpkg-reconfigure tzdata&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you ever like to plug a keyboard into the Pi don&#039;t forget to change the keymap: &amp;lt;code&amp;gt;sudo dpkg-reconfigure keyboard-configuration&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Enable Swap (optional, needed for Pi with &amp;lt;= 2GB RAM)===&lt;br /&gt;
Compiling the OpenMower software will need more than 2GB of RAM. In order to still do this on a Pi with &amp;lt;= 2GB of RAM, we will add a 2GB swap file to the system by entering the following commands:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Create a new 2GB swap file&lt;br /&gt;
sudo fallocate -l 2G /swapfile&lt;br /&gt;
# Change permissions, so that only root can read and write&lt;br /&gt;
sudo chmod 600 /swapfile&lt;br /&gt;
# Create swap space in the file&lt;br /&gt;
sudo mkswap /swapfile&lt;br /&gt;
# Add it to the fstab&lt;br /&gt;
echo &#039;/swapfile swap swap defaults 0 0&#039; | sudo tee -a /etc/fstab /swapfile swap swap defaults 0 0&lt;br /&gt;
# Reboot to activate&lt;br /&gt;
sudo reboot&lt;br /&gt;
&lt;br /&gt;
# Check if it&#039;s activated&lt;br /&gt;
sudo swapon --show&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Installing a WiFi Hot-Spot (optional, but recommended)===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Since we will be configuring the WiFi interface, make sure that you have connected Ethernet to your Raspberry Pi for this step.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As soon as you have closed your mower&#039;s enclosure, you won&#039;t have physical access to your Raspberry Pi anymore. If for some reason it&#039;s unable to connect to your WiFi (e.g. you have changed your password), you would need to open the case to get access to the SD card or Ethernet port on the Pi to regain access.&lt;br /&gt;
&lt;br /&gt;
To prevent this, we&#039;re going to install a hot-spot software which helps you to connect to WiFi by opening a hot-spot each time the Pi cannot connect to a known WiFi connection.&lt;br /&gt;
&lt;br /&gt;
Now is the best time to do this, because we have a serial terminal anyways and can mess with the network interfaces without shutting us out of the system!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just use the following commands for this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# We need to disable systemd-resolveds caching DNS stub resolver&lt;br /&gt;
# if you want to know why check: https://github.com/pi-hole/docker-pi-hole/#installing-on-ubuntu&lt;br /&gt;
sudo sed -r -i.orig &#039;s/#?DNSStubListener=yes/DNSStubListener=no/g&#039; /etc/systemd/resolved.conf&lt;br /&gt;
sudo systemctl restart systemd-resolved.service&lt;br /&gt;
&lt;br /&gt;
ping ntp.org&lt;br /&gt;
# This will throw an dns error:&lt;br /&gt;
#   ping: ntp.org: Temporary failure in name resolution&lt;br /&gt;
sudo sh -c &#039;rm /etc/resolv.conf &amp;amp;&amp;amp; ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf&#039;&lt;br /&gt;
sudo systemctl restart systemd-resolved.service&lt;br /&gt;
nslookup ntp.org&lt;br /&gt;
# DNS should work now&lt;br /&gt;
&lt;br /&gt;
# Install comitup using the latest version from the projects repo&lt;br /&gt;
wget https://davesteele.github.io/comitup/latest/davesteele-comitup-apt-source_latest.deb&lt;br /&gt;
sudo dpkg -i --force-all davesteele-comitup-apt-source_latest.deb&lt;br /&gt;
rm davesteele-comitup-apt-source_latest.deb&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install comitup --no-install-recommends&lt;br /&gt;
&lt;br /&gt;
sudo systemctl stop comitup&lt;br /&gt;
# Now use network-manager to:&lt;br /&gt;
# - add you wifi network&lt;br /&gt;
# optional:&lt;br /&gt;
# - change your hostname&lt;br /&gt;
# - add a dhcp ethernet connection without any device assigned&lt;br /&gt;
# (if even the hotspot malfunctions you can plug in a usb ethernet adapter)&lt;br /&gt;
sudo nmtui&lt;br /&gt;
&lt;br /&gt;
# Edit comitup.conf to change the wifi name and password (I use OpenMower-&amp;lt;nn&amp;gt;)&lt;br /&gt;
sudo nano /etc/comitup.conf&lt;br /&gt;
sudo systemctl restart comitup&lt;br /&gt;
# reboot - it should work now&lt;br /&gt;
sudo reboot&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Disable Serial Console===&lt;br /&gt;
Now that we have setup the network and can access the Pi even if our WiFi is not in range, we need to disable that serial console so that we can use the serial port for hardware.&lt;br /&gt;
&lt;br /&gt;
To do this, enter: &amp;lt;code&amp;gt;sudo nano /boot/firmware/cmdline.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and remove the &amp;lt;code&amp;gt;console=serial0,115200&amp;lt;/code&amp;gt; part of the line.&lt;br /&gt;
&lt;br /&gt;
Save the file and reboot. You should still see the bootloader output, but no serial output after that.&lt;br /&gt;
&lt;br /&gt;
==Installing Tools==&lt;br /&gt;
If you&#039;re happy with your basic Ubuntu setup, it&#039;s time to install some tools required for the OpenMower&lt;br /&gt;
&lt;br /&gt;
=== General Dependencies ===&lt;br /&gt;
Just install them with apt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install --no-install-recommends build-essential git&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===STR2STR (optional, recommended; only needed if you&#039;re using NTRIP, so probably most of you)===&lt;br /&gt;
We need a newer version than the one available in apt, so install it from source:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install gfortran&lt;br /&gt;
git clone https://github.com/rtklibexplorer/RTKLIB&lt;br /&gt;
cd RTKLIB&lt;br /&gt;
git checkout tags/b34c&lt;br /&gt;
cd app/consapp/&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
sudo make install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;You should now be able to run str2str from anywhere.&lt;br /&gt;
&lt;br /&gt;
=== OpenOCD (optional, recommended; only needed if you want to flash Pico from Raspberry Pi)===&lt;br /&gt;
We need to get the OpenOCD version from the Raspberry Pi foundation, because the &amp;quot;original&amp;quot; one doesn&#039;t have the Pico support built in yet.&lt;br /&gt;
&lt;br /&gt;
Install it from source:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install automake autoconf build-essential libtool libftdi-dev libusb-1.0-0-dev texinfo pkg-config rpi.gpio-common&lt;br /&gt;
git clone https://github.com/raspberrypi/openocd.git --recursive --branch rp2040 --depth=1&lt;br /&gt;
cd openocd&lt;br /&gt;
./bootstrap&lt;br /&gt;
./configure --enable-ftdi --enable-sysfsgpio --enable-bcm2835gpio&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
sudo make install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;You can test if it was a success by running:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
ubuntu@ubuntu:~$ openocd -v&lt;br /&gt;
Open On-Chip Debugger 0.11.0-g610f137-dirty (2022-06-07-00:39)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
	http://openocd.org/doc/doxygen/bugs.html&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Installing ROS and OpenMower==&lt;br /&gt;
We&#039;re using ROS Noetic for the OpenMower project. In this step we will install it, get the OpenMower sources, build the sources and create a basic configuration file for your mower.&lt;br /&gt;
&lt;br /&gt;
===Install ROS Noetic===&lt;br /&gt;
Since we&#039;re running Ubuntu 20.04 installing ROS is as easy as running the following commands:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Get the ROS apt repository&lt;br /&gt;
sudo sh -c &#039;echo &amp;quot;deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main&amp;quot; &amp;gt; /etc/apt/sources.list.d/ros-latest.list&#039;&lt;br /&gt;
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -&lt;br /&gt;
&lt;br /&gt;
# Install the ROS base system&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install --no-install-recommends ros-noetic-ros-base&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;We only need to register the ROS installation in your &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt; file. This will enable you to call ROS specific commands from your terminal:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# If you&#039;re using bash (default on Ubuntu):&lt;br /&gt;
echo &amp;quot;source /opt/ros/noetic/setup.bash&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
source ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
# Else if you&#039;re using zsh&lt;br /&gt;
echo &amp;quot;source /opt/ros/noetic/setup.zsh&amp;quot; &amp;gt;&amp;gt; ~/.zshrc&lt;br /&gt;
source ~/.zshrc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Installing OpenMower Software===&lt;br /&gt;
Now we&#039;re finally able to install the OpenMower software. First, we&#039;re checking out the current version of the sources, then we&#039;re getting the dependencies and finally we&#039;re building the sources:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Clone the GitHub Repository:&lt;br /&gt;
git clone --recursive https://github.com/ClemensElflein/open_mower_ros.git&lt;br /&gt;
&lt;br /&gt;
# Get rosdep, only needed once&lt;br /&gt;
sudo apt install --no-install-recommends python3-rosdep&lt;br /&gt;
sudo rosdep init&lt;br /&gt;
rosdep update&lt;br /&gt;
&lt;br /&gt;
# Get the dependencies using rosdep&lt;br /&gt;
cd ~/open_mower_ros/&lt;br /&gt;
sudo apt-get install --no-install-recommends $(rosdep install --from-paths src --ignore-src --simulate | sed --expression &#039;1d&#039; | sort | tr -d &#039;\n&#039; | sed -e &#039;s/  sudo -H apt-get install//g&#039;)&lt;br /&gt;
&lt;br /&gt;
# Finally, build the sources. This will take a while! &lt;br /&gt;
catkin_make -j1 # on 2GB Pi with SWAP - this takes at least 30min&lt;br /&gt;
# OR&lt;br /&gt;
catkin_make -j2 # on 4/8GB Pi - this takes at least 20min&lt;br /&gt;
&lt;br /&gt;
# Copy the default configuration file to your home directory&lt;br /&gt;
cp ~/open_mower_ros/src/open_mower/config/mower_config.sh.example ~/mower_config.sh&lt;br /&gt;
&lt;br /&gt;
# The next step is to also source the OpenMower ROS install&lt;br /&gt;
# If you&#039;re using bash (default on Ubuntu):&lt;br /&gt;
echo &amp;quot;source ~/open_mower_ros/devel/setup.sh&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
echo &amp;quot;source ~/mower_config.sh&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
source ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
# Else if you&#039;re using zsh&lt;br /&gt;
echo &amp;quot;source ~/open_mower_ros/devel/setup.zsh&amp;quot; &amp;gt;&amp;gt; ~/.zshrc&lt;br /&gt;
echo &amp;quot;source ~/mower_config.sh&amp;quot; &amp;gt;&amp;gt; ~/.zshrc&lt;br /&gt;
source ~/.zshrc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;At this point the OpenMower software is successfully installed! You will need to configure the OpenMower software and then you&#039;re finally ready to mow.&lt;br /&gt;
&lt;br /&gt;
== Some Additional Issues==&lt;br /&gt;
&lt;br /&gt;
===I&#039;m using an external WiFi dongle for better coverage, but sometimes it doesn&#039;t work===&lt;br /&gt;
It seems that the Ubuntu sometimes puts external WiFi dongles to sleep. To prevent this, we create a service which disables powersave:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Enter this to create the service&lt;br /&gt;
sudo systemctl --full --force edit wifi_powersave@.service&lt;br /&gt;
&lt;br /&gt;
# Paste the following:&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Set WiFi power save %i&lt;br /&gt;
After=sys-subsystem-net-devices-wlan1.device&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=oneshot&lt;br /&gt;
RemainAfterExit=yes&lt;br /&gt;
ExecStart=/sbin/iw dev wlan1 set power_save %i&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=sys-subsystem-net-devices-wlan1.device&lt;br /&gt;
&lt;br /&gt;
# Save and exit, then activate using:&lt;br /&gt;
sudo systemctl disable wifi_powersave@on.service&lt;br /&gt;
sudo systemctl enable wifi_powersave@off.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Development&amp;diff=468</id>
		<title>Development</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Development&amp;diff=468"/>
		<updated>2026-06-20T20:47:35Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[OpenMower]]&lt;br /&gt;
+ [[OpenMower OLD Barmetal installation]]&lt;br /&gt;
* [[OpenMower Crosscompiling]]&lt;br /&gt;
* https://twitter.com/perborgen/status/1580930648797483010 CSS Grid&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=OpenMower_Crosscompiling&amp;diff=467</id>
		<title>OpenMower Crosscompiling</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=OpenMower_Crosscompiling&amp;diff=467"/>
		<updated>2026-06-20T20:46:06Z</updated>

		<summary type="html">&lt;p&gt;Damme: Created page with &amp;quot;Warning! You are in for a treat! :D - You have been warned. But reward is good, from 3250sec with docker buildx using qemu to 304s on my machine (Clean build)    = Instructions = These instructions are made for Ubuntu 20.04.6 LTS   &amp;#039;&amp;#039;&amp;#039;&amp;lt;code&amp;gt;&amp;lt;big&amp;gt;PLEASE DONT RUN ANY SCRIPTS AS SUDO / ROOT! MY SCRIPTS ARE NOT &amp;quot;SAFE&amp;quot;!&amp;lt;/big&amp;gt;&amp;lt;/code&amp;gt;&amp;#039;&amp;#039;&amp;#039;  Instead give yourself write-access to /opt, &amp;lt;code&amp;gt;sudo chmod 777 /opt/&amp;lt;/code&amp;gt; for example.  &amp;amp;nbsp;  ===== INSTALL ROS https://wiki.ros.org/no...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Warning! You are in for a treat! :D - You have been warned. But reward is good, from 3250sec with docker buildx using qemu to 304s on my machine (Clean build)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Instructions =&lt;br /&gt;
These instructions are made for Ubuntu 20.04.6 LTS&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;lt;big&amp;gt;PLEASE DONT RUN ANY SCRIPTS AS SUDO / ROOT! MY SCRIPTS ARE NOT &amp;quot;SAFE&amp;quot;!&amp;lt;/big&amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Instead give yourself write-access to /opt, &amp;lt;code&amp;gt;sudo chmod 777 /opt/&amp;lt;/code&amp;gt; for example.&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
===== INSTALL ROS https://wiki.ros.org/noetic/Installation/Ubuntu =====&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== Update source files ====&lt;br /&gt;
* Add &#039;&#039;&#039;&amp;lt;code&amp;gt;[arch=amd64]&amp;lt;/code&amp;gt;&#039;&#039;&#039; after deb on each line in &amp;lt;code&amp;gt;/etc/apt/sources.list&amp;lt;/code&amp;gt; (This should be changed to your current machines native arch!)&lt;br /&gt;
* Add &#039;&#039;&#039;&amp;lt;code&amp;gt;[arch=amd64,arm64]&amp;lt;/code&amp;gt;&#039;&#039;&#039; after deb in &amp;lt;code&amp;gt;/etc/apt/sources.list.d/ros-latest.list&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Create &amp;lt;code&amp;gt;/etc/apt/sources.list.d/arm-cross-compile-sources.list&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal main restricted&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal-updates main restricted&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal universe&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal-updates universe&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal multiverse&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal-updates multiverse&lt;br /&gt;
deb [arch=arm64] http://ports.ubuntu.com/ focal-backports main restricted universe multiverse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Update and install packages ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo dpkg --add-architecture arm64&lt;br /&gt;
&lt;br /&gt;
sudo apt install crossbuild-essential-arm64 parallel&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Clone open_mower_ros repository ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/&lt;br /&gt;
&lt;br /&gt;
git clone https://github.com/ClemensElflein/open_mower_ros&lt;br /&gt;
git submodule update --init --recursive&lt;br /&gt;
cd /opt/open_mower_ros&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Setup sysroot and prepare open_mower_ros ====&lt;br /&gt;
&lt;br /&gt;
We will use CMAKE_SYSROOT /opt/sysroot_arm64 and /opt/sysroot_arm64_download - change these accordingly in the files for your needs. Total size to download is about 200MB and extracted is ~1.1GB. Change the number of download threads as desired.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Create &amp;lt;code&amp;gt;toolchain.cmake&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cmake&amp;quot;&amp;gt;&lt;br /&gt;
set(CMAKE_SYSTEM_NAME Linux)&lt;br /&gt;
set(CMAKE_SYSTEM_VERSION 1)&lt;br /&gt;
set(CMAKE_SYSTEM_PROCESSOR aarch64)&lt;br /&gt;
&lt;br /&gt;
# Specify the cross compiler&lt;br /&gt;
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)&lt;br /&gt;
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)&lt;br /&gt;
&lt;br /&gt;
#set(CMAKE_EXE_LINKER_FLAGS &amp;quot;${CMAKE_EXE_LINKER_FLAGS} -static&amp;quot;)&lt;br /&gt;
#set(CMAKE_SHARED_LINKER_FLAGS &amp;quot;${CMAKE_SHARED_LINKER_FLAGS} -static&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Specify the target system root&lt;br /&gt;
set(CMAKE_SYSROOT /opt/sysroot_arm64)&lt;br /&gt;
&lt;br /&gt;
set(SYSROOT_PATH ${CMAKE_SYSROOT})&lt;br /&gt;
&lt;br /&gt;
unset(CMAKE_SYSTEM_PREFIX_PATH)&lt;br /&gt;
list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${CMAKE_SYSROOT}/opt/ros/noetic)&lt;br /&gt;
&lt;br /&gt;
set(CMAKE_PREFIX_PATH ${CMAKE_SYSROOT}/opt/ros/noetic ${CMAKE_SYSROOT}/opt/ros/noetic/share)&lt;br /&gt;
set(CMAKE_LIBRARY_PATH ${CMAKE_SYSROOT}/opt/ros/noetic/lib)&lt;br /&gt;
set(CMAKE_INCLUDE_PATH ${CMAKE_SYSROOT}/opt/ros/noetic/include)&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})&lt;br /&gt;
&lt;br /&gt;
# Search for programs in the build host directories&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)&lt;br /&gt;
&lt;br /&gt;
# For libraries and headers in the target directories&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)&lt;br /&gt;
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)&lt;br /&gt;
&lt;br /&gt;
set(ENV{PKG_CONFIG_PATH} ${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/pkgconfig/)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Create &amp;lt;code&amp;gt;1_setup-sysroot.bash&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
SYSROOT=/opt/sysroot_arm64&lt;br /&gt;
DOWNLOADDIR=/opt/sysroot_downloads&lt;br /&gt;
PARALLELDOWNLOAD=6&lt;br /&gt;
&lt;br /&gt;
#########################&lt;br /&gt;
&lt;br /&gt;
rm -rf $SYSROOT&lt;br /&gt;
mkdir -p $SYSROOT&lt;br /&gt;
mkdir -p $DOWNLOADDIR&lt;br /&gt;
&lt;br /&gt;
# Link might not be needed? Cant remember :D&lt;br /&gt;
ln -s $SYSROOT/usr/lib $SYSROOT/lib&lt;br /&gt;
&lt;br /&gt;
install_package() {&lt;br /&gt;
#  for PKG in &amp;quot;${PACKAGES[@]}&amp;quot;; do&lt;br /&gt;
    PKG=$1&lt;br /&gt;
    URL=$(apt-get download --print-uris $PKG | cut -d\&#039; -f2)&lt;br /&gt;
    if [ -n &amp;quot;$URL&amp;quot; ]; then&lt;br /&gt;
      echo &amp;quot;Downloading $PKG ($URL)&amp;quot;&lt;br /&gt;
      wget -q -nc $URL -P $DOWNLOADDIR &amp;amp;&amp;amp; dpkg -x $DOWNLOADDIR/$(basename $URL) $SYSROOT&lt;br /&gt;
# --show-progress&lt;br /&gt;
#      dpkg -x $DOWNLOADDIR/$(basename $URL) $SYSROOT&lt;br /&gt;
      echo &amp;quot;Done installing $PKG&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      echo &amp;quot;$PKG NOT FOUND!&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
#  done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
export -f install_package&lt;br /&gt;
export DOWNLOADDIR&lt;br /&gt;
export SYSROOT&lt;br /&gt;
&lt;br /&gt;
# read packages.txt into PACKAGES&lt;br /&gt;
while IFS= read -r line; do&lt;br /&gt;
    PACKAGES+=(&amp;quot;$line&amp;quot;)&lt;br /&gt;
done &amp;lt; &amp;quot;packages.txt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
parallel -j $PARALLELDOWNLOAD install_package ::: &amp;quot;${PACKAGES[@]}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Done!&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Download &amp;lt;code&amp;gt;packages.txt&amp;lt;/code&amp;gt; # Focal Ubuntu 20.04.6 LTS! =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
wget https://gist.githubusercontent.com/Damme/3161f92ccadf452b4d5f3eee32da097e/raw/8df0172858e95da76091b04f8492705fc0cf0396/packages.txt -O packages.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Create &amp;lt;code&amp;gt;2-fix-links-cmake.bash&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
SYSROOT=/opt/sysroot_arm64&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Linking some missing library links, broken links /hardcoded to /lib/...&amp;quot;&lt;br /&gt;
ln -sfv $SYSROOT/usr/lib/aarch64-linux-gnu/libPocoFoundation.so.62 $SYSROOT/usr/lib/aarch64-linux-gnu/libPocoFoundation.so&lt;br /&gt;
ln -sfv $SYSROOT/usr/lib/aarch64-linux-gnu/blas/libblas.so.3 $SYSROOT/usr/lib/aarch64-linux-gnu/libblas.so.3&lt;br /&gt;
ln -sfv $SYSROOT/usr/lib/aarch64-linux-gnu/lapack/liblapack.so.3 $SYSROOT/usr/lib/aarch64-linux-gnu/liblapack.so.3&lt;br /&gt;
&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/librt.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/librt.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libpthread.so.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libpthread.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libBrokenLocale.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libBrokenLocale.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libanl.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libanl.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libblkid.so.1.1.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libblkid.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libbz2.so.1.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libbz2.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libexpat.so.1.6.11 $SYSROOT/usr/lib/aarch64-linux-gnu/libexpat.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libgpg-error.so.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libgpg-error.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libkeyutils.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libkeyutils.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/liblzma.so.5.2.4 $SYSROOT/usr/lib/aarch64-linux-gnu/liblzma.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libm.so.6 $SYSROOT/usr/lib/aarch64-linux-gnu/libm.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libmount.so.1.1.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libmount.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnsl.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libnsl.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_compat.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_compat.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_dns.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_dns.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_files.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_files.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_hesiod.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_hesiod.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_nis.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_nis.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libnss_nisplus.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_nisplus.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libpcre.so.3 $SYSROOT/usr/lib/aarch64-linux-gnu/libpcre.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libresolv.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libresolv.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libthread_db.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libthread_db.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libutil.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libutil.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libuuid.so.1.3.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libuuid.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libz.so.1.2.11 $SYSROOT/usr/lib/aarch64-linux-gnu/libz.so&lt;br /&gt;
ln -sfv $SYSROOT/lib/aarch64-linux-gnu/libdl.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libdl.so&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Fix cmake files with hardcoded paths..&amp;quot;&lt;br /&gt;
find $SYSROOT/opt/ros/noetic/ -name &amp;quot;*.cmake&amp;quot; | xargs -i sh -c &#039;echo {}; sed -i s@/opt/ros/noetic/lib@\${SYSROOT_PATH}/opt/ros/noetic/lib@g {}&#039;&lt;br /&gt;
find $SYSROOT/opt/ros/noetic/ -name &amp;quot;*.cmake&amp;quot; | xargs -i sh -c &#039;echo {}; sed -i s@PREFIX\ /opt/ros/noetic@PREFIX\ \${SYSROOT_PATH}/opt/ros/noetic@g {}&#039;&lt;br /&gt;
find $SYSROOT/opt/ros/noetic/ -name &amp;quot;*.cmake&amp;quot; | xargs -i sh -c &#039;echo {}; sed -i s@\;/usr/@\;\$\{SYSROOT_PATH\}/usr/@g {}&#039;&lt;br /&gt;
find $SYSROOT/opt/ros/noetic/ -name &amp;quot;*.cmake&amp;quot; | xargs -i sh -c &#039;echo {}; sed -i s@\&amp;quot;/usr/@\&amp;quot;\$\{SYSROOT_PATH\}/usr/@g {}&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Create &amp;lt;code&amp;gt;3-patch-openmower-cmake.bash&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
cd src/lib/slic3r_coverage_planner&lt;br /&gt;
&lt;br /&gt;
patch CMakeLists.txt &amp;lt;&amp;lt;&#039;EOF&#039;&lt;br /&gt;
@@ -33,7 +33,9 @@ ExternalProject_Add(&lt;br /&gt;
&lt;br /&gt;
         CMAKE_CACHE_ARGS&lt;br /&gt;
         SOURCE_SUBDIR src&lt;br /&gt;
-        CMAKE_ARGS -DSLIC3R_BUILD_TESTS=OFF&lt;br /&gt;
+        CMAKE_ARGS -DSLIC3R_BUILD_TESTS=OFF -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}&lt;br /&gt;
+               -DCMAKE_EXE_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu&lt;br /&gt;
+               -DCMAKE_SHARED_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu&lt;br /&gt;
         BUILD_COMMAND ${CMAKE_COMMAND} --build &amp;lt;BINARY_DIR&amp;gt; --config Release&lt;br /&gt;
 )&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
cd ../../../&lt;br /&gt;
&lt;br /&gt;
cd src/lib/xbot_driver_gps&lt;br /&gt;
&lt;br /&gt;
patch CMakeLists.txt &amp;lt;&amp;lt;&#039;EOF&#039;&lt;br /&gt;
@@ -32,6 +32,9 @@ ExternalProject_Add(&lt;br /&gt;
         INSTALL_COMMAND cmake -E echo &amp;quot;Skipping install step.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
         CMAKE_CACHE_ARGS&lt;br /&gt;
+        CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}&lt;br /&gt;
+               -DCMAKE_EXE_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu&lt;br /&gt;
+               -DCMAKE_SHARED_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu&lt;br /&gt;
         BUILD_COMMAND ${CMAKE_COMMAND} --build &amp;lt;BINARY_DIR&amp;gt; --config Release&lt;br /&gt;
 )&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
cd ../../../&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Execute scripts ====&lt;br /&gt;
* run the created scripts:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ bash 1-setup_sysroot.bash&lt;br /&gt;
$ bash 2-fix-links-cmake.bash&lt;br /&gt;
$ bash 3-patch-openmower-cmake.bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Compilation  ====&lt;br /&gt;
* build with the following command, change -j1 for number of parallel processes. For some reason catkin_make does not parse toolchain.cmake without forcing it...&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;code&amp;gt;$ catkin_make -DCMAKE_TOOLCHAIN_FILE=/opt/open_mower_ros/toolchain.cmake -j1&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* check the build with&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ find devel/ -type f -executable |xargs file&lt;br /&gt;
devel/_setup_util.py:                                      Python script, ASCII text executable&lt;br /&gt;
devel/env.sh:                                              a /usr/bin/env sh script, ASCII text executable&lt;br /&gt;
devel/lib/mower_utils/planner_test:                        ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_utils/xbot_pose_converter:                 ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xesc_driver/xesc_driver_node:                    ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/libxesc_2040_driver.so:                          ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/ntrip_client/ntrip_ros.py:                       Python script, ASCII text executable&lt;br /&gt;
devel/lib/mower_simulation/mower_simulation:               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/libvesc_driver.so:                               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_comms/mower_comms:                         ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_map/mower_map_service:                     ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/libftc_local_planner.so:                         ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_positioning/xbot_positioning:               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_monitoring/xbot_sensor_example:             ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_monitoring/xbot_monitoring:                 ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_monitoring/heatmap_generator:               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_driver_gps/driver_gps_node:                 ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_logic/mag_calibration:                     ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_logic/monitoring:                          ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_logic/mower_odometry:                      ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/mower_logic/mower_logic:                         ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/libxesc_driver.so:                               ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/slic3r_coverage_planner/slic3r_coverage_planner: ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
devel/lib/xbot_remote/xbot_remote:                         ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* rsync folder to raspberry pi, note the section below!&lt;br /&gt;
&lt;br /&gt;
==== TODO/Fix me ====&lt;br /&gt;
* Fix &amp;lt;code&amp;gt;[project]/devel/setup.sh&amp;lt;/code&amp;gt; - scripts to use correct paths, maybe have a wrapper for setup.sh that setup some env vars for example CMAKE_PREFIX_PATH to omit sysroot_arm64 path, need to figure out what paths are wrong. Seems &amp;lt;code&amp;gt;_setup_util.py&amp;lt;/code&amp;gt; is the script that setup ros enviroment. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# One temporary fix is to create a link on the RPi:&lt;br /&gt;
$ ln -s / /opt/sysroot_arm64/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* a script to generate packages.txt&lt;br /&gt;
&lt;br /&gt;
Good luck!&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Development&amp;diff=466</id>
		<title>Development</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Development&amp;diff=466"/>
		<updated>2026-06-20T20:46:02Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[OpenMower]]&lt;br /&gt;
* [[OpenMower Crosscompiling]]&lt;br /&gt;
* https://twitter.com/perborgen/status/1580930648797483010 CSS Grid&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Main_Page&amp;diff=446</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Main_Page&amp;diff=446"/>
		<updated>2025-05-26T13:08:02Z</updated>

		<summary type="html">&lt;p&gt;Damme: /* Damme&amp;#039;s stuff */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== World Wide Wiegert Wiki - The best wiki in the world! ==&lt;br /&gt;
 Skapa en sida genom att skapa dig ett konto, editera denna sida och skriv länken inom brackets&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[namn på sidan]]&amp;lt;/nowiki&amp;gt; - spara och klicka på länken så är det bara att skriva vidare!&lt;br /&gt;
&lt;br /&gt;
== Damme&#039;s stuff ==&lt;br /&gt;
[[Daniel Wiegert - About me]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;[[Damme&#039;s linux stuff]]&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Damme&#039;s windows stuff]]&lt;br /&gt;
&lt;br /&gt;
[[Ubuntu Server LTS]]&lt;br /&gt;
&lt;br /&gt;
[[Hårdvara]]&lt;br /&gt;
&lt;br /&gt;
[[Development]]&lt;br /&gt;
&lt;br /&gt;
[[Dammes other stuff]]&lt;br /&gt;
&lt;br /&gt;
[[Resor mm]]&lt;br /&gt;
&lt;br /&gt;
[[Hiseeu 5MP PTZ gk7605v100 sc223a]]&lt;br /&gt;
&lt;br /&gt;
== Plupp&#039;s stuff ==&lt;br /&gt;
&lt;br /&gt;
[[Joachim&#039;s research page]]&lt;br /&gt;
&lt;br /&gt;
[[Useful EXWINGS stuff]]&lt;br /&gt;
&lt;br /&gt;
== Thesse&#039;s stuff ==&lt;br /&gt;
&lt;br /&gt;
[[CHANG-ES Interim wiki]] (needs login access)&lt;br /&gt;
&lt;br /&gt;
== Other pages ==&lt;br /&gt;
&lt;br /&gt;
== Wiki ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;[[Cheat sheet]]&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[MediaWiki format help]]&lt;br /&gt;
&lt;br /&gt;
[[Sandbox]] In here you can test wiki language.&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki]&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Main_Page&amp;diff=445</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Main_Page&amp;diff=445"/>
		<updated>2025-05-26T13:07:44Z</updated>

		<summary type="html">&lt;p&gt;Damme: /* Damme&amp;#039;s stuff */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== World Wide Wiegert Wiki - The best wiki in the world! ==&lt;br /&gt;
 Skapa en sida genom att skapa dig ett konto, editera denna sida och skriv länken inom brackets&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[namn på sidan]]&amp;lt;/nowiki&amp;gt; - spara och klicka på länken så är det bara att skriva vidare!&lt;br /&gt;
&lt;br /&gt;
== Damme&#039;s stuff ==&lt;br /&gt;
[[About me - Daniel Wiegert]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;[[Damme&#039;s linux stuff]]&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Damme&#039;s windows stuff]]&lt;br /&gt;
&lt;br /&gt;
[[Ubuntu Server LTS]]&lt;br /&gt;
&lt;br /&gt;
[[Hårdvara]]&lt;br /&gt;
&lt;br /&gt;
[[Development]]&lt;br /&gt;
&lt;br /&gt;
[[Dammes other stuff]]&lt;br /&gt;
&lt;br /&gt;
[[Resor mm]]&lt;br /&gt;
&lt;br /&gt;
[[Hiseeu 5MP PTZ gk7605v100 sc223a]]&lt;br /&gt;
&lt;br /&gt;
== Plupp&#039;s stuff ==&lt;br /&gt;
&lt;br /&gt;
[[Joachim&#039;s research page]]&lt;br /&gt;
&lt;br /&gt;
[[Useful EXWINGS stuff]]&lt;br /&gt;
&lt;br /&gt;
== Thesse&#039;s stuff ==&lt;br /&gt;
&lt;br /&gt;
[[CHANG-ES Interim wiki]] (needs login access)&lt;br /&gt;
&lt;br /&gt;
== Other pages ==&lt;br /&gt;
&lt;br /&gt;
== Wiki ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;[[Cheat sheet]]&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[MediaWiki format help]]&lt;br /&gt;
&lt;br /&gt;
[[Sandbox]] In here you can test wiki language.&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki]&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=World_Wide_Wiegert_Wiki_-_WWWW:Copyrights&amp;diff=422</id>
		<title>World Wide Wiegert Wiki - WWWW:Copyrights</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=World_Wide_Wiegert_Wiki_-_WWWW:Copyrights&amp;diff=422"/>
		<updated>2024-08-31T14:07:07Z</updated>

		<summary type="html">&lt;p&gt;Damme: Created page with &amp;quot;Copyright? Its on the internet right? There is no copyright ^^ Unless some page specifically says otherwise.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Copyright? Its on the internet right? There is no copyright ^^ Unless some page specifically says otherwise.&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Damme%27s_linux_stuff&amp;diff=409</id>
		<title>Damme&#039;s linux stuff</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Damme%27s_linux_stuff&amp;diff=409"/>
		<updated>2024-02-28T10:26:52Z</updated>

		<summary type="html">&lt;p&gt;Damme: /* Docker */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Profile.d/damme.sh ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
alias ls=&#039;ls --group-directories-first -hF --color=auto&#039;&lt;br /&gt;
alias more=&#039;less&#039;&lt;br /&gt;
alias nano=&#039;nano -w&#039;&lt;br /&gt;
alias du=&#039;du -c -h&#039;&lt;br /&gt;
alias diff=&#039;diff --color=auto&#039;&lt;br /&gt;
alias grep=&#039;grep --color=auto -ni&#039;&lt;br /&gt;
alias fgrep=&#039;fgrep --color=auto&#039;&lt;br /&gt;
alias egrep=&#039;egrep --color=auto&#039;&lt;br /&gt;
alias free=&#039;free -h&#039;&lt;br /&gt;
alias ip=&#039;ip -color=auto&#039;&lt;br /&gt;
alias ll=&#039;ls -l&#039;&lt;br /&gt;
alias la=&#039;ls -A&#039;&lt;br /&gt;
alias l=&#039;ls -lrtha&#039;&lt;br /&gt;
&lt;br /&gt;
function cdl(){&lt;br /&gt;
  cd &amp;quot;&amp;quot;&lt;br /&gt;
  ls&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function cdal(){&lt;br /&gt;
  cd &amp;quot;&amp;quot;&lt;br /&gt;
  ls -al&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
export LESS=-R&lt;br /&gt;
export LESS_TERMCAP_mb=$&#039;\E[1;31m&#039;     # begin blink&lt;br /&gt;
export LESS_TERMCAP_md=$&#039;\E[1;36m&#039;     # begin bold&lt;br /&gt;
export LESS_TERMCAP_me=$&#039;\E[0m&#039;        # reset bold/blink&lt;br /&gt;
export LESS_TERMCAP_so=$&#039;\E[01;44;33m&#039; # begin reverse video&lt;br /&gt;
export LESS_TERMCAP_se=$&#039;\E[0m&#039;        # reset reverse video&lt;br /&gt;
export LESS_TERMCAP_us=$&#039;\E[1;32m&#039;     # begin underline&lt;br /&gt;
export LESS_TERMCAP_ue=$&#039;\E[0m&#039;        # reset underline&lt;br /&gt;
&lt;br /&gt;
export EDITOR=&amp;quot;nano&amp;quot;&lt;br /&gt;
&lt;br /&gt;
export TERM=&#039;xterm-256color&#039;&lt;br /&gt;
# if term == rxvt-unicode-256color &amp;amp;&amp;amp; file not exists -&amp;gt; xterm-256color&lt;br /&gt;
&lt;br /&gt;
_islinux=false&lt;br /&gt;
[[ &amp;quot;$(uname -s)&amp;quot; =~ Linux|GNU|GNU/* ]] &amp;amp;&amp;amp; _islinux=true&lt;br /&gt;
&lt;br /&gt;
_isarch=false&lt;br /&gt;
[[ -f /etc/arch-release ]] &amp;amp;&amp;amp; _isarch=true&lt;br /&gt;
&lt;br /&gt;
_isxrunning=false&lt;br /&gt;
[[ -n &amp;quot;$DISPLAY&amp;quot; ]] &amp;amp;&amp;amp; _isxrunning=true&lt;br /&gt;
&lt;br /&gt;
_isroot=false&lt;br /&gt;
[[ $UID -eq 0 ]] &amp;amp;&amp;amp; _isroot=true&lt;br /&gt;
&lt;br /&gt;
C=$(cat /etc/hostname | md5sum)&lt;br /&gt;
I=&amp;quot;${C:0:1}&amp;quot;&lt;br /&gt;
H=&amp;quot;${C:1:2}&amp;quot;&lt;br /&gt;
CSERV=$((0x${H}))&lt;br /&gt;
&lt;br /&gt;
if [ $CSERV -lt 16 ] ; then&lt;br /&gt;
  CSERV=$(($CSERV+16))&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ $CSERV -gt 231 ] ; then&lt;br /&gt;
  CSERV=$(($CSERV-25))&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
CSERV=&amp;quot;$(tput setaf $CSERV)&amp;quot;&lt;br /&gt;
CNONE=&amp;quot;$(tput sgr0)&amp;quot;&lt;br /&gt;
CROOT=&amp;quot;$(tput setaf 48)&amp;quot;&lt;br /&gt;
if $_isroot; then&lt;br /&gt;
  CROOT=&amp;quot;$(tput setaf 196)&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
CPATH=&amp;quot;$(tput setaf 38)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
export PS1=&amp;quot;[$CSERV\u@\h$CNONE]$CPATH\w$CROOT\$$CNONE &amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[ -f /bin/neofetch ]] &amp;amp;&amp;amp; neofetch --disable packages gpu&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Text manipulation ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
sed -e # Show result, Will not change anything&lt;br /&gt;
&lt;br /&gt;
sed -i &#039;s/[Search]/[Replace]/g&#039; [File]&lt;br /&gt;
sed -i &#039;/[row containing]/ s/$/ [append]/&#039; [File] # append to end of line of search&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SSH ==&lt;br /&gt;
&lt;br /&gt;
=== SOCKS5 proxy ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
ssh -C -N -D [local port] [name]@[server]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generate SSH keys ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#generate all keys - don&#039;t ask for passkey, save in ~/.ssh/id_rsa&lt;br /&gt;
ssh-keygen -t ed25519 -N &#039;&#039; -f ~/.ssh/id_rsa&lt;br /&gt;
&lt;br /&gt;
# if ~/.ssh/id_rsa.pub is missing!&lt;br /&gt;
ssh-keygen -y -f ~/.ssh/id_rsa &amp;gt; ~/.ssh/id_rsa.pub&lt;br /&gt;
&lt;br /&gt;
# copy local &#039;id_rsa.pub&#039; to remote host &#039;~/.ssh/authorized_keys&#039;&lt;br /&gt;
ssh-copy-id user@host&lt;br /&gt;
&lt;br /&gt;
# Generate all keys for server&lt;br /&gt;
ssh-keygen -A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sshpiper auth process:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
(client)[id_rsa.pub] -&amp;gt; (sshpiper)[authorized_keys] [id_rsa.pub] -&amp;gt; (target) [authorized_keys]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== pacman ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
pacman -F $filename # Search package including $filename&lt;br /&gt;
pacman -Qo $filename # Search package including $filename&lt;br /&gt;
pacman -Ss $package # Search $package&lt;br /&gt;
pacman -S $package # Install $package&lt;br /&gt;
pacman -R $package # Remove $package&lt;br /&gt;
&lt;br /&gt;
# remove partial packages:&lt;br /&gt;
find /var/cache/pacman/pkg/ -iname &amp;quot;*.part&amp;quot; -delete&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Filesystems and LVM ==&lt;br /&gt;
=== MDADM ===&lt;br /&gt;
Growing -&amp;gt; https://raid.wiki.kernel.org/index.php/Growing&lt;br /&gt;
&lt;br /&gt;
=== LVM ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
lvcreate -L [SIZE]g -n [NAME] [VG] /dev/[PV]&lt;br /&gt;
&lt;br /&gt;
lvcreate --type cache --cachemode writethrough -L 20G -n dataLV_cachepool dataVG/dataLV /dev/fast&lt;br /&gt;
# writethrough ensures that any data written will be stored both in the cache pool LV and on the origin LV. The loss of a device associated with the cache pool LV in this case would not mean the loss of any data;&lt;br /&gt;
# writeback ensures better performance, but at the cost of a higher risk of data loss in case the drive used for cache fails.&lt;br /&gt;
&lt;br /&gt;
lvconvert --splitcache MyVolGroup/rootvol&lt;br /&gt;
lvconvert --uncache MyVolGroup/rootvol&lt;br /&gt;
&lt;br /&gt;
lvresize --resizefs -L +XG vg/lv &lt;br /&gt;
&lt;br /&gt;
# Move LV Between physical drives in same VG - Can be done LIVE&lt;br /&gt;
# Create mirror&lt;br /&gt;
lvconvert -m 1 [LV] [NEW DEV] &lt;br /&gt;
# wait for it to copy data (Check via lvs)&lt;br /&gt;
# Remove mirror&lt;br /&gt;
lvconvert -m 0 [LV] [OLD DEV] &lt;br /&gt;
&lt;br /&gt;
# Alt: pvmove -n [LV] [OLD DEV] [NEW DEV]&lt;br /&gt;
&lt;br /&gt;
lvcreate --type thin-pool -n thin-pool -L size vg [pv?]&lt;br /&gt;
&lt;br /&gt;
lvs -o +devices&lt;br /&gt;
&lt;br /&gt;
lvremove [LVM]&lt;br /&gt;
# Logical volume [LVM] is used by another device.&lt;br /&gt;
kpartx -d /dev/mapper/[LVM]&lt;br /&gt;
#dmsetup ls&lt;br /&gt;
dmsetup remove [LVM]&lt;br /&gt;
lvremove [LVM]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== fstab ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/source /destination none defaults,bind 0 0&lt;br /&gt;
&lt;br /&gt;
#check fstab:&lt;br /&gt;
mount -fav&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
pv -s 20G &amp;lt; /dev/foo &amp;gt; /dev/baz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
diskspd.exe –c50G -d300 -r -w40 -t8 -o32 -b64K -Sh -L E:\diskpsdtmp.dat &amp;gt; DiskSpeedResults.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Resue Data ===&lt;br /&gt;
https://www.gnu.org/software/ddrescue/manual/ddrescue_manual.html&lt;br /&gt;
&lt;br /&gt;
=== BTRFS ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Resize BTRFS&lt;br /&gt;
btrfs filesystem resize max /path&lt;br /&gt;
btrfs device usage /path&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Raid sas etc ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# spin down sas&lt;br /&gt;
sdparm --readonly --command=stop /dev/xxx&lt;br /&gt;
&lt;br /&gt;
# spin up sas&lt;br /&gt;
sdparm --command=start /dev/xxx&lt;br /&gt;
&lt;br /&gt;
# check status, &amp;quot;Not ready&amp;quot; = not spinning, &amp;quot;Ready&amp;quot; = Spinning&lt;br /&gt;
sdparm --command=ready /dev/xxx&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Low level format SATA ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
hdparm -I /dev/sda&lt;br /&gt;
# if frozen need to unfreeze&lt;br /&gt;
hdparm --user-master u --security-set-pass llformat /dev/sd_&lt;br /&gt;
hdparm --user-master u --security-erase llformat /dev/sd_&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Docker ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
docker ps [-a/--all] # print (all) running containers&lt;br /&gt;
docker exec -it [container_id] /bin/bash # run shell in container#&lt;br /&gt;
docker update --cpuset-cpus=&amp;quot;1-5&amp;quot; [container_id]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reinstall Portainer&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
docker stop portainer&lt;br /&gt;
docker rm portainer&lt;br /&gt;
docker pull portainer/portainer-ce&lt;br /&gt;
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=unless-stopped -v /var/run/docker.sock:/var/run/docker.sock -v /opt/portainer/data:/data portainer/portainer-ce&lt;br /&gt;
&lt;br /&gt;
docker stop portainer &amp;amp;&amp;amp; docker rm portainer &amp;amp;&amp;amp; docker pull portainer/portainer-ce &amp;amp;&amp;amp; docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=unless-stopped -v /var/run/docker.sock:/var/run/docker.sock -v /opt/portainer/data:/data portainer/portainer-ce&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generate rsa keys for encrypted communication between &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#server:&lt;br /&gt;
export PASS=SuperSecret&lt;br /&gt;
export SUBJ=&#039;/C=SE/L=Skällinge/O=Unimatrix&#039;&lt;br /&gt;
export DAYS=3650&lt;br /&gt;
&lt;br /&gt;
openssl genrsa -aes256 -out ca-key.pem -passout pass:$PASS 4096&lt;br /&gt;
openssl req -new -x509 -days $DAYS -key ca-key.pem -sha256 -out ca.pem -passin pass:$PASS -subj $SUBJ&lt;br /&gt;
&lt;br /&gt;
openssl genrsa -out server-key.pem 4096&lt;br /&gt;
&lt;br /&gt;
#client:&lt;br /&gt;
openssl req -subj &amp;quot;/CN=$HOSTNAME&amp;quot; -sha256 -new -key server-key.pem -out server.csr&lt;br /&gt;
&lt;br /&gt;
echo subjectAltName = DNS:$HOSTNAME,IP:10.0.0.200,IP:127.0.0.1 &amp;gt;&amp;gt; extfile.cnf&lt;br /&gt;
echo extendedKeyUsage = serverAuth &amp;gt;&amp;gt; extfile.cnf&lt;br /&gt;
openssl x509 -req -days $DAYS -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \&lt;br /&gt;
  -CAcreateserial -out server-cert.pem -extfile extfile.cnf -passin pass:$PASS&lt;br /&gt;
&lt;br /&gt;
openssl genrsa -out key.pem 4096&lt;br /&gt;
openssl req -subj &#039;/CN=client&#039; -new -key key.pem -out client.csr&lt;br /&gt;
echo extendedKeyUsage = clientAuth &amp;gt; extfile-client.cnf&lt;br /&gt;
openssl x509 -req -days $DAYS -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \&lt;br /&gt;
  -CAcreateserial -out cert.pem -extfile extfile-client.cnf -passin pass:$PASS&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== /etc/systemd/system/docker.service.d/execstart.conf ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
[Service]&lt;br /&gt;
ExecStart=&lt;br /&gt;
#ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:4243&lt;br /&gt;
ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/etc/docker/ssl/ca.pem --tlscert=/etc/docker/ssl/server-cert.pem --tlskey=/etc/docker/ssl/server-key.pem -H fd:// -H tcp://0.0.0.0:2376&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== netcat ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;test&amp;quot; | nc wiegert.link 12345 # client&lt;br /&gt;
nc -l 12345 -k # listener server, k = continuous&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== systemd ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
systemctl edit --full lvm2-lvmetad.service # edit service&lt;br /&gt;
systemctl edit lvm2-lvmetad.service # edit service override&lt;br /&gt;
systemctl daemon-reload # Reload systemd manager configuration&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== rsync ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
rsync -rav&lt;br /&gt;
rsync -ravHAX&lt;br /&gt;
rsync -avHAX --one-file-system&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ZFS ==&lt;br /&gt;
[[ZFS Best practices]]&lt;br /&gt;
&lt;br /&gt;
== Other stuff ==&lt;br /&gt;
Fixperm on files (664) and folders (775):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
find . -type d -exec chown root:share {} \; -exec chmod 775 {} \;&lt;br /&gt;
find . -type f -exec chown root:share {} \; -exec chmod 664 {} \;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
docker + kvm + networking = :( https://serverfault.com/questions/963759/docker-breaks-libvirt-bridge-network&lt;br /&gt;
&lt;br /&gt;
pfsense port forwarding while not being default gw: https://docs.netgate.com/pfsense/en/latest/troubleshooting/nat.html#figure-manual-outbound-nat-local-device&lt;br /&gt;
&lt;br /&gt;
smtprelay via gmail with postfix mailutils, s-nail&lt;br /&gt;
https://www.howtoforge.com/tutorial/configure-postfix-to-use-gmail-as-a-mail-relay/&lt;br /&gt;
&lt;br /&gt;
Nut sending mails -&amp;gt; https://freekode.org/nut-sending-emails/&lt;br /&gt;
&lt;br /&gt;
Secure rsync over SSH without shell access - https://lxadm.com/Secure_rsync_over_SSH_without_shell_access&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
ipv4=$(curl -s -X GET -4 https://ifconfig.co)&lt;br /&gt;
ipv6=$(curl -s -X GET -6 https://ifconfig.co)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fail2ban ==&lt;br /&gt;
https://wiki.archlinux.org/index.php/Fail2ban&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
sudo pacman -Sy&lt;br /&gt;
sudo pacman --noconfirm -S fail2ban&lt;br /&gt;
sudo cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;gt; /etc/fail2ban/jail.local&lt;br /&gt;
[DEFAULT]&lt;br /&gt;
bantime = 5d&lt;br /&gt;
&lt;br /&gt;
[sshd]&lt;br /&gt;
enabled = true&lt;br /&gt;
mode = aggressive&lt;br /&gt;
EOF&lt;br /&gt;
sudo systemctl enable fail2ban.service&lt;br /&gt;
sudo systemctl start fail2ban.service&lt;br /&gt;
&lt;br /&gt;
# Fail2ban status&lt;br /&gt;
fail2ban-client status sshd&lt;br /&gt;
&lt;br /&gt;
# Unban ip:&lt;br /&gt;
fail2ban-client set sshd unbanip 1.2.3.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UDEV fun! ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
KERNEL==&amp;quot;ttyACM*&amp;quot;, SUBSYSTEM==&amp;quot;tty&amp;quot;, ENV{ID_USB_INTERFACE_NUM}==&amp;quot;00&amp;quot;, ENV{ID_VENDOR_ID}==&amp;quot;0451&amp;quot;, SYMLINK+=&amp;quot;TIherdsman&amp;quot;&lt;br /&gt;
KERNEL==&amp;quot;ttyACM*&amp;quot;, SUBSYSTEM==&amp;quot;tty&amp;quot;, ENV{ID_USB_INTERFACE_NUM}==&amp;quot;03&amp;quot;, ENV{ID_VENDOR_ID}==&amp;quot;0451&amp;quot;, SYMLINK+=&amp;quot;TImcu&amp;quot;&lt;br /&gt;
&lt;br /&gt;
SUBSYSTEMS==&amp;quot;usb&amp;quot;, ATTRS{idVendor}==&amp;quot;047c&amp;quot;, ATTRS{idProduct}==&amp;quot;ffff&amp;quot;, SYMLINK+=&amp;quot;DellUPS0&amp;quot;, MODE=&amp;quot;0666&amp;quot;&lt;br /&gt;
&lt;br /&gt;
KERNEL==&amp;quot;ttyUSB*&amp;quot;, SUBSYSTEM==&amp;quot;tty&amp;quot;, ENV{ID_USB_INTERFACE_NUM}==&amp;quot;00&amp;quot;, ENV{ID_VENDOR_ID}==&amp;quot;1a86&amp;quot;, SYMLINK+=&amp;quot;GSM-SIM800&amp;quot;, MODE=&amp;quot;0666&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Reload and re-trigger udev rules without reboot&lt;br /&gt;
udevadm control --reload-rules &amp;amp;&amp;amp; udevadm trigger&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wireshark ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
ssh user@remote &amp;quot;tcpdump -s0 -w - &#039;port 1234&#039;&amp;quot; | wireshark -k -i -&lt;br /&gt;
&lt;br /&gt;
# Filter macaddress beginning with:&lt;br /&gt;
(ether [0:4] &amp;amp; 0xffffff00 = 0x000c2200) or (ether [6:4] &amp;amp; 0xffffff00 = 0x000c2200)&lt;br /&gt;
&lt;br /&gt;
# First / Last&lt;br /&gt;
eth.addr[0:3] == bc:05:43&lt;br /&gt;
eth.addr[4:2] == 28:06&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Server Queen Specific changes ==&lt;br /&gt;
* https://forums.servethehome.com/index.php?threads/flash-crossflash-dell-h330-raid-card-to-hba330-12gbps-hba-it-firmware.25498/#post-236242&lt;br /&gt;
* DISABLE WATCHDOG! Server will reboot due to watchdog during reboot in filesystem tasks.. BAD!&lt;br /&gt;
* Added &amp;quot;TimeoutSec=900&amp;quot; in [Service]-Section &#039;&#039;&#039;/etc/systemd/system/lvm2-lvmetad.service&#039;&#039;&#039; , otherwise shutdown takes too long time and lvmetad gets killed instead of clean shutdown, Results in failed lv which needs lvchange -ay [lvm] or worse - lvconvert --repair.&lt;br /&gt;
*  &amp;lt;del&amp;gt; Docker &#039;&#039;&#039;/etc/docker/daemon.json&#039;&#039;&#039; added &amp;quot;iptables&amp;quot;: false.&amp;lt;/del&amp;gt; Update: Use /etc/sysctl.d/30-ipforward.conf and /etc/udev/rules.d/99-bridge.rules instead. Docker kills kvm bridges without it. &lt;br /&gt;
* sysctl rules:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#/etc/sysctl.d/40-ipv6.conf:&lt;br /&gt;
# Disable IPv6&lt;br /&gt;
net.ipv6.conf.all.disable_ipv6 = 1&lt;br /&gt;
net.ipv6.conf.nic0.disable_ipv6 = 1&lt;br /&gt;
...&lt;br /&gt;
net.ipv6.conf.nicN.disable_ipv6 = 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Note on sysctl reload : https://serverfault.com/questions/963759/docker-breaks-libvirt-bridge-network&lt;br /&gt;
&lt;br /&gt;
* udev rules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# /etc/sysctl.d/30-ipforward.conf&lt;br /&gt;
net.ipv4.ip_forward=1&lt;br /&gt;
net.ipv6.conf.default.forwarding=1&lt;br /&gt;
net.ipv6.conf.all.forwarding=1&lt;br /&gt;
&lt;br /&gt;
# /etc/udev/rules.d/60-md-stripe-cache.rules&lt;br /&gt;
# Change stripe cache size to maximum, we got the ram! memory_consumed = system_page_size * nr_disks * stripe_cache_size&lt;br /&gt;
# https://www.cyberciti.biz/tips/linux-raid-increase-resync-rebuild-speed.html&lt;br /&gt;
SUBSYSTEM==&amp;quot;block&amp;quot;, KERNEL==&amp;quot;md*&amp;quot;, ACTION==&amp;quot;change&amp;quot;, TEST==&amp;quot;md/stripe_cache_size&amp;quot;, ATTR{md/stripe_cache_size}=&amp;quot;32768&amp;quot;&lt;br /&gt;
&lt;br /&gt;
## TODO ? sudo blockdev --setra ?? -&amp;gt; https://unix.stackexchange.com/questions/71364/persistent-blockdev-setra-read-ahead-setting&lt;br /&gt;
&lt;br /&gt;
# /etc/udev/rules.d/89-usb.rules&lt;br /&gt;
#ups and TI zigbee module fix:&lt;br /&gt;
KERNEL==&amp;quot;ttyACM*&amp;quot;, SUBSYSTEM==&amp;quot;tty&amp;quot;, ENV{ID_USB_INTERFACE_NUM}==&amp;quot;00&amp;quot;, ENV{ID_VENDOR_ID}==&amp;quot;0451&amp;quot;, SYMLINK+=&amp;quot;TIherdsman&amp;quot;&lt;br /&gt;
KERNEL==&amp;quot;ttyACM*&amp;quot;, SUBSYSTEM==&amp;quot;tty&amp;quot;, ENV{ID_USB_INTERFACE_NUM}==&amp;quot;03&amp;quot;, ENV{ID_VENDOR_ID}==&amp;quot;0451&amp;quot;, SYMLINK+=&amp;quot;TImcu&amp;quot;&lt;br /&gt;
SUBSYSTEMS==&amp;quot;usb&amp;quot;, ATTRS{idVendor}==&amp;quot;047c&amp;quot;, ATTRS{idProduct}==&amp;quot;ffff&amp;quot;, SYMLINK+=&amp;quot;DellUPS0&amp;quot;, MODE=&amp;quot;0666&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# /etc/udev/rules.d/99-bridge.rules&lt;br /&gt;
# reload sysctl if br_netfilter is loaded, wierd stuff happens otherwise.&lt;br /&gt;
ACTION==&amp;quot;add&amp;quot;, SUBSYSTEM==&amp;quot;module&amp;quot;, KERNEL==&amp;quot;br_netfilter&amp;quot;, RUN+=&amp;quot;/sbin/sysctl --system&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# /usr/lib/udev/rules.d/11-dm-lvm.rules&lt;br /&gt;
# Create symlinks for top-level devices only.&lt;br /&gt;
## EDIT BY DAMME 2020-07-22 to populate partitions for libvirt&lt;br /&gt;
ENV{DM_VG_NAME}==&amp;quot;?*&amp;quot;, ENV{DM_LV_NAME}==&amp;quot;?*&amp;quot;, SYMLINK+=&amp;quot;$env{DM_VG_NAME}/$env{DM_LV_NAME}&amp;quot;&lt;br /&gt;
ENV{DM_VG_NAME}==&amp;quot;?*&amp;quot;, ENV{DM_LV_NAME}==&amp;quot;?*&amp;quot;, RUN+=&amp;quot;/sbin/kpartx -un /dev/%E{DM_VG_NAME}/%E{DM_LV_NAME}&amp;quot;, GOTO=&amp;quot;lvm_end&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== New server thoughts ==&lt;br /&gt;
* https://www.youtube.com/watch?v=MucGkPUMjNo Building a Power Efficient Home Server!&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=H%C3%A5rdvara&amp;diff=389</id>
		<title>Hårdvara</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=H%C3%A5rdvara&amp;diff=389"/>
		<updated>2023-12-17T11:08:19Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= URL =&lt;br /&gt;
* http://falstad.com/circuit/circuitjs.html&lt;br /&gt;
= Kicad =&lt;br /&gt;
* https://www.youtube.com/watch?v=aVUqaB0IMh4&lt;br /&gt;
&lt;br /&gt;
= Battery =&lt;br /&gt;
* https://rightbattery.com&lt;br /&gt;
&lt;br /&gt;
= Chip Hacking =&lt;br /&gt;
* https://github.com/debug-silicon/C8051F34x_Glitch&lt;br /&gt;
* https://www.mouser.se/ProductDetail/NewAE/NAE-CWLITE-ARM?qs=sGAEpiMZZMurtJ7VwBTl0Rm64lZhrtuCiY9L%252BSlUYJCrD9xW0HP9GQ%3D%3D&lt;br /&gt;
&lt;br /&gt;
= Retro = &lt;br /&gt;
* https://www.c64-tools.com/&lt;br /&gt;
* https://sourceforge.net/projects/hxcfloppyemu/&lt;br /&gt;
* https://www.ultimateretro.net/en/ motherboard list&lt;br /&gt;
* http://rom.by bios patcher&lt;br /&gt;
* http://www.vgmuseum.com&lt;br /&gt;
* https://www.youtube.com/watch?v=F1685u-QQ0k MCE adapter etc&lt;br /&gt;
* http://15khz.wikidot.com&lt;br /&gt;
* https://github.com/planeturban/15khzvgatester&lt;br /&gt;
* https://github.com/mecparts/RetroWiFiModem&lt;br /&gt;
&lt;br /&gt;
= Diverse projekt =&lt;br /&gt;
&lt;br /&gt;
== CosmicPi ==&lt;br /&gt;
http://cosmicpi.org&lt;br /&gt;
&lt;br /&gt;
https://github.com/CosmicPi/CosmicPiV1.7PCB&lt;br /&gt;
&lt;br /&gt;
http://www.amcrys.com/allpdf.html&lt;br /&gt;
&lt;br /&gt;
https://www.ketek.net/store/products/pm3325-wb/&lt;br /&gt;
&lt;br /&gt;
* https://www.digikey.se/product-detail/sv/AFBR-S4K33C0125B/516-AFBR-S4K33C0125B-ND/15768924?itemSeq=383463954 Kontrollera!&lt;br /&gt;
* https://www.digikey.se/product-detail/sv/AFBR-S4K33C0115L/516-AFBR-S4K33C0115L-ND/15768970?itemSeq=383464099 15µm 38400microcells&lt;br /&gt;
* https://www.digikey.se/product-detail/sv/AFBR-S4K33C0135L/516-AFBR-S4K33C0135L-ND/15768855?itemSeq=383464105 35µm 7396microcells&lt;br /&gt;
&lt;br /&gt;
== E-ink display + pi zero ==&lt;br /&gt;
* Vädericoner som font: https://www.alessioatzeni.com/meteocons/&lt;br /&gt;
* https://www.waveshare.com/7.8inch-e-Paper-HAT.htm&lt;br /&gt;
* http://www.waveshare.com/wiki/7.8inch_e-Paper_HAT&lt;br /&gt;
* https://archlinuxarm.org/platforms/armv6/raspberry-pi&lt;br /&gt;
* https://github.com/GregDMeyer/IT8951&lt;br /&gt;
* https://github.com/Mari0nV/IT8951/commits/master async&lt;br /&gt;
&lt;br /&gt;
Annat?&lt;br /&gt;
* https://gist.github.com/gavinhungry/1ab5b5450e0409765ad8906fcdd69997&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
==&amp;gt; /etc/udev/rules.d/10-local_i2c_group.rules &amp;lt;==&lt;br /&gt;
KERNEL==&amp;quot;i2c-[0-9]*&amp;quot;, GROUP=&amp;quot;i2c&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==&amp;gt; /etc/udev/rules.d/10-local_spi_group.rules &amp;lt;==&lt;br /&gt;
KERNEL==&amp;quot;spidev0.0&amp;quot;, GROUP=&amp;quot;spi&amp;quot;&lt;br /&gt;
&lt;br /&gt;
##################################################&lt;br /&gt;
ACTION==&amp;quot;add&amp;quot;, KERNEL==&amp;quot;spidev0.0&amp;quot;, MODE=&amp;quot;0666&amp;quot;&lt;br /&gt;
ACTION==&amp;quot;add&amp;quot;, KERNEL==&amp;quot;i2c-[0-1]*&amp;quot;, MODE=&amp;quot;0666&amp;quot;&lt;br /&gt;
ACTION==&amp;quot;add&amp;quot;, KERNEL==&amp;quot;dialout&amp;quot;, MODE=&amp;quot;0666&amp;quot;&lt;br /&gt;
ACTION==&amp;quot;add&amp;quot;, KERNEL==&amp;quot;ttyACM0&amp;quot;, MODE=&amp;quot;0666&amp;quot;&lt;br /&gt;
ACTION==&amp;quot;add&amp;quot;, KERNEL==&amp;quot;ttyAMA0&amp;quot;, MODE=&amp;quot;0666&amp;quot;&lt;br /&gt;
ACTION==&amp;quot;add&amp;quot;, KERNEL==&amp;quot;gpio&amp;quot;, MODE=&amp;quot;0666&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Voltcraft / Mansom xxxxx ==&lt;br /&gt;
&lt;br /&gt;
* https://asset.conrad.com/media10/add/160267/c1/-/en/000511632CD01/circuit-diagramm-511632-voltcraft-lsp-1403-bench-psu-adjustable-voltage-0-36-v-dc-0-5-a-80-w-masterslave-communication-protocol-no-of.pdf&lt;br /&gt;
&lt;br /&gt;
== Price tag displays ==&lt;br /&gt;
* https://github.com/atc1441/E-Paper_Pricetags/tree/main/Custom_PriceTag_AccesPoint&lt;br /&gt;
&lt;br /&gt;
== HAN meter to MQTT via Esp ==&lt;br /&gt;
* https://github.com/alekslt/HANToMQTT&lt;br /&gt;
* https://www.nek.no/wp-content/uploads/2018/11/Aidon-HAN-Interface-Description-v10A-ID-34331.pdf&lt;br /&gt;
&lt;br /&gt;
== Nord pool day ahead ==&lt;br /&gt;
https://www.nordpoolgroup.com/Market-data1/Dayahead/Area-Prices/ALL1/Hourly/?view=table&lt;br /&gt;
&lt;br /&gt;
== SR VMA test ==&lt;br /&gt;
https://vmaapi.sr.se/testapi/v2/alerts&lt;br /&gt;
&lt;br /&gt;
== Thunderbolt optical ==&lt;br /&gt;
* https://www.videodata.de/shop/products/de/Kabel-Adapter-Verbrauchsmaterial/Computer/Thunderbolt-3-Kabel/Corning-Thunderbolt-3-Kabel-50-m.html?XTCsid=4c3fgahuga73bsu2hlf0o0asg1&lt;br /&gt;
* https://eurocapa.com/cable-optique-thunderbolt3-25m.html&lt;br /&gt;
* https://www.avshop.ca/wire-amp-cable-data-cables-thunderbolt/corning-thunderbolt-3-usboptical-cable-50-meter&lt;br /&gt;
&lt;br /&gt;
= 3D skrivare mm =&lt;br /&gt;
* https://www.prusaprinters.org/prints/66965-delta-p-fan-duct-v2-r2-with-square-nut&lt;br /&gt;
* https://guides.bear-lab.com/Guide/Extrusion+multiplier+and+filament+diameter/8&lt;br /&gt;
* https://forum.prusaprinters.org/forum/original-prusa-i3-mk2-s-others-archive/pause-print-in-gcode/paged/2/&lt;br /&gt;
* https://www.thingiverse.com/thing:3288815&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Spis mm =&lt;br /&gt;
* https://ventilation.se/anslutningsror-insatskassett-162.htm&lt;br /&gt;
* https://www.karles.se/produkt/vattenmantlad-insatskamin-maja-12-hoger/&lt;br /&gt;
* https://kominki.eu/maja-pw-12-prawy-bs&lt;br /&gt;
* https://e-kominki24h.pl/p/767/4270/wklad-kominkowy-wodny-oliwia-17-prawy-pw-oliwia-kratki-wklady-z-plaszczem-wodnym-wklady-kominkowe.html&lt;br /&gt;
* https://kominki.eu/maja-pw-12-prawy&lt;br /&gt;
* BImSchV 2&lt;br /&gt;
&lt;br /&gt;
== WV ==&lt;br /&gt;
* https://www.classicvw.se/styrdampare-t1-1302-03/product_details.php/products_id/296&lt;br /&gt;
* https://www.classicvw.se/styrledssats-t1-1302-03-07-74-4-/product_details.php/products_id/4400&lt;br /&gt;
* https://www.classicvw.se/gummitatning-t1-68-framskarm-lykta-par-/product_details.php/products_id/3502&lt;br /&gt;
* https://www.classicvw.se/reflektor-stralkastare-t1-68-t2-68-73-t3-04-61-73-hella-1-/product_details.php/products_id/751&lt;br /&gt;
* https://www.classicvw.se/bussningar-framvagn-t1-1303-08-73-/product_details.php/products_id/5114&lt;br /&gt;
&lt;br /&gt;
== Raspberry pi ==&lt;br /&gt;
* https://iosoft.blog/2020/07/16/raspberry-pi-smi/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== External pcie ==&lt;br /&gt;
* OCuLink https://www.aliexpress.com/item/1005005512284033.html&lt;br /&gt;
alt&lt;br /&gt;
* M.2 To U.2 SFF-8643 https://www.aliexpress.com/item/1005006019873428.html&lt;br /&gt;
* SFF-8643 SAS SFF-8654 (slimsas) https://www.aliexpress.com/item/1005006261695531.html&lt;br /&gt;
* SFF-8654 8i to PCIe 4.0 x16 https://www.aliexpress.com/item/1005005811987501.html&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Sandbox&amp;diff=384</id>
		<title>Sandbox</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Sandbox&amp;diff=384"/>
		<updated>2023-11-20T16:49:16Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Welcome! ==&lt;br /&gt;
[[Random link]]&lt;br /&gt;
&lt;br /&gt;
== Syntax highlightning: ==&lt;br /&gt;
Code:&lt;br /&gt;
{{ #tag: syntaxhighlight |&lt;br /&gt;
&amp;lt;&amp;lt;noinclude/&amp;gt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def quick_sort(arr):&lt;br /&gt;
	less = []&lt;br /&gt;
	pivot_list = []&lt;br /&gt;
	more = []&lt;br /&gt;
	if len(arr) &amp;lt;= 1:&lt;br /&gt;
		return arr&lt;br /&gt;
	else:&lt;br /&gt;
		pass&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| lang=python }}&lt;br /&gt;
Result:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def quick_sort(arr):&lt;br /&gt;
	less = []&lt;br /&gt;
	pivot_list = []&lt;br /&gt;
	more = []&lt;br /&gt;
	if len(arr) &amp;lt;= 1:&lt;br /&gt;
		return arr&lt;br /&gt;
	else:&lt;br /&gt;
		pass&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Supported languages: https://www.mediawiki.org/wiki/Extension:SyntaxHighlight#Supported_languages&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:8472.png]]&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=File:8472.png&amp;diff=383</id>
		<title>File:8472.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=File:8472.png&amp;diff=383"/>
		<updated>2023-11-20T16:48:12Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Damme%27s_windows_stuff&amp;diff=382</id>
		<title>Damme&#039;s windows stuff</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Damme%27s_windows_stuff&amp;diff=382"/>
		<updated>2023-08-26T07:02:13Z</updated>

		<summary type="html">&lt;p&gt;Damme: /* DISM */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== DISM ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# https://www.risual.com/2022/03/adding-surface-drivers-to-windows-image/&lt;br /&gt;
Mount-WindowsImage -Path C:\Temp\surface\mount\ -ImagePath .\boot.wim -Index 1&lt;br /&gt;
Mount-WindowsImage -Path C:\Temp\surface\mount\ -ImagePath .\boot.wim -Index 2&lt;br /&gt;
&lt;br /&gt;
dism /export-image /SourceImageFile:&amp;quot;install.esd&amp;quot; /SourceIndex:6 /DestinationImageFile:install.wim /Compress:max /CheckIntegrity&lt;br /&gt;
&lt;br /&gt;
Mount-WindowsImage -Path C:\Temp\surface\mount\ -ImagePath .\install.wim -Index 1&lt;br /&gt;
Add-WindowsDriver -Path C:\Temp\surface\mount\ -Driver C:\Temp\surface\unpacked\SurfaceUpdate\ -Recurse&lt;br /&gt;
Dismount-WindowsImage -Path C:\Temp\surface\mount\ -Save&lt;br /&gt;
&lt;br /&gt;
DISM /Export-Image /SourceImageFile:install.wim /SourceIndex:1 /DestinationImageFile:install.esd /DestinationName:&amp;quot;Windows 10 Pro - Surface 5 drivers&amp;quot; /Compress:recovery&lt;br /&gt;
&lt;br /&gt;
DISM /Get-WimInfo /WimFile:&amp;quot;install.esd&amp;quot;&lt;br /&gt;
dism /Delete-Image /ImageFile:install.esd /Index:3&lt;br /&gt;
DISM /Export-Image /SourceImageFile:install.wim /SourceIndex:1 /DestinationImageFile:new.esd /Compress:recovery&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fixes ==&lt;br /&gt;
* windows debloater https://github.com/Sycnex/Windows10Debloater&lt;br /&gt;
* Win 11 explorer https://github.com/valinet/ExplorerPatcher&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
* https://github.com/integralfx/MemTestHelper&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Damme%27s_windows_stuff&amp;diff=381</id>
		<title>Damme&#039;s windows stuff</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Damme%27s_windows_stuff&amp;diff=381"/>
		<updated>2023-08-26T07:02:02Z</updated>

		<summary type="html">&lt;p&gt;Damme: /* DISM */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== DISM ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# https://www.risual.com/2022/03/adding-surface-drivers-to-windows-image/&lt;br /&gt;
Mount-WindowsImage -Path C:\Temp\surface\mount\ -ImagePath .\boot.wim -Index 1&lt;br /&gt;
Mount-WindowsImage -Path C:\Temp\surface\mount\ -ImagePath .\boot.wim -Index 2&lt;br /&gt;
&lt;br /&gt;
dism /export-image /SourceImageFile:&amp;quot;install.esd&amp;quot; /SourceIndex:6 /DestinationImageFile:install.wim /Compress:max /CheckIntegrity&lt;br /&gt;
&lt;br /&gt;
Mount-WindowsImage -Path C:\Temp\surface\mount\ -ImagePath .\install.wim -Index 1&lt;br /&gt;
Add-WindowsDriver -Path C:\Temp\surface\mount\ -Driver C:\Temp\surface\unpacked\SurfaceUpdate\ -Recurse&lt;br /&gt;
Dismount-WindowsImage -Path C:\Temp\surface\mount\ -Save&lt;br /&gt;
&lt;br /&gt;
DISM /Export-Image /SourceImageFile:install.wim /SourceIndex:1 /DestinationImageFile:install.esd /DestinationName:&amp;quot;Windows 10 Pro - Surface 5 drivers&amp;quot; /Compress:recovery&lt;br /&gt;
&lt;br /&gt;
DISM /Get-WimInfo /WimFile:&amp;quot;install.esd&amp;quot;&lt;br /&gt;
dism /Delete-Image /ImageFile:install.esd /Index:3&lt;br /&gt;
DISM /Export-Image /SourceImageFile:install.wim /SourceIndex:1 /DestinationImageFile:new.esd /Compress:recovery&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fixes ==&lt;br /&gt;
* windows debloater https://github.com/Sycnex/Windows10Debloater&lt;br /&gt;
* Win 11 explorer https://github.com/valinet/ExplorerPatcher&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
* https://github.com/integralfx/MemTestHelper&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Damme%27s_windows_stuff&amp;diff=380</id>
		<title>Damme&#039;s windows stuff</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Damme%27s_windows_stuff&amp;diff=380"/>
		<updated>2023-08-26T07:01:47Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== DISM ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Mount-WindowsImage -Path C:\Temp\surface\mount\ -ImagePath .\boot.wim -Index 1&lt;br /&gt;
Mount-WindowsImage -Path C:\Temp\surface\mount\ -ImagePath .\boot.wim -Index 2&lt;br /&gt;
&lt;br /&gt;
dism /export-image /SourceImageFile:&amp;quot;install.esd&amp;quot; /SourceIndex:6 /DestinationImageFile:install.wim /Compress:max /CheckIntegrity&lt;br /&gt;
&lt;br /&gt;
Mount-WindowsImage -Path C:\Temp\surface\mount\ -ImagePath .\install.wim -Index 1&lt;br /&gt;
Add-WindowsDriver -Path C:\Temp\surface\mount\ -Driver C:\Temp\surface\unpacked\SurfaceUpdate\ -Recurse&lt;br /&gt;
Dismount-WindowsImage -Path C:\Temp\surface\mount\ -Save&lt;br /&gt;
&lt;br /&gt;
DISM /Export-Image /SourceImageFile:install.wim /SourceIndex:1 /DestinationImageFile:install.esd /DestinationName:&amp;quot;Windows 10 Pro - Surface 5 drivers&amp;quot; /Compress:recovery&lt;br /&gt;
&lt;br /&gt;
DISM /Get-WimInfo /WimFile:&amp;quot;install.esd&amp;quot;&lt;br /&gt;
dism /Delete-Image /ImageFile:install.esd /Index:3&lt;br /&gt;
DISM /Export-Image /SourceImageFile:install.wim /SourceIndex:1 /DestinationImageFile:new.esd /Compress:recovery&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fixes ==&lt;br /&gt;
* windows debloater https://github.com/Sycnex/Windows10Debloater&lt;br /&gt;
* Win 11 explorer https://github.com/valinet/ExplorerPatcher&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
* https://github.com/integralfx/MemTestHelper&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Hiseeu_5MP_PTZ_gk7605v100_sc223a&amp;diff=379</id>
		<title>Hiseeu 5MP PTZ gk7605v100 sc223a</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Hiseeu_5MP_PTZ_gk7605v100_sc223a&amp;diff=379"/>
		<updated>2023-08-09T14:05:20Z</updated>

		<summary type="html">&lt;p&gt;Damme: /* uart */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sensor ==&lt;br /&gt;
Camera needs _4l driver, got it from telegram channel. Source?&lt;br /&gt;
config as follows:&lt;br /&gt;
* /etc/sensors/sc223a_4l_i2c_1080p.ini&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
[sensor]&lt;br /&gt;
Sensor_type=stSnsSc223aObj&lt;br /&gt;
Mode=WDR_MODE_NONE&lt;br /&gt;
DllFile=libsns_sc223a_4l.so&lt;br /&gt;
&lt;br /&gt;
[mode]&lt;br /&gt;
input_mode=INPUT_MODE_MIPI&lt;br /&gt;
raw_bitness=10&lt;br /&gt;
&lt;br /&gt;
[mipi]&lt;br /&gt;
lane_id = 0|1|-1|-1|-1|-1|-1|-1|      ;lane_id: -1 - disable&lt;br /&gt;
&lt;br /&gt;
[isp_image]&lt;br /&gt;
Isp_FrameRate=30&lt;br /&gt;
Isp_Bayer=BAYER_BGGR&lt;br /&gt;
&lt;br /&gt;
[vi_dev]&lt;br /&gt;
Input_mod=VI_MODE_MIPI&lt;br /&gt;
Work_mod =0     ;VI_WORK_MODE_1Multiplex = 0&lt;br /&gt;
                ;VI_WORK_MODE_2Multiplex,&lt;br /&gt;
                ;VI_WORK_MODE_4Multiplex&lt;br /&gt;
Combine_mode =0 ;Y/C composite or separation mode&lt;br /&gt;
                ;VI_COMBINE_COMPOSITE = 0 /*Composite mode */&lt;br /&gt;
                ;VI_COMBINE_SEPARATE,     /*Separate mode */&lt;br /&gt;
Comp_mode    =0 ;Component mode (single-component or dual-component)&lt;br /&gt;
                ;VI_COMP_MODE_SINGLE = 0, /*single component mode */&lt;br /&gt;
                ;VI_COMP_MODE_DOUBLE = 1, /*double component mode */&lt;br /&gt;
Clock_edge   =1 ;Clock edge mode (sampling on the rising or falling edge)&lt;br /&gt;
                ;VI_CLK_EDGE_SINGLE_UP=0, /*rising edge */&lt;br /&gt;
                ;VI_CLK_EDGE_SINGLE_DOWN, /*falling edge */&lt;br /&gt;
Mask_num     =2 ;Component mask&lt;br /&gt;
Mask_0       =0xFFF00000&lt;br /&gt;
Mask_1       =0x0&lt;br /&gt;
Scan_mode    = 1;VI_SCAN_INTERLACED = 0&lt;br /&gt;
                ;VI_SCAN_PROGRESSIVE,&lt;br /&gt;
Data_seq     =2 ;data sequence (ONLY for YUV format)&lt;br /&gt;
                ;----2th component U/V sequence in bt1120&lt;br /&gt;
                ;    VI_INPUT_DATA_VUVU = 0,&lt;br /&gt;
                ;    VI_INPUT_DATA_UVUV,&lt;br /&gt;
                ;----input sequence for yuv&lt;br /&gt;
                ;    VI_INPUT_DATA_UYVY = 0,&lt;br /&gt;
                ;    VI_INPUT_DATA_VYUY,&lt;br /&gt;
                ;    VI_INPUT_DATA_YUYV,&lt;br /&gt;
                ;    VI_INPUT_DATA_YVYU&lt;br /&gt;
&lt;br /&gt;
Vsync   =1      ; vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_FIELD = 0,&lt;br /&gt;
                ;VI_VSYNC_PULSE,&lt;br /&gt;
VsyncNeg=1      ;Polarity of the vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_VSYNC_NEG_LOW /*if VIU_VSYNC_E&lt;br /&gt;
Hsync  =0       ;Attribute of the horizontal synchronization signal&lt;br /&gt;
                ;VI_HSYNC_VALID_SINGNAL = 0,&lt;br /&gt;
                ;VI_HSYNC_PULSE,&lt;br /&gt;
HsyncNeg =0     ;Polarity of the horizontal synchronization signal&lt;br /&gt;
                ;VI_HSYNC_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_HSYNC_NEG_LOW&lt;br /&gt;
VsyncValid =1   ;Attribute of the valid vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_NORM_PULSE = 0,&lt;br /&gt;
                ;VI_VSYNC_VALID_SINGAL,&lt;br /&gt;
VsyncValidNeg =0;Polarity of the valid vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_VALID_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_VSYNC_VALID_NEG_LOW&lt;br /&gt;
Timingblank_HsyncHfb =0     ;Horizontal front blanking width&lt;br /&gt;
Timingblank_HsyncAct =1920  ;Horizontal effetive width&lt;br /&gt;
Timingblank_HsyncHbb =0     ;Horizontal back blanking width&lt;br /&gt;
Timingblank_VsyncVfb =0     ;Vertical front blanking height&lt;br /&gt;
Timingblank_VsyncVact =1080  ;Vertical effetive width&lt;br /&gt;
Timingblank_VsyncVbb=0      ;Vertical back blanking height&lt;br /&gt;
Timingblank_VsyncVbfb =0    ;Even-field vertical front blanking height(interlace, invalid progressive)&lt;br /&gt;
Timingblank_VsyncVbact=0    ;Even-field vertical effetive width(interlace, invalid progressive)&lt;br /&gt;
Timingblank_VsyncVbbb =0    ;Even-field vertical back blanking height(interlace, invalid progressive)&lt;br /&gt;
InputDataType=1 ;VI_DATA_TYPE_YUV = 0,VI_DATA_TYPE_RGB = 1,&lt;br /&gt;
DataRev      =FALSE ;Data reverse. FALSE = 0; TRUE = 1&lt;br /&gt;
DevRect_x=200&lt;br /&gt;
DevRect_y=20&lt;br /&gt;
DevRect_w=1920&lt;br /&gt;
DevRect_h=1080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== uart ==&lt;br /&gt;
* ./general/package/all-patches/linux/9000-enable-uart1.patch&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
--- a/arch/arm/boot/dts/gk7605v100-demb.dts       2023-08-09 13:43:00.715983714 +0200&lt;br /&gt;
+++ b/arch/arm/boot/dts/gk7605v100-demb.dts       2023-08-09 13:42:25.609040743 +0200&lt;br /&gt;
@@ -20,7 +20,7 @@&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;uart1 {&lt;br /&gt;
-       status = &amp;quot;disabled&amp;quot;;&lt;br /&gt;
+       status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;uart2 {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
ipctool reginfo | grep UART&lt;br /&gt;
&lt;br /&gt;
devmem 0x112c0078 32 0x01&lt;br /&gt;
devmem 0x112c007c 32 0x01&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== reflash kernel via uboot ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
## does not work?&lt;br /&gt;
setenv ipaddr 192.168.1.10; setenv serverip 192.168.1.11&lt;br /&gt;
setenv flash_addr 0x50000&lt;br /&gt;
setenv uimage_size 0x300000&lt;br /&gt;
&lt;br /&gt;
mw.b ${baseaddr} 0xff 0x1000000&lt;br /&gt;
tftpboot ${baseaddr} uImage&lt;br /&gt;
sf probe 0; sf lock 0;&lt;br /&gt;
&lt;br /&gt;
sf erase ${flash_addr} ${uimage_size}&lt;br /&gt;
sf write ${loadaddr} ${flash_addr} ${filesize}&lt;br /&gt;
original:&lt;br /&gt;
&lt;br /&gt;
uknor16m=mw.b ${baseaddr} ff 1000000; tftpboot ${baseaddr} uImage.${soc} &amp;amp;&amp;amp; sf probe 0; sf erase 0x50000 0x300000; sf write ${baseaddr} 0x50000 ${filesize}&lt;br /&gt;
urnor16m=mw.b ${baseaddr} ff 1000000; tftpboot ${baseaddr} rootfs.squashfs.${soc} &amp;amp;&amp;amp; sf probe 0; sf erase 0x350000 0xa00000; sf write ${baseaddr} 0x350000 ${filesize}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Hiseeu_5MP_PTZ_gk7605v100_sc223a&amp;diff=378</id>
		<title>Hiseeu 5MP PTZ gk7605v100 sc223a</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Hiseeu_5MP_PTZ_gk7605v100_sc223a&amp;diff=378"/>
		<updated>2023-08-09T13:24:48Z</updated>

		<summary type="html">&lt;p&gt;Damme: /* reflash kernel via uboot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sensor ==&lt;br /&gt;
Camera needs _4l driver, got it from telegram channel. Source?&lt;br /&gt;
config as follows:&lt;br /&gt;
* /etc/sensors/sc223a_4l_i2c_1080p.ini&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
[sensor]&lt;br /&gt;
Sensor_type=stSnsSc223aObj&lt;br /&gt;
Mode=WDR_MODE_NONE&lt;br /&gt;
DllFile=libsns_sc223a_4l.so&lt;br /&gt;
&lt;br /&gt;
[mode]&lt;br /&gt;
input_mode=INPUT_MODE_MIPI&lt;br /&gt;
raw_bitness=10&lt;br /&gt;
&lt;br /&gt;
[mipi]&lt;br /&gt;
lane_id = 0|1|-1|-1|-1|-1|-1|-1|      ;lane_id: -1 - disable&lt;br /&gt;
&lt;br /&gt;
[isp_image]&lt;br /&gt;
Isp_FrameRate=30&lt;br /&gt;
Isp_Bayer=BAYER_BGGR&lt;br /&gt;
&lt;br /&gt;
[vi_dev]&lt;br /&gt;
Input_mod=VI_MODE_MIPI&lt;br /&gt;
Work_mod =0     ;VI_WORK_MODE_1Multiplex = 0&lt;br /&gt;
                ;VI_WORK_MODE_2Multiplex,&lt;br /&gt;
                ;VI_WORK_MODE_4Multiplex&lt;br /&gt;
Combine_mode =0 ;Y/C composite or separation mode&lt;br /&gt;
                ;VI_COMBINE_COMPOSITE = 0 /*Composite mode */&lt;br /&gt;
                ;VI_COMBINE_SEPARATE,     /*Separate mode */&lt;br /&gt;
Comp_mode    =0 ;Component mode (single-component or dual-component)&lt;br /&gt;
                ;VI_COMP_MODE_SINGLE = 0, /*single component mode */&lt;br /&gt;
                ;VI_COMP_MODE_DOUBLE = 1, /*double component mode */&lt;br /&gt;
Clock_edge   =1 ;Clock edge mode (sampling on the rising or falling edge)&lt;br /&gt;
                ;VI_CLK_EDGE_SINGLE_UP=0, /*rising edge */&lt;br /&gt;
                ;VI_CLK_EDGE_SINGLE_DOWN, /*falling edge */&lt;br /&gt;
Mask_num     =2 ;Component mask&lt;br /&gt;
Mask_0       =0xFFF00000&lt;br /&gt;
Mask_1       =0x0&lt;br /&gt;
Scan_mode    = 1;VI_SCAN_INTERLACED = 0&lt;br /&gt;
                ;VI_SCAN_PROGRESSIVE,&lt;br /&gt;
Data_seq     =2 ;data sequence (ONLY for YUV format)&lt;br /&gt;
                ;----2th component U/V sequence in bt1120&lt;br /&gt;
                ;    VI_INPUT_DATA_VUVU = 0,&lt;br /&gt;
                ;    VI_INPUT_DATA_UVUV,&lt;br /&gt;
                ;----input sequence for yuv&lt;br /&gt;
                ;    VI_INPUT_DATA_UYVY = 0,&lt;br /&gt;
                ;    VI_INPUT_DATA_VYUY,&lt;br /&gt;
                ;    VI_INPUT_DATA_YUYV,&lt;br /&gt;
                ;    VI_INPUT_DATA_YVYU&lt;br /&gt;
&lt;br /&gt;
Vsync   =1      ; vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_FIELD = 0,&lt;br /&gt;
                ;VI_VSYNC_PULSE,&lt;br /&gt;
VsyncNeg=1      ;Polarity of the vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_VSYNC_NEG_LOW /*if VIU_VSYNC_E&lt;br /&gt;
Hsync  =0       ;Attribute of the horizontal synchronization signal&lt;br /&gt;
                ;VI_HSYNC_VALID_SINGNAL = 0,&lt;br /&gt;
                ;VI_HSYNC_PULSE,&lt;br /&gt;
HsyncNeg =0     ;Polarity of the horizontal synchronization signal&lt;br /&gt;
                ;VI_HSYNC_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_HSYNC_NEG_LOW&lt;br /&gt;
VsyncValid =1   ;Attribute of the valid vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_NORM_PULSE = 0,&lt;br /&gt;
                ;VI_VSYNC_VALID_SINGAL,&lt;br /&gt;
VsyncValidNeg =0;Polarity of the valid vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_VALID_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_VSYNC_VALID_NEG_LOW&lt;br /&gt;
Timingblank_HsyncHfb =0     ;Horizontal front blanking width&lt;br /&gt;
Timingblank_HsyncAct =1920  ;Horizontal effetive width&lt;br /&gt;
Timingblank_HsyncHbb =0     ;Horizontal back blanking width&lt;br /&gt;
Timingblank_VsyncVfb =0     ;Vertical front blanking height&lt;br /&gt;
Timingblank_VsyncVact =1080  ;Vertical effetive width&lt;br /&gt;
Timingblank_VsyncVbb=0      ;Vertical back blanking height&lt;br /&gt;
Timingblank_VsyncVbfb =0    ;Even-field vertical front blanking height(interlace, invalid progressive)&lt;br /&gt;
Timingblank_VsyncVbact=0    ;Even-field vertical effetive width(interlace, invalid progressive)&lt;br /&gt;
Timingblank_VsyncVbbb =0    ;Even-field vertical back blanking height(interlace, invalid progressive)&lt;br /&gt;
InputDataType=1 ;VI_DATA_TYPE_YUV = 0,VI_DATA_TYPE_RGB = 1,&lt;br /&gt;
DataRev      =FALSE ;Data reverse. FALSE = 0; TRUE = 1&lt;br /&gt;
DevRect_x=200&lt;br /&gt;
DevRect_y=20&lt;br /&gt;
DevRect_w=1920&lt;br /&gt;
DevRect_h=1080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== uart ==&lt;br /&gt;
* ./general/package/all-patches/linux/9000-enable-uart1.patch&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
--- a/arch/arm/boot/dts/gk7605v100-demb.dts       2023-08-09 13:43:00.715983714 +0200&lt;br /&gt;
+++ b/arch/arm/boot/dts/gk7605v100-demb.dts       2023-08-09 13:42:25.609040743 +0200&lt;br /&gt;
@@ -20,7 +20,7 @@&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;uart1 {&lt;br /&gt;
-       status = &amp;quot;disabled&amp;quot;;&lt;br /&gt;
+       status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;uart2 {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
ipctool reginfo | grep UART&lt;br /&gt;
&lt;br /&gt;
devmem 0x100c000c 32 0x02&lt;br /&gt;
devmem 0x100c0010 32 0x02&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== reflash kernel via uboot ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
## does not work?&lt;br /&gt;
setenv ipaddr 192.168.1.10; setenv serverip 192.168.1.11&lt;br /&gt;
setenv flash_addr 0x50000&lt;br /&gt;
setenv uimage_size 0x300000&lt;br /&gt;
&lt;br /&gt;
mw.b ${baseaddr} 0xff 0x1000000&lt;br /&gt;
tftpboot ${baseaddr} uImage&lt;br /&gt;
sf probe 0; sf lock 0;&lt;br /&gt;
&lt;br /&gt;
sf erase ${flash_addr} ${uimage_size}&lt;br /&gt;
sf write ${loadaddr} ${flash_addr} ${filesize}&lt;br /&gt;
original:&lt;br /&gt;
&lt;br /&gt;
uknor16m=mw.b ${baseaddr} ff 1000000; tftpboot ${baseaddr} uImage.${soc} &amp;amp;&amp;amp; sf probe 0; sf erase 0x50000 0x300000; sf write ${baseaddr} 0x50000 ${filesize}&lt;br /&gt;
urnor16m=mw.b ${baseaddr} ff 1000000; tftpboot ${baseaddr} rootfs.squashfs.${soc} &amp;amp;&amp;amp; sf probe 0; sf erase 0x350000 0xa00000; sf write ${baseaddr} 0x350000 ${filesize}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Hiseeu_5MP_PTZ_gk7605v100_sc223a&amp;diff=377</id>
		<title>Hiseeu 5MP PTZ gk7605v100 sc223a</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Hiseeu_5MP_PTZ_gk7605v100_sc223a&amp;diff=377"/>
		<updated>2023-08-09T12:06:52Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sensor ==&lt;br /&gt;
Camera needs _4l driver, got it from telegram channel. Source?&lt;br /&gt;
config as follows:&lt;br /&gt;
* /etc/sensors/sc223a_4l_i2c_1080p.ini&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
[sensor]&lt;br /&gt;
Sensor_type=stSnsSc223aObj&lt;br /&gt;
Mode=WDR_MODE_NONE&lt;br /&gt;
DllFile=libsns_sc223a_4l.so&lt;br /&gt;
&lt;br /&gt;
[mode]&lt;br /&gt;
input_mode=INPUT_MODE_MIPI&lt;br /&gt;
raw_bitness=10&lt;br /&gt;
&lt;br /&gt;
[mipi]&lt;br /&gt;
lane_id = 0|1|-1|-1|-1|-1|-1|-1|      ;lane_id: -1 - disable&lt;br /&gt;
&lt;br /&gt;
[isp_image]&lt;br /&gt;
Isp_FrameRate=30&lt;br /&gt;
Isp_Bayer=BAYER_BGGR&lt;br /&gt;
&lt;br /&gt;
[vi_dev]&lt;br /&gt;
Input_mod=VI_MODE_MIPI&lt;br /&gt;
Work_mod =0     ;VI_WORK_MODE_1Multiplex = 0&lt;br /&gt;
                ;VI_WORK_MODE_2Multiplex,&lt;br /&gt;
                ;VI_WORK_MODE_4Multiplex&lt;br /&gt;
Combine_mode =0 ;Y/C composite or separation mode&lt;br /&gt;
                ;VI_COMBINE_COMPOSITE = 0 /*Composite mode */&lt;br /&gt;
                ;VI_COMBINE_SEPARATE,     /*Separate mode */&lt;br /&gt;
Comp_mode    =0 ;Component mode (single-component or dual-component)&lt;br /&gt;
                ;VI_COMP_MODE_SINGLE = 0, /*single component mode */&lt;br /&gt;
                ;VI_COMP_MODE_DOUBLE = 1, /*double component mode */&lt;br /&gt;
Clock_edge   =1 ;Clock edge mode (sampling on the rising or falling edge)&lt;br /&gt;
                ;VI_CLK_EDGE_SINGLE_UP=0, /*rising edge */&lt;br /&gt;
                ;VI_CLK_EDGE_SINGLE_DOWN, /*falling edge */&lt;br /&gt;
Mask_num     =2 ;Component mask&lt;br /&gt;
Mask_0       =0xFFF00000&lt;br /&gt;
Mask_1       =0x0&lt;br /&gt;
Scan_mode    = 1;VI_SCAN_INTERLACED = 0&lt;br /&gt;
                ;VI_SCAN_PROGRESSIVE,&lt;br /&gt;
Data_seq     =2 ;data sequence (ONLY for YUV format)&lt;br /&gt;
                ;----2th component U/V sequence in bt1120&lt;br /&gt;
                ;    VI_INPUT_DATA_VUVU = 0,&lt;br /&gt;
                ;    VI_INPUT_DATA_UVUV,&lt;br /&gt;
                ;----input sequence for yuv&lt;br /&gt;
                ;    VI_INPUT_DATA_UYVY = 0,&lt;br /&gt;
                ;    VI_INPUT_DATA_VYUY,&lt;br /&gt;
                ;    VI_INPUT_DATA_YUYV,&lt;br /&gt;
                ;    VI_INPUT_DATA_YVYU&lt;br /&gt;
&lt;br /&gt;
Vsync   =1      ; vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_FIELD = 0,&lt;br /&gt;
                ;VI_VSYNC_PULSE,&lt;br /&gt;
VsyncNeg=1      ;Polarity of the vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_VSYNC_NEG_LOW /*if VIU_VSYNC_E&lt;br /&gt;
Hsync  =0       ;Attribute of the horizontal synchronization signal&lt;br /&gt;
                ;VI_HSYNC_VALID_SINGNAL = 0,&lt;br /&gt;
                ;VI_HSYNC_PULSE,&lt;br /&gt;
HsyncNeg =0     ;Polarity of the horizontal synchronization signal&lt;br /&gt;
                ;VI_HSYNC_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_HSYNC_NEG_LOW&lt;br /&gt;
VsyncValid =1   ;Attribute of the valid vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_NORM_PULSE = 0,&lt;br /&gt;
                ;VI_VSYNC_VALID_SINGAL,&lt;br /&gt;
VsyncValidNeg =0;Polarity of the valid vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_VALID_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_VSYNC_VALID_NEG_LOW&lt;br /&gt;
Timingblank_HsyncHfb =0     ;Horizontal front blanking width&lt;br /&gt;
Timingblank_HsyncAct =1920  ;Horizontal effetive width&lt;br /&gt;
Timingblank_HsyncHbb =0     ;Horizontal back blanking width&lt;br /&gt;
Timingblank_VsyncVfb =0     ;Vertical front blanking height&lt;br /&gt;
Timingblank_VsyncVact =1080  ;Vertical effetive width&lt;br /&gt;
Timingblank_VsyncVbb=0      ;Vertical back blanking height&lt;br /&gt;
Timingblank_VsyncVbfb =0    ;Even-field vertical front blanking height(interlace, invalid progressive)&lt;br /&gt;
Timingblank_VsyncVbact=0    ;Even-field vertical effetive width(interlace, invalid progressive)&lt;br /&gt;
Timingblank_VsyncVbbb =0    ;Even-field vertical back blanking height(interlace, invalid progressive)&lt;br /&gt;
InputDataType=1 ;VI_DATA_TYPE_YUV = 0,VI_DATA_TYPE_RGB = 1,&lt;br /&gt;
DataRev      =FALSE ;Data reverse. FALSE = 0; TRUE = 1&lt;br /&gt;
DevRect_x=200&lt;br /&gt;
DevRect_y=20&lt;br /&gt;
DevRect_w=1920&lt;br /&gt;
DevRect_h=1080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== uart ==&lt;br /&gt;
* ./general/package/all-patches/linux/9000-enable-uart1.patch&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
--- a/arch/arm/boot/dts/gk7605v100-demb.dts       2023-08-09 13:43:00.715983714 +0200&lt;br /&gt;
+++ b/arch/arm/boot/dts/gk7605v100-demb.dts       2023-08-09 13:42:25.609040743 +0200&lt;br /&gt;
@@ -20,7 +20,7 @@&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;uart1 {&lt;br /&gt;
-       status = &amp;quot;disabled&amp;quot;;&lt;br /&gt;
+       status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;uart2 {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
ipctool reginfo | grep UART&lt;br /&gt;
&lt;br /&gt;
devmem 0x100c000c 32 0x02&lt;br /&gt;
devmem 0x100c0010 32 0x02&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== reflash kernel via uboot ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
setenv ipaddr 192.168.1.10; setenv serverip 192.168.1.11&lt;br /&gt;
setenv flash_addr 0x50000&lt;br /&gt;
&lt;br /&gt;
mw.b ${baseaddr} 0xff 0x1000000&lt;br /&gt;
tftpboot ${baseaddr} uImage&lt;br /&gt;
sf probe 0; sf lock 0;&lt;br /&gt;
&lt;br /&gt;
sf erase ${flash_addr} ${filesize}&lt;br /&gt;
sf write ${loadaddr} ${flash_addr} ${filesize}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Hiseeu_5MP_PTZ_gk7605v100_sc223a&amp;diff=376</id>
		<title>Hiseeu 5MP PTZ gk7605v100 sc223a</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Hiseeu_5MP_PTZ_gk7605v100_sc223a&amp;diff=376"/>
		<updated>2023-08-09T11:59:46Z</updated>

		<summary type="html">&lt;p&gt;Damme: /* uart */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sensor ==&lt;br /&gt;
Camera needs _4l driver, got it from telegram channel. Source?&lt;br /&gt;
config as follows:&lt;br /&gt;
* /etc/sensors/sc223a_4l_i2c_1080p.ini&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
[sensor]&lt;br /&gt;
Sensor_type=stSnsSc223aObj&lt;br /&gt;
Mode=WDR_MODE_NONE&lt;br /&gt;
DllFile=libsns_sc223a_4l.so&lt;br /&gt;
&lt;br /&gt;
[mode]&lt;br /&gt;
input_mode=INPUT_MODE_MIPI&lt;br /&gt;
raw_bitness=10&lt;br /&gt;
&lt;br /&gt;
[mipi]&lt;br /&gt;
lane_id = 0|1|-1|-1|-1|-1|-1|-1|      ;lane_id: -1 - disable&lt;br /&gt;
&lt;br /&gt;
[isp_image]&lt;br /&gt;
Isp_FrameRate=30&lt;br /&gt;
Isp_Bayer=BAYER_BGGR&lt;br /&gt;
&lt;br /&gt;
[vi_dev]&lt;br /&gt;
Input_mod=VI_MODE_MIPI&lt;br /&gt;
Work_mod =0     ;VI_WORK_MODE_1Multiplex = 0&lt;br /&gt;
                ;VI_WORK_MODE_2Multiplex,&lt;br /&gt;
                ;VI_WORK_MODE_4Multiplex&lt;br /&gt;
Combine_mode =0 ;Y/C composite or separation mode&lt;br /&gt;
                ;VI_COMBINE_COMPOSITE = 0 /*Composite mode */&lt;br /&gt;
                ;VI_COMBINE_SEPARATE,     /*Separate mode */&lt;br /&gt;
Comp_mode    =0 ;Component mode (single-component or dual-component)&lt;br /&gt;
                ;VI_COMP_MODE_SINGLE = 0, /*single component mode */&lt;br /&gt;
                ;VI_COMP_MODE_DOUBLE = 1, /*double component mode */&lt;br /&gt;
Clock_edge   =1 ;Clock edge mode (sampling on the rising or falling edge)&lt;br /&gt;
                ;VI_CLK_EDGE_SINGLE_UP=0, /*rising edge */&lt;br /&gt;
                ;VI_CLK_EDGE_SINGLE_DOWN, /*falling edge */&lt;br /&gt;
Mask_num     =2 ;Component mask&lt;br /&gt;
Mask_0       =0xFFF00000&lt;br /&gt;
Mask_1       =0x0&lt;br /&gt;
Scan_mode    = 1;VI_SCAN_INTERLACED = 0&lt;br /&gt;
                ;VI_SCAN_PROGRESSIVE,&lt;br /&gt;
Data_seq     =2 ;data sequence (ONLY for YUV format)&lt;br /&gt;
                ;----2th component U/V sequence in bt1120&lt;br /&gt;
                ;    VI_INPUT_DATA_VUVU = 0,&lt;br /&gt;
                ;    VI_INPUT_DATA_UVUV,&lt;br /&gt;
                ;----input sequence for yuv&lt;br /&gt;
                ;    VI_INPUT_DATA_UYVY = 0,&lt;br /&gt;
                ;    VI_INPUT_DATA_VYUY,&lt;br /&gt;
                ;    VI_INPUT_DATA_YUYV,&lt;br /&gt;
                ;    VI_INPUT_DATA_YVYU&lt;br /&gt;
&lt;br /&gt;
Vsync   =1      ; vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_FIELD = 0,&lt;br /&gt;
                ;VI_VSYNC_PULSE,&lt;br /&gt;
VsyncNeg=1      ;Polarity of the vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_VSYNC_NEG_LOW /*if VIU_VSYNC_E&lt;br /&gt;
Hsync  =0       ;Attribute of the horizontal synchronization signal&lt;br /&gt;
                ;VI_HSYNC_VALID_SINGNAL = 0,&lt;br /&gt;
                ;VI_HSYNC_PULSE,&lt;br /&gt;
HsyncNeg =0     ;Polarity of the horizontal synchronization signal&lt;br /&gt;
                ;VI_HSYNC_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_HSYNC_NEG_LOW&lt;br /&gt;
VsyncValid =1   ;Attribute of the valid vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_NORM_PULSE = 0,&lt;br /&gt;
                ;VI_VSYNC_VALID_SINGAL,&lt;br /&gt;
VsyncValidNeg =0;Polarity of the valid vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_VALID_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_VSYNC_VALID_NEG_LOW&lt;br /&gt;
Timingblank_HsyncHfb =0     ;Horizontal front blanking width&lt;br /&gt;
Timingblank_HsyncAct =1920  ;Horizontal effetive width&lt;br /&gt;
Timingblank_HsyncHbb =0     ;Horizontal back blanking width&lt;br /&gt;
Timingblank_VsyncVfb =0     ;Vertical front blanking height&lt;br /&gt;
Timingblank_VsyncVact =1080  ;Vertical effetive width&lt;br /&gt;
Timingblank_VsyncVbb=0      ;Vertical back blanking height&lt;br /&gt;
Timingblank_VsyncVbfb =0    ;Even-field vertical front blanking height(interlace, invalid progressive)&lt;br /&gt;
Timingblank_VsyncVbact=0    ;Even-field vertical effetive width(interlace, invalid progressive)&lt;br /&gt;
Timingblank_VsyncVbbb =0    ;Even-field vertical back blanking height(interlace, invalid progressive)&lt;br /&gt;
InputDataType=1 ;VI_DATA_TYPE_YUV = 0,VI_DATA_TYPE_RGB = 1,&lt;br /&gt;
DataRev      =FALSE ;Data reverse. FALSE = 0; TRUE = 1&lt;br /&gt;
DevRect_x=200&lt;br /&gt;
DevRect_y=20&lt;br /&gt;
DevRect_w=1920&lt;br /&gt;
DevRect_h=1080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== uart ==&lt;br /&gt;
* ./general/package/all-patches/linux/9000-enable-uart1.patch&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
--- a/arch/arm/boot/dts/gk7605v100-demb.dts       2023-08-09 13:43:00.715983714 +0200&lt;br /&gt;
+++ b/arch/arm/boot/dts/gk7605v100-demb.dts       2023-08-09 13:42:25.609040743 +0200&lt;br /&gt;
@@ -20,7 +20,7 @@&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;uart1 {&lt;br /&gt;
-       status = &amp;quot;disabled&amp;quot;;&lt;br /&gt;
+       status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;uart2 {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
ipctool reginfo | grep UART&lt;br /&gt;
&lt;br /&gt;
devmem 0x100c000c 32 0x02&lt;br /&gt;
devmem 0x100c0010 32 0x02&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Hiseeu_5MP_PTZ_gk7605v100_sc223a&amp;diff=375</id>
		<title>Hiseeu 5MP PTZ gk7605v100 sc223a</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Hiseeu_5MP_PTZ_gk7605v100_sc223a&amp;diff=375"/>
		<updated>2023-08-09T11:59:15Z</updated>

		<summary type="html">&lt;p&gt;Damme: /* uart */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sensor ==&lt;br /&gt;
Camera needs _4l driver, got it from telegram channel. Source?&lt;br /&gt;
config as follows:&lt;br /&gt;
* /etc/sensors/sc223a_4l_i2c_1080p.ini&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
[sensor]&lt;br /&gt;
Sensor_type=stSnsSc223aObj&lt;br /&gt;
Mode=WDR_MODE_NONE&lt;br /&gt;
DllFile=libsns_sc223a_4l.so&lt;br /&gt;
&lt;br /&gt;
[mode]&lt;br /&gt;
input_mode=INPUT_MODE_MIPI&lt;br /&gt;
raw_bitness=10&lt;br /&gt;
&lt;br /&gt;
[mipi]&lt;br /&gt;
lane_id = 0|1|-1|-1|-1|-1|-1|-1|      ;lane_id: -1 - disable&lt;br /&gt;
&lt;br /&gt;
[isp_image]&lt;br /&gt;
Isp_FrameRate=30&lt;br /&gt;
Isp_Bayer=BAYER_BGGR&lt;br /&gt;
&lt;br /&gt;
[vi_dev]&lt;br /&gt;
Input_mod=VI_MODE_MIPI&lt;br /&gt;
Work_mod =0     ;VI_WORK_MODE_1Multiplex = 0&lt;br /&gt;
                ;VI_WORK_MODE_2Multiplex,&lt;br /&gt;
                ;VI_WORK_MODE_4Multiplex&lt;br /&gt;
Combine_mode =0 ;Y/C composite or separation mode&lt;br /&gt;
                ;VI_COMBINE_COMPOSITE = 0 /*Composite mode */&lt;br /&gt;
                ;VI_COMBINE_SEPARATE,     /*Separate mode */&lt;br /&gt;
Comp_mode    =0 ;Component mode (single-component or dual-component)&lt;br /&gt;
                ;VI_COMP_MODE_SINGLE = 0, /*single component mode */&lt;br /&gt;
                ;VI_COMP_MODE_DOUBLE = 1, /*double component mode */&lt;br /&gt;
Clock_edge   =1 ;Clock edge mode (sampling on the rising or falling edge)&lt;br /&gt;
                ;VI_CLK_EDGE_SINGLE_UP=0, /*rising edge */&lt;br /&gt;
                ;VI_CLK_EDGE_SINGLE_DOWN, /*falling edge */&lt;br /&gt;
Mask_num     =2 ;Component mask&lt;br /&gt;
Mask_0       =0xFFF00000&lt;br /&gt;
Mask_1       =0x0&lt;br /&gt;
Scan_mode    = 1;VI_SCAN_INTERLACED = 0&lt;br /&gt;
                ;VI_SCAN_PROGRESSIVE,&lt;br /&gt;
Data_seq     =2 ;data sequence (ONLY for YUV format)&lt;br /&gt;
                ;----2th component U/V sequence in bt1120&lt;br /&gt;
                ;    VI_INPUT_DATA_VUVU = 0,&lt;br /&gt;
                ;    VI_INPUT_DATA_UVUV,&lt;br /&gt;
                ;----input sequence for yuv&lt;br /&gt;
                ;    VI_INPUT_DATA_UYVY = 0,&lt;br /&gt;
                ;    VI_INPUT_DATA_VYUY,&lt;br /&gt;
                ;    VI_INPUT_DATA_YUYV,&lt;br /&gt;
                ;    VI_INPUT_DATA_YVYU&lt;br /&gt;
&lt;br /&gt;
Vsync   =1      ; vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_FIELD = 0,&lt;br /&gt;
                ;VI_VSYNC_PULSE,&lt;br /&gt;
VsyncNeg=1      ;Polarity of the vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_VSYNC_NEG_LOW /*if VIU_VSYNC_E&lt;br /&gt;
Hsync  =0       ;Attribute of the horizontal synchronization signal&lt;br /&gt;
                ;VI_HSYNC_VALID_SINGNAL = 0,&lt;br /&gt;
                ;VI_HSYNC_PULSE,&lt;br /&gt;
HsyncNeg =0     ;Polarity of the horizontal synchronization signal&lt;br /&gt;
                ;VI_HSYNC_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_HSYNC_NEG_LOW&lt;br /&gt;
VsyncValid =1   ;Attribute of the valid vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_NORM_PULSE = 0,&lt;br /&gt;
                ;VI_VSYNC_VALID_SINGAL,&lt;br /&gt;
VsyncValidNeg =0;Polarity of the valid vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_VALID_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_VSYNC_VALID_NEG_LOW&lt;br /&gt;
Timingblank_HsyncHfb =0     ;Horizontal front blanking width&lt;br /&gt;
Timingblank_HsyncAct =1920  ;Horizontal effetive width&lt;br /&gt;
Timingblank_HsyncHbb =0     ;Horizontal back blanking width&lt;br /&gt;
Timingblank_VsyncVfb =0     ;Vertical front blanking height&lt;br /&gt;
Timingblank_VsyncVact =1080  ;Vertical effetive width&lt;br /&gt;
Timingblank_VsyncVbb=0      ;Vertical back blanking height&lt;br /&gt;
Timingblank_VsyncVbfb =0    ;Even-field vertical front blanking height(interlace, invalid progressive)&lt;br /&gt;
Timingblank_VsyncVbact=0    ;Even-field vertical effetive width(interlace, invalid progressive)&lt;br /&gt;
Timingblank_VsyncVbbb =0    ;Even-field vertical back blanking height(interlace, invalid progressive)&lt;br /&gt;
InputDataType=1 ;VI_DATA_TYPE_YUV = 0,VI_DATA_TYPE_RGB = 1,&lt;br /&gt;
DataRev      =FALSE ;Data reverse. FALSE = 0; TRUE = 1&lt;br /&gt;
DevRect_x=200&lt;br /&gt;
DevRect_y=20&lt;br /&gt;
DevRect_w=1920&lt;br /&gt;
DevRect_h=1080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== uart ==&lt;br /&gt;
* ./general/package/all-patches/linux/9000-enable-uart2.patch&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
--- a/arch/arm/boot/dts/gk7605v100-demb.dts       2023-08-09 13:43:00.715983714 +0200&lt;br /&gt;
+++ b/arch/arm/boot/dts/gk7605v100-demb.dts       2023-08-09 13:42:25.609040743 +0200&lt;br /&gt;
@@ -20,7 +20,7 @@&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;uart1 {&lt;br /&gt;
-       status = &amp;quot;disabled&amp;quot;;&lt;br /&gt;
+       status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;uart2 {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
ipctool reginfo | grep UART&lt;br /&gt;
&lt;br /&gt;
devmem 0x100c000c 32 0x02&lt;br /&gt;
devmem 0x100c0010 32 0x02&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Hiseeu_5MP_PTZ_gk7605v100_sc223a&amp;diff=374</id>
		<title>Hiseeu 5MP PTZ gk7605v100 sc223a</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Hiseeu_5MP_PTZ_gk7605v100_sc223a&amp;diff=374"/>
		<updated>2023-08-09T11:58:52Z</updated>

		<summary type="html">&lt;p&gt;Damme: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sensor ==&lt;br /&gt;
Camera needs _4l driver, got it from telegram channel. Source?&lt;br /&gt;
config as follows:&lt;br /&gt;
* /etc/sensors/sc223a_4l_i2c_1080p.ini&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
[sensor]&lt;br /&gt;
Sensor_type=stSnsSc223aObj&lt;br /&gt;
Mode=WDR_MODE_NONE&lt;br /&gt;
DllFile=libsns_sc223a_4l.so&lt;br /&gt;
&lt;br /&gt;
[mode]&lt;br /&gt;
input_mode=INPUT_MODE_MIPI&lt;br /&gt;
raw_bitness=10&lt;br /&gt;
&lt;br /&gt;
[mipi]&lt;br /&gt;
lane_id = 0|1|-1|-1|-1|-1|-1|-1|      ;lane_id: -1 - disable&lt;br /&gt;
&lt;br /&gt;
[isp_image]&lt;br /&gt;
Isp_FrameRate=30&lt;br /&gt;
Isp_Bayer=BAYER_BGGR&lt;br /&gt;
&lt;br /&gt;
[vi_dev]&lt;br /&gt;
Input_mod=VI_MODE_MIPI&lt;br /&gt;
Work_mod =0     ;VI_WORK_MODE_1Multiplex = 0&lt;br /&gt;
                ;VI_WORK_MODE_2Multiplex,&lt;br /&gt;
                ;VI_WORK_MODE_4Multiplex&lt;br /&gt;
Combine_mode =0 ;Y/C composite or separation mode&lt;br /&gt;
                ;VI_COMBINE_COMPOSITE = 0 /*Composite mode */&lt;br /&gt;
                ;VI_COMBINE_SEPARATE,     /*Separate mode */&lt;br /&gt;
Comp_mode    =0 ;Component mode (single-component or dual-component)&lt;br /&gt;
                ;VI_COMP_MODE_SINGLE = 0, /*single component mode */&lt;br /&gt;
                ;VI_COMP_MODE_DOUBLE = 1, /*double component mode */&lt;br /&gt;
Clock_edge   =1 ;Clock edge mode (sampling on the rising or falling edge)&lt;br /&gt;
                ;VI_CLK_EDGE_SINGLE_UP=0, /*rising edge */&lt;br /&gt;
                ;VI_CLK_EDGE_SINGLE_DOWN, /*falling edge */&lt;br /&gt;
Mask_num     =2 ;Component mask&lt;br /&gt;
Mask_0       =0xFFF00000&lt;br /&gt;
Mask_1       =0x0&lt;br /&gt;
Scan_mode    = 1;VI_SCAN_INTERLACED = 0&lt;br /&gt;
                ;VI_SCAN_PROGRESSIVE,&lt;br /&gt;
Data_seq     =2 ;data sequence (ONLY for YUV format)&lt;br /&gt;
                ;----2th component U/V sequence in bt1120&lt;br /&gt;
                ;    VI_INPUT_DATA_VUVU = 0,&lt;br /&gt;
                ;    VI_INPUT_DATA_UVUV,&lt;br /&gt;
                ;----input sequence for yuv&lt;br /&gt;
                ;    VI_INPUT_DATA_UYVY = 0,&lt;br /&gt;
                ;    VI_INPUT_DATA_VYUY,&lt;br /&gt;
                ;    VI_INPUT_DATA_YUYV,&lt;br /&gt;
                ;    VI_INPUT_DATA_YVYU&lt;br /&gt;
&lt;br /&gt;
Vsync   =1      ; vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_FIELD = 0,&lt;br /&gt;
                ;VI_VSYNC_PULSE,&lt;br /&gt;
VsyncNeg=1      ;Polarity of the vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_VSYNC_NEG_LOW /*if VIU_VSYNC_E&lt;br /&gt;
Hsync  =0       ;Attribute of the horizontal synchronization signal&lt;br /&gt;
                ;VI_HSYNC_VALID_SINGNAL = 0,&lt;br /&gt;
                ;VI_HSYNC_PULSE,&lt;br /&gt;
HsyncNeg =0     ;Polarity of the horizontal synchronization signal&lt;br /&gt;
                ;VI_HSYNC_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_HSYNC_NEG_LOW&lt;br /&gt;
VsyncValid =1   ;Attribute of the valid vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_NORM_PULSE = 0,&lt;br /&gt;
                ;VI_VSYNC_VALID_SINGAL,&lt;br /&gt;
VsyncValidNeg =0;Polarity of the valid vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_VALID_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_VSYNC_VALID_NEG_LOW&lt;br /&gt;
Timingblank_HsyncHfb =0     ;Horizontal front blanking width&lt;br /&gt;
Timingblank_HsyncAct =1920  ;Horizontal effetive width&lt;br /&gt;
Timingblank_HsyncHbb =0     ;Horizontal back blanking width&lt;br /&gt;
Timingblank_VsyncVfb =0     ;Vertical front blanking height&lt;br /&gt;
Timingblank_VsyncVact =1080  ;Vertical effetive width&lt;br /&gt;
Timingblank_VsyncVbb=0      ;Vertical back blanking height&lt;br /&gt;
Timingblank_VsyncVbfb =0    ;Even-field vertical front blanking height(interlace, invalid progressive)&lt;br /&gt;
Timingblank_VsyncVbact=0    ;Even-field vertical effetive width(interlace, invalid progressive)&lt;br /&gt;
Timingblank_VsyncVbbb =0    ;Even-field vertical back blanking height(interlace, invalid progressive)&lt;br /&gt;
InputDataType=1 ;VI_DATA_TYPE_YUV = 0,VI_DATA_TYPE_RGB = 1,&lt;br /&gt;
DataRev      =FALSE ;Data reverse. FALSE = 0; TRUE = 1&lt;br /&gt;
DevRect_x=200&lt;br /&gt;
DevRect_y=20&lt;br /&gt;
DevRect_w=1920&lt;br /&gt;
DevRect_h=1080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== uart ==&lt;br /&gt;
* ./general/package/all-patches/linux/9000-enable-uart2.patch&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;patch&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
--- a/arch/arm/boot/dts/gk7605v100-demb.dts       2023-08-09 13:43:00.715983714 +0200&lt;br /&gt;
+++ b/arch/arm/boot/dts/gk7605v100-demb.dts       2023-08-09 13:42:25.609040743 +0200&lt;br /&gt;
@@ -20,7 +20,7 @@&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;uart1 {&lt;br /&gt;
-       status = &amp;quot;disabled&amp;quot;;&lt;br /&gt;
+       status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;uart2 {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
ipctool reginfo | grep UART&lt;br /&gt;
&lt;br /&gt;
devmem 0x100c000c 32 0x02&lt;br /&gt;
devmem 0x100c0010 32 0x02&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Hiseeu_5MP_PTZ_gk7605v100_sc223a&amp;diff=373</id>
		<title>Hiseeu 5MP PTZ gk7605v100 sc223a</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Hiseeu_5MP_PTZ_gk7605v100_sc223a&amp;diff=373"/>
		<updated>2023-08-09T11:55:38Z</updated>

		<summary type="html">&lt;p&gt;Damme: Created page with &amp;quot;== Sensor == Camera needs _4l driver, got it from telegram channel. Source? config as follows: * /etc/sensors/sc223a_4l_i2c_1080p.ini &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt; [sensor] Sensor_type=stSnsSc223aObj Mode=WDR_MODE_NONE DllFile=libsns_sc223a_4l.so  [mode] input_mode=INPUT_MODE_MIPI raw_bitness=10  [mipi] lane_id = 0|1|-1|-1|-1|-1|-1|-1|      ;lane_id: -1 - disable  [isp_image] Isp_FrameRate=30 Isp_Bayer=BAYER_BGGR  [vi_dev] Input_mod=VI_MODE_MIPI Work_mod =0...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sensor ==&lt;br /&gt;
Camera needs _4l driver, got it from telegram channel. Source?&lt;br /&gt;
config as follows:&lt;br /&gt;
* /etc/sensors/sc223a_4l_i2c_1080p.ini&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
[sensor]&lt;br /&gt;
Sensor_type=stSnsSc223aObj&lt;br /&gt;
Mode=WDR_MODE_NONE&lt;br /&gt;
DllFile=libsns_sc223a_4l.so&lt;br /&gt;
&lt;br /&gt;
[mode]&lt;br /&gt;
input_mode=INPUT_MODE_MIPI&lt;br /&gt;
raw_bitness=10&lt;br /&gt;
&lt;br /&gt;
[mipi]&lt;br /&gt;
lane_id = 0|1|-1|-1|-1|-1|-1|-1|      ;lane_id: -1 - disable&lt;br /&gt;
&lt;br /&gt;
[isp_image]&lt;br /&gt;
Isp_FrameRate=30&lt;br /&gt;
Isp_Bayer=BAYER_BGGR&lt;br /&gt;
&lt;br /&gt;
[vi_dev]&lt;br /&gt;
Input_mod=VI_MODE_MIPI&lt;br /&gt;
Work_mod =0     ;VI_WORK_MODE_1Multiplex = 0&lt;br /&gt;
                ;VI_WORK_MODE_2Multiplex,&lt;br /&gt;
                ;VI_WORK_MODE_4Multiplex&lt;br /&gt;
Combine_mode =0 ;Y/C composite or separation mode&lt;br /&gt;
                ;VI_COMBINE_COMPOSITE = 0 /*Composite mode */&lt;br /&gt;
                ;VI_COMBINE_SEPARATE,     /*Separate mode */&lt;br /&gt;
Comp_mode    =0 ;Component mode (single-component or dual-component)&lt;br /&gt;
                ;VI_COMP_MODE_SINGLE = 0, /*single component mode */&lt;br /&gt;
                ;VI_COMP_MODE_DOUBLE = 1, /*double component mode */&lt;br /&gt;
Clock_edge   =1 ;Clock edge mode (sampling on the rising or falling edge)&lt;br /&gt;
                ;VI_CLK_EDGE_SINGLE_UP=0, /*rising edge */&lt;br /&gt;
                ;VI_CLK_EDGE_SINGLE_DOWN, /*falling edge */&lt;br /&gt;
Mask_num     =2 ;Component mask&lt;br /&gt;
Mask_0       =0xFFF00000&lt;br /&gt;
Mask_1       =0x0&lt;br /&gt;
Scan_mode    = 1;VI_SCAN_INTERLACED = 0&lt;br /&gt;
                ;VI_SCAN_PROGRESSIVE,&lt;br /&gt;
Data_seq     =2 ;data sequence (ONLY for YUV format)&lt;br /&gt;
                ;----2th component U/V sequence in bt1120&lt;br /&gt;
                ;    VI_INPUT_DATA_VUVU = 0,&lt;br /&gt;
                ;    VI_INPUT_DATA_UVUV,&lt;br /&gt;
                ;----input sequence for yuv&lt;br /&gt;
                ;    VI_INPUT_DATA_UYVY = 0,&lt;br /&gt;
                ;    VI_INPUT_DATA_VYUY,&lt;br /&gt;
                ;    VI_INPUT_DATA_YUYV,&lt;br /&gt;
                ;    VI_INPUT_DATA_YVYU&lt;br /&gt;
&lt;br /&gt;
Vsync   =1      ; vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_FIELD = 0,&lt;br /&gt;
                ;VI_VSYNC_PULSE,&lt;br /&gt;
VsyncNeg=1      ;Polarity of the vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_VSYNC_NEG_LOW /*if VIU_VSYNC_E&lt;br /&gt;
Hsync  =0       ;Attribute of the horizontal synchronization signal&lt;br /&gt;
                ;VI_HSYNC_VALID_SINGNAL = 0,&lt;br /&gt;
                ;VI_HSYNC_PULSE,&lt;br /&gt;
HsyncNeg =0     ;Polarity of the horizontal synchronization signal&lt;br /&gt;
                ;VI_HSYNC_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_HSYNC_NEG_LOW&lt;br /&gt;
VsyncValid =1   ;Attribute of the valid vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_NORM_PULSE = 0,&lt;br /&gt;
                ;VI_VSYNC_VALID_SINGAL,&lt;br /&gt;
VsyncValidNeg =0;Polarity of the valid vertical synchronization signal&lt;br /&gt;
                ;VI_VSYNC_VALID_NEG_HIGH = 0,&lt;br /&gt;
                ;VI_VSYNC_VALID_NEG_LOW&lt;br /&gt;
Timingblank_HsyncHfb =0     ;Horizontal front blanking width&lt;br /&gt;
Timingblank_HsyncAct =1920  ;Horizontal effetive width&lt;br /&gt;
Timingblank_HsyncHbb =0     ;Horizontal back blanking width&lt;br /&gt;
Timingblank_VsyncVfb =0     ;Vertical front blanking height&lt;br /&gt;
Timingblank_VsyncVact =1080  ;Vertical effetive width&lt;br /&gt;
Timingblank_VsyncVbb=0      ;Vertical back blanking height&lt;br /&gt;
Timingblank_VsyncVbfb =0    ;Even-field vertical front blanking height(interlace, invalid progressive)&lt;br /&gt;
Timingblank_VsyncVbact=0    ;Even-field vertical effetive width(interlace, invalid progressive)&lt;br /&gt;
Timingblank_VsyncVbbb =0    ;Even-field vertical back blanking height(interlace, invalid progressive)&lt;br /&gt;
InputDataType=1 ;VI_DATA_TYPE_YUV = 0,VI_DATA_TYPE_RGB = 1,&lt;br /&gt;
DataRev      =FALSE ;Data reverse. FALSE = 0; TRUE = 1&lt;br /&gt;
DevRect_x=200&lt;br /&gt;
DevRect_y=20&lt;br /&gt;
DevRect_w=1920&lt;br /&gt;
DevRect_h=1080&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
	<entry>
		<id>https://wiki.wiegert.link/index.php?title=Main_Page&amp;diff=372</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.wiegert.link/index.php?title=Main_Page&amp;diff=372"/>
		<updated>2023-08-09T11:51:47Z</updated>

		<summary type="html">&lt;p&gt;Damme: /* Damme&amp;#039;s stuff */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== World Wide Wiegert Wiki - The best wiki in the world! ==&lt;br /&gt;
 Skapa en sida genom att skapa dig ett konto, editera denna sida och skriv länken inom brackets&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[namn på sidan]]&amp;lt;/nowiki&amp;gt; - spara och klicka på länken så är det bara att skriva vidare!&lt;br /&gt;
&lt;br /&gt;
== Damme&#039;s stuff ==&lt;br /&gt;
&amp;lt;strong&amp;gt;[[Damme&#039;s linux stuff]]&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Damme&#039;s windows stuff]]&lt;br /&gt;
&lt;br /&gt;
[[Ubuntu Server LTS]]&lt;br /&gt;
&lt;br /&gt;
[[Hårdvara]]&lt;br /&gt;
&lt;br /&gt;
[[Development]]&lt;br /&gt;
&lt;br /&gt;
[[Dammes other stuff]]&lt;br /&gt;
&lt;br /&gt;
[[Resor mm]]&lt;br /&gt;
&lt;br /&gt;
[[Hiseeu 5MP PTZ gk7605v100 sc223a]]&lt;br /&gt;
&lt;br /&gt;
== Plupp&#039;s stuff ==&lt;br /&gt;
&lt;br /&gt;
TBA&lt;br /&gt;
&lt;br /&gt;
== Other pages ==&lt;br /&gt;
&lt;br /&gt;
== Wiki ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;[[Cheat sheet]]&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[MediaWiki format help]]&lt;br /&gt;
&lt;br /&gt;
[[Sandbox]] In here you can test wiki language.&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki]&lt;/div&gt;</summary>
		<author><name>Damme</name></author>
	</entry>
</feed>