Nearby measurements, an answer in the opposite direction
Imagine two orientation estimates for a part on a rotary table: +179° and −179°. Their arrows nearly overlap, both pointing left just one degree from 180°. Yet the arithmetic average adds the numbers and divides by two, giving 0°, which points right. A program could turn nearly agreeing observations into an opposite orientation while performing addition and division correctly.
We ask not only how to avoid that result, but which mean is being computed, what it minimises, and when no reliable mean direction exists. We build the method from vectors on a circle, work through the numbers, and compare two distance definitions. The title describes a mathematical risk, not an incident or an EL-AI robot test. All observations are synthetic and calculations reproducible.
An angle is not a point on a line
For lengths, 179 and −179 are far apart. For a direction, adding a full turn leaves the arrow unchanged: −179° and 181° represent the same orientation. Rewriting the second observation as 181° makes the arithmetic average 180°. Only the numerical representative changed. A direction mean should be equivalent after adding or subtracting 360° from any observation; ordinary averaging lacks that invariance.
Our object is a planar direction, not an axis’s total turn count. A joint after three revolutions may point like one after none, while unwrapped position, mechanical limits, and cable state differ. Removing turns would then discard information. The data meaning must be chosen before the method. This article concerns directions on a circle, not every joint variable.
Turn measurements into arrows
Associate theta with unit vector u(theta)=(cos theta, sin theta). Its length is one, representing direction without arbitrary magnitude. Trigonometric functions use radians; multiply degrees by pi/180. Average horizontal and vertical components separately using nonnegative weights w_i with positive total W. Denote the averages c and s. Equal weights give an unweighted mean.
atan2 uses both components to identify the quadrant; arctan(s/c) alone loses that information and divides by c. rho is the mean vector’s length, between zero and one: agreeing arrows reinforce and opposing arrows cancel. mu is a direction only for a nonzero resultant. Code uses a numerical threshold for floating-point residues, distinct from any physical quality threshold.
The worked example, number by number
For +179° and −179°, both cosines are about −0.9998476952. Sines are about +0.0174524064 and −0.0174524064 and cancel. Equal weighting gives c≈−0.9998476952, s≈0, and rho≈0.9998476952. The long resultant points left: atan2 returns 180°, equivalent to −180°. The observations are only 2° apart along the shortest arc. A jump between −180° and +180° changes a numerical label, not a physical turn.
Adding 360° to the first observation preserves the direction, checked by code. Giving the first measurement three times the weight yields about 179.4999619°, closer to it. Weighting is a fusion-model choice, not justified merely by naming a number “confidence”. Reliability interpretation needs an error and dependence model. Two sensors sharing a systematic bias can have rho near one while both point incorrectly.
Which error does this mean minimise?
Why is this a mean rather than just a recipe? Measure straight-line distance between unit-arrow tips, a circle chord, and seek mu minimising the weighted sum of squared distances. This objective is dimensionless: not position error in metres and not yet squared angular distance. Choosing the distance is part of the statistical problem.
The first identity uses unit-vector dot products: each squared norm is one and the dot product is cosine difference. Expanding cos(theta−mu) collects c and s. For positive rho the cost is minimised when the last cosine is one, mu=alpha modulo a turn. At rho=0 the cost is 2W for every mu. This derives both the formula and its indeterminate case.
For +179°/−179° with unit weights, chordal cost is about 7.99939078 at arithmetic mean 0° and 0.0006092194 at circular mean 180°. These are values of the defined objective, not robot success percentages. The contrast exposes representation error in this case, not collision distance or vision-system quality.
When the resultant disappears
Equal-weight directions 0° and 180° cancel exactly: c=s=0. The data prefers no chordal mean direction. Arithmetic 90° discovers no hidden information; it selects a representation-dependent number. Floating-point sin(pi) may leave a residue around 10⁻¹⁶, allowing atan2 to return a number without resolving the mathematical ambiguity.
Our implementation returns None for rho≤10⁻¹², an explicit experimental policy, not a certified sensor-fusion or statistical-confidence threshold. Applications need criteria based on noise and defined behaviour when no estimate can be produced. SciPy circmean documents an implementation-dependent result at zero resultant. Our declared behaviour differs; we did not execute SciPy or fabricate a comparison.
A defined result can be highly sensitive
Replace 180° by 179.999°. Now rho≈8.72665×10⁻⁶ and the mean is about +89.9995°. Using −179.999°, physically only 0.002° away from the previous direction, gives about −89.9995°. The means nearly oppose. This is not merely a representation jump: their arrows differ too. Near cancellation of opposing directions, a tiny perturbation selects among many nearly equivalent minima.
atan2’s derivative explains sensitivity. Small component changes dc, ds give first-order dmu=(c ds−s dc)/rho² in radians. The gradient norm with respect to (c, s) is 1/rho: shorter resultants can amplify the same component error into larger angle error. This is local for sufficiently small perturbations and positive rho, not a confidence interval. Code sweeps epsilon from 1° to 0.001°.

Distance along the circle gives another mean
A chord joins points by a straight segment; an arc follows the circle. They are close for small deviations but differ for large ones. An intrinsic mean can minimise squared shortest angular deviations, wrapped into a one-turn interval. It is not generally the chordal mean. Calling a method “circular” does not specify its objective: the distance matters.
For observations 0°,0°,180°, two right arrows outweigh one left arrow: rho=1/3 and chordal mean 0°. For angular distance on 0°≤mu≤180°, cost is 2mu²+(180°−mu)². Its derivative 6mu−360° gives mu=60°. The negative semicircle yields another minimum −60°. Angular cost is 21,600 degree² at either minimum versus 32,400 at zero. Chordal cost instead is 4 at zero and about 5 at ±60°. Different objectives explain the difference.
Degrees make this comparison readable. Converting to radians scales angular costs by (pi/180)² without changing minima. Code compares stated values; the semicircle derivation establishes minima. Neither mean is universally “truer”: choose the error the application should reduce. Multimodal data may warrant multiple hypotheses rather than one summary.
| Case, degrees | Arithmetic mean | Circular chordal mean | rho |
|---|---|---|---|
| 179, -179 | 0 | 180 | 0.9998476952 |
| 179, 181 | 180 | -180 | 0.9998476952 |
| 0, 180 | 90 | — | ~0 |
| 0, 179.999 | 89.9995 | 89.9995 | 0.00000872665 |
| 0, 0, 180 | 60 | ~0 | 1/3 |
The dash means our method returns no direction below its numerical threshold; +180° and −180° are equivalent. Ordinary means may depend on interval cuts, while a circular mean may optimise its objective yet be uninformative or sensitive. Retaining rho and observations preserves this distinction; rho alone does not reconstruct the distribution.
Unwrapping is a different operation
Unwrapping adds full turns to make a time sequence continuous. If an axis moves slightly from 179° to −179°, the second sample can be represented as 181°. That uses temporal information or a prior. Simultaneous measurements without a reference may have no unique turn assignment. If motion between samples can exceed half a turn, the smallest-jump rule may choose wrongly. We execute no unwrapping algorithm or trajectory simulation; we distinguish assumptions.
Geometric frames must also agree. Camera-relative and robot-base-relative angles cannot be fused merely because both use degrees. Axis, sign, and frame transforms must be consistent. Circular averaging fixes neither bad calibration nor timestamp mismatch. Our narrower question assumes comparable planar observations and studies their summary.
What the code executes and what remains outside
experiment.py uses Python 3.14.0 and math, retaining observations, weights, components, rho, means, and costs. It is deterministic, with no seed. fsum accumulates weights/components; empty inputs, negative or nonfinite weights, and zero totals are rejected. Assertions use explicit tolerances, while antipodal cancellation is also explained exactly. The short listing isolates the main case; the archive adds all cases and objectives. plot.py generates four Matplotlib figures; instructions specify Chinese font handling.
One pass takes work proportional to observations and constant aggregate state: weight total, cosine sum, and sine sum. Our script retains additional data for inspection, so this algorithm property is not total program memory. We measure no microcontroller runtime, encoder accuracy, or controller behaviour. Three sums do not establish whole-robot latency.
The consulted SciPy 1.18.0 documentation distinguishes resultant-based circmean from Rotation.mean, defined by a chordal matrix loss. This prevents conflating planar directions with general 3D rotations; this article does not justify separately averaging Euler angles. These APIs were not executed and our results are not attributed to SciPy. We do not claim to have read books or papers listed by the documentation. This is mathematical teaching analysis, not new peer-reviewed research.
Answering the initial problem
A robot can receive an opposite direction when circular coordinates are treated as linear numbers. Unit arrows and circular averaging remove that error for +179° and −179°, yielding 180°. Yet small resultants, opposing groups, distance choices, frames, and accumulated turns constrain interpretation. The solution is choosing the data geometry and recognising when one orientation poorly summarises observations, not trusting a magic formula.
Industrial and collaborative robotics is a user-stated exploration direction for EL-AI. The application link here remains hypothetical: calculations are no robot test, safety demonstration, or evidence of products, clients, or installations. Evidence consists of derived identities and executed synthetic cases. Real cells need sensor protocols, calibration, and specific dynamic and safety validation beyond this article.
Sources and reproducible materials
SciPy 1.18.0 — scipy.stats.circmean, definition and zero-resultant behaviour.
SciPy 1.18.0 — Rotation.mean, chordal objective.
import math
angles=[179,-179]
c=math.fsum(math.cos(math.radians(a)) for a in angles)/len(angles)
s=math.fsum(math.sin(math.radians(a)) for a in angles)/len(angles)
rho=math.hypot(c,s)
mean=math.degrees(math.atan2(s,c)) if rho>1e-12 else None
assert abs(abs(mean)-180)<1e-10
print(sum(angles)/len(angles),mean,rho)
Code, data, and instructions · JSON. Educational calculations executed with Python 3.14.0; figures with Matplotlib 3.11.2. AI-assisted analysis, without claiming peer review or human review. Original illustrative ImageGen cover: it does not document EL-AI people, premises, or installations. Sources accessed 24 October 2026.

