mirror of
https://github.com/Klipper3d/klipper.git
synced 2026-01-17 21:35:49 -07:00
Prepares update of winch forward transform by adding some reference code and docs
This commit is contained in:
parent
f3bafca35c
commit
bb20c4b311
28 changed files with 1594 additions and 0 deletions
241
ai_docs/Quadratic_Approximation_Approach.md
Normal file
241
ai_docs/Quadratic_Approximation_Approach.md
Normal file
|
|
@ -0,0 +1,241 @@
|
|||

|
||||
|
||||
# Fast and Reliable Iterative Cable-Driven Parallel Robot Forward Kinematics: A Quadratic Approximation Approach
|
||||
|
||||
Henry Mahnke and Ryan J. Caverly(B[\)](http://orcid.org/0000-0001-7315-7322)
|
||||
|
||||
Department of Aerospace Engineering and Mechanics, University of Minnesota, Minneapolis, MN 55455, USA {mahnk040,rcaverly}@umn.edu
|
||||
|
||||
Abstract. This paper presents iterative forward kinematics algorithms for cable-driven parallel robots (CDPRs) that are based on Halley's method. In contrast to other iterative forward kinematics methods that use a linearization of the CDPRs loop-closure equations, such as Newton's method or the Levenberg-Marquardt method, Halley's method uses a second-order Taylor series approximation of these equations. A hybrid method is also proposed that performs a Halley update for the first few iterations and then switches to a Levenberg-Marquardt update. The proposed algorithms are applied to a six degree-of-freedom suspended CDPR and are shown to reduce the number of iterations and increase the rate of successful convergence to the truth pose compared to the Levenberg-Marquardt method. The proposed hybrid method reduces the computation time required for convergence compared to the Levenberg-Marquardt method in the presence of large initial estimation errors.
|
||||
|
||||
Keywords: Cable-driven parallel robots · Pose estimation · Forward kinematics · Halley's method
|
||||
|
||||
# 1 Introduction
|
||||
|
||||
Cable-driven parallel robots (CDPRs) use the actuation of cables to transmit actuating forces to an end-effector or payload. Compared to traditional serial manipulators, CDPRs can feature significantly larger workspaces and payloadto-weight ratios. Forward kinematics is typically used to determine a CDPR's end-effector pose (position and orientation) during operation through measurements of the CDPR's cable lengths obtained from winch encoders. It is critical that the CDPR's pose be estimated accurately and quickly in order to control the end-effector motion precisely, especially during high-acceleration maneuvers.
|
||||
|
||||
Forward kinematics algorithms are computed based on the CDPR's loopclosure equations that describe how cable-length measurements relate to the CDPR's geometry. In their simplest form, these loop-closure equations assume straight, inelastic, and massless cables. More complex features can be incorporated into the loop-closure equations, such as cable sag [8], pulley kinematics [17], and cable elasticity [9]. Even the simplest of loop-closure equations are nonlinear functions of the CDPR end-effector's pose, and these nonlinearities typically become more pronounced with more complex models. This highlights one of the challenges of CDPR forward kinematics, which in essence is a nonlinear root solving problem that may have multiple feasible pose solutions. This challenge is exacerbated when significant measurement noise and/or calibration errors are present [3,12]. A common practical method of solving a CDPR's forward kinematics involves linearizing the CDPR's nonlinear loop-closure equations about an initial pose estimate and iteratively solving for an improved estimate using Newton's method or a damped version of this, known as the Levenberg-Marquardt method [2,11–14,17]. Although these approaches can be effective in practice, they can potentially suffer from a large number of iterations and computation time, or not even converge within a reasonable tolerance of the true pose, especially when the initial pose estimation error is relatively large, such as on startup of a CDPR.
|
||||
|
||||
Recently, Halley's method, also known as the method of tangent hyperbolas [15, pp. 122–124], [18], was proposed as a faster alternative to Newton's method when solving the inverse kinematics of overactuated serial manipulators [7]. Halley's method uses a second-order Taylor series expansion of the loop-closure equations, rather than the first-order expansion used with Netwon's method. This quadratic approximation of the nonlinearities in the loop-closure equations allows for convergence of an iterative method with fewer iterations and increases the rate of successful convergence for larger initial errors.
|
||||
|
||||
This paper adapts the work of [7] to yield novel CDPR iterative forward kinematics algorithms based on Halley's method that are both fast and have a high success rate. The first algorithm proposed is directly based on Halley's method, while the second algorithm is a hybrid method that implements Halley's method for the first few iterations, then switches to the Levenberg-Marquardt method for subsequent iterations. Although the proposed algorithms are adaptable to any form of loop-closure equations that are twice differentiable with respect to the end-effector pose, the preliminary investigation in this paper focuses on an .8-cable .6-degree-of-freedom (DOF) CDPR. Analytic matrix expressions for the majority of the quadratic terms involved in the algorithm are derived, which assist in speeding up the computation time. Confidence intervals on the pose estimates obtained with the proposed algorithms are also computed in the form of covariance matrices leveraging the work of [11,12]. This allows for the methods to be used effectively within a sensor fusion scheme with additional measurements [5,10]. The contributions of this paper are the formulation and numerical evaluation of two novel CDPR iterative forward kinematics algorithms that are faster and have a higher rate of successful convergence compared to the Levenberg-Marquardt method. It is worth noting that unlike the work of [1,8], the algorithms proposed in this paper are not aimed at solving for all possible forward kinematics solutions. Rather, they are aimed at quickly and reliably solving for a local solution within a reasonable neighborhood of an initial pose estimate, with the intention of accounting for relatively large errors on startup.
|
||||
|
||||
The remainder of this section presents important notation and a description of the CDPR considered in this paper.
|
||||
|
||||

|
||||
|
||||
Fig. 1. A suspended 6-DOF CDPR with a rigid-body end-effector payload.
|
||||
|
||||
#### 1.1 Notation and System Description
|
||||
|
||||
In this paper, an $n \times n$ identity matrix is denoted as $\mathbf{1}\_{n \times n}$ and an $n \times m$ matrix of zeros is $\mathbf{0}\_{n \times m}$ . The cross operator, $(\cdot)^{\times} : \mathbb{R}^3 \to \mathfrak{so}(3)$ , satisfies $\mathbf{u}^{\times} \mathbf{w} = -\mathbf{w}^{\times} \mathbf{u}$ for all $\mathbf{u}, \mathbf{w} \in \mathbb{R}^3$ , where $\mathfrak{so}(3) = {\mathbf{S} \in \mathbb{R}^{3 \times 3} | \mathbf{S} + \mathbf{S}^\mathsf{T} = \mathbf{0}}$ [\[6\]](#page-2-6), pp. 525–526.This work considers an overconstrained 6-DOF CDPR with $m$ cables, where
|
||||
|
||||
$m > 6$ . An example of a 6-DOF CDPR with 8 cables is shown in Fig. 1. The
|
||||
|
||||
reference frame $\mathcal{F}\_o$ is an inertial frame with point $o$ at its origin, while $\mathcal{F}\_p$ is an
|
||||
|
||||
end-effector-fixed frame centered at point $p$ , the end-effector's center of mass.
|
||||
|
||||
The position vector of point $p$ relative to $o$ is $\underline{r}$ , which is resolved in $\mathcal{F}\_o$ as
|
||||
|
||||
$\mathbf{r} \in \mathbb{R}^3$ . The position vector of the $i$ <sup>th</sup> cable's anchoring pulley relative to point
|
||||
|
||||
$o$ is $\underline{a}\_i$ , which is resolved in $\mathcal{F}\_o$ as $\mathbf{a}\_i$ . The position vector of the $i$ <sup>th</sup> cable's
|
||||
|
||||
attachment point on the end-effector relative to its anchoring point is $\underline{l}\_i$ , which
|
||||
|
||||
is resolved in $\mathcal{F}\_o$ as $\mathbf{l}\_i$ . The position vector of the $i$ <sup>th</sup> cable's attachment point
|
||||
|
||||
on the end-effector relative to point $p$ is $\underline{b}\_i$ , which is resolved in $\mathcal{F}\_p$ as $\mathbf{b}\_i$ . The
|
||||
|
||||
pose of the CDPR's end-effector is described by $\rho \in \mathbb{R}^6$ , where $\rho^\text{T} = [\mathbf{r}^\text{T} \,\mathbf{\theta}^\text{T}]$
|
||||
|
||||
and $\mathbf{\theta} \in \mathbb{R}^3$ represents an unconstrained parameterization of the rotation matrix
|
||||
|
||||
$\mathbf{R}\_{po}(\mathbf{\theta})$ or direction cosine matrix (DCM) $(\mathbf{C}\_{po}(\mathbf{\theta}) = \mathbf{R}\_{po}^\text{T}(\mathbf{\theta}))$ that describes the
|
||||
|
||||
orientation of $\mathcal{F}\_p$ relative to $\mathcal{F}\_o$ . In this paper a 3-2-1 Euler angle sequence (yaw-
|
||||
|
||||
pitch-roll) is used to parameterize the end-effector orientation, although other
|
||||
|
||||
unconstrained parameterizations could be used, such as those discussed in [\[11\]](#page-2-1).### 2 Forward Kinematics Formulation
|
||||
|
||||
This section presents the proposed iterative forward kinematics methods, including the loop-closure and measurement equations, a second-order Taylor series expansion of the measurement equations, and the two proposed algorithms.
|
||||
|
||||
### 2.1 Loop-Closure and Measurement Equations
|
||||
|
||||
Assuming that the cables are inelastic and pulley kinematics can be ignored, the pose-dependent position vector of the $i^{th}$ cable's attachment point on the end-effector relative to its attachment is given by the loop-closure equation
|
||||
|
||||
$$\ell\_i(\rho) = \mathbf{r} + \mathbf{C}\_{po}^{\top}(\theta)\mathbf{b}\_i - \mathbf{a}\_i \dots$$
|
||||
|
||||
It is also assumed that measurements of the CDPR's cable lengths are avail-able through the use of incremental encoders and calibration. Each cable-lengthmeasurement satisfies $y\_i = ||l\_i(\rho)||\_2 + v\_i$ , where $y\_i$ is the length measurement ofthe $i^{th}$ cable and $v\_i$ represents uncertainty or noise in the cable-length measurement. For the purpose of simplicity in this preliminary study, it is assumed that $v\_i \in N(0, \sigma\_i<sup>2</sup>)$ is zero-mean Gaussian white noise with standard deviation $\sigma\_i$ .The measurements for all .m cables are concatenated together to form the measurement equation
|
||||
|
||||
$$\mathbf{f}(\mathbf{y}, \boldsymbol{\rho}, \mathbf{v}) = \mathbf{0}\_{m \times 1},\tag{1}$$
|
||||
|
||||
where $\mathbf{f}^{\text{T}}(\mathbf{y}, \boldsymbol{\rho}, \mathbf{v}) = [f\_1(y\_1, \boldsymbol{\rho}, v\_1) \cdots f\_m(y\_m, \boldsymbol{\rho}, v\_m)], \mathbf{y}^{\text{T}} = [y\_1 \cdots y\_m], \mathbf{v}^{\text{T}} = [v\_1 \cdots v\_m]$ , and
|
||||
$$f\_{i}(y\_{i}, \rho, v\_{i}) = -y\_{i} + ||\ell\_{i}(\rho)||\_{2} + v\_{i}.$$
|
||||
|
||||
Although cable-length measurement equations are used in this paper, it is
|
||||
worth noting that the formulation presented in this section can be adapted to
|
||||
other measurement equations, such as the cable-length-squared equations used
|
||||
in [\[11\]](#page-3-1), provided that the equations are twice differentiable with respect the
|
||||
CDPR pose.### 2.2 Taylor Series Expansion
|
||||
|
||||
Performing a Taylor series expansion of [\(1\)](#page-3-1) about $\rho = \bar{\rho}$ and $\mathbf{v} = \mathbb{E}[\mathbf{v}] = \mathbf{0}\_{m \times 1}$ results in
|
||||
$$\mathbf{f}(\mathbf{y},\rho,\mathbf{v}) \approx \mathbf{f}(\mathbf{y},\bar{\rho},\mathbf{0}) + \mathbf{J}\_{\rho}(\bar{\rho})\delta\rho + \frac{1}{2}\bar{\mathbf{H}}\_{\rho\rho}(\bar{\rho},\delta\rho)\delta\rho + \mathbf{v},\tag{2}$$
|
||||
|
||||
where $\mathbf{J}\_{\rho}(\bar{\rho}) = \frac{\partial \mathbf{f}}{\partial \rho}|\_{\mathbf{y},\bar{\rho},\mathbf{0}}$ is the Jacobian of $\mathbf{f}(\mathbf{y}, \rho, \mathbf{v})$ evaluated at $\bar{\rho}$ , while
|
||||
|
||||
$\mathbf{\bar{H}}\_{\rho\rho}(\bar{\rho}, \delta\rho)$ is based on the Hessian of the individual entries of $\mathbf{f}(\mathbf{y}, \rho, \mathbf{v})$ . Specifically,
|
||||
$$\mathbf{J}\_{\rho}(\boldsymbol{\rho}) = \begin{bmatrix} \frac{\ell\_{1}^{\mathsf{T}}(\boldsymbol{\rho})}{\|\ell\_{1}(\boldsymbol{\rho})\|} \begin{bmatrix} \mathbf{1}\_{3\times3} & -\mathbf{C}\_{po}^{\mathsf{T}}(\boldsymbol{\theta})\mathbf{b}\_{1}^{\mathsf{X}}\mathbf{S}(\boldsymbol{\theta}) \end{bmatrix} \\ \vdots \\ \frac{\ell\_{m}^{\mathsf{T}}(\boldsymbol{\rho})}{\|\ell\_{m}(\boldsymbol{\rho})\|} \begin{bmatrix} \mathbf{1}\_{3\times3} & -\mathbf{C}\_{po}^{\mathsf{T}}(\boldsymbol{\theta})\mathbf{b}\_{m}^{\mathsf{X}}\mathbf{S}(\boldsymbol{\theta}) \end{bmatrix} \end{bmatrix}, \quad \bar{\mathbf{H}}\_{\rho\rho}(\boldsymbol{\rho},\boldsymbol{\delta}\boldsymbol{\rho}) = \begin{bmatrix} \boldsymbol{\delta}\boldsymbol{\rho}^{\mathsf{T}}\mathbf{H}\_{\rho\rho,1}(\boldsymbol{\rho}) \\ \vdots \\ \boldsymbol{\delta}\boldsymbol{\rho}^{\mathsf{T}}\mathbf{H}\_{\rho\rho,m}(\boldsymbol{\rho}) \end{bmatrix},$$
|
||||
|
||||
where $J\_p(\rho)$ was derived in [\[11\]](#page-3-1) and the entries of $\overline{H}\_{\rho\rho}(\rho, \delta\rho)$ are computed through the Hessian matrices
|
||||
$$\mathbf{H}\_{\rho\rho,i}(\rho) = \begin{bmatrix} \frac{\partial^2 f\_i}{\partial \mathbf{r} \partial \mathbf{r}^\mathsf{T}} & \frac{\partial^2 f\_i}{\partial \theta \partial \mathbf{r}^\mathsf{T}}\\ \left(\frac{\partial^2 f\_i}{\partial \theta \partial \mathbf{r}^\mathsf{T}}\right)^\mathsf{T} & \frac{\partial^2 f\_i}{\partial \theta \partial \theta^\mathsf{T}} \end{bmatrix}, \quad i = 1, \cdots, m,$$
|
||||
|
||||
where
|
||||
|
||||
$$\frac{\partial^2 f\_i}{\partial \mathbf{r} \partial \mathbf{r}^\mathsf{T}} = \frac{\mathbf{1}\_{3 \times 3}}{\left\| \ell\_i(\rho) \right\|} - \frac{\ell\_i(\rho) \ell\_i^\mathsf{T}(\rho)}{\left\| \ell\_i(\rho) \right\|^3}, \quad \frac{\partial^2 f\_i}{\partial \theta \partial \mathbf{r}^\mathsf{T}} = \frac{\partial^2 f\_i}{\partial \mathbf{r} \partial \mathbf{r}^\mathsf{T}} (-\mathbf{C}\_{po}^\mathsf{T}(\theta) \mathbf{b}\_i^\times \mathbf{S}(\theta)),$$
|
||||
|
||||
$$\frac{\partial^2 f\_i}{\partial \theta \partial \theta^\mathsf{T}} = \mathbf{S}^\mathsf{T}(\theta) \mathbf{b}\_i^\times \mathbf{C}\_{po}(\theta) \frac{\partial^2 f\_i}{\partial \theta \partial \mathbf{r}^\mathsf{T}} + \frac{1}{\left\| \ell\_i(\bar{\rho}) \right\|} \frac{\partial}{\partial \theta} \left( \mathbf{S}^\mathsf{T}(\theta) \mathbf{b}\_i^\times \mathbf{C}\_{po}(\theta) \ell\_i(\bar{\rho}) \right).$$
|
||||
|
||||
The term $S(\theta)$ is a mapping matrix based on the orientation kinematics $\omega =$
|
||||
$S(\theta)\dot{\theta}$ , where $\omega$ is the angular velocity of $\mathcal{F}\_p$ relative to $\mathcal{F}\_o$ resolved in $\mathcal{F}\_p$ and
|
||||
expressions for $S(\theta)$ with different orientation parameterizations can be found
|
||||
in [\[11\]](#page-4-0). For the 3-2-1 Euler angle sequence used in this paper, $S(\theta)$ is given by
|
||||
$$\mathbf{S}(\boldsymbol{\theta}) = \begin{bmatrix} 1 & 0 & -\sin(\theta\_2) \\ 0 & \cos(\theta\_1) & \sin(\theta\_1)\cos(\theta\_2) \\ 0 & -\sin(\theta\_1) & \cos(\theta\_1)\cos(\theta\_2) \end{bmatrix}.$$
|
||||
|
||||
Note that the use of $\ell\_i(\bar{\rho})$ in the final partial derivative of $\frac{\partial^2 f\_i}{\partial \theta \partial \theta^\top}$ denotes that $\ell\_i(\bar{\rho})$ is held constant in this partial derivative. The derivations of the terms within the Hessian matrix are provided in the Appendix. Note that the partial derivative $\frac{\partial}{\partial \theta} \left(\mathbf{S}^\top(\theta) \mathbf{b}\_i^\times \mathbf{C}\_{po} \ell\_i(\bar{\rho})\right)$ in the term $\frac{\partial^2 f\_i}{\partial \theta \partial \theta^\top}$ is not known to be representable through simple matrix expressions like the other partial derivatives. Instead, it can be derived for a given Euler angle sequence using a symbolic manipulation software package.#### 2.3 Forward Kinematics Algorithm 1: Halley's Method
|
||||
|
||||
A numerically-damped version of Halley's method inspired by the DQuIK method in [\[7\]](#page-4-0) begins with an initial end-effector pose estimate $\rho^{(0)}$ and starts the *j<sup>th</sup>* iteration with the computation
|
||||
$$\delta \boldsymbol{\rho}^{(j)} = \left(\mathbf{J}\_{\rho}^{\mathsf{T}}(\boldsymbol{\rho}^{(j)})\mathbf{J}\_{\rho}(\boldsymbol{\rho}^{(j)}) + \eta \mathbf{1}\right)^{-1} \mathbf{J}\_{\rho}^{\mathsf{T}}(\boldsymbol{\rho}^{(j)}) \mathbf{f}(\mathbf{y}, \boldsymbol{\rho}^{(j)}, \mathbf{0}\_{m \times 1}), \tag{3}$$
|
||||
|
||||
where $\eta > 0$ is a tunable parameter that provides numerical damping to the calculation, especially if $\rho^{(j)}$ is near a singularity. This is then followed by the update
|
||||
$$\boldsymbol{\rho}^{(j+1)} = \boldsymbol{\rho}^{(j)} + \left(\bar{\mathbf{J}}\_{\rho}^{\mathsf{T}} \bar{\mathbf{J}}\_{\rho} + \eta \mathbf{1}\right)^{-1} \bar{\mathbf{J}}\_{\rho}^{\mathsf{T}} \mathbf{f}(\mathbf{y}, \boldsymbol{\rho}^{(j)}, \mathbf{0}\_{m \times 1}),\tag{4}$$
|
||||
|
||||
where $\overline{\mathbf{J}}\_{\rho} = \mathbf{J}\_{\rho}(\rho^{(j)}) + \frac{1}{2}\overline{\mathbf{H}}(\rho^{(j)}, \delta\rho^{(j)})$ . The iteration index *j* is increased and the iteration proceeds until a specified stopping criterion is satisfied, such as $\|\rho^{(j+1)} - \rho^{(j)}\|\_{2} < \epsilon$ or a maximum number of iterations is reached.The first step of Halley's method in (3) is derived by setting (2) equal to $\mathbf{0}\_{m \times 1}$ , dropping the second-order term, and isolating for $\delta \boldsymbol{\rho}$ . The second step in (4) is found through the same procedure with the inclusion of the second-order term in (2). It is worth noting that if only the second step in (4) is performed with $\delta \boldsymbol{\rho}^{(j)} = \mathbf{0}\_{6 \times 1}$ , the damped version of Halley's method reverts to the Levenberg-Marquardt method.If it is desired to compute the covariance of the error in the pose estimate, for example to use the forward kinematics solution within a sensor fusion algorithm [\[5,10\]](#page-5-1), then (3) and (4) are respectively modified as
|
||||
$$\delta\boldsymbol{\rho}^{(j)} = \left(\mathbf{J}\_{\rho}^{\mathrm{T}}(\boldsymbol{\rho}^{(j)})\mathbf{V}^{-1}\mathbf{J}\_{\rho}(\boldsymbol{\rho}^{(j)}) + \eta\mathbf{1}\right)^{-1}\mathbf{J}\_{\rho}^{\mathrm{T}}(\boldsymbol{\rho}^{(j)})\mathbf{V}^{-1}\mathbf{f}(\mathbf{y},\boldsymbol{\rho}^{(j)},\mathbf{0}\_{m\times 1}),$$
|
||||
|
||||
$$\boldsymbol{\rho}^{(j+1)} = \boldsymbol{\rho}^{(j)} + \left(\bar{\mathbf{J}}\_{\rho}^{\mathrm{T}}\mathbf{V}^{-1}\bar{\mathbf{J}}\_{\rho} + \eta\mathbf{1}\right)^{-1}\bar{\mathbf{J}}\_{\rho}^{\mathrm{T}}\mathbf{V}^{-1}\mathbf{f}(\mathbf{y},\boldsymbol{\rho}^{(j)},\mathbf{0}\_{m\times 1}),$$
|
||||
|
||||
where $\mathbf{V} = \mathbb{E}[\mathbf{v}\mathbf{v}^{\mathsf{T}}] = \text{diag}\{\sigma\_1^2, ..., \sigma\_m^2\}$ is the measurement covariance. The covariance matrix is then computed at the $j$ <sup>th</sup> iteration as [\[4, p. 84\]](#page-4-1)
|
||||
$$\mathbf{P}^{(j)} = \mathbb{E}[(\rho\_{\text{true}} - \rho^{(j)})(\rho\_{\text{true}} - \rho^{(j)})^\mathsf{T}] = \left(\bar{\mathbf{J}}\_{\rho}^{\mathsf{T}} \mathbf{V}^{-1} \bar{\mathbf{J}}\_{\rho}\right)^{-1}.\tag{5}$$
|
||||
|
||||
If the measurement noise on each individual cable is the same (i.e., $\sigma\_i = \sigma$ , $i = 1,...,m$ , and $\mathbf{V} = \sigma \mathbf{1}\_{m \times m}$ ), then (3) and (4) can be used directly and the covariance of the pose estimation error is simply $\mathbf{P}^{(j)} = \sigma (\overline{\mathbf{J}}\_{\rho}^T \overline{\mathbf{J}}\_{\rho})^{-1}$ .### 2.4 Forward Kinematics Algorithm 2: Hybrid Method
|
||||
|
||||
A potential disadvantage of Halley's method in comparison to Newton's method
|
||||
or the Levenberg-Marquardt method is that it requires the additional computa-
|
||||
tion of the term $\bar{H}\_{\rho\rho}(\bar{\rho}, \delta\rho)$ and it involves two matrix inversions within the same
|
||||
iteration by solving both (3) and (4). To reduce the need for unnecessary higher-
|
||||
order computations, a hybrid method is proposed that follows Halley's method
|
||||
for a prescribed number of iterations, then sets $\bar{H}\_{\rho\rho}(\bar{\rho}, \delta\rho) = 0\_{m\times6}$ and follows
|
||||
the Levenberg-Marquardt for all subsequent iterations by only solving for (4).
|
||||
This proposed hybrid method is designed to take advantage of Halley's method's
|
||||
ability to converge relatively quickly in the presence of large initial pose estima-
|
||||
tion errors, as well as the computational efficiency of the Levenberg-Marquardt
|
||||
method when the pose estimation error becomes smaller in later iterations.
|
||||
|
||||
### 3 Results
|
||||
|
||||
The proposed forward kinematics algorithms are implemented in a numerical simulation of a 6-DOF suspended CDPR with 8 cables modeled after CoGiRo [\[19\]](#page-5-1) whose dimensions are provided in Table 1. All computations presented in this section are performed on a laptop computer with an AMD Ryzen 8945HS @ 4.0 GHz with 16 GB memory and the code is run in Python.A Monte-Carlo assessment is performed with end-effector poses randomly selected from uniform distributions $\mathbf{r}\_{\text{min}} \leq \mathbf{r} \leq \mathbf{r}\_{\text{max}}$ and $-\boldsymbol{\theta}\_{\text{max}} \leq \boldsymbol{\theta} \leq \boldsymbol{\theta}\_{\text{max}}$ , where $\mathbf{r}\_{\text{min}} = \begin{bmatrix} -6.75 & -4.75 & 0 \end{bmatrix}^{\text{T}}$ m, $\mathbf{r}\_{\text{max}} = \begin{bmatrix} 6.75 & 4.75 & 4.75 \end{bmatrix}^{\text{T}}$ m, and $\boldsymbol{\theta}\_{\text{max}} = \begin{bmatrix} 30 & 30 & 30 \end{bmatrix}^{\text{T}}$ degrees are chosen based on a rough estimate of the bounds on the static workspace values of the CDPR. Each of these randomly-generated poses is assessed for static feasibility with a payload mass of 100 kg, a maximum cable
|
||||
|
||||
| Cable | Pulley position, $aiT$ (m) | Cable End-Effector Attachment Point, $biT$ (m) |
|
||||
|-------|----------------------------|------------------------------------------------|
|
||||
| 1 | [-7.20 -5.44 5.39] | [0.503 -0.493 0.000] |
|
||||
| 2 | [-7.48 -5.15 5.40] | [-0.510 0.351 0.998] |
|
||||
| 3 | [-7.41 5.19 5.40] | [-0.503 -0.270 0.000] |
|
||||
| 4 | [-7.12 5.47 5.41] | [0.496 0.356 1.000] |
|
||||
| 5 | [7.22 5.37 5.41] | [-0.503 0.493 0.000] |
|
||||
| 6 | [7.51 5.08 5.42] | [0.500 -0.340 0.999] |
|
||||
| 7 | [7.43 -5.26 5.39] | [0.502 0.275 -0.001] |
|
||||
| 8 | [7.14 -5.54 5.40] | [-0.505 -0.346 0.998] |
|
||||
|
||||
Table 1. Dimensions used for the numerical simulations based on CoGiRo [19].
|
||||
|
||||
tension of 6,000 N, and a minimum cable tension of 10 N. This process is repeated until 10,000 statically-feasible poses are randomly generated. The inverse kinematics of each pose is then solved assuming straight and rigid cables to obtain the cable lengths associated with each pose. Perfect measurements with no noise are then used with the proposed forward kinematics algorithm and the Levenberg-Marquardt method using a stopping tolerance of $\epsilon = 10^{-9}$ , a maximum of 30 iterations, numerical damping of $\eta = 10^{-6}$ , and 3 iterations of Halley's method when using the proposed hybrid method. All methods are initialized with a pose estimate of $\rho^{(0)} = \rho\_{true} + \delta\rho^{(0)}$ , where $\rho\_{true}$ is the randomly-generated truth pose within the static feasible workspace and $\delta\rho^{(0)} = {\begin{bmatrix} \delta\mathbf{r}^{(0)T} & \delta\mathbf{\theta}^{(0)T} \end{bmatrix}}^T$ is an initial perturbation. To assess the performance of these methods as a function of the initial pose estimation error, $\delta\mathbf{r}^{(0)}$ and $\delta\mathbf{\theta}^{(0)}$ are drawn from uniform distributions $-\delta\mathbf{r}\_{max}^{(0)} \leq \delta\mathbf{r}^{(0)} \leq \delta\mathbf{r}\_{max}^{(0)}$ and $-\delta\mathbf{\theta}\_{max}^{(0)} \leq \delta\mathbf{\theta}^{(0)} \leq \delta\mathbf{\theta}\_{max}^{(0)}$ . The Monte Carlo assessment is performed for each of the three forward kinematics algorithms with $\mathbf{r}\_{max}^{(0)} = {\begin{bmatrix} 1 & 1 & 1 \end{bmatrix}}^T$ m and ten different values of $\mathbf{\theta}\_{max}^{(0)}$ ranging from a small initial maximum orientation error of $\mathbf{\theta}\_{max}^{(0)} = {\begin{bmatrix} 2 & 2 & 2 \end{bmatrix}}^T$ deg to a large initial maximum orientation error of $\mathbf{\theta}\_{max}^{(0)} = {\begin{bmatrix} 40 & 40 & 40 \end{bmatrix}}^T$ deg.The results of this Monte-Carlo assessment are shown in Fig. 2, which include the mean and . 99th percentile of the number of iterations and computation time required to meet the specified stopping conditions, as well as the percentage of runs that successfully converge within .0.1 m and . 1 deg of the true end-effector pose. It is observed in Fig. 2 that for small initial pose estimation errors the proposed forward kinematics algorithms provide a small reduction in the number of iterations required and an increase in the computation time compared to the Levenberg-Marquardt method, with a small improvement in the success rate of accurate convergence. However, for large errors (roughly larger than .20 deg) the number of iterations is substantially decreased and the success rate is greatly increased with the proposed methods in comparison to the Levenberg-Marquardt method. Additionally, the . 99th-percentile computation times with the proposed hybrid method are reduced with large initial estimation errors compared to the
|
||||
|
||||

|
||||
|
||||
Fig. 2. Monte-Carlo assessment of the proposed forward kinematics methods (labeled
|
||||
"Halley" and "Hybrid"), as well as the Levenberg-Marquardt method (labeled "LM")
|
||||
with no noise or cable elasticity, including (a) number of iterations, (b) computation
|
||||
time required, and (c) success rate of convergence.
|
||||
|
||||
Levenberg-Marquardt method. Further assessment of the Monte Carlo simula-
|
||||
|
||||
sions with the three methods is provided in Fig. 3, which includes the mean and
|
||||
|
||||
99th-percentile errors in the final position and orientation estimates. These errors
|
||||
|
||||
are computed as $\|\mathbf{r}\_{true} - \mathbf{r}^{(j)}\|\_{2}$ and $\|\boldsymbol{\theta}\_{true} - \boldsymbol{\theta}^{(j)}\|\_{2}$ , respectively, where $j$ repre-
|
||||
|
||||
sents the number of iterations required to meet the stopping criteria. Figure 3
|
||||
|
||||
demonstrates that the estimation errors obtained with the proposed methods
|
||||
|
||||
are considerably lower than those with the Levenberg-Marquardt method. Inter-
|
||||
|
||||
estingly, even in situations where Fig. 2c shows less than a percent difference
|
||||
|
||||
in the success rates between the three methods, there is a notable reduction in
|
||||
|
||||
Fig. 3. Monte-Carlo assessment of the proposed forward kinematics methods (labeled "Halley" and "Hybrid"), as well as the Levenberg-Marquardt method (labeled "LM") with no noise or cable elasticity, including (a) position estimation error and (b) orientation estimation error. Note that (b) uses a linear y-axis scale below . 5 deg and a logarithmic scale above this.
|
||||
|
||||
the orientation estimation error with the proposed methods compared to the Levenberg-Marquardt method. This seems to suggest that when the Levenberg-Marquardt method fails to converge, it tends to incur very large errors. In contrast, the proposed methods appear less prone to large errors, even when they fail to converge correctly.
|
||||
|
||||
To assess the robustness of the proposed algorithms to model uncertainty, measurement noise and cable elasticity are added to the simulation. In particular, the cable-length measurements are adjusted to be $y\_i = ||l\_i(\rho)||\_2/(1+\frac{T\_i}{EA\_0}) + v\_i$ , where $T\_i$ is the tension in the *i*<sup>th</sup> cable, $E$ is the cable's elastic modulus, and $A\_0$ is the cross-sectional area of the cable [\[9\]](#page-8-1). Numerical values of $E = 35$ GPa and $A\_0 = 8.205 \times 10^{-6}$ m<sup>2</sup> are used to match the CoGiRo values from [\[9\]](#page-8-1), while the zero-mean Gaussian white noise $v\_i$ has a standard deviation of 5 mm. A quadratic program is solved to determine the cable tensions associated with each statically-feasible pose. The Monte-Carlo assessment is performed again with the noisy and elastic cable measurements and the results are included in Fig. 4. It is demonstrated in Fig. 4 that the trends seen with the idealized cable model in Fig. 2 also hold with elastic and noisy cable measurements. The only notable differences are that the number of iterations and computation time of all algorithms increases, the number of successful convergences decreases, and there is less of a distinction in successful convergence rate between the methods for small initial pose estimation error. This assessment provides confidence that the proposed algorithms can substantially improve the rate of successful convergence
|
||||
|
||||
Fig. 4. Monte-Carlo assessment of the proposed forward kinematics methods (labeled "Halley" and "Hybrid"), as well as the Levenberg-Marquardt method (labeled "LM") with noise and cable elasticity, including (a) number of iterations, (b) computation time required, and (c) success rate of convergence.
|
||||
|
||||
and in the case of the hybrid method reduce the computation time required in the presence of modeling errors and measurement uncertainty.
|
||||
|
||||
### 4 Conclusion
|
||||
|
||||
This paper presented two iterative forward kinematic algorithms for overconstrained CDPRs based on Halley's method that make use of second-order terms in the Taylor series expansion of the CDPR's loop-closure equations. It was shown through a numerical example of a suspended .6-DOF CDPR with. 8 cables that both proposed algorithms reduce the number of iterations required to reach a convergence tolerance and have a greater success rate of convergence to the true CDPR pose compared to the standard iterative Levenberg-Marquardt method. This trend is amplified as the initial pose estimation error increases. The proposed hybrid method also demonstrated quicker computation times compared to the Levenberg-Marquardt method in the presence of relatively large initial pose estimation errors. Future work on this topic will involve experimental implementation and validation of the proposed algorithms in a real-time framework, as well as comparisons to other forward kinematics algorithms in the literature.
|
||||
|
||||
Disclosure of Interests. The authors have no competing interests to declare that are relevant to the content of this article.
|
||||
|
||||
# Appendix: Derivation of Terms in Hessian
|
||||
|
||||
.
|
||||
|
||||
This appendix presents the derivation of the terms in the Hessian matrix from
|
||||
in Sect. 2.2. Knowing that $\frac{\partial^2 f\_i}{\partial \mathbf{r} \partial \mathbf{r}^\top} = \frac{\partial}{\partial \mathbf{r}} \left( \frac{\partial f\_i}{\partial \mathbf{r}} \right)^\top$ , the first Hessian term is
|
||||
$$\begin{split} \frac{\partial^2 f\_i}{\partial \mathbf{r} \partial \mathbf{r}^\mathsf{T}} &= \frac{\partial}{\partial \mathbf{r}} \left( \frac{\ell\_i(\rho)}{\|\ell\_i(\rho)\|} \right) = \frac{\partial}{\partial \mathbf{r}} \left( \ell\_i(\rho) \right) \frac{1}{\|\ell\_i(\rho)\|} + \ell\_i(\rho) \frac{\partial}{\partial \mathbf{r}} \left( \frac{1}{\|\ell\_i(\rho)\|} \right) \\ &= \left( \mathbf{1}\_{3 \times 3} \right) \frac{1}{\|\ell\_i(\rho)\|} + \ell\_i(\rho) \left( -\frac{\ell\_i^\mathsf{T}(\rho)}{\|\ell\_i(\rho)\|^3} \right) = \frac{\mathbf{1}\_{3 \times 3}}{\|\ell\_i(\rho)\|} - \frac{\ell\_i(\rho) \ell\_i^\mathsf{T}(\rho)}{\|\ell\_i(\rho)\|^3}. \end{split}$$
|
||||
|
||||
Starting with $\frac{\partial^2 f\_i}{\partial \theta \partial \mathbf{r}^\mathsf{T}} = \frac{\partial}{\partial \theta} \left( \frac{\partial f\_i}{\partial \mathbf{r}} \right)^\mathsf{T}$ and using the DCM identity $\frac{\partial}{\partial \theta} (\mathbf{C}\_{po}^\mathsf{T}(\theta) \mathbf{u}) = -\mathbf{C}\_{po}^\mathsf{T}(\theta) \mathbf{u}^\times \mathbf{S}(\theta)$ ) [\[16\]](#page-10-573), the second Hessian term is computed as
|
||||
$$\begin{split} \frac{\partial^2 f\_i}{\partial \boldsymbol{\theta} \partial \mathbf{r}^{\mathsf{T}}} &= \frac{\partial}{\partial \boldsymbol{\theta}} \left( \ell\_i(\boldsymbol{\rho}) \right) \frac{1}{\|\ell\_i(\boldsymbol{\rho})\|} + \ell\_i(\boldsymbol{\rho}) \frac{\partial}{\partial \boldsymbol{\theta}} \left( \frac{1}{\|\ell\_i(\boldsymbol{\rho})\|} \right) \\ &= \frac{\partial}{\partial \boldsymbol{\theta}} \left( \mathbf{C}\_{po}^{\mathsf{T}}(\boldsymbol{\theta}) \mathbf{b}\_i \right) \frac{1}{\|\ell\_i(\boldsymbol{\rho})\|} + \ell\_i(\boldsymbol{\rho}) \left( -\frac{\ell\_i^{\mathsf{T}}(\boldsymbol{\rho})}{\|\ell\_i(\boldsymbol{\rho})\|^3} \frac{\partial}{\partial \boldsymbol{\theta}} \left( \mathbf{C}\_{po}^{\mathsf{T}}(\boldsymbol{\theta}) \mathbf{b}\_i \right) \right) \\ &= -\left( \frac{\mathbf{1}\_{3 \times 3}}{\|\ell\_i(\boldsymbol{\rho})\|} - \frac{\ell\_i(\boldsymbol{\rho}) \ell\_i^{\mathsf{T}}(\boldsymbol{\rho})}{\|\ell\_i(\boldsymbol{\rho})\|^3} \right) \mathbf{C}\_{po}^{\mathsf{T}}(\boldsymbol{\theta}) \mathbf{b}\_i^{\mathsf{X}} \mathbf{S}(\boldsymbol{\theta}) = \frac{\partial^2 f\_i}{\partial \mathbf{r} \partial \mathbf{r}^{\mathsf{T}}} (-\mathbf{C}\_{po}^{\mathsf{T}}(\boldsymbol{\theta}) \mathbf{b}\_i^{\mathsf{X}} \mathbf{S}(\boldsymbol{\theta})). \end{split}$$
|
||||
|
||||
The final Hessian term is found starting with $\frac{\partial^2 f\_i}{\partial \theta \partial \theta^\mathsf{T}} = \frac{\partial}{\partial \theta} \left( \frac{\partial f\_i}{\partial \theta} \right)^\mathsf{T}$ , resulting in
|
||||
$$
|
||||
\begin{split}
|
||||
\frac{\partial^2 f\_i}{\partial \theta \partial \theta^{\mathsf{T}}} &= \mathbf{S}^{\mathsf{T}}(\theta) \mathbf{b}\_i^{\times} \mathbf{C}\_{po}(\theta) \ell\_i(\rho) \frac{\partial}{\partial \theta} \left( \frac{1}{\|\ell\_i(\rho)\|} \right) \\
|
||||
&+ \frac{\partial}{\partial \theta} \left( \mathbf{S}^{\mathsf{T}}(\theta) \mathbf{b}\_i^{\times} \mathbf{C}\_{po}(\theta) \ell\_i(\rho) \right) \frac{1}{\|\ell\_i(\rho)\|} \\
|
||||
&= -\mathbf{S}^{\mathsf{T}}(\theta) \mathbf{b}\_i^{\times} \mathbf{C}\_{po}(\theta) \left( \frac{\mathbf{1}\_{3 \times 3}}{\|\ell\_i(\rho)\|} - \frac{\ell\_i(\rho) \ell\_i^{\mathsf{T}}(\rho)}{\|\ell\_i(\rho)\|^3} \right) \mathbf{C}\_{po}^{\mathsf{T}}(\theta) \mathbf{b}\_i^{\times} \mathbf{S}(\theta) \\
|
||||
&+ \frac{1}{\|\ell\_i(\bar{\rho})\|} \frac{\partial}{\partial \theta} \left( \mathbf{S}^{\mathsf{T}}(\theta) \mathbf{b}\_i^{\times} \mathbf{C}\_{po}(\theta) \ell\_i(\bar{\rho}) \right) \\
|
||||
&= \mathbf{S}^{\mathsf{T}}(\theta) \mathbf{b}\_i^{\times} \mathbf{C}\_{po}(\theta) \frac{\partial^2 f\_i}{\partial \theta \partial \mathbf{r}^{\mathsf{T}}} + \frac{1}{\|\ell\_i(\bar{\rho})\|} \frac{\partial}{\partial \theta} \left( \mathbf{S}^{\mathsf{T}}(\theta) \mathbf{b}\_i^{\times} \mathbf{C}\_{po}(\theta) \ell\_i(\bar{\rho}) \right).
|
||||
\end{split}
|
||||
$$
|
||||
|
||||
# References
|
||||
|
||||
.
|
||||
|
||||
- 1. Baskar, A., Plecnik, M., Hauenstein, J.D., Wampler, C.W.: A numerical continuation approach using monodromy to solve the forward kinematics of cable-driven parallel robots with sagging cables. Mech. Mach. Theory 195, 105609 (2024)
|
||||
- 2. Bieber, J., Pallmer, S., Beitelschmidt, M.: Computationally efficient implementation of the Gauss-Newton method for solving the forward kinematics of redundant cable-driven parallel robots. PMM-J. Appl. Math. Mech. 23(3), e202300231 (2023)
|
||||
- 3. Caverly, R.J., Cheah, S.K., Bunker, K.R., Patel, S., Sexton, N., Nguyen, V.L.: Online self-calibration of cable-driven parallel robots using covariance-based data quality assessment metrics. J. Mech. Robot. 17(1), 010904 (2025)
|
||||
- 4. Crassidis, J.L., Junkins, J.L.: Optimal Estimation of Dynamic Systems. CRC Press, Boca Raton (2004)
|
||||
- 5. Garant, X., Campeau-Lecours, A., Cardou, P., Gosselin, C.: Improving the forward kinematics of cable-driven parallel robots through cable angle sensors. In: Cable-Driven Parallel Robots, pp. 167–179. Springer, Cham (2018)
|
||||
- 6. Hughes, P.C.: Spacecraft Attitude Dynamics. Dover, Mineola (2004)
|
||||
- 7. Lloyd, S., Irani, R.A., Ahmadi, M.: Fast and robust inverse kinematics of serial robots using Halley's method. IEEE T. Robot. 38(5), 2768–2780 (2022)
|
||||
- 8. Merlet, J.P.: Some properties of the Irvine cable model and their use for the kinematic analysis of cable-driven parallel robots. Mech. Mach. Theory 135, 271–280 (2019)
|
||||
- 9. Nguyen, D.Q., Gouttefarde, M., Company, O., Pierrot, F.: On the simplifications of cable model in static analysis of large-dimension cable-driven parallel robots. In: IEEE International Conference on Intelligent Robots, pp. 928–934 (2013)
|
||||
- 10. Nguyen, V.L., Caverly, R.J.: Cable-driven parallel robot pose estimation using extended Kalman filtering with inertial payload measurements. IEEE Rob. Autom. Lett. 6(2), 3615–3622 (2021)
|
||||
- 11. Nguyen, V.L., Caverly, R.J.: CDPR forward kinematics with error covariance bounds for unconstrained end-effector attitude parameterizations. In: International Conference on Cable-Driven Parallel Robots, pp. 37–49. Springer, Cham (2021)
|
||||
- 12. Patel, S., Nguyen, V.L., Caverly, R.J.: Forward kinematics of a cable-driven parallel robot with pose estimation error covariance bounds. Mech. Mach. Theory 183, 105231 (2023)
|
||||
- 13. Pott, A., Schmidt, V.: On the forward kinematics of cable-driven parallel robots. In: IEEE International Conference on Intelligent Robots, pp. 3182–3187 (2015)
|
||||
- 14. Pott, A.: An algorithm for real-time forward kinematics of cable-driven parallel robots. In: Advances in Robot Kinematics: Motion in Man and Machine, pp. 529– 538. Springer, Dordrecht (2010)
|
||||
- 15. Rheinboldt, W.C.: Methods for Solving Systems of Nonlinear Equations, 2nd edn. SIAM, Philadelphia (1998)
|
||||
- 16. de Ruiter, A.H., Forbes, J.R.: General identities for parameterizations of SO(3) with applications. J. Appl. Mech. 81(7) (2014)
|
||||
- 17. Santos, J.C., Gouttefarde, M.: A real-time capable forward kinematics algorithm for cable-driven parallel robots considering pulley kinematics. In: Advances in Robot Kinematics 2020, pp. 199–208. Springer, Cham (2021)
|
||||
- 18. Scavo, T., Thoo, J.: On the geometry of Halley's method. Am. Math. Mon. 102(5), 417–426 (1995)
|
||||
- 19. Tempel, P., Herve, P.E., Tempier, O., Gouttefarde, M., Pott, A.: Estimating inertial parameters of suspended cable-driven parallel robots—use case on CoGiRo. In: IEEE International Conference on Robotics and Automation, pp. 6093–6098 (2017)
|
||||
|
|
@ -0,0 +1,690 @@
|
|||
Here’s the markdown version, organized to be friendly for an LLM that will implement the forward kinematics / forward transform.
|
||||
|
||||
---
|
||||
|
||||
# Fast and Reliable Iterative CDPR Forward Kinematics
|
||||
|
||||
## A Quadratic Approximation (Halley) Approach
|
||||
|
||||
*Source: Mahnke & Caverly, “Fast and Reliable Iterative Cable-Driven Parallel Robot Forward Kinematics: A Quadratic Approximation Approach” *
|
||||
|
||||
This document restates the paper in implementation-oriented form. It focuses on:
|
||||
|
||||
* The forward kinematics problem formulation for an overconstrained CDPR
|
||||
* The loop-closure and measurement equations
|
||||
* The Jacobian and Hessian terms needed for Halley’s method
|
||||
* Two iterative algorithms:
|
||||
|
||||
* A Halley-based forward kinematics solver
|
||||
* A hybrid Halley + Levenberg–Marquardt solver
|
||||
|
||||
All notation assumes a 6-DOF end-effector pose, but the formulation generalizes to any twice-differentiable measurement model.
|
||||
|
||||
---
|
||||
|
||||
## 1. System and Notation
|
||||
|
||||
### 1.1 Frames and Pose
|
||||
|
||||
* Inertial/world frame: ( F_o ), origin at point ( o )
|
||||
* End-effector frame: ( F_p ), origin at the end-effector CoM ( p )
|
||||
|
||||
**Pose vector**
|
||||
|
||||
[
|
||||
\rho \in \mathbb{R}^6, \quad \rho^T = \begin{bmatrix} r^T & \theta^T \end{bmatrix}
|
||||
]
|
||||
|
||||
* ( r \in \mathbb{R}^3 ): position of ( p ) expressed in ( F_o )
|
||||
* ( \theta \in \mathbb{R}^3 ): orientation parameterization (here: 3-2-1 / yaw–pitch–roll Euler angles)
|
||||
|
||||
**Rotation / Direction Cosine Matrix**
|
||||
|
||||
* ( R_{po}(\theta) ): rotation from ( F_o ) to ( F_p )
|
||||
* ( C_{po}(\theta) = R_{po}^T(\theta) ): DCM describing orientation of ( F_p ) w.r.t. ( F_o )
|
||||
|
||||
**Cross-operator**
|
||||
|
||||
* For ( u \in \mathbb{R}^3 ):
|
||||
[
|
||||
u_\times \in \text{so}(3), \quad u_\times w = u \times w
|
||||
]
|
||||
|
||||
---
|
||||
|
||||
### 1.2 CDPR Geometry
|
||||
|
||||
For cable ( i \in {1,\dots,m} ) (with ( m > 6 ), i.e. overconstrained 6-DOF CDPR):
|
||||
|
||||
* Pulley/anchor position (in ( F_o )):
|
||||
|
||||
[
|
||||
a_i \in \mathbb{R}^3
|
||||
]
|
||||
|
||||
* End-effector attachment point (in ( F_p )):
|
||||
|
||||
[
|
||||
b_i \in \mathbb{R}^3
|
||||
]
|
||||
|
||||
* Pose-dependent attachment point position in ( F_o ):
|
||||
|
||||
[
|
||||
i(\rho) = r + C_{po}^T(\theta), b_i - a_i ;\in \mathbb{R}^3
|
||||
]
|
||||
|
||||
This is the vector from pulley anchor ( a_i ) to end-effector attachment point expressed in the world frame.
|
||||
|
||||
---
|
||||
|
||||
### 1.3 Orientation Kinematics Mapping (S(\theta))
|
||||
|
||||
Angular velocity mapping (for Euler 3-2-1, yaw–pitch–roll):
|
||||
|
||||
[
|
||||
\omega = S(\theta) \dot\theta
|
||||
]
|
||||
|
||||
For 3-2-1 Euler angles ( \theta = [\theta_1, \theta_2, \theta_3]^T ):
|
||||
|
||||
[
|
||||
S(\theta) =
|
||||
\begin{bmatrix}
|
||||
1 & 0 & -\sin(\theta_2) \
|
||||
0 & \cos(\theta_1) & \sin(\theta_1)\cos(\theta_2) \
|
||||
0 & -\sin(\theta_1) & \cos(\theta_1)\cos(\theta_2)
|
||||
\end{bmatrix}
|
||||
]
|
||||
|
||||
In code, you can generalize this or swap for another unconstrained attitude parameterization with its own ( S(\theta) ).
|
||||
|
||||
---
|
||||
|
||||
## 2. Forward Kinematics: Model
|
||||
|
||||
### 2.1 Measurement Model (Cable Lengths)
|
||||
|
||||
Assume:
|
||||
|
||||
* Cables are straight, massless, inelastic (for the main derivation).
|
||||
* Cable length measurements are available from encoders.
|
||||
|
||||
Cable ( i ) measured length:
|
||||
|
||||
[
|
||||
y_i = | i(\rho) |_2 + v_i
|
||||
]
|
||||
|
||||
* ( y_i ): measured cable length
|
||||
* ( v_i \sim \mathcal{N}(0, \sigma_i^2) ): measurement noise
|
||||
|
||||
Define stacked vectors:
|
||||
|
||||
* ( y = [y_1, \dots, y_m]^T \in \mathbb{R}^m )
|
||||
* ( v = [v_1, \dots, v_m]^T \in \mathbb{R}^m )
|
||||
|
||||
Define residual functions:
|
||||
|
||||
[
|
||||
f_i(y_i, \rho, v_i) = -y_i + | i(\rho) |_2 + v_i
|
||||
]
|
||||
|
||||
Stacked:
|
||||
|
||||
[
|
||||
f(y,\rho,v) =
|
||||
\begin{bmatrix}
|
||||
f_1(y_1,\rho,v_1)\
|
||||
\vdots\
|
||||
f_m(y_m,\rho,v_m)
|
||||
\end{bmatrix}
|
||||
\in \mathbb{R}^m
|
||||
]
|
||||
|
||||
The **forward kinematics problem** is:
|
||||
|
||||
> Find ( \rho ) such that
|
||||
> [
|
||||
> f(y,\rho,v) = 0
|
||||
> ]
|
||||
>
|
||||
> (in practice, ( v ) is unknown and we solve for ( f(y,\rho,0) \approx 0 )).
|
||||
|
||||
---
|
||||
|
||||
### 2.2 Taylor Expansion Around a Nominal Pose
|
||||
|
||||
Let:
|
||||
|
||||
* Linearization point ( \bar{\rho} ) (current pose estimate)
|
||||
* ( \delta\rho = \rho - \bar{\rho} )
|
||||
|
||||
Taylor expand ( f(y,\rho,v) ) around ( \rho = \bar{\rho} ), ( v = 0 ):
|
||||
|
||||
[
|
||||
f(y,\rho,v) \approx f(y,\bar{\rho},0) + J_\rho(\bar{\rho}) , \delta\rho + \frac{1}{2} \bar{H}_{\rho\rho}(\bar{\rho},\delta\rho), \delta\rho + v
|
||||
\tag{TS}
|
||||
]
|
||||
|
||||
Where:
|
||||
|
||||
* ( J_\rho(\rho) = \dfrac{\partial f}{\partial \rho} \in \mathbb{R}^{m \times 6} ) is the Jacobian
|
||||
* ( \bar{H}*{\rho\rho}(\rho,\delta\rho) \in \mathbb{R}^{m \times 6} ) is constructed from the Hessians ( H*{\rho\rho,i} ):
|
||||
|
||||
For each cable ( i ),
|
||||
|
||||
[
|
||||
H_{\rho\rho,i}(\rho) =
|
||||
\begin{bmatrix}
|
||||
\dfrac{\partial^2 f_i}{\partial r \partial r^T} &
|
||||
\dfrac{\partial^2 f_i}{\partial \theta \partial r^T} \
|
||||
\left(\dfrac{\partial^2 f_i}{\partial \theta \partial r^T}\right)^T &
|
||||
\dfrac{\partial^2 f_i}{\partial \theta \partial \theta^T}
|
||||
\end{bmatrix}
|
||||
\in \mathbb{R}^{6 \times 6}
|
||||
]
|
||||
|
||||
and
|
||||
|
||||
[
|
||||
\bar{H}*{\rho\rho}(\rho,\delta\rho) =
|
||||
\begin{bmatrix}
|
||||
\delta\rho^T H*{\rho\rho,1}(\rho) \
|
||||
\vdots \
|
||||
\delta\rho^T H_{\rho\rho,m}(\rho)
|
||||
\end{bmatrix}
|
||||
\in \mathbb{R}^{m \times 6}
|
||||
]
|
||||
|
||||
Then ( \bar{H}*{\rho\rho}(\rho,\delta\rho) \delta\rho \in \mathbb{R}^m ) has elements ( \delta\rho^T H*{\rho\rho,i}(\rho) \delta\rho ).
|
||||
|
||||
---
|
||||
|
||||
## 3. Derivatives Needed for Halley’s Method
|
||||
|
||||
This section gives expressions for:
|
||||
|
||||
* Jacobian ( J_\rho(\rho) )
|
||||
* Hessian terms ( H_{\rho\rho,i}(\rho) )
|
||||
|
||||
You must implement the following building blocks.
|
||||
|
||||
### 3.1 Jacobian ( J_\rho(\rho) )
|
||||
|
||||
Recall:
|
||||
|
||||
[
|
||||
f_i(y_i,\rho,0) = -y_i + | i(\rho) |
|
||||
]
|
||||
|
||||
Let:
|
||||
|
||||
* ( i = i(\rho) \in \mathbb{R}^3 )
|
||||
* ( \ell_i = | i(\rho) | )
|
||||
|
||||
Then:
|
||||
|
||||
1. Derivative w.r.t. position ( r ):
|
||||
|
||||
[
|
||||
\frac{\partial f_i}{\partial r} =
|
||||
\frac{i^T}{\ell_i} \quad \in \mathbb{R}^{1 \times 3}
|
||||
]
|
||||
|
||||
2. Derivative w.r.t. orientation ( \theta ):
|
||||
|
||||
* First note:
|
||||
[
|
||||
i(\rho) = r + C_{po}^T(\theta)b_i - a_i
|
||||
]
|
||||
|
||||
* Use identity (DCM derivative w.r.t. parameter vector ( \theta )):
|
||||
|
||||
[
|
||||
\frac{\partial}{\partial \theta}
|
||||
\left[ C_{po}^T(\theta) u \right]
|
||||
= - C_{po}^T(\theta) u_\times S(\theta)
|
||||
]
|
||||
for any vector ( u \in \mathbb{R}^3 ).
|
||||
|
||||
* So:
|
||||
[
|
||||
\frac{\partial i}{\partial \theta} =
|
||||
\frac{\partial}{\partial \theta} \left[ C_{po}^T(\theta) b_i \right]
|
||||
= - C_{po}^T(\theta) (b_i)_\times S(\theta)
|
||||
\in \mathbb{R}^{3 \times 3}
|
||||
]
|
||||
|
||||
* Then:
|
||||
|
||||
[
|
||||
\frac{\partial f_i}{\partial \theta} =
|
||||
\frac{i^T}{\ell_i} \frac{\partial i}{\partial \theta}
|
||||
=====================================================
|
||||
|
||||
\frac{i^T}{\ell_i} \left( - C_{po}^T(\theta) (b_i)_\times S(\theta) \right)
|
||||
\quad \in \mathbb{R}^{1 \times 3}
|
||||
]
|
||||
|
||||
**Jacobian row ( i ):**
|
||||
|
||||
[
|
||||
\left[ \frac{\partial f_i}{\partial r} ;; \frac{\partial f_i}{\partial \theta} \right]
|
||||
======================================================================================
|
||||
|
||||
\left[
|
||||
\frac{i^T}{\ell_i}
|
||||
;;
|
||||
\frac{i^T}{\ell_i}
|
||||
\left(-C_{po}^T(\theta) (b_i)_\times S(\theta)\right)
|
||||
\right]
|
||||
]
|
||||
|
||||
Stack all rows for ( i = 1,\dots,m ) to form ( J_\rho(\rho) \in \mathbb{R}^{m \times 6} ).
|
||||
|
||||
---
|
||||
|
||||
### 3.2 Hessian Terms
|
||||
|
||||
We need:
|
||||
|
||||
* ( \dfrac{\partial^2 f_i}{\partial r \partial r^T} )
|
||||
* ( \dfrac{\partial^2 f_i}{\partial \theta \partial r^T} )
|
||||
* ( \dfrac{\partial^2 f_i}{\partial \theta \partial \theta^T} )
|
||||
|
||||
Again, let ( i = i(\rho) ), ( \ell_i = | i(\rho) | ).
|
||||
|
||||
#### 3.2.1 ( \partial^2 f_i / \partial r \partial r^T )
|
||||
|
||||
From the appendix:
|
||||
|
||||
[
|
||||
\frac{\partial^2 f_i}{\partial r \partial r^T}
|
||||
==============================================
|
||||
|
||||
\frac{1}{\ell_i} I_{3\times 3}
|
||||
|
||||
* \frac{1}{\ell_i^3} i, i^T
|
||||
\in \mathbb{R}^{3 \times 3}
|
||||
]
|
||||
|
||||
#### 3.2.2 ( \partial^2 f_i / \partial \theta \partial r^T )
|
||||
|
||||
Using identity:
|
||||
|
||||
[
|
||||
\frac{\partial^2 f_i}{\partial \theta \partial r^T}
|
||||
===================================================
|
||||
|
||||
\frac{\partial^2 f_i}{\partial r \partial r^T}
|
||||
\left( - C_{po}^T(\theta) (b_i)_\times S(\theta) \right)
|
||||
]
|
||||
|
||||
So:
|
||||
|
||||
[
|
||||
\frac{\partial^2 f_i}{\partial \theta \partial r^T}
|
||||
===================================================
|
||||
|
||||
\left( \frac{1}{\ell_i} I - \frac{1}{\ell_i^3} i i^T \right)
|
||||
\left( - C_{po}^T(\theta) (b_i)_\times S(\theta) \right)
|
||||
\in \mathbb{R}^{3 \times 3}
|
||||
]
|
||||
|
||||
#### 3.2.3 ( \partial^2 f_i / \partial \theta \partial \theta^T )
|
||||
|
||||
From the appendix:
|
||||
|
||||
[
|
||||
\frac{\partial^2 f_i}{\partial \theta \partial \theta^T}
|
||||
========================================================
|
||||
|
||||
S^T(\theta) (b_i)*\times C*{po}(\theta)
|
||||
\frac{\partial^2 f_i}{\partial \theta \partial r^T}
|
||||
+
|
||||
\frac{1}{|i(\bar{\rho})|}
|
||||
\frac{\partial}{\partial \theta}
|
||||
\left[ S^T(\theta) (b_i)*\times C*{po}(\theta), i(\bar{\rho}) \right]
|
||||
]
|
||||
|
||||
Important notes for implementation:
|
||||
|
||||
* The last term depends on ( i(\bar{\rho}) ) held constant while differentiating w.r.t ( \theta ).
|
||||
* The paper suggests deriving this term symbolically for the chosen attitude parameterization (e.g. with a CAS tool).
|
||||
* **Practical option for implementation:**
|
||||
|
||||
* Either (a) pre-generate closed-form code for this term symbolically and paste it, or
|
||||
* (b) approximate ( \partial^2 f_i / \partial \theta \partial \theta^T ) via finite differences of ( \partial f_i / \partial \theta ) if performance allows.
|
||||
|
||||
#### 3.2.4 Building ( H_{\rho\rho,i} ) and ( \bar{H}_{\rho\rho} )
|
||||
|
||||
For each cable ( i ):
|
||||
|
||||
[
|
||||
H_{\rho\rho,i}(\rho) =
|
||||
\begin{bmatrix}
|
||||
\dfrac{\partial^2 f_i}{\partial r \partial r^T} &
|
||||
\dfrac{\partial^2 f_i}{\partial \theta \partial r^T} \
|
||||
\left(\dfrac{\partial^2 f_i}{\partial \theta \partial r^T}\right)^T &
|
||||
\dfrac{\partial^2 f_i}{\partial \theta \partial \theta^T}
|
||||
\end{bmatrix}
|
||||
\in \mathbb{R}^{6 \times 6}
|
||||
]
|
||||
|
||||
Given ( \delta\rho \in \mathbb{R}^6 ), build:
|
||||
|
||||
[
|
||||
\bar{H}*{\rho\rho}(\rho,\delta\rho) =
|
||||
\begin{bmatrix}
|
||||
\delta\rho^T H*{\rho\rho,1}(\rho) \
|
||||
\vdots \
|
||||
\delta\rho^T H_{\rho\rho,m}(\rho)
|
||||
\end{bmatrix}
|
||||
\in \mathbb{R}^{m \times 6}
|
||||
]
|
||||
|
||||
This is what Halley’s method needs.
|
||||
|
||||
---
|
||||
|
||||
## 4. Halley-Based Forward Kinematics Algorithm
|
||||
|
||||
We solve for the pose ( \rho ) that makes ( f(y,\rho,0) \approx 0 ).
|
||||
|
||||
Define:
|
||||
|
||||
* Residual vector at iteration ( j ): ( r^{(j)} := f(y,\rho^{(j)},0) )
|
||||
* Jacobian: ( J^{(j)} := J_\rho(\rho^{(j)}) )
|
||||
* Hessian-based matrix: ( \bar{H}^{(j)} := \bar{H}_{\rho\rho}(\rho^{(j)},\delta\rho^{(j)}) ) (for the second step)
|
||||
|
||||
A small positive scalar ( \eta > 0 ) adds numerical damping (Levenberg–Marquardt style).
|
||||
|
||||
### 4.1 Baseline Halley Update
|
||||
|
||||
Algorithm parameters:
|
||||
|
||||
* Damping ( \eta > 0 ) (e.g. ( \eta = 10^{-6} ))
|
||||
* Initial pose guess ( \rho^{(0)} )
|
||||
* Tolerances:
|
||||
|
||||
* Pose update norm threshold ( \varepsilon )
|
||||
* Maximum iterations ( j_{\max} )
|
||||
|
||||
#### Step 0: Initialization
|
||||
|
||||
* Set ( j = 0 )
|
||||
* Set ( \rho^{(0)} ) (e.g. nominal pose or approximate initial estimate)
|
||||
|
||||
#### Step 1: First (Newton/LM-like) update to get ( \delta\rho^{(j)} )
|
||||
|
||||
Compute:
|
||||
|
||||
1. Residual:
|
||||
[
|
||||
r^{(j)} = f(y,\rho^{(j)},0)
|
||||
]
|
||||
|
||||
2. Jacobian:
|
||||
[
|
||||
J^{(j)} = J_\rho(\rho^{(j)})
|
||||
]
|
||||
|
||||
3. Damped least-squares step (LM-like):
|
||||
|
||||
[
|
||||
\delta\rho^{(j)} =
|
||||
\left( {J^{(j)}}^T J^{(j)} + \eta I_6 \right)^{-1} {J^{(j)}}^T r^{(j)}
|
||||
\tag{H1}
|
||||
]
|
||||
|
||||
#### Step 2: Form second-order Jacobian ( \bar{J} ) and update ( \rho )
|
||||
|
||||
1. Build Hessian-based matrix:
|
||||
|
||||
[
|
||||
\bar{H}^{(j)} =
|
||||
\bar{H}_{\rho\rho}(\rho^{(j)}, \delta\rho^{(j)})
|
||||
\in \mathbb{R}^{m \times 6}
|
||||
]
|
||||
|
||||
2. Define effective Jacobian:
|
||||
|
||||
[
|
||||
\bar{J}^{(j)} = J^{(j)} + \frac{1}{2}\bar{H}^{(j)}
|
||||
]
|
||||
|
||||
3. Second (Halley) step:
|
||||
|
||||
[
|
||||
\Delta\rho^{(j)} =
|
||||
\left( {\bar{J}^{(j)}}^T \bar{J}^{(j)} + \eta I_6 \right)^{-1}
|
||||
{\bar{J}^{(j)}}^T r^{(j)}
|
||||
]
|
||||
|
||||
4. Update pose:
|
||||
|
||||
[
|
||||
\rho^{(j+1)} = \rho^{(j)} + \Delta\rho^{(j)}
|
||||
\tag{H2}
|
||||
]
|
||||
|
||||
#### Step 3: Check stopping criterion
|
||||
|
||||
If:
|
||||
|
||||
[
|
||||
|\rho^{(j+1)} - \rho^{(j)}|_2 < \varepsilon
|
||||
]
|
||||
|
||||
or ( j+1 \geq j_{\max} ), then stop and return ( \rho^{(j+1)} ).
|
||||
|
||||
Otherwise, set ( j \leftarrow j+1 ) and repeat from Step 1.
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Covariance-Aware Variant
|
||||
|
||||
If you know the measurement covariance:
|
||||
|
||||
* ( V = E[v v^T] = \operatorname{diag}{\sigma_1^2,\dots,\sigma_m^2} )
|
||||
|
||||
replace (H1) and (H2) with:
|
||||
|
||||
1. First step:
|
||||
|
||||
[
|
||||
\delta\rho^{(j)} =
|
||||
\left( {J^{(j)}}^T V^{-1} J^{(j)} + \eta I_6 \right)^{-1}
|
||||
{J^{(j)}}^T V^{-1} r^{(j)}
|
||||
]
|
||||
|
||||
2. Halley step:
|
||||
|
||||
[
|
||||
\Delta\rho^{(j)} =
|
||||
\left( {\bar{J}^{(j)}}^T V^{-1} \bar{J}^{(j)} + \eta I_6 \right)^{-1}
|
||||
{\bar{J}^{(j)}}^T V^{-1} r^{(j)}
|
||||
]
|
||||
|
||||
The covariance of the pose estimate at iteration ( j ) can be approximated by:
|
||||
|
||||
[
|
||||
P^{(j)} = \left( {\bar{J}^{(j)}}^T V^{-1} \bar{J}^{(j)} \right)^{-1}
|
||||
]
|
||||
|
||||
If ( \sigma_i = \sigma ) for all ( i ) so ( V = \sigma^2 I ), then:
|
||||
|
||||
[
|
||||
P^{(j)} = \sigma^2 \left( {\bar{J}^{(j)}}^T \bar{J}^{(j)} \right)^{-1}
|
||||
]
|
||||
|
||||
---
|
||||
|
||||
### 4.3 Pseudocode (Halley Method)
|
||||
|
||||
```pseudo
|
||||
function forward_kinematics_halley(y, rho0, eta, eps, max_iter):
|
||||
rho = rho0
|
||||
|
||||
for j in 0 .. max_iter-1:
|
||||
# Residual and Jacobian
|
||||
r = f(y, rho) # size m
|
||||
J = J_rho(rho) # size m x 6
|
||||
|
||||
# First (LM-like) step
|
||||
A1 = J^T * J + eta * I6 # 6x6
|
||||
b1 = J^T * r # 6x1
|
||||
delta_rho = solve(A1, b1) # 6x1
|
||||
|
||||
# Build Hessian-based matrix
|
||||
Hbar = compute_Hbar(rho, delta_rho) # m x 6
|
||||
|
||||
# Effective Jacobian
|
||||
Jbar = J + 0.5 * Hbar # m x 6
|
||||
|
||||
# Halley step
|
||||
A2 = Jbar^T * Jbar + eta * I6
|
||||
b2 = Jbar^T * r
|
||||
Delta_rho = solve(A2, b2)
|
||||
|
||||
# Update pose
|
||||
rho_new = rho + Delta_rho
|
||||
|
||||
# Convergence check
|
||||
if norm(rho_new - rho, 2) < eps:
|
||||
return rho_new
|
||||
|
||||
rho = rho_new
|
||||
|
||||
return rho # last iterate if not converged
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Hybrid Halley + Levenberg–Marquardt Method
|
||||
|
||||
Halley’s method is more expensive per iteration (needs Hessian terms and two solves per iteration), but converges more robustly from larger initial errors.
|
||||
|
||||
A **hybrid** method:
|
||||
|
||||
1. Run a fixed number ( N_H ) of Halley iterations as above.
|
||||
2. Then switch to standard Levenberg–Marquardt (LM) iterations (no Hessian term).
|
||||
|
||||
### 5.1 LM Update (for this problem)
|
||||
|
||||
LM iteration (same f/J as above):
|
||||
|
||||
[
|
||||
\Delta\rho^{(j)} =
|
||||
\left( {J^{(j)}}^T J^{(j)} + \eta I_6 \right)^{-1}
|
||||
{J^{(j)}}^T r^{(j)}
|
||||
]
|
||||
|
||||
[
|
||||
\rho^{(j+1)} = \rho^{(j)} + \Delta\rho^{(j)}
|
||||
]
|
||||
|
||||
### 5.2 Hybrid Algorithm Outline
|
||||
|
||||
Parameters:
|
||||
|
||||
* ( N_H ): number of initial Halley iterations (e.g. 3)
|
||||
* ( \eta, \varepsilon, j_{\max} ): as before
|
||||
|
||||
Algorithm:
|
||||
|
||||
```pseudo
|
||||
function forward_kinematics_hybrid(y, rho0, eta, eps, max_iter, N_H):
|
||||
rho = rho0
|
||||
|
||||
# Phase 1: Halley iterations
|
||||
for j in 0 .. N_H-1:
|
||||
r = f(y, rho)
|
||||
J = J_rho(rho)
|
||||
A1 = J^T * J + eta * I6
|
||||
b1 = J^T * r
|
||||
delta_rho = solve(A1, b1)
|
||||
|
||||
Hbar = compute_Hbar(rho, delta_rho)
|
||||
Jbar = J + 0.5 * Hbar
|
||||
|
||||
A2 = Jbar^T * Jbar + eta * I6
|
||||
b2 = Jbar^T * r
|
||||
Delta_rho = solve(A2, b2)
|
||||
|
||||
rho_new = rho + Delta_rho
|
||||
if norm(rho_new - rho, 2) < eps:
|
||||
return rho_new
|
||||
|
||||
rho = rho_new
|
||||
|
||||
# Phase 2: Levenberg–Marquardt iterations
|
||||
for j in N_H .. max_iter-1:
|
||||
r = f(y, rho)
|
||||
J = J_rho(rho)
|
||||
|
||||
A = J^T * J + eta * I6
|
||||
b = J^T * r
|
||||
Delta_rho = solve(A, b)
|
||||
|
||||
rho_new = rho + Delta_rho
|
||||
if norm(rho_new - rho, 2) < eps:
|
||||
return rho_new
|
||||
|
||||
rho = rho_new
|
||||
|
||||
return rho
|
||||
```
|
||||
|
||||
The paper finds that:
|
||||
|
||||
* For small initial errors, Halley and LM behave similarly.
|
||||
* For large initial orientation errors (e.g. >~ 20°), Halley and Hybrid converge more often and with fewer iterations than LM.
|
||||
* Hybrid typically has better worst-case runtime than pure LM when initial errors are large.
|
||||
|
||||
---
|
||||
|
||||
## 6. Example CDPR Geometry (CoGiRo-Like System)
|
||||
|
||||
The paper evaluates the algorithms on a suspended 6-DOF CDPR with 8 cables (CoGiRo-like). The anchor positions ( a_i ) and attachment points ( b_i ) are given by:
|
||||
|
||||
| Cable | Pulley position (a_i^T) [m] | End-effector attachment (b_i^T) [m] |
|
||||
| ----- | --------------------------- | ----------------------------------- |
|
||||
| 1 | ([-7.20,\ -5.44,\ 5.39]) | ([0.503,\ -0.493,\ 0.000]) |
|
||||
| 2 | ([-7.48,\ -5.15,\ 5.40]) | ([-0.510,\ 0.351,\ 0.998]) |
|
||||
| 3 | ([-7.41,\ 5.19,\ 5.40]) | ([-0.503,\ -0.270,\ 0.000]) |
|
||||
| 4 | ([-7.12,\ 5.47,\ 5.41]) | ([0.496,\ 0.356,\ 1.000]) |
|
||||
| 5 | ([7.22,\ 5.37,\ 5.41]) | ([-0.503,\ 0.493,\ 0.000]) |
|
||||
| 6 | ([7.51,\ 5.08,\ 5.42]) | ([0.500,\ -0.340,\ 0.999]) |
|
||||
| 7 | ([7.43,\ -5.26,\ 5.39]) | ([0.502,\ 0.275,\ -0.001]) |
|
||||
| 8 | ([7.14,\ -5.54,\ 5.40]) | ([-0.505,\ -0.346,\ 0.998]) |
|
||||
|
||||
These values can be used to build a test harness for the forward kinematics implementation.
|
||||
|
||||
---
|
||||
|
||||
## 7. Extensions: Elastic Cables and Noise
|
||||
|
||||
To model elastic cables with tension ( T_i ), Young’s modulus ( E ), and cross-sectional area ( A_0 ), the “effective measured length” can be approximated as:
|
||||
|
||||
[
|
||||
y_i = \frac{| i(\rho) |}{1 + \dfrac{T_i}{E A_0}} + v_i
|
||||
]
|
||||
|
||||
Implementation notes:
|
||||
|
||||
* You can:
|
||||
|
||||
* Solve a static equilibrium + tension distribution (e.g. via QP) for ( T_i ), then plug into the above equation when simulating measurements.
|
||||
* For the forward kinematics solver itself, the measurement model simply changes from ( y_i = | i(\rho) | + v_i ) to the elastic form. The derivatives must be updated accordingly if you want exact consistency.
|
||||
|
||||
The paper shows that the proposed methods retain their robustness and relative benefits under elastic/noisy cable measurements.
|
||||
|
||||
---
|
||||
|
||||
This markdown should be directly suitable as a spec for an LLM to implement:
|
||||
|
||||
* A CDPR forward kinematics function mapping cable lengths ( y ) to pose ( \rho ).
|
||||
* Both pure Halley and hybrid Halley+LM solvers.
|
||||
* Optional covariance output, and optional extension to elastic cable models.
|
||||
30
ai_docs/dataset_usage.md
Normal file
30
ai_docs/dataset_usage.md
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
## Synthetic Dataset Usage
|
||||
|
||||
Paths:
|
||||
- `datasets/<scenario>_<geometry>.jsonl`
|
||||
|
||||
Each `.jsonl` file has one JSON object per line:
|
||||
- `dataset`: scenario name (`clean_baseline`, `larger_baseline`, `near_singularities`, `at_singularities`, `outside_singularities`, `systematic_bias`)
|
||||
- `geometry`: `HP5`, `Slideprinter`, `Spidercam`, or `CubeCorners`
|
||||
- `anchor_set`: 0-based set index (only `larger_baseline` has three sets; others use set 0)
|
||||
- `anchors`: list of anchor `[x, y, z]` in mm; length depends on geometry (HP5=5, Slideprinter=3, Spidercam=4, CubeCorners=8)
|
||||
- `real_xyz`: list of mover poses (mm) to feed forward transforms
|
||||
- `config`: overrides for generation; only `systematic_bias` sets `{"min_force": 50.0}`; others are `{}`. See `generate_synthetic_data.py` for available keys (spool radii, buildup factor, gear teeth, mechanical_advantage, lines_per_spool, spring_k_per_unit_length, mover_weight, min/max force, guy_wire_lengths, use_flex, ignore_gravity, ignore_pretension, lambda_reg, tol, max_iters_target, g).
|
||||
- `config_used`: fully resolved values passed to `pos_to_motor_pos_samples` (arrays are lists). Includes `spool_buildup_factor`, `spool_r_in_origin`, `spool_gear_teeth`, `motor_gear_teeth`, `spool_to_motor_gearing_factor`, `mechanical_advantage`, `lines_per_spool`, `min_force`, `max_force`, `spring_k_per_unit_length`, `mover_weight`, `use_flex`, `ignore_gravity`, `ignore_pretension`, `lambda_reg`, `tol`, `max_iters_target`, `g`, and optional `guy_wire_lengths`.
|
||||
- `motor_samples`: generated motor positions in degrees (360° per rotation), matching `real_xyz` order; five columns for HP5, etc.
|
||||
|
||||
Scenarios mapped to the suggested comparison suite:
|
||||
- Clean baseline → suite #1 (no noise, flex enabled); HP5 positions mirror `simulation_data_for_hangprinter_forward_transform.py`; Slideprinter is Z=0 projection of those points.
|
||||
- Larger baseline → suite #2 (3 anchor sets per geometry, 10 random poses each; ≥1000×1000 mm reach).
|
||||
- Near/At/Outside singularities → suite #6 boundary stress: HP5/Slideprinter points projected radially to the reachable boundary (−0.1 mm inside, exactly on, +0.1 mm outside). Spidercam/CubeCorners use rectangle footprints similarly.
|
||||
- Systematic bias → suite #4 pretension variant (min_force=50).
|
||||
Noise/quantization/bias for other suites (#3, #5, #8, #9, #10) should be injected in the C++ tests themselves.
|
||||
|
||||
Practical hints for the C++ forward-transform tests:
|
||||
- Inputs are degrees, not steps; convert if your harness assumes steps (gear ratio 255/20, mechAdv HP5 default [2,2,2,2,4]). For non-HP5 geometries, check the anchor count and use the corresponding motor column count.
|
||||
- Each line is standalone JSON; your loader can stream line by line. The JSON is compact (no extra spacing), and keys stay in the order written by the generator (`dataset`, `geometry`, `anchor_set`, `anchors`, `real_xyz`, `config`, `motor_samples`).
|
||||
- To add noise or biases, perturb `motor_samples` or derived lengths in your test harness (e.g., Gaussian σ=1–5 mm on lengths, per-line constant offset for bias, 2–5% mislength for infeasible mixes, quantize to encoder resolution).
|
||||
- Flex is enabled in these datasets (generation default `use_flex=true`); if you need non-flex variants, re-run generation with `config.use_flex=false`.
|
||||
- Anchor set 0 is the canonical geometry per type; sets 1 and 2 (only in `larger_baseline`) are larger/smaller variants to test generality.
|
||||
|
||||
Files on disk are compact JSONL (one object per line, no extra whitespace); keep that form for downstream parsers.***
|
||||
1
ai_docs/datasets/at_singularities_CubeCorners.jsonl
Normal file
1
ai_docs/datasets/at_singularities_CubeCorners.jsonl
Normal file
File diff suppressed because one or more lines are too long
1
ai_docs/datasets/at_singularities_HP5.jsonl
Normal file
1
ai_docs/datasets/at_singularities_HP5.jsonl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"at_singularities","geometry":"HP5","anchor_set":0,"anchors":[[0.0,-2000.0,-120.0],[2000.0,0.0,-120.0],[0.0,2000.0,-120.0],[-2000.0,0.0,-120.0],[0.0,0.0,2000.0]],"real_xyz":[[964.173982925749,-948.5591783950058,-27.497151],[-719.5698727769299,-688.2211347702399,507.741532],[-497.59098246182526,-490.10712697213705,953.040004],[-1859.9179585591871,-1.9037488936433073,26.4689901],[-1371.5533098398869,-8.617398650679272,537.019049],[-868.3705268565786,30.52552974719478,1047.17018],[-1000.9316453031034,925.997907149727,-42.5453256],[-726.5145875398869,656.9940266110565,533.480869],[-462.61901198441126,452.10590310992825,1030.39159],[32.431590292563676,-1879.469242065927,-26.6148823],[-14.852991064627272,-1383.6109589353725,517.628213],[-69.1030097619738,-881.9005543889695,991.936222],[-968.1382530857868,-888.6978134236471,31.7537695],[-667.9365658325002,786.1013813373113,458.719776],[539.7356098337328,359.57601280777675,1046.72968],[39.64758253318758,1888.898504070586,-44.2588518],[-51.728036433774484,1347.3241286605653,517.004705],[-74.62140930128558,892.149593528903,975.222737],[899.7710296374892,-962.444458758737,26.0515823],[665.0383748320579,-716.5829563000176,535.481389],[467.42323006399454,-508.7760595586472,965.228753],[1843.7079896425694,-82.72029347063788,-42.0139801],[1308.209812190019,-81.11111516847154,527.319817],[888.8665588797583,-56.07596376175122,998.360926],[894.2185351344076,953.5085452429507,41.4092948],[727.0015723778614,704.2454493202517,482.878157],[512.2978253267424,448.39552939023866,981.665044]],"config":{},"motor_samples":[[-11155.956604053403,-11582.846726276244,21515.856824516566,21713.207081081306,17063.64423792795],[-7411.501395779825,17023.454810207277,16594.186666980142,-8171.462384105899,-7997.516690316112],[-1666.3527959632945,14818.296126335288,14712.030720311628,-1818.7515108717216,-28695.877108931316],[14260.669367948154,36471.891241898265,14315.204392538555,-34850.490617505304,27595.69596604149],[9798.25539065451,28034.277312448987,10066.51521840781,-21294.569025275232,-67.06028136492293],[9645.662334978453,21384.632744814186,8680.575496952402,-7507.512866398955,-27751.934086127563],[21316.601358666714,22261.034266439754,-10369.169126294644,-12420.126115968931,17836.589034264358],[16166.864771735562,17121.56927263868,-6666.5744067953365,-8336.612307864467,-9177.87528811238],[14536.204151766773,14685.900465544773,-395.7227354259123,-603.0772882371044,-32272.651270859493],[-35743.82959342546,14042.82582234425,36828.240778181906,14968.18778390724,29771.640933017723],[-21747.561397693273,10195.215361493692,28196.040349837123,9733.134523977842,688.8507311509222],[-8383.135573808975,9864.153915977162,21244.177524801216,7661.508938665592,-25699.304941620783],[-10145.918288129207,21485.684747395353,20471.349850490922,-12306.621275944706,14303.319712076687],[17969.461105820053,16361.373764094242,-9761.902538172337,-6849.912658203756,-5642.330622701802],[13346.772641545036,-1958.9729182195533,1568.920186997556,15911.247061901366,-32764.36958888164],[37008.280989846266,14057.948666639726,-36043.49084047213,15186.802905578605,30593.82882240686],[27498.743953821366,10388.637835699708,-21221.511749336747,8766.856151020427,-146.50384854668178],[21317.500869597126,9880.359881429362,-8739.073596298025,7498.2296059310365,-24934.197492005984],[-12096.036894963903,-10390.352920068663,21436.077647092232,20636.57923101495,14561.33493844064],[-8099.0396207252115,-6861.650585693851,16982.468223848606,16274.427543230599,-9282.797255025554],[-1967.449278299528,-1129.3563863667262,15032.731423880188,14445.272358672788,-29248.156295238787],[12838.40345942946,-35023.24699878345,15219.303975907176,36129.90963536313,29428.49566891845],[7946.228435128735,-20477.60921868391,10507.322218672203,26792.594857254262,-1316.3881768773238],[7974.929570191814,-8421.297305034428,9758.544152313541,21412.084456801807,-25765.99925024139],[21251.69189817742,-10391.343515676428,-12002.270621804304,20493.349176722782,13838.27243805988],[16822.455622889785,-8338.900805139585,-7782.509179814367,17133.148161756337,-6839.331874511111],[14252.138625663765,-1927.2954459075163,-641.0025589992857,15160.474140227492,-29990.461668234075]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0,4.0],"lines_per_spool":[1.0,1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
1
ai_docs/datasets/at_singularities_Slideprinter.jsonl
Normal file
1
ai_docs/datasets/at_singularities_Slideprinter.jsonl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"at_singularities","geometry":"Slideprinter","anchor_set":0,"anchors":[[-1000.0,-577.0,0.0],[1000.0,-577.0,0.0],[0.0,1154.0,0.0]],"real_xyz":[[586.498344878686,-577.0,0.0],[-603.2825724407588,-577.0,0.0],[-585.8106954171992,-577.0,0.0],[-667.061109827178,-0.6827811108451938,0.0],[-669.0952576356099,-4.203890967240714,0.0],[-653.3976531299176,22.968662432112634,0.0],[-434.46570367362887,401.93986694094826,0.0],[-437.89923351314417,395.9964267887475,0.0],[-426.1015164924649,416.4182749515432,0.0],[9.956548997971224,-577.0,0.0],[-6.194064732534575,-577.0,0.0],[-45.21194190685679,-577.0,0.0],[-628.5778625677834,-576.9999999999999,0.0],[-396.8485635172984,467.0551365515564,0.0],[481.3934169045349,320.7079953382502,0.0],[23.372998634595458,1113.5413393635154,0.0],[-41.54470955852095,1082.0861077542004,0.0],[-84.31556154283355,1008.049762969355,0.0],[539.4263319572759,-576.9999999999999,0.0],[535.4957704540202,-577.0,0.0],[530.1019941482446,-577.0000000000001,0.0],[684.4059737799156,-30.706740613033762,0.0],[691.432662385265,-42.86993858889359,0.0],[691.8826284602262,-43.648829864651525,0.0],[412.54011646201144,439.89305840425806,0.0],[427.4551144904945,414.0751968169539,0.0],[442.7795003626787,387.5486848722031,0.0]],"config":{},"motor_samples":[[8427.750894673116,-14393.133399779988,13155.268347229301],[-14718.187626817511,8755.774102575919,13262.07265793197],[-14379.815036542373,8414.312693953354,13150.950234601487],[-9506.240408152413,11896.348360896349,3498.9356533643936],[-9585.151600270385,11911.54478643034,3578.2505537466577],[-8976.125974637147,11798.870178312269,2966.2381796658387],[-466.86482610230723,11364.10184341621,-5554.298601164027],[-600.5301118737178,11354.305620375255,-5420.884069001958],[-141.22262387433392,11390.173840753492,-5879.27075517713],[-2814.307180165274,-3201.7237926955636,11264.05397218412],[-3128.524137345229,-2887.5096053838797,11263.71057866582],[-3887.518023136325,-2128.2805595264044,11275.043356081902],[-15207.993075054354,9250.213659317129,13428.105871300444],[998.0075747857394,11505.882166473844,-7015.497270600874],[11276.06552801791,-2293.1265298319267,-3730.239598668121],[16054.146411568136,15587.717216612247,-21476.671680136842],[14875.900143465251,15716.248779355097,-20774.974586266562],[13201.28142450879,14962.306628112146,-19122.61685614924],[7508.023111754639,-13481.281461844459,12870.271779120329],[7431.239956697086,-13405.125880123313,12847.455105707044],[7325.876812784602,-13300.616389600764,12816.3929058284],[12031.57990959637,-10179.023976667588,4175.320903370242],[12089.992210261984,-10451.528076955043,4449.386841468569],[12093.803601725796,-10468.977332936774,4466.938130602801],[11439.083778628203,386.8506834309514,-6406.079266164602],[11385.74239577356,-193.92496409923652,-5826.682544144306],[11341.29087564956,-790.5039520210415,-5231.2422964425305]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0],"min_force":[3.0,3.0,3.0],"max_force":[120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
1
ai_docs/datasets/at_singularities_Spidercam.jsonl
Normal file
1
ai_docs/datasets/at_singularities_Spidercam.jsonl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"at_singularities","geometry":"Spidercam","anchor_set":0,"anchors":[[1500.0,1500.0,3500.0],[-1500.0,1500.0,3500.0],[-1500.0,-1500.0,3500.0],[1500.0,-1500.0,3500.0]],"real_xyz":[[1500.0,-1475.7074893007994,200.0],[-1500.0,-1434.6510897842825,507.741532],[-1499.9999999999998,-1477.4397373943698,953.040004],[-1500.0,-1.5353490874818543,200.0],[-1500.0,-9.42442257496202,537.019049],[-1500.0,52.72898285313941,1047.17018],[-1500.0,1387.7040127989687,200.0],[-1500.0,1356.4642153348086,533.480869],[-1500.0,1465.912202258873,1030.39159],[25.88357625122502,-1500.0,200.0],[-16.102421315081216,-1500.0,517.628213],[-117.5353775741511,-1500.0,991.936222],[-1500.0,-1376.9177241851523,200.0],[-1274.5237097081742,1500.0,458.719776],[1500.0,999.3115321366655,1046.72968],[31.484684683491597,1500.0,200.0],[-57.58974622372378,1500.0,517.004705],[-125.46339174933684,1500.0,975.222737],[1402.3214868906655,-1500.0,200.0],[1392.1033893951999,-1500.0,535.481389],[1378.0814405933565,-1500.0,965.228753],[1500.0,-67.29939930998059,200.0],[1500.0,-93.00241568210704,527.319817],[1500.0,-94.63056608703553,998.360926],[1406.728664775464,1500.0,200.0],[1500.0,1453.0479907013555,482.878157],[1500.0,1312.8950794518394,981.665044]],"config":{},"motor_samples":[[6853.644364856605,24844.165522187126,7173.387350729783,-15413.445108927952],[20771.555231613092,1929.776808655608,-21350.45177489669,2836.6886776082047],[16466.490438824592,-3385.5868872016927,-29945.895696749365,-3050.301283542623],[11981.381645541705,-9090.66699221852,-9115.386984158527,11962.224924075123],[7538.409062008028,-14910.652673922834,-15075.816612344777,7414.997654076097],[865.4143248080622,-24137.248689555116,-23074.226575525783,1607.2143256343752],[7199.705630566788,-15378.341115253686,5712.428906487779,23893.533898917147],[2520.807845978924,-21794.29395629172,508.2115769866822,19610.403068529155],[-4013.6866528837663,-31431.436115839424,-4527.15915759832,15555.49722129625],[11811.581583865258,12134.529631166737,-8893.169043353018,-9309.900868948114],[7833.4306301325805,7623.156019021217,-14798.016715956577,-14517.241227312354],[2719.0950611924673,1078.5754923811153,-23831.976209819866,-21500.866368639327],[23778.421066627747,5573.916986156133,-15370.914277876514,7205.263460061379],[479.216641568684,-20256.478888816797,3620.7259473065615,19586.791606166047],[-30777.823941490977,-3591.7061504519834,10134.74127193686,-11465.26331529958],[-9354.269862339883,-8847.36378386928,12170.073524510093,11777.243203406471],[-14137.75059555213,-15141.665685749816,7366.362131730113,8118.285977857707],[-21146.427601877345,-23622.737816555924,1224.701154995141,2971.74939189911],[7192.986156798153,24050.02604715018,5900.618844472504,-15387.317765656566],[2472.7016586236896,19981.525294619525,963.4836441536282,-21861.96903764402],[-3168.004402550927,15179.578846201259,-5000.0959810686545,-30126.186533686425],[-8551.2051560507,12400.108710712606,11560.480914803264,-9634.614796989308],[-13992.981133052906,8226.875426042157,7010.931172594267,-15618.264512819323],[-21844.419665068086,2475.087109324331,1152.9366725966563,-23725.087808208664],[-15389.77847236604,5957.466138772238,24097.31938031206,7191.14370185118],[-20877.017769251055,3175.023002989622,21261.396580447115,2526.992675761831],[-30365.375029309314,-3323.8860764917704,14261.777606519001,-6159.533774057701]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
1
ai_docs/datasets/clean_baseline_CubeCorners.jsonl
Normal file
1
ai_docs/datasets/clean_baseline_CubeCorners.jsonl
Normal file
File diff suppressed because one or more lines are too long
1
ai_docs/datasets/clean_baseline_HP5.jsonl
Normal file
1
ai_docs/datasets/clean_baseline_HP5.jsonl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"clean_baseline","geometry":"HP5","anchor_set":0,"anchors":[[0.0,-2000.0,-120.0],[2000.0,0.0,-120.0],[0.0,2000.0,-120.0],[-2000.0,0.0,-120.0],[0.0,0.0,2000.0]],"real_xyz":[[17.9255679,-17.6352632,-27.497151],[-523.885148,-501.061599,507.741532],[-538.35251,-530.255594,953.040004],[-545.189816,-0.558037791,26.4689901],[-520.999273,-3.27341154,537.019049],[-470.799477,16.5498517,1047.17018],[-505.362595,467.529134,-42.5453256],[-513.234032,464.122399,533.480869],[-538.29312,526.060302,1030.39159],[8.98405788,-520.642383,-26.6148823],[-5.52678502,-514.840431,517.628213],[-38.6000122,-492.617793,991.936222],[-507.629503,-465.97604,31.7537695],[-30.5601452,35.9665477,458.719776],[43.2898928,28.8400594,1046.72968],[10.5874156,504.407891,-44.2588518],[-19.9804722,520.41744,517.004705],[-37.9958866,454.266612,975.222737],[455.930483,-487.688259,26.0515823],[482.712486,-520.125685,535.481389],[495.517745,-539.35609,965.228753],[500.096373,-22.437457,-42.0139801],[490.657689,-30.4215669,527.319817],[506.742907,-31.9689121,998.360926],[490.590662,523.118645,41.4092948],[517.848381,501.639033,482.878157],[525.399857,459.863258,981.665044]],"config":{},"motor_samples":[[-370.3697770252581,-376.07488581298213,316.28639574270477,321.8856247496485,1077.0867866177177],[-5810.315263831471,12594.40098415143,12255.96631013353,-6334.538475545839,-13332.467105622001],[-2061.161716667053,15684.773470226133,15571.570681745867,-2227.604718324707,-27437.761720493003],[1441.9597706197878,10653.246408919947,1462.8972451298366,-10534.688036819107,1840.7014555664812],[3158.1664477076524,11745.086806688145,3276.0815728811303,-7512.510560973411,-17369.741177650027],[7284.585515952449,14240.150317462261,6734.815632175256,-1608.6742133231114,-36273.59503866239],[10077.047707375656,10660.840416330984,-7563.535080290544,-8486.791357405184,6049.581913335447],[11651.954953006585,12385.851972582694,-5051.952415905567,-6164.8370322529045,-14774.889603943611],[16096.413355527071,16265.773253056377,-1127.8932081320281,-1373.4880803241117,-29889.475715954715],[-10142.764168825519,1100.0934825190598,10124.939277784339,1438.9293642551565,3596.661452096344],[-7552.681599700208,3175.1553225337434,11533.976048683862,2975.3766230214496,-16739.947743926252],[-2585.6054423181463,7221.074113655764,14181.433959713768,5926.892408512603,-33983.79984594886],[-7420.554472391005,10764.080179644428,10122.284804172734,-8433.847105120989,3310.4763936950612],[2206.660765377757,2106.9643630716805,858.7747844219751,961.7295262635515,-17772.937365900965],[6576.325099275927,5353.327852138266,5601.410268559995,6816.798902753826,-40377.71330430531],[9796.189483771965,976.85825049266,-9847.192445348534,1377.0598612234662,4110.438108752241],[11638.15569148509,3458.500370950992,-7655.26348968365,2736.4698337528466,-16642.68936443671],[13362.10757184317,6908.729509765615,-2162.9682279212084,5627.121711145271,-34014.24162981192],[-8131.750385409179,-7363.527568880854,10339.067123686724,9846.333431744746,3249.9624886402435],[-6169.996732642389,-5318.897917770716,12589.161881755874,12033.185445848247,-14558.58608014488],[-2290.800484087149,-1396.8286668756991,15669.999170472352,15054.177964396553,-28340.020276852498],[733.7983175925032,-9758.935458789812,1582.3277490349594,9714.806200627308,3988.8663545631016],[2470.878254293256,-7041.484321953494,3572.142050904487,11126.259102943077,-17384.629895749847],[6157.738850819929,-2736.8715516160387,7227.050677409309,14483.681997559606,-33974.366529091734],[11162.489153239549,-7758.528801517794,-8555.582996867628,10665.916353692315,3323.0280696996024],[12129.377483878727,-6400.794508161293,-6026.899003689132,12370.535936798027,-12522.201985167394],[14501.964817875092,-2071.6843590311714,-749.1509051077785,15429.175007984586,-29613.47413052238]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0,4.0],"lines_per_spool":[1.0,1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
1
ai_docs/datasets/clean_baseline_Slideprinter.jsonl
Normal file
1
ai_docs/datasets/clean_baseline_Slideprinter.jsonl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"clean_baseline","geometry":"Slideprinter","anchor_set":0,"anchors":[[-1000.0,-577.0,0.0],[1000.0,-577.0,0.0],[0.0,1154.0,0.0]],"real_xyz":[[17.9255679,-17.6352632,0.0],[-523.885148,-501.061599,0.0],[-538.35251,-530.255594,0.0],[-545.189816,-0.558037791,0.0],[-520.999273,-3.27341154,0.0],[-470.799477,16.5498517,0.0],[-505.362595,467.529134,0.0],[-513.234032,464.122399,0.0],[-538.29312,526.060302,0.0],[8.98405788,-520.642383,0.0],[-5.52678502,-514.840431,0.0],[-38.6000122,-492.617793,0.0],[-507.629503,-465.97604,0.0],[-30.5601452,35.9665477,0.0],[43.2898928,28.8400594,0.0],[10.5874156,504.407891,0.0],[-19.9804722,520.41744,0.0],[-37.9958866,454.266612,0.0],[455.930483,-487.688259,0.0],[482.712486,-520.125685,0.0],[495.517745,-539.35609,0.0],[500.096373,-22.437457,0.0],[490.657689,-30.4215669,0.0],[506.742907,-31.9689121,0.0],[490.590662,523.118645,0.0],[517.848381,501.639033,0.0],[525.399857,459.863258,0.0]],"config":{},"motor_samples":[[135.64769618576926,-473.8121545649105,346.1876333492736],[-13068.024931456896,7227.381338479618,11361.251709153992],[-13421.891257722522,7477.199775017008,11991.433815902383],[-8179.665150637004,9653.594697722068,2381.64788832023],[-7923.266010060338,9192.155342864087,2234.7332232167573],[-6993.6822911268655,8418.976449664717,1494.3873826714168],[23.423612288734404,13234.941157329093,-5867.155911197269],[-101.89196050412775,13323.821956792635,-5722.941824546199],[803.8757100279379,14422.70190417729,-6359.619330595452],[-2822.3049507076607,-3170.984289909286,10161.617264299866],[-3095.6194571296123,-2881.175189203615,10047.86670558865],[-3699.807121683404,-2204.1411937453518,9622.011271473017],[-12628.49355094599,6958.252453691888,10611.082860428067],[-147.31054973030982,867.8790795083348,-692.5485032465788],[1011.3618245009827,-431.0898281018808,-545.7079506161488],[6349.559298222874,6068.679598325823,-9805.078535431081],[6177.385134233543,6703.320148228441,-10111.317496332702],[4986.227304546615,6019.309336249273,-8813.852112020591],[5918.382202595339,-11726.648528814487,10731.856088593124],[6401.045509200351,-12329.029673820074,11485.133079837102],[6629.824009182821,-12613.285364639929,11916.383647382816],[8678.353743674454,-7937.045950416275,2415.880443366058],[8451.338945828758,-7927.065596757625,2488.964796252671],[8736.373511529391,-8160.812587045125,2637.6254736536343],[13633.290462269084,1126.2649256200425,-6901.688585384636],[13818.88163157195,525.373311438095,-6246.388687687652],[13473.377771281153,-276.66492128261814,-5514.8189011219865]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0],"min_force":[3.0,3.0,3.0],"max_force":[120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
1
ai_docs/datasets/clean_baseline_Spidercam.jsonl
Normal file
1
ai_docs/datasets/clean_baseline_Spidercam.jsonl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"clean_baseline","geometry":"Spidercam","anchor_set":0,"anchors":[[1500.0,1500.0,3500.0],[-1500.0,1500.0,3500.0],[-1500.0,-1500.0,3500.0],[1500.0,-1500.0,3500.0]],"real_xyz":[[17.9255679,-17.6352632,200.0],[-523.885148,-501.061599,507.741532],[-538.35251,-530.255594,953.040004],[-545.189816,-0.558037791,200.0],[-520.999273,-3.27341154,537.019049],[-470.799477,16.5498517,1047.17018],[-505.362595,467.529134,200.0],[-513.234032,464.122399,533.480869],[-538.29312,526.060302,1030.39159],[8.98405788,-520.642383,200.0],[-5.52678502,-514.840431,517.628213],[-38.6000122,-492.617793,991.936222],[-507.629503,-465.97604,200.0],[-30.5601452,35.9665477,458.719776],[43.2898928,28.8400594,1046.72968],[10.5874156,504.407891,200.0],[-19.9804722,520.41744,517.004705],[-37.9958866,454.266612,975.222737],[455.930483,-487.688259,200.0],[482.712486,-520.125685,535.481389],[495.517745,-539.35609,965.228753],[500.096373,-22.437457,200.0],[490.657689,-30.4215669,527.319817],[506.742907,-31.9689121,998.360926],[490.590662,523.118645,200.0],[517.848381,501.639033,482.878157],[525.399857,459.863258,981.665044]],"config":{},"motor_samples":[[-3303.085958205653,-3036.4643784964974,-3298.7608435721263,-3566.2716875693363],[731.0672509905346,-7058.108522760161,-15361.93021744878,-6701.830674809072],[-4859.804404575993,-13529.516337724108,-23327.573084149608,-13390.907297348549],[1362.9436759175117,-6695.393004884067,-6704.081885052752,1355.0921373051615],[-3959.668392147365,-12225.748593640801,-12280.797856659447,-4008.860774022242],[-11927.051821454867,-20315.939703623375,-20001.457641347068,-11650.608271185418],[-1856.6395941360643,-9629.342489008113,-2412.1708563526086,4713.63639607678],[-7016.965109969672,-15529.179609586929,-7788.964941894259,-81.66382209886126],[-14482.051114161617,-24609.717807349283,-14695.006775157244,-5892.040492438482],[1061.4663153292738,1188.2244822838234,-6506.548906391123,-6646.205471952114],[-3717.0196849963922,-3799.836426042931,-11943.766384519186,-11851.29778079008],[-10472.490107116531,-11108.140630574873,-19796.30182065016,-19071.495123406195],[4720.362958269433,-2438.2328743075896,-9632.848613838392,-1826.6250104450412],[-7517.850922996836,-8000.492162899195,-7432.792956557325,-6953.813370809616],[-17133.33105555425,-16354.564418433309,-15840.913222504938,-16613.462542760895],[-6575.439487774987,-6411.040157600305,1045.9566306303795,896.3016573039112],[-11749.711011932885,-12084.097309677069,-3841.7638323085794,-3542.617000820956],[-18572.820504357525,-19280.43286772328,-11289.15424172432,-10661.803442954715],[-1970.3718569051603,4451.911639562891,-2437.0852718424453,-9468.348220737711],[-7074.6794574943715,130.8056359830752,-7662.525895892944,-15716.765890725723],[-13360.418987419966,-5361.560045024867,-14113.938573331143,-23311.305729732965],[-6295.9607936765215,1089.9085257182512,772.5997508614673,-6644.258540322624],[-11667.074917403226,-3914.2551107622235,-4372.360640857116,-12176.235469054436],[-19323.335867207534,-10461.624869425,-10987.586210651674,-19925.498457508158],[-9851.854036427321,-2273.72824231628,5079.405359560811,-1796.6785657743044],[-14894.34540227585,-6381.615545843627,1030.8811685691699,-6633.394330261381],[-23254.612325231134,-13550.951428705052,-6080.556980126463,-14683.802938839244]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
3
ai_docs/datasets/larger_baseline_CubeCorners.jsonl
Normal file
3
ai_docs/datasets/larger_baseline_CubeCorners.jsonl
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{"dataset":"larger_baseline","geometry":"CubeCorners","anchor_set":0,"anchors":[[1500.0,1500.0,3500.0],[-1500.0,1500.0,3500.0],[-1500.0,-1500.0,3500.0],[1500.0,-1500.0,3500.0],[1500.0,1500.0,0.0],[-1500.0,1500.0,0.0],[-1500.0,-1500.0,0.0],[1500.0,-1500.0,0.0]],"real_xyz":[[802.9851537615568,-904.7991579176248,537.3819696124713],[-581.2656135858514,-195.76078199768085,1510.2713313774227],[-186.43942831918275,-1210.1972306474247,1811.9844030572065],[629.0941137686191,1244.7600874499726,1696.2318599395915],[1122.8580268059409,1175.1118829028592,773.467439769466],[-1127.412211300106,-858.8790672305458,2209.9702390734237],[-621.4803345791836,-1008.180417893958,2747.146397969696],[477.33241977062585,1191.267295195547,1089.6763918397842],[-800.1284540323497,-944.3492019937278,2747.1197801459675],[-873.1705022044939,786.1155910862576,771.5443424509402]],"config":{},"motor_samples":[[-4151.5557599979875,7114.933436734986,-5705.837248993081,-19269.53486976736,17177.738078269496,49226.070952439244,12389.95422325074,-40927.15558374731],[-14582.257238478112,-25625.702502296786,-29883.841095022988,-18083.257043148715,37634.88757865581,12820.93383220998,2942.935978841124,29859.482463985143],[-9355.675306153265,-12427.235634059098,-37392.869142468706,-32681.00831174093,61080.61455125075,54874.701348004324,5279.391511164442,14491.196589228372],[-40064.937962167016,-25005.873664492618,-3464.6202671289466,-13486.249674997924,-7684.690540391288,23984.517129098982,68885.50773833199,48006.61021104204],[-25608.79185018148,-5737.791245843269,10567.335998368364,-4939.2406830314885,-46383.24478098875,24757.093343661367,67271.79426048073,26974.728905688466],[-6475.696503921222,-26697.846634525224,-50230.3285038247,-21253.043323317637,80917.23544621126,44504.02334319876,8183.487452837871,53990.825179686486],[-14038.688540217732,-25787.675917912245,-54666.07652412379,-34624.98240315416,85621.76397006551,67144.76487686577,31535.141087605698,54508.84157448384],[-28205.04448714724,-18620.99343869906,514.8329035451065,-6564.334469197388,-23087.766747903337,6138.850818097627,54796.86315414431,37557.671130835966],[-12690.744761380367,-27921.85292112386,-56353.402295084226,-31175.554167394017,87837.73961506934,63982.953657259575,30075.345711181453,59295.07302512077],[-7904.835939700404,-23336.40194920721,-9294.236067201007,3626.4435857819994,18540.981483903182,-34724.32833579165,14516.104256957686,49684.44034032243]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0,75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0,4.0,4.0,4.0,4.0],"lines_per_spool":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0,120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
{"dataset":"larger_baseline","geometry":"CubeCorners","anchor_set":1,"anchors":[[1800.0,1800.0,4000.0],[-1800.0,1800.0,4000.0],[-1800.0,-1800.0,4000.0],[1800.0,-1800.0,4000.0],[1800.0,1800.0,0.0],[-1800.0,1800.0,0.0],[-1800.0,-1800.0,0.0],[1800.0,-1800.0,0.0]],"real_xyz":[[1161.3418856001845,-1418.6413526679598,1420.535712047434],[-313.82081587383254,1523.974772699636,3072.7274607172108],[-369.7541352651897,-241.01493350882106,2488.465323778944],[448.3660064683545,1261.2880256622884,2399.020074936873],[48.997988245731676,1282.189600045791,1259.1753529079049],[-424.1712432486129,-475.41605742360116,1766.4380808365547],[-1488.8658348133965,-150.69838266637407,1213.1762206266708],[-821.8078698853514,-808.2337882335771,2752.141251500835],[-366.1085914744699,1538.3803421478847,1520.8059247929118],[632.6635679563319,-622.8074250286376,2844.786880640213]],"config":{},"motor_samples":[[-11015.59824412741,6573.200749968288,-15438.372997516724,-39749.83322770926,40448.541470089214,81271.85920073159,29815.88410385555,-36438.29490688671],[-46684.50308708688,-57202.49752935536,-19081.54600588899,-13478.04449920874,46953.49098689829,34467.955673680124,87951.14783614807,97309.55467929685],[-27152.037056608406,-35348.958535497084,-41391.535587805534,-32368.69532774474,52583.490099755894,38320.941428768194,28230.7628233927,43436.94370595354],[-49716.86322833043,-37290.562196477615,-12023.932246781722,-20002.758201730536,10156.379540908461,30812.177158472772,77003.44032690657,61987.87750100187],[-28049.127766322825,-27024.830007956145,-4293.077497847142,-5055.5459562363185,-12728.17671686475,-9697.158862118895,49679.14380926028,47828.36190346247],[-16571.140001741678,-24599.49523268422,-34891.29440304153,-25633.639441028423,42969.66823549759,25318.45062018422,2178.6046943478527,23024.727166464138],[-175.65945210630176,-25683.903863857402,-28820.49669611806,-2436.5835067395683,57767.376653168445,-8844.375122329075,-18423.267269195698,52289.100841779364],[-16276.773007725391,-32700.68513367178,-55347.760258944516,-32393.058781950705,81726.012317386,53950.94214211119,21084.63987820079,54446.84654154006],[-27863.883279575894,-36072.93422014619,-6655.975386451214,-1012.9320347676176,4444.285330148744,-17047.652774671213,54861.38190271404,67694.15037482804],[-35116.72972207807,-21710.284594594137,-34883.98007623071,-52481.08372695899,53907.52802867668,75651.83402278663,54267.84491547277,29268.620071177284]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0,75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0,4.0,4.0,4.0,4.0],"lines_per_spool":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0,120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
{"dataset":"larger_baseline","geometry":"CubeCorners","anchor_set":2,"anchors":[[1200.0,1200.0,3200.0],[-1200.0,1200.0,3200.0],[-1200.0,-1200.0,3200.0],[1200.0,-1200.0,3200.0],[1200.0,1200.0,0.0],[-1200.0,1200.0,0.0],[-1200.0,-1200.0,0.0],[1200.0,-1200.0,0.0]],"real_xyz":[[-573.8601389570656,-449.6258723988558,902.0440388016362],[-741.2877469533365,501.1910434630256,1235.6378001315516],[-748.109583013746,72.42734524870684,1371.9733318536553],[10.501250050808608,424.99922336738086,359.67593474892556],[-16.11595350015091,-896.7910629675362,2542.6206374937155],[319.7984835529264,-661.6294559727589,2406.95223078884],[-650.0220673746192,-290.822307105532,313.9711703512429],[-257.4710811093644,462.8179227764947,492.48841357960293],[553.969138761458,-145.83561173740293,2125.586990409093],[-652.1452147966063,804.6934824290217,1945.4295403063882]],"config":{},"motor_samples":[[-5501.619520135888,-14076.645829018884,-21818.648298654996,-12115.627356414401,34822.797949128384,11111.278288023961,-14260.403353872327,16796.5727109055],[-15011.278525852777,-28802.271086188677,-19075.399916193543,-7352.453667490039,27726.631871596423,-7982.21228930806,17786.02626534925,45781.1273407507],[-14024.597925161259,-27646.74066479705,-26146.41612643369,-12874.488725121819,36845.91800243882,5280.440673124761,8894.75403344717,39421.87777185561],[-8687.556338800585,-8533.605697895497,-2588.6794530696957,-2729.44191157995,-9041.393709597227,-8377.185983500707,14099.089822948587,13617.981545985554],[-21539.200664802553,-21837.342807705812,-43181.58276790254,-42653.112431679976,71746.34361381558,71304.34980369266,44169.090450279764,44711.352533889214],[-27427.600774887596,-21174.136936248076,-35325.515889205606,-44828.81967878399,57945.202187118986,67277.61680062601,47183.96240905803,36162.675428021306],[2270.7172294763086,-6379.747051150698,-10639.082297720823,-1462.2619997707636,27398.37851267774,-3009.5339089542554,-22847.971271162205,15162.602283712782],[-8950.113812246993,-12871.234689641564,-5988.071817019615,-2453.1662801781276,345.78233982735395,-15655.246872901653,10803.360697374628,22234.358296868617],[-34506.76336023499,-22574.459763561325,-25408.803577684317,-38374.892429160136,35319.90121955624,53932.94109275502,49307.5624389311,29857.111304835336],[-26160.581389156847,-42436.789104826225,-23154.32112954529,-12005.59861968928,39969.04921543147,14154.324585510718,45184.88076941471,65293.90424712695]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0,75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0,4.0,4.0,4.0,4.0],"lines_per_spool":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0,120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
3
ai_docs/datasets/larger_baseline_HP5.jsonl
Normal file
3
ai_docs/datasets/larger_baseline_HP5.jsonl
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{"dataset":"larger_baseline","geometry":"HP5","anchor_set":0,"anchors":[[0.0,-2000.0,-120.0],[2000.0,0.0,-120.0],[0.0,2000.0,-120.0],[-2000.0,0.0,-120.0],[0.0,0.0,2000.0]],"real_xyz":[[-576.5595949917629,592.7458989886723,332.3847597668903],[-179.36706696996282,-215.41772144174416,1126.970767229225],[-597.5654793465059,123.07208962332584,989.006493849326],[-191.43249959513935,169.46574460400814,1596.9910715277888],[-677.8161815912724,-18.710569564673847,1111.0102919876592],[186.62356390895195,-99.24100885948312,1499.0694572097063],[-407.09652577420286,-267.95696906462183,1229.0528490942177],[-539.1293146899854,-79.82639646010671,213.0152139028341],[952.3546904036702,-340.81289963895085,401.56522007466464],[-1418.2636804247322,62.76369114770591,159.16026483364448]],"config":{},"motor_samples":[[13489.525209159368,13253.73802495862,-8154.724395286298,-7760.978270685556,-5474.300475485185],[3493.844780152621,10080.505083525633,10636.900710043461,4137.382298700983,-41852.199653730335],[9075.019488078764,16090.33866282256,4975.428104551938,-4218.0560782654675,-31823.984996423053],[15036.698939792874,15346.223153258694,9885.042137071416,9524.244931179543,-58684.15786475081],[8294.621139345822,18447.422871729894,8898.916846031168,-4012.3323956732393,-34312.05848239094],[9719.309385904144,8301.914740932007,12771.139205089394,14043.208659534463,-56110.527403476415],[4356.650440365773,15017.520913328384,13014.659296044234,1808.4647973636127,-42171.71490498033],[355.3416077739786,10902.000295672082,3325.529885703822,-9794.89972321722,-5140.386401245307],[-479.12474790557536,-15318.067537188352,11259.45697188521,19823.214254756662,-4409.557912371242],[10054.94891214154,27940.404098845298,8048.850598272263,-26290.689913562,12520.742467699358]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0,4.0],"lines_per_spool":[1.0,1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
{"dataset":"larger_baseline","geometry":"HP5","anchor_set":1,"anchors":[[0.0,-2500.0,-150.0],[2500.0,0.0,-150.0],[0.0,2500.0,-150.0],[-2500.0,0.0,-150.0],[0.0,0.0,2300.0]],"real_xyz":[[125.4798355094448,424.99875596519007,1694.9579991854027],[646.0190309384813,214.54666339748184,1422.040858293242],[1119.200659416533,-1.5976476440060594,1046.9906190729414],[-179.6072223508204,555.4271254745756,474.9236832289738],[1403.961521921532,-163.2296722106178,594.8709539808148],[-829.9185736161514,-257.5531569536049,613.6395089816716],[627.1316866722686,-788.2471600705229,-89.45309919402325],[538.1323543865246,-1142.5325148800948,42.984147924686056],[-212.41955197057996,-1108.3683095053045,539.2156131611382],[-101.74297492132928,-88.86474068228017,357.65061247941355]],"config":{},"motor_samples":[[18689.732437183568,10317.23098313974,5115.215109563169,14306.014524389111,-59774.369279586],[13636.249062616953,-1472.9708706021254,6618.028468735126,19924.94042862473,-46079.230300922485],[9432.588375826295,-13339.692797807393,9484.833476072321,25595.799332203725,-24338.531764499825],[12092.20009632076,5899.153619889101,-8851.445020695628,-751.841183882101,-14925.98190598802],[6199.119245341868,-22813.482185509423,11653.08971256105,28858.68160617266,-3727.8025329835586],[80.95913173639481,18013.422198106233,9264.188613465132,-12680.107386430429,-15715.11714020894],[-13246.132976358174,-9195.63108460233,16484.02585442484,14082.681675844042,11421.884566836492],[-20054.858887770348,-4445.612362673389,23139.844630237243,14593.522442670543,11120.194811221707],[-18247.788663634765,9867.131810501012,22994.671941491626,2485.2399178462556,-8234.414440177736],[-750.9944383747488,2880.4190408438603,2643.1839141647106,-1006.2942443673077,-13709.570939396217]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0,4.0],"lines_per_spool":[1.0,1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
{"dataset":"larger_baseline","geometry":"HP5","anchor_set":2,"anchors":[[0.0,-1800.0,-100.0],[1800.0,0.0,-100.0],[0.0,1800.0,-100.0],[-1800.0,0.0,-100.0],[0.0,0.0,2100.0]],"real_xyz":[[-555.78938929645,-360.99219607099644,422.1798545660755],[-47.04943078063252,-759.0039648611917,432.07154310890047],[-511.9870026771316,336.383662208861,866.9166038451252],[1076.6462526440346,-263.6609141582357,283.2415916758149],[138.4692227261213,-281.8812223074427,1338.4829640839016],[-305.3606989372959,-251.60742634737437,1355.7639790793912],[60.89259195949546,205.20305991804696,1093.4049362884682],[-753.0646916701655,274.3095518069641,272.59210107906824],[1227.7514052697493,-58.317904624863445,99.61254556417884],[-307.6533719660548,-330.93381834819246,1094.029261485149]],"config":{},"motor_samples":[[-3417.177857602206,12438.51789107839,9539.13050416859,-7925.378106626549,-11563.15974493683],[-12317.943102003217,5143.60032657479,15853.104291589858,3507.2841330540136,-10423.849846237199],[11664.061808018281,14175.032358993545,394.82719730511985,-3169.0554298839797,-28197.98324901486],[2103.486425365433,-18361.420281631374,10856.474841590489,21737.042392679585,867.1331907753843],[5639.6936395730745,8013.548602242911,14288.275619480444,12252.131437554905,-49279.001424058726],[6600.459703908207,15026.661339613474,14284.21992440133,5689.8754898696225,-48629.11193859142],[10373.146424867487,6163.43537374787,3685.0065073901915,8143.265285519393,-41373.965899227296],[8491.499684187043,15470.815625194808,-1211.1492903787666,-12813.592245905418,-4126.19044789083],[6572.145276472385,-23164.8920882587,8456.000882206583,24112.66576045124,9594.15624420768],[2162.3502995783238,12537.473654464968,12871.822228090943,2589.997224224089,-38660.940644407885]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0,4.0],"lines_per_spool":[1.0,1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
3
ai_docs/datasets/larger_baseline_Slideprinter.jsonl
Normal file
3
ai_docs/datasets/larger_baseline_Slideprinter.jsonl
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{"dataset":"larger_baseline","geometry":"Slideprinter","anchor_set":0,"anchors":[[-1000.0,-577.0,0.0],[1000.0,-577.0,0.0],[0.0,1154.0,0.0]],"real_xyz":[[176.76235468171672,806.6212284216593,0.0],[-628.3080789679709,-311.73204060879743,0.0],[822.9826004034139,-451.5641372586201,0.0],[92.72422894295104,518.1123723801613,0.0],[84.37983548581741,104.03865844449979,0.0],[-161.1942828606986,-304.9045687899181,0.0],[-85.7251335177038,-269.2450826120734,0.0],[92.2748316503351,-199.60410560039327,0.0],[863.4406402474013,-392.49544255808405,0.0],[60.84532501289118,-173.87089019578605,0.0]],"config":{},"motor_samples":[[12923.824400032257,8846.959104798136,-14852.327961659003],[-13558.197794503183,9664.602683212888,8597.138807303392],[13137.79430364076,-18197.309330019038,12694.109661198016],[7656.664694335544,5215.2192653228185,-9942.917589513574],[2454.9691403178404,-261.51580548956616,-1960.4659020915096],[-5308.194970063551,740.0248843033343,6119.0950997860355],[-3697.0421472424755,-508.9410388273946,5300.01145372266],[20.45508705964275,-3338.9814979631115,3952.0718414737944],[14024.066665472852,-17956.830168358018,12024.407240991024],[-383.9802684933235,-2580.6707832668603,3416.0228188907954]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0],"min_force":[3.0,3.0,3.0],"max_force":[120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
{"dataset":"larger_baseline","geometry":"Slideprinter","anchor_set":1,"anchors":[[-1200.0,-692.4,0.0],[1200.0,-692.4,0.0],[0.0,1384.8,0.0]],"real_xyz":[[-364.40435286328176,121.37453016666075,0.0],[-712.2257186386287,149.03739498222137,0.0],[-115.01061856460902,411.8206480985151,0.0],[-210.1433327494264,-403.4326779043622,0.0],[-674.7741403006316,-195.81785829216255,0.0],[17.281092904569107,53.48268204312774,0.0],[441.3240709174626,-551.7632659511835,0.0],[632.2084233344635,-315.2770279293172,0.0],[-286.79441456424576,681.6360494245703,0.0],[641.8570299798251,254.85043731088075,0.0]],"config":{},"motor_samples":[[-4266.251386537939,7372.677644549255,-1364.0575665343702],[-8029.262296186788,13744.219293714943,807.9596015060357],[3168.0842578727643,6469.05293509271,-7878.954674401829],[-6894.129512385957,1048.3117753466097,8110.4996539687145],[-12876.800811603795,10813.463616356725,6504.88019201986],[821.9888168297571,250.0459396716071,-1039.5796536651342],[5095.077214442704,-11933.945039902692,11741.168160426998],[9467.885883122173,-13673.18134992727,8369.016073559256],[5138.091698291684,12477.792575977803,-12160.600074058928],[13391.663048189988,-5583.442681226648,-1683.2285956073715]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0],"min_force":[3.0,3.0,3.0],"max_force":[120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
{"dataset":"larger_baseline","geometry":"Slideprinter","anchor_set":2,"anchors":[[-1500.0,-865.5,0.0],[1500.0,-865.5,0.0],[0.0,1731.0,0.0]],"real_xyz":[[-280.4232228980667,454.87093541941476,0.0],[-709.5065216885973,-597.4011395386945,0.0],[409.1258184663736,697.812957794552,0.0],[-345.4863346057438,-357.89022180566684,0.0],[1062.5651889535773,-467.4954078885564,0.0],[-242.23010677517487,587.6606072938107,0.0],[-598.094577704399,-776.4560686240792,0.0],[577.054714682534,-179.1356021423652,0.0],[-953.7373647141476,-44.43134166540142,0.0],[-518.8569150036393,185.27486567631695,0.0]],"config":{},"motor_samples":[[1274.6611426641105,9460.424753428664,-8257.033751319565],[-17416.318316790024,9633.126144513184,13731.764640412712],[14371.059420772259,3384.5541565098824,-12053.239857863986],[-9152.045433031819,3550.1995549556923,7534.727206203349],[16835.62270019691,-22118.674411749755,13875.11505037096],[3700.856603811072,10479.505423647543,-10932.082590755525],[-16042.45780401469,7150.281759308329,16547.397300996316],[8892.135528607741,-11305.445658101391,5152.908440333652],[-14503.188823540286,16721.453874049843,5501.724055109611],[-5728.8428054056185,10620.964785645121,-1963.2437113587978]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0],"min_force":[3.0,3.0,3.0],"max_force":[120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
3
ai_docs/datasets/larger_baseline_Spidercam.jsonl
Normal file
3
ai_docs/datasets/larger_baseline_Spidercam.jsonl
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{"dataset":"larger_baseline","geometry":"Spidercam","anchor_set":0,"anchors":[[1500.0,1500.0,3500.0],[-1500.0,1500.0,3500.0],[-1500.0,-1500.0,3500.0],[1500.0,-1500.0,3500.0]],"real_xyz":[[980.0803451631423,-14.377673494448572,1120.4313374021765],[1297.9455472925224,119.53472895415666,1018.9940391345198],[-336.3055778169024,509.25388293853416,524.6657353245921],[671.3750892387893,997.795777807185,1482.8540908980017],[-163.0077670877963,-927.9015895009527,1341.4040977064235],[687.4704053858272,-223.64344226665116,1873.8136153281382],[-1186.173348874489,-728.714028231471,750.3375286437315],[1251.051107672089,-1184.170307062321,781.3599408189854],[-1218.3619917244473,362.7916543974434,1963.560138855575],[-401.6440960914779,-1205.47823569393,1374.5281995677879]],"config":{},"motor_samples":[[-23748.37453745433,-6541.09408756786,-6764.538736952407,-24039.712582952532],[-24169.13259678123,-2062.7050851381573,-330.60907912848376,-21785.548486630443],[-8918.71130652227,-14531.72092540711,-6194.573171735229,-1160.2180650342461],[-35888.59836652979,-21076.182669477035,-4207.5943897720945,-15076.367228568604],[-8603.974459009041,-11253.957761573216,-28865.19183771489,-25362.8432400048],[-30740.825685586293,-16839.282623454026,-21002.846871712853,-36201.655179150854],[6850.352567872992,-10476.532761856943,-23664.566147763806,-3338.685397217564],[-5128.616844023338,12021.811102985577,-4116.5808158243035,-26072.589104097467],[-14933.737546953958,-41749.31002366161,-32167.19905948748,-8869.620228616863],[-3134.43602397253,-9342.281117666716,-32566.639105818744,-23761.376731573215]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
{"dataset":"larger_baseline","geometry":"Spidercam","anchor_set":1,"anchors":[[1800.0,1800.0,4000.0],[-1800.0,1800.0,4000.0],[-1800.0,-1800.0,4000.0],[1800.0,-1800.0,4000.0]],"real_xyz":[[-1051.7483719467841,-234.48244635150172,1392.9928083836057],[-892.5237232873144,1093.251023963489,2416.3681585780205],[-93.93538200713829,-321.0069980728954,548.9276370977148],[329.723365576383,13.286236897906292,3097.2194109633547],[1500.5117400258468,990.7049313952843,2973.4280392453966],[-13.472875736242713,-403.8969406995616,1732.7686200408082],[99.9762407367432,1016.6297424239565,683.220356026899],[321.78846394611264,1299.167305488315,911.884858791474],[-678.8375865689652,1095.086720561279,2285.9772598185787],[1489.487815658274,454.667953124429,3237.8652561832837]],"config":{},"motor_samples":[[-7273.100162643181,-26182.097343677702,-31171.818751632265,-11114.43561467426],[-29795.9476110429,-53670.99373273616,-25586.514687259867,-9389.539906531494],[-5242.530363716482,-6726.646767894965,-11998.108142868925,-10421.527683755068],[-43616.99441302593,-35191.714519300935,-34878.08607694459,-43249.51650087651],[-65396.73289891843,-23087.154316610493,-5802.996565494848,-33922.450943054086],[-21262.270487219193,-21519.955373541536,-29726.97856301414,-29436.214557248975],[-18114.93517760824,-16305.710126228121,145.05272572911105,-1343.3219416734944],[-24846.918090332918,-18657.534665168187,2373.3737175882497,-2386.6330996256625],[-31869.34119439332,-49685.64224916334,-23164.38201477061,-10917.62343201992],[-60922.58058648153,-21450.546487972824,-13228.656285123103,-45225.03406988177]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
{"dataset":"larger_baseline","geometry":"Spidercam","anchor_set":2,"anchors":[[1200.0,1200.0,3200.0],[-1200.0,1200.0,3200.0],[-1200.0,-1200.0,3200.0],[1200.0,-1200.0,3200.0]],"real_xyz":[[653.6967704781443,349.33596986727184,655.9705966420397],[-572.9336267776469,726.0594238281737,1001.417437406767],[372.8715650534441,-129.24856227007137,1302.437023095733],[-978.8499199394845,644.6448896863099,947.4787141114076],[-325.73309839702415,-856.7961975114675,1699.1049836013992],[557.2243008774553,22.082524568488793,1346.5037193969517],[544.2142512612888,-806.5539866170868,1498.2040109360544],[497.76731441978313,-267.3845829188999,2302.7131431788634],[-86.36964483213205,-768.2072112781044,2544.536753337394],[-88.19853421893527,505.5782571908551,387.8076939336375]],"config":{},"motor_samples":[[-17184.730775916232,-7022.369199065494,-2206.1281466787264,-11538.503893631607],[-14721.628234704427,-24964.975022724746,-12285.390108994588,-3952.866534209883],[-22537.30090398631,-15953.091955875896,-18142.73245963857,-25038.642697225274],[-8535.992125625558,-25050.445806958534,-13635.480461315961,287.96146842698283],[-12694.415416061878,-18042.25620197352,-35821.218583597285,-28178.146494045744],[-25854.511217829757,-15713.489808013454,-15349.55315286301,-25409.75384343651],[-17666.468907385763,-9041.228304850152,-22370.37771668402,-33994.4706523167],[-34141.48146931466,-23370.289212027223,-28808.71081170161,-41540.23577632628],[-22903.509495760933,-24571.35583404383,-43651.0334658862,-40883.085729926046],[-8792.490540303046,-10104.325837615184,-2920.3920940741573,-1742.0218553633574]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
1
ai_docs/datasets/near_singularities_CubeCorners.jsonl
Normal file
1
ai_docs/datasets/near_singularities_CubeCorners.jsonl
Normal file
File diff suppressed because one or more lines are too long
1
ai_docs/datasets/near_singularities_HP5.jsonl
Normal file
1
ai_docs/datasets/near_singularities_HP5.jsonl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"near_singularities","geometry":"HP5","anchor_set":0,"anchors":[[0.0,-2000.0,-120.0],[2000.0,0.0,-120.0],[0.0,2000.0,-120.0],[-2000.0,0.0,-120.0],[0.0,0.0,2000.0]],"real_xyz":[[964.1235747453284,-948.5095865754266,-27.497151],[-719.5187593752305,-688.1722481719395,507.741532],[-497.5406036084379,-490.0575058255245,953.040004],[-1859.8180608111313,-1.9036466416990947,26.4689901],[-1371.4539342118287,-8.616774278737623,537.019049],[-868.2739227475189,30.522133856254673,1047.17018],[-1000.8797009212224,925.9498515316079,-42.5453256],[-726.4620750668811,656.9465390840625,533.480869],[-462.56843732482224,452.0564777695172,1030.39159],[32.42989399170206,-1879.3709383667888,-26.6148823],[-14.851928971388142,-1383.5120210286118,517.628213],[-69.09574343697072,-881.8078207139725,991.936222],[-968.0861139513448,-888.6499525580892,31.7537695],[-667.8906291657761,786.0473180040354,458.719776],[539.6755933059526,359.536029335557,1046.72968],[39.64552670559763,1888.8005598981758,-44.2588518],[-51.72433907082231,1347.2278260235173,517.004705],[-74.61369067825252,892.057312151936,975.222737],[899.7227124027092,-962.392775993517,26.0515823],[664.9902401977811,-716.5310909342946,535.481389],[467.3753481166266,-508.72394150601525,965.228753],[1843.6122836146938,-82.71599949851364,-42.0139801],[1308.1156503742407,-81.10527698424995,527.319817],[888.7724932051186,-56.07002943639088,998.360926],[894.1701395382921,953.4569408390662,41.4092948],[726.950777402476,704.1962442956373,482.878157],[512.2444994842339,448.34885523274727,981.665044]],"config":{},"motor_samples":[[-11155.908540832055,-11582.775428539351,21514.62370934649,21711.96754699045,17062.108181354553],[-7411.174012018032,17022.277132756146,16593.03075985956,-8171.074087061048,-7999.044243504365],[-1665.8468270885874,14817.231179033648,14710.974491805748,-1818.2314808536319,-28697.392621417795],[14259.339564188376,36469.918634564405,14313.872985465174,-34849.78927007223,27575.978530951907],[9797.201525283988,28032.35628935845,10065.447595820675,-21294.032932347585,-73.18890435053255],[9644.951775121863,21382.87457068773,8679.95931190246,-7506.215585157266,-27754.429291201166],[21315.378414364917,22259.78093920332,-10369.174119792582,-12420.021922122209,17835.04553382147],[16165.726974860125,17120.381857440654,-6666.274651587776,-8336.174322801153,-9179.404968878309],[14535.173328262708,14684.856096827942,-395.2012213944214,-602.5342880666103,-32274.16496421812],[-35742.38761667423,14041.52074232014,36826.29832569518,14966.856496287599,29768.70749912196],[-21746.24184895807,10194.139020112729,28194.125344508117,9732.081411486133,686.2354061963302],[-8381.955634084803,9863.399440248837,21242.475443876363,7660.956624868874,-25701.803933887662],[-10145.882771511615,21484.435437328968,20470.134976528207,-12306.46185935657,14301.78273763029],[17968.244328187408,16360.23481533749,-9761.452616797522,-6849.692769367826,-5643.867722441632],[13345.849130783814,-1958.229427745586,1569.2306495788519,15910.086879080527,-32765.93556305848],[37006.34520714529,14056.647147127349,-36042.01828668823,15185.469845298563,30591.009541385924],[27496.880283809227,10387.578678860531,-21220.266093687474,8765.879719954606,-149.3424127966454],[21315.802595375288,9879.593766092856,-8737.88495634924,7497.677716258369,-24936.663919711875],[-12095.894401201227,-10390.307750205207,21434.831832100655,20635.360447447474,14559.79874239004],[-8098.618677434139,-6861.331767070221,16981.287956331926,16273.284149560048,-9284.325337714048],[-1966.8868561562024,-1128.8873876638993,15031.649476608285,14444.239338828947,-29249.67397604465],[12837.165953000773,-35021.79904802905,15217.998469720553,36128.01769841507,29425.895448773877],[7945.320952552737,-20476.33240066759,10506.280955448921,26790.773577321655,-1318.9603012018158],[7974.345835671659,-8420.147057080954,9757.795917522539,21410.359542023354,-25768.616121939147],[21250.4480562832,-10391.286572083012,-12002.1205346634,20492.131268559555,13836.736735872655],[16821.292038031894,-8338.532429158906,-7782.184230375232,17131.96918622005,-6840.859723358826],[14251.123929933565,-1926.7025713330838,-640.5568828356824,15159.382232620494,-29991.982492247436]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0,4.0],"lines_per_spool":[1.0,1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
1
ai_docs/datasets/near_singularities_Slideprinter.jsonl
Normal file
1
ai_docs/datasets/near_singularities_Slideprinter.jsonl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"near_singularities","geometry":"Slideprinter","anchor_set":0,"anchors":[[-1000.0,-577.0,0.0],[1000.0,-577.0,0.0],[0.0,1154.0,0.0]],"real_xyz":[[586.4270593216361,-576.929868913055,0.0],[-603.2103050900729,-576.9308810443885,0.0],[-585.7394510045932,-576.9298271158324,0.0],[-666.9611098795624,-0.6826787542929805,0.0],[-668.9952596093234,-4.203262684803123,0.0],[-653.2977148581732,22.965149336501185,0.0],[-434.3922987065864,401.87195736273213,0.0],[-437.82506324286135,395.9293539104272,0.0],[-426.0299978463784,416.3483815808851,0.0],[9.954823683066722,-576.9000148846653,0.0],[-6.192991299629174,-576.9000057614569,0.0],[-45.20413015962975,-576.9003055838813,0.0],[-628.5041940857675,-576.9323763742656,0.0],[-396.7838127242334,466.97893068040815,0.0],[481.31019424972703,320.6525517657939,0.0],[23.370900117838755,1113.4413613848028,0.0],[-41.54087306862511,1081.9861813745736,0.0],[-84.30722642226766,1007.9501109459678,0.0],[539.3580397342089,-576.9269508913909,0.0],[535.4277451249861,-576.9267022878269,0.0],[530.0343395233945,-576.9263599854945,0.0],[684.3060742773087,-30.702258495355885,0.0],[691.332854042849,-42.86375031092699,0.0],[691.7828268669383,-43.642533677138715,0.0],[412.4717099617616,439.8201162989721,0.0],[427.38328862541647,414.0056191976659,0.0],[442.7042525159753,387.48282318708567,0.0]],"config":{},"motor_samples":[[8426.357843244858,-14391.752839280192,13153.520024612979],[-14716.788227063353,8754.361681074965,13260.329072014767],[-14378.435265810689,8412.9204539964,13149.201712214017],[-9505.26811460891,11894.49952495257,3497.9583150002713],[-9584.170518226076,11909.697869615386,3577.2643206533658],[-8975.214843524289,11797.008406697194,2965.322698629456],[-467.29479605329664,11362.166653357564,-5553.869566145478],[-600.9384954795393,11352.368361139259,-5420.476535261681],[-141.7044848426005,11388.244056061441,-5878.790053827353],[-2814.3406518652355,-3201.6904211346555,11262.097689784183],[-3128.503447469217,-2887.5303929930583,11261.75421720622],[-3887.3662818965104,-2128.432494437914,11273.089588980112],[-15206.566811830442,9248.773570922742,13426.36892100328],[997.3530178967259,11503.974726628205,-7014.844840669595],[11274.110904827523,-2293.250552804931,-3730.115735683917],[16052.448681371181,15586.041238603922,-21475.019555309365],[14874.242545733023,15714.550164296918,-20773.33989189406],[13199.673635506027,14960.60297216639,-19121.02934589303],[7506.689043550079,-13479.958408799092,12868.508743694165],[7429.911142796193,-13403.807959198499,12845.6907469105],[7324.555295687051,-13299.305598114464,12814.626707474483],[12029.747300733125,-10177.979337578452,4174.270292870675],[12088.166052914625,-10450.455774904553,4448.308180213305],[12091.977854418661,-10467.903291118886,4465.857704524734],[11437.163754329184,386.28696539881355,-6405.517122514595],[11383.811702557328,-194.39849672883403,-5826.210133119419],[11339.350834103052,-790.881386930837,-5230.8655978470015]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0],"min_force":[3.0,3.0,3.0],"max_force":[120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
1
ai_docs/datasets/near_singularities_Spidercam.jsonl
Normal file
1
ai_docs/datasets/near_singularities_Spidercam.jsonl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"near_singularities","geometry":"Spidercam","anchor_set":0,"anchors":[[1500.0,1500.0,3500.0],[-1500.0,1500.0,3500.0],[-1500.0,-1500.0,3500.0],[1500.0,-1500.0,3500.0]],"real_xyz":[[1499.9287144429502,-1475.6373582138544,200.0],[-1499.9277326493143,-1434.5819708286708,507.741532],[-1499.9287555873939,-1477.369564510202,953.040004],[-1499.9000000523845,-1.535246730929641,200.0],[-1499.9000019737134,-9.423794292524429,537.019049],[-1499.9000617282557,52.72546975752796,1047.17018],[-1499.9265950329577,1387.6361032207526,200.0],[-1499.925829729717,1356.3971424564882,533.480869],[-1499.9284813539134,1465.842308888215,1030.39159],[25.881850936320518,-1499.9000148846656,200.0],[-16.101347882175816,-1499.900005761457,517.628213],[-117.52756582692406,-1499.9003055838814,991.936222],[-1499.926331517984,-1376.850100559418,200.0],[-1274.4589589151092,1499.9237941288518,458.719776],[1499.9167773451923,999.2560885642092,1046.72968],[31.482586166734894,1499.9000220212874,200.0],[-57.58590973382795,1499.9000736203734,517.004705],[-125.45505662877093,1499.9003479766127,975.222737],[1402.2531946675983,-1499.926950891391,200.0],[1392.035364066166,-1499.926702287827,535.481389],[1378.0137859685065,-1499.9263599854946,965.228753],[1499.900100497393,-67.29491719230272,200.0],[1499.900191657584,-92.99622740414043,527.319817],[1499.9001984067122,-94.62426989952272,998.360926],[1406.660258275214,1499.9270578947137,200.0],[1499.9281741349218,1452.9784130820674,482.878157],[1499.9247521532968,1312.8292177667217,981.665044]],"config":{},"motor_samples":[[6852.727148185271,24842.615336302115,7172.458217295321,-15413.435346814153],[20769.956384635952,1928.8334497059334,-21350.42287989256,2835.7118800331114],[16464.811318007578,-3386.624128743462,-29945.88405011327,-3051.350009225857],[11980.133433621793,-9090.667903738107,-9115.386247978486,11960.97773913321],[7537.096370190011,-14910.658314182754,-15075.81124378926,7413.691404781946],[864.0260742812834,-24137.21435781227,-23074.263041786344,1605.7891279362425],[7198.774859518303,-15378.29661330306,5711.555916249848,23891.99324842625],[2519.8246583676896,-21794.231594291254,507.30525671219857,19608.807748065577],[-4014.748461569514,-31431.41788189801,-4528.203452645195,15553.806013436986],[11810.342571133351,12133.273308446554,-8893.183215811263,-9309.887269586243],[7832.119294543667,7621.855677767517,-14798.007546486073,-14517.250771667586],[2717.6587417760456,1077.2210761604617,-23831.903502544388,-21500.948393062226],[23776.881619467833,5573.0495627741975,-15370.865690506489,7204.3323380856355],[478.36650120186493,-20256.386591413284,3619.750131114949,19585.218396544424],[-30777.610795120978,-3592.8106929794885,10133.094889992459,-11466.030517052957],[-9354.253355520837,-8847.381055188107,12168.815344600474,11776.00607739755],[-14137.785159204479,-15141.633397521047,7365.076210912374,8116.96077211215],[-21146.515015856454,-23622.660956108517,1223.3527857364202,2970.3137062327014],[7192.055808096462,24048.48377855597,5899.738361323232,-15387.278862901147],[2471.719439675107,19979.92593651727,962.5580702744355,-21861.921504394628],[-3169.0572768212396,15177.906249941938,-5001.082929062712,-30126.124260499048],[-8551.242651985802,12398.838740535513,11559.255903188281,-9634.580171128158],[-13993.037960404778,8225.536521322912,7009.655651798376,-15618.213278602316],[-21844.48525071223,2473.6571765227955,1151.5727943819468,-23725.02837611838],[-15389.741271685798,5956.583408048863,24095.776626657225,7190.213468548997],[-20876.997110671848,3174.050400114192,21259.80018859875,2526.0438149136485],[-30365.281382150337,-3324.944752462639,14260.108179029541,-6160.48720873667]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
1
ai_docs/datasets/outside_singularities_CubeCorners.jsonl
Normal file
1
ai_docs/datasets/outside_singularities_CubeCorners.jsonl
Normal file
File diff suppressed because one or more lines are too long
1
ai_docs/datasets/outside_singularities_HP5.jsonl
Normal file
1
ai_docs/datasets/outside_singularities_HP5.jsonl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"outside_singularities","geometry":"HP5","anchor_set":0,"anchors":[[0.0,-2000.0,-120.0],[2000.0,0.0,-120.0],[0.0,2000.0,-120.0],[-2000.0,0.0,-120.0],[0.0,0.0,2000.0]],"real_xyz":[[964.2243911061697,-948.6087702145851,-27.497151],[-719.6209861786293,-688.2700213685404,507.741532],[-497.6413613152127,-490.1567481187497,953.040004],[-1860.0178563072427,-1.9038511455875198,26.4689901],[-1371.6526854679453,-8.618023022620921,537.019049],[-868.4671309656386,30.52892563813489,1047.17018],[-1000.9835896849843,926.045962767846,-42.5453256],[-726.5671000128928,657.0415141380506,533.480869],[-462.6695866440002,452.1553284503393,1030.39159],[32.433286593425294,-1879.5675457650655,-26.6148823],[-14.854053157866401,-1383.7098968421333,517.628213],[-69.11027608697687,-881.9932880639665,991.936222],[-968.1903922202289,-888.7456742892051,31.7537695],[-667.9825024992241,786.1554446705873,458.719776],[539.7956263615132,359.6159962799965,1046.72968],[39.649638360777516,1888.9964482429957,-44.2588518],[-51.73173379672665,1347.4204312976128,517.004705],[-74.62912792431862,892.2418749058698,975.222737],[899.8193468722692,-962.496141523957,26.0515823],[665.0865094663349,-716.6348216657407,535.481389],[467.4711120113626,-508.8281776112792,965.228753],[1843.8036956704452,-82.72458744276214,-42.0139801],[1308.3039740057973,-81.11695335269314,527.319817],[888.9606245543979,-56.081898087111554,998.360926],[894.2669307305229,953.5601496468353,41.4092948],[727.052367353247,704.2946543448661,482.878157],[512.3511511692511,448.4422035477301,981.665044]],"config":{},"motor_samples":[[-11156.00459952657,-11582.917955316701,21517.08994699555,21714.44662221021,17065.180350958322],[-7411.828723022837,17024.63249772422,16595.342585117683,-8171.8506246720435,-7995.989061150994],[-1666.8587208483723,14819.361088592725,14713.086964134938,-1819.2714971092425,-28694.361489284147],[14261.999210883856,36473.86385085536,14316.535838673433,-34851.186681243584,27615.557520132163],[9799.309310857328,28036.19833907617,10067.582894961064,-21295.102653449598,-60.92029996388893],[9646.372957832285,21386.39092861295,8681.191748799858,-7508.81008767647,-27749.438727078665],[21317.824310741413,22262.287600171552,-10369.16406672246,-12420.230239056615,17838.13259092668],[16168.002580500895,17122.756697558747,-6666.874106120473,-8337.050237350499,-9176.345529950584],[14537.234991599289,14686.944850040125,-396.24420728848366,-603.6202465761694,-32271.13746196907],[-35745.27103789782,14044.130940636587,36830.183232204,14969.519107944945,29774.57644546042],[-21748.880834680043,10196.291755668972,28197.955358543448,9734.18769073115,691.4661587315674],[-8384.315200489309,9864.908447754482,21245.87961413678,7662.061316603834,-25696.805345399614],[-10145.953739202203,21486.93406418499,20472.564732639832,-12306.78062261777,14304.85674465158],[17970.677891991832,16362.512724801245,-9762.352401388716,-6850.132489325447,-5640.793448986873],[13347.696174329074,-1959.7163695914671,1568.609770715695,15912.407257055813,-32762.803493603198],[37010.21677406378,14059.25022408284,-36044.96287478779,15188.13600156938,30596.649126539865],[27500.607627114256,10389.697041990643,-21222.757014274004,8767.832636579602,-143.66381402723982],[21319.199151943354,9881.126051844401,-8740.261975312167,7498.781559345453,-24931.730544703438],[-12096.179319214662,-10390.398023903736,21437.323468928735,20637.79802257453,14562.871192437235],[-8099.460508461212,-6861.969348530655,16983.64850136157,16275.570948507631,-9281.269094908359],[-1968.011657575778,-1129.8253406661477,15033.813385459945,14446.305394847494,-29246.63850582523],[12839.641004582638,-35024.69460209026,15220.609516137842,36131.8015737809,29431.09607978373],[7947.135972677044,-20478.88586128874,10508.363528995433,26794.416140487414,-1313.8155557191521],[7975.51336956758,-8422.447044919028,9759.292445264426,21413.809380189403,-25763.381433083814],[21252.935747006857,-10391.40039328878,-12002.420639763055,20494.56709292398,13839.808198620873],[16823.6192184088,-8339.269123863254,-7782.834072034634,17134.327147281663,-6837.803950907098],[14253.153338557697,-1927.8882784139385,-641.448190635882,15161.566061816444,-29988.940733646497]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0,4.0],"lines_per_spool":[1.0,1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"outside_singularities","geometry":"Slideprinter","anchor_set":0,"anchors":[[-1000.0,-577.0,0.0],[1000.0,-577.0,0.0],[0.0,1154.0,0.0]],"real_xyz":[[586.5696304357359,-577.070131086945,0.0],[-603.3548397914448,-577.0691189556117,0.0],[-585.8819398298053,-577.0701728841677,0.0],[-667.1611097747937,-0.6828834673974071,0.0],[-669.1952556618963,-4.204519249678304,0.0],[-653.4975914016618,22.972175527724087,0.0],[-434.5391086406714,402.0077765191644,0.0],[-437.97340378342705,396.06349966706773,0.0],[-426.17303513855137,416.4881683222013,0.0],[9.958274312875727,-577.0999851153347,0.0],[-6.1951381654399755,-577.0999942385431,0.0],[-45.21975365408382,-577.0996944161187,0.0],[-628.6515310497994,-577.0676236257343,0.0],[-396.9133143103633,467.1313424227047,0.0],[481.47663955934274,320.76343891070655,0.0],[23.375097151352165,1113.6413173422277,0.0],[-41.54854604841679,1082.186034133827,0.0],[-84.32389666339944,1008.1494149927422,0.0],[539.494624180343,-577.073049108609,0.0],[535.5637957830543,-577.0732977121731,0.0],[530.1696487730947,-577.0736400145056,0.0],[684.5058732825225,-30.71122273071164,0.0],[691.5324707276808,-42.87612686686019,0.0],[691.982430053514,-43.655126052164334,0.0],[412.60852296226136,439.9660005095441,0.0],[427.5269403555726,414.14477443624196,0.0],[442.8547482093821,387.61454655732064,0.0]],"config":{},"motor_samples":[[8429.144007449308,-14394.513729097891,13157.016692754416],[-14719.586792533415,8757.186583101968,13263.81626715581],[-14381.194576198866,8415.70499535577,13152.698779879884],[-9507.212482903153,11898.197210101716,3499.9131016383744],[-9586.132463522896,11913.391716706288,3579.2368957595468],[-8977.036886968348,11800.731961839449,2967.1537774140324],[-466.43469222706057,11366.037037390035,-5554.72742314936],[-600.1215625316199,11356.242883293226,-5421.2913903149565],[-140.74060344643635,11392.103629967625,-5879.751242169801],[-2814.2735158785117,-3201.756967710556,11266.010256108315],[-3128.544631377344,-2887.4886244390477,11265.66694164002],[-3887.6695618089893,-2128.1284395465495,11276.997124994747],[-15209.419099035224,9251.653803420126,13429.842845445963],[998.66227520474,11507.789613320843,-7016.149483065212],[11278.020152921823,-2293.002319911446,-3730.363260255044],[16055.844167679912,15589.393222693594,-21478.322693296985],[14877.55777133938,15717.94742044494,-20776.60861841578],[13202.889249362306,14964.010310085703,-19124.203991836006],[7509.3572483751195,-13482.604289661089,12872.034836171466],[7432.568839643012,-13406.443576200818,12849.219486010756],[7327.198399799641,-13301.926956736088,12818.159125523876],[12033.412533385961,-10180.068396934026,4176.371615542778],[12091.818383188944,-10452.600160128277,4450.465601196679],[12095.629364653572,-10470.05115587113,4468.018654951412],[11441.003808538544,387.41455357373377,-6406.641193741083],[11387.673093409994,-193.4512712824,-5827.154741011976],[11343.23092056518,-790.1263488252029,-5231.618783535381]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0],"min_force":[3.0,3.0,3.0],"max_force":[120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
1
ai_docs/datasets/outside_singularities_Spidercam.jsonl
Normal file
1
ai_docs/datasets/outside_singularities_Spidercam.jsonl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"outside_singularities","geometry":"Spidercam","anchor_set":0,"anchors":[[1500.0,1500.0,3500.0],[-1500.0,1500.0,3500.0],[-1500.0,-1500.0,3500.0],[1500.0,-1500.0,3500.0]],"real_xyz":[[1500.0712855570498,-1475.7776203877443,200.0],[-1500.072267350686,-1434.720208739894,507.741532],[-1500.071244412606,-1477.5099102785375,953.040004],[-1500.0999999476157,-1.5354514440340674,200.0],[-1500.0999980262864,-9.42505085739961,537.019049],[-1500.0999382717441,52.73249594875085,1047.17018],[-1500.0734049670425,1387.7719223771846,200.0],[-1500.0741702702828,1356.5312882131288,533.480869],[-1500.0715186460866,1465.9820956295314,1030.39159],[25.885301566129517,-1500.0999851153347,200.0],[-16.103494747986616,-1500.0999942385429,517.628213],[-117.54318932137812,-1500.0996944161188,991.936222],[-1500.073668482016,-1376.9853478108869,200.0],[-1274.588460501239,1500.0762058711482,458.719776],[1500.0832226548077,999.3669757091218,1046.72968],[31.486783200248304,1500.0999779787126,200.0],[-57.59358271361962,1500.0999263796266,517.004705],[-125.47172686990272,1500.099652023387,975.222737],[1402.3897791137324,-1500.073049108609,200.0],[1392.171414724234,-1500.0732977121731,535.481389],[1378.1490952182066,-1500.0736400145056,965.228753],[1500.099899502607,-67.30388142765847,200.0],[1500.099808342416,-93.00860396007364,527.319817],[1500.0998015932878,-94.63686227454835,998.360926],[1406.797071275714,1500.072942105286,200.0],[1500.0718258650782,1453.1175683206434,482.878157],[1500.0752478467034,1312.9609411369568,981.665044]],"config":{},"motor_samples":[[6854.561616116119,24845.71572292413,7174.316518389827,-15413.454812344491],[20773.154092445682,1930.720203569979,-21350.480605343102,2837.6655100249573],[16468.169571337898,-3384.549609710194,-29945.90726776878,-3049.2525223601297],[11982.629882743948,-9090.666027139834,-9115.387666761124,11963.472134330746],[7539.721778429047,-14910.646975398262,-15075.821922489346,7416.303928190519],[866.8025992816928,-24137.28295352564,-23074.190042750164,1608.6395458526297],[7200.636435797887,-15378.385558566439,5713.3019326401945,23895.074564633254],[2521.791068409608,-21794.356253298487,509.11793465017826,19611.99840307608],[-4012.624808631165,-31431.454271850493,-4526.114826279675,15557.188440518174],[11812.820622160492,12135.785978918664,-8893.154817482933,-9309.91441459059],[7834.741990289733,7624.456385212029,-14798.02582726237,-14517.231625038647],[2720.531402493138,1079.9299336050283,-23832.048849764804,-21500.784279568423],[23779.960529060674,5574.784445617675,-15370.962806621219,7206.1946162095965],[480.06682052914863,-20256.571122961857,3621.7017980559363,19588.36483054648],[-30778.037011885077,-3590.6015737230364,10136.387667297351,-11464.496066617174],[-9354.286315407664,-8847.346459174822,12171.331729394484,11778.480355036176],[-14137.715974324594,-15141.697915525634,7367.648077962473,8119.611207700755],[-21146.34012365194,-23622.814609932546,1226.049549412589,2973.185099414039],[7193.916539693079,24051.568330906834,5901.499363314163,-15387.356609759145],[2473.6839124332455,19983.124666642416,964.4092547994798,-21862.016505796393],[-3166.9514928407416,15181.25145448422,-4999.1089950714395,-30126.248731058684],[-8551.167606970756,12401.378705499461,11561.705952406455,-9634.649368902688],[-13992.924248279385,8228.214354433529,7012.2067191934475,-15618.315688182154],[-21844.354014355886,2476.5170642814596,1154.3005754872738,-23725.147173064484],[-15389.815614388617,5958.348905120405,24098.862149110028,7192.073969349975],[-20877.03836377806,3175.995640669535,21262.992986176043,2527.941572207285],[-30365.468600386175,-3322.827365169868,14263.447046220399,-6158.580299949326]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0,1.0],"min_force":[3.0,3.0,3.0,3.0],"max_force":[120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
1
ai_docs/datasets/systematic_bias_CubeCorners.jsonl
Normal file
1
ai_docs/datasets/systematic_bias_CubeCorners.jsonl
Normal file
File diff suppressed because one or more lines are too long
1
ai_docs/datasets/systematic_bias_HP5.jsonl
Normal file
1
ai_docs/datasets/systematic_bias_HP5.jsonl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"systematic_bias","geometry":"HP5","anchor_set":0,"anchors":[[0.0,-2000.0,-120.0],[2000.0,0.0,-120.0],[0.0,2000.0,-120.0],[-2000.0,0.0,-120.0],[0.0,0.0,2000.0]],"real_xyz":[[17.9255679,-17.6352632,-27.497151],[-523.885148,-501.061599,507.741532],[-538.35251,-530.255594,953.040004],[-545.189816,-0.558037791,26.4689901],[-520.999273,-3.27341154,537.019049],[-470.799477,16.5498517,1047.17018],[-505.362595,467.529134,-42.5453256],[-513.234032,464.122399,533.480869],[-538.29312,526.060302,1030.39159],[8.98405788,-520.642383,-26.6148823],[-5.52678502,-514.840431,517.628213],[-38.6000122,-492.617793,991.936222],[-507.629503,-465.97604,31.7537695],[-30.5601452,35.9665477,458.719776],[43.2898928,28.8400594,1046.72968],[10.5874156,504.407891,-44.2588518],[-19.9804722,520.41744,517.004705],[-37.9958866,454.266612,975.222737],[455.930483,-487.688259,26.0515823],[482.712486,-520.125685,535.481389],[495.517745,-539.35609,965.228753],[500.096373,-22.437457,-42.0139801],[490.657689,-30.4215669,527.319817],[506.742907,-31.9689121,998.360926],[490.590662,523.118645,41.4092948],[517.848381,501.639033,482.878157],[525.399857,459.863258,981.665044]],"config":{"min_force":50.0},"motor_samples":[[-370.5993651472125,-376.2639329793512,316.0709537953,321.7208620981126,1074.9286102458339],[-5731.185393224393,12699.169895916693,12361.516659814022,-6251.753819832119,-13442.453157959539],[-1922.646518310387,15782.40204960943,15669.460967886855,-2088.7073520005465,-27444.978358147273],[1504.6987715208045,10731.503326164871,1525.708866918446,-10465.455507195233,1844.8028235223296],[3284.852182843592,11851.816571939304,3402.3290764447747,-7451.307500304783,-17515.67742092543],[7401.602918165139,14341.117773929858,6855.704423004311,-1518.1418515190023,-36304.52833121565],[10166.198315531154,10758.626651737597,-7506.653760936458,-8424.283118519154,6048.559102564377],[11758.899697221419,12491.102431325577,-4977.943950693394,-6086.175354923207,-14884.756174124741],[16193.090192511145,16362.058473128047,-991.5213276921896,-1236.5520995706183,-29892.680124625873],[-10076.563755385381,1103.796344059872,10235.407774640027,1442.1074692763777,3595.210010402965],[-7491.6555447922265,3301.635038591105,11641.193115930888,3100.849553246489,-16883.88241830177],[-2498.0970926453824,7338.237870045338,14282.537084547206,6053.1434865757265,-34022.84048931684],[-7343.833115347374,10873.074042917342,10232.759424704002,-8355.628148930406,3320.3936688688336],[2335.3683500551924,2235.9012366068832,984.3748627232579,1088.0189264687137,-17818.740389191607],[6694.974397662006,5465.751089600586,5718.737688590871,6934.89417756367,-40434.083360389675],[9907.416334531643,968.6796135615313,-9783.054587758881,1368.5737759692013,4107.1563079684765],[11745.132288278308,3584.32814004323,-7593.529736563015,2858.79042950791,-16787.65250737727],[13465.103487708122,7026.612973644866,-2082.2996314441216,5753.246118859721,-34063.446458151986],[-8060.261734787741,-7293.218309589196,10440.552264943357,9948.783220984555,3258.5127847248855],[-6087.460353942145,-5242.003303760159,12693.942891267478,12139.250135678716,-14661.24504635184],[-2151.7580210150118,-1259.839078506561,15767.661906326546,15153.264233760503,-28350.33480729001],[727.4690373021581,-9695.264716103467,1575.8280381864665,9824.358701329065,3985.860739645623],[2589.5346669843757,-6981.626603947957,3697.708322607655,11234.41718119873,-17529.455044039394],[6282.563668492323,-2647.1076566961406,7344.200661698896,14584.086723662434,-34010.30833620635],[11270.563618508811,-7687.308262109573,-8482.981410195118,10775.136725362643,3326.019803397125],[12235.220098003983,-6321.714561803411,-5950.385791734523,12475.82175927438,-12644.860548946892],[14602.327295595594,-1939.1741855049725,-613.6490515865536,15527.394473873232,-29633.670551233896]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0,4.0],"lines_per_spool":[1.0,1.0,1.0,1.0,1.0],"min_force":[50.0,50.0,50.0,50.0,50.0],"max_force":[120.0,120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
1
ai_docs/datasets/systematic_bias_Slideprinter.jsonl
Normal file
1
ai_docs/datasets/systematic_bias_Slideprinter.jsonl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"systematic_bias","geometry":"Slideprinter","anchor_set":0,"anchors":[[-1000.0,-577.0,0.0],[1000.0,-577.0,0.0],[0.0,1154.0,0.0]],"real_xyz":[[17.9255679,-17.6352632,0.0],[-523.885148,-501.061599,0.0],[-538.35251,-530.255594,0.0],[-545.189816,-0.558037791,0.0],[-520.999273,-3.27341154,0.0],[-470.799477,16.5498517,0.0],[-505.362595,467.529134,0.0],[-513.234032,464.122399,0.0],[-538.29312,526.060302,0.0],[8.98405788,-520.642383,0.0],[-5.52678502,-514.840431,0.0],[-38.6000122,-492.617793,0.0],[-507.629503,-465.97604,0.0],[-30.5601452,35.9665477,0.0],[43.2898928,28.8400594,0.0],[10.5874156,504.407891,0.0],[-19.9804722,520.41744,0.0],[-37.9958866,454.266612,0.0],[455.930483,-487.688259,0.0],[482.712486,-520.125685,0.0],[495.517745,-539.35609,0.0],[500.096373,-22.437457,0.0],[490.657689,-30.4215669,0.0],[506.742907,-31.9689121,0.0],[490.590662,523.118645,0.0],[517.848381,501.639033,0.0],[525.399857,459.863258,0.0]],"config":{"min_force":50.0},"motor_samples":[[134.8781314621602,-474.4959459188431,345.37391521186123],[-13065.220936239331,7142.940781856742,11334.48910755695],[-13414.36837224533,7400.429862274822,11963.183246363567],[-8203.400691642617,9630.86230616978,2309.5472196617447],[-7949.801408800305,9170.511519873195,2161.2793327330714],[-7026.751893782931,8399.156167256717,1422.0780399837395],[23.368558289144588,13203.753366349749,-5853.381828413207],[-101.65248325127683,13292.424169965498,-5709.505929275558],[801.986021280676,14388.707218261348,-6344.690545631025],[-2864.8706769936002,-3211.834565230092,10137.68618184728],[-3138.4054944070804,-2925.033865717322,10024.204041066745],[-3744.0186692948614,-2256.1952621921455,9599.353393806503],[-12629.799525825676,6871.588547192986,10586.091053203187],[-149.5464214603138,865.8389110237088,-694.5648237643184],[1008.984296849725,-433.71075787941606,-548.2563809051089],[6334.616999130044,6051.515832397009,-9796.854547334624],[6156.775637229892,6687.544253671625,-10103.341466566557],[4964.265326361466,6005.145127287529,-8810.828870121057],[5836.4640726506,-11731.385496341283,10706.579228239872],[6324.545039203335,-12327.809273548492,11458.078002351034],[6561.487124239799,-12607.59958264212,11888.310303588523],[8657.921782487414,-7964.797456376987,2340.940401124711],[8431.442347694456,-7955.307872280883,2413.7665368658263],[8715.804716156212,-8187.32460373844,2562.0615240613324],[13601.16144639234,1123.617222090644,-6885.489041198751],[13786.314047809617,524.1383719117192,-6231.725380331252],[13441.626617005404,-276.0146963924771,-5501.871095529545]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0],"min_force":[50.0,50.0,50.0],"max_force":[120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
1
ai_docs/datasets/systematic_bias_Spidercam.jsonl
Normal file
1
ai_docs/datasets/systematic_bias_Spidercam.jsonl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"dataset":"systematic_bias","geometry":"Spidercam","anchor_set":0,"anchors":[[1500.0,1500.0,3500.0],[-1500.0,1500.0,3500.0],[-1500.0,-1500.0,3500.0],[1500.0,-1500.0,3500.0]],"real_xyz":[[17.9255679,-17.6352632,200.0],[-523.885148,-501.061599,507.741532],[-538.35251,-530.255594,953.040004],[-545.189816,-0.558037791,200.0],[-520.999273,-3.27341154,537.019049],[-470.799477,16.5498517,1047.17018],[-505.362595,467.529134,200.0],[-513.234032,464.122399,533.480869],[-538.29312,526.060302,1030.39159],[8.98405788,-520.642383,200.0],[-5.52678502,-514.840431,517.628213],[-38.6000122,-492.617793,991.936222],[-507.629503,-465.97604,200.0],[-30.5601452,35.9665477,458.719776],[43.2898928,28.8400594,1046.72968],[10.5874156,504.407891,200.0],[-19.9804722,520.41744,517.004705],[-37.9958866,454.266612,975.222737],[455.930483,-487.688259,200.0],[482.712486,-520.125685,535.481389],[495.517745,-539.35609,965.228753],[500.096373,-22.437457,200.0],[490.657689,-30.4215669,527.319817],[506.742907,-31.9689121,998.360926],[490.590662,523.118645,200.0],[517.848381,501.639033,482.878157],[525.399857,459.863258,981.665044]],"config":{"min_force":50.0},"motor_samples":[[-3295.4125389824903,-3029.8314174699794,-3291.1042917299164,-3557.572602363282],[718.4739531490579,-7043.582160467328,-15315.099611922573,-6688.677686444594],[-4859.244024022229,-13499.407933893614,-23263.794839594466,-13361.295985584864],[1352.6558854741313,-6673.84573967034,-6682.501371082621,1344.8356435669075],[-3956.7281472881527,-12192.140874725324,-12246.992637409487,-4005.736810817631],[-11903.751936310688,-20264.24221501436,-19950.78926560753,-11628.247006882448],[-1854.9313025949145,-9595.2401472785,-2408.2118621079676,4691.655673243218],[-7002.726920851887,-15482.911624384305,-7771.785382896609,-92.34321225325685],[-14449.626483969707,-24543.395875590548,-14661.829064743431,-5889.05470822562],[1052.3475275371727,1178.6009549555192,-6485.798465654989,-6624.920219617258],[-3714.6163677153004,-3797.122751871048,-11910.752408406253,-11818.616863042253],[-10453.470598864855,-11086.940152173616,-19745.412917562633,-19022.999068566198],[4698.366367627152,-2434.174908436577,-9598.72387371534,-1825.0451903954179],[-7500.2937642357065,-7981.144174486575,-7415.55188230188,-6938.3545204749835],[-17092.44737160025,-16316.285164928739,-15804.356627634199,-16574.316313044834],[-6554.471641081229,-6390.702192461524,1036.8787174482757,887.8192478855693],[-11717.367607185995,-12050.54958584092,-3838.8767486859074,-3540.851354693565],[-18525.778453065348,-19231.043017006265,-11267.096940663065,-10641.903248259972],[-1967.9305229258164,4430.5482868988065,-2432.7604666958305,-9435.195681874571],[-7060.48613047631,119.62595850842584,-7646.085291215248,-15669.631279927447],[-13330.8220262578,-5359.820587266674,-14081.660225873404,-23248.101492915415],[-6276.075366674608,1080.6509245663804,764.6045699302967,-6623.038438556566],[-11635.332137350357,-3911.3151300778527,-4367.708464557524,-12142.660373619306],[-19274.08324857785,-10442.731331205741,-10966.889658716702,-19874.261716988454],[-9816.440398293413,-2270.6941145849387,5056.561735013313,-1795.587818788128],[-14848.569661595839,-6369.117215715228,1017.5816821188074,-6619.921818615509],[-23191.99503688193,-13520.951054448475,-6076.5578716019845,-14649.80037859421]],"config_used":{"spool_buildup_factor":0.043003,"spool_r_in_origin":[75.0,75.0,75.0,75.0],"spool_gear_teeth":255.0,"motor_gear_teeth":20.0,"spool_to_motor_gearing_factor":12.75,"mechanical_advantage":[2.0,2.0,2.0,2.0],"lines_per_spool":[1.0,1.0,1.0,1.0],"min_force":[50.0,50.0,50.0,50.0],"max_force":[120.0,120.0,120.0,120.0],"spring_k_per_unit_length":20000.0,"mover_weight":2.0,"use_flex":true,"ignore_gravity":false,"ignore_pretension":false,"lambda_reg":0.001,"tol":0.001,"max_iters_target":100,"g":9.81,"guy_wire_lengths":null}}
|
||||
601
ai_docs/motorstepstocartesiantest_quadratic.cpp
Normal file
601
ai_docs/motorstepstocartesiantest_quadratic.cpp
Normal file
|
|
@ -0,0 +1,601 @@
|
|||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <Matrix.h>
|
||||
#include <flex.hpp>
|
||||
#include <util.hpp>
|
||||
|
||||
// Quadratic (Halley) forward transform following Quadratic_Approximation_Approach.md,
|
||||
// specialized to a translational (T3) effector.
|
||||
|
||||
static float g_stepsPerDegree = 25.0F / 360.0F;
|
||||
|
||||
// Borrowed from hangprinter-flex-compensation (cross shaped lower anchors + top anchor)
|
||||
constexpr std::array<Point, 4> fourAnchors = {{
|
||||
{16.4F, -1610.98F, -131.53F},
|
||||
{1314.22F, 1268.14F, -121.28F},
|
||||
{-1415.73F, 707.61F, -121.82F},
|
||||
{0.0F, 0.0F, 2299.83F},
|
||||
}};
|
||||
|
||||
constexpr std::array<Point, 5> fiveAnchors = {{
|
||||
{0.0F, -2000.0F, -120.0F},
|
||||
{2000.0F, 0.0F, -120.0F},
|
||||
{0.0F, 2000.0F, -120.0F},
|
||||
{-2000.0F, 0.0F, -120.0F},
|
||||
{0.0F, 0.0F, 2000.0F},
|
||||
}};
|
||||
|
||||
static std::array<Point, HANGPRINTER_MAX_ANCHORS> activeAnchors = {
|
||||
fiveAnchors[A_AXIS], fiveAnchors[B_AXIS], fiveAnchors[C_AXIS], fiveAnchors[D_AXIS], fiveAnchors[I_AXIS]};
|
||||
static size_t activeNumAnchors = 5;
|
||||
static FlexConfig g_flexConfig{};
|
||||
static bool g_hasConfig{false};
|
||||
static size_t g_configAnchors{0};
|
||||
|
||||
static void setActiveAnchors(const std::vector<Point> &anchors) {
|
||||
activeAnchors.fill(Point{0.0F, 0.0F, 0.0F});
|
||||
activeNumAnchors = std::min(anchors.size(), static_cast<size_t>(HANGPRINTER_MAX_ANCHORS));
|
||||
for (size_t i{0}; i < activeNumAnchors; ++i) {
|
||||
activeAnchors[i] = anchors[i];
|
||||
}
|
||||
}
|
||||
|
||||
static bool parseConfigLine(const std::string &line) {
|
||||
std::istringstream iss(line);
|
||||
std::string tag;
|
||||
if (!(iss >> tag) || tag != "CFG") {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t count = 0;
|
||||
float stepsPerRev = 25.0F;
|
||||
int useFlexInt = 1;
|
||||
int ignoreGravity = 0;
|
||||
int ignorePretension = 0;
|
||||
|
||||
FlexConfig cfg{};
|
||||
if (!(iss >> count >> cfg.spoolBuildupFactor >> cfg.springKPerUnitLength >> cfg.moverWeightKg >> cfg.spoolGearTeeth >>
|
||||
cfg.motorGearTeeth >> stepsPerRev >> useFlexInt >> ignoreGravity >> ignorePretension >> cfg.lambdaReg >>
|
||||
cfg.tol >> cfg.maxItersTarget >> cfg.gravity)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cfg.ignoreGravity = ignoreGravity != 0;
|
||||
cfg.ignorePretension = ignorePretension != 0;
|
||||
cfg.stepsPerRevolution = stepsPerRev;
|
||||
cfg.providedAnchors = count;
|
||||
|
||||
auto loadArray = [&](std::array<float, HANGPRINTER_MAX_ANCHORS> &dest, bool *hasExplicit) -> bool {
|
||||
size_t const limit = std::min(count, static_cast<size_t>(HANGPRINTER_MAX_ANCHORS));
|
||||
float last = 0.0F;
|
||||
bool explicitValues = true;
|
||||
for (size_t i{0}; i < limit; ++i) {
|
||||
float val = 0.0F;
|
||||
if (!(iss >> val)) {
|
||||
return false;
|
||||
}
|
||||
if (std::isnan(val)) {
|
||||
val = 0.0F;
|
||||
explicitValues = false;
|
||||
}
|
||||
dest[i] = val;
|
||||
last = val;
|
||||
}
|
||||
if (limit > 0) {
|
||||
for (size_t i{limit}; i < HANGPRINTER_MAX_ANCHORS; ++i) {
|
||||
dest[i] = last;
|
||||
}
|
||||
}
|
||||
if (hasExplicit) {
|
||||
*hasExplicit = explicitValues;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
bool hasGuyWireLengths = true;
|
||||
if (!loadArray(cfg.spoolRadii, nullptr) || !loadArray(cfg.mechanicalAdvantage, nullptr) || !loadArray(cfg.linesPerSpool, nullptr) ||
|
||||
!loadArray(cfg.minPlannedForce, nullptr) || !loadArray(cfg.maxPlannedForce, nullptr) || !loadArray(cfg.guyWireLengths, &hasGuyWireLengths)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cfg.hasGuyWireLengths = hasGuyWireLengths && count > 0;
|
||||
|
||||
g_configAnchors = count;
|
||||
g_flexConfig = cfg;
|
||||
g_hasConfig = true;
|
||||
g_stepsPerDegree = stepsPerRev / 360.0F;
|
||||
return true;
|
||||
}
|
||||
|
||||
static Flex makeFlex(size_t numAnchors) {
|
||||
std::array<Point, HANGPRINTER_MAX_ANCHORS> anchors{};
|
||||
anchors.fill(Point{0.0F, 0.0F, 0.0F});
|
||||
size_t const limit = std::min(numAnchors, activeNumAnchors);
|
||||
for (size_t i{0}; i < limit; ++i) {
|
||||
anchors[i] = activeAnchors[i];
|
||||
}
|
||||
Flex flex{anchors, numAnchors};
|
||||
if (g_hasConfig) {
|
||||
g_flexConfig.providedAnchors = g_configAnchors;
|
||||
flex.ApplyConfig(g_flexConfig, numAnchors);
|
||||
}
|
||||
return flex;
|
||||
}
|
||||
|
||||
static std::array<float, HANGPRINTER_MAX_ANCHORS> originLengths(size_t numAnchors) {
|
||||
std::array<float, HANGPRINTER_MAX_ANCHORS> lengths{};
|
||||
lengths.fill(0.0F);
|
||||
size_t const limit = std::min(numAnchors, activeNumAnchors);
|
||||
for (size_t i = 0; i < limit; ++i) {
|
||||
lengths[i] = hyp3(activeAnchors[i], Point{0.0F, 0.0F, 0.0F});
|
||||
}
|
||||
return lengths;
|
||||
}
|
||||
|
||||
struct SolverResult {
|
||||
Point pos{0.0F, 0.0F, 0.0F};
|
||||
bool converged{false};
|
||||
size_t iterations{0};
|
||||
float cost{std::numeric_limits<float>::infinity()};
|
||||
};
|
||||
|
||||
static float residualsAndDerivatives(const std::vector<Point> &anchors, const std::vector<float> &lengths,
|
||||
const Point &pos, std::vector<float> &residuals,
|
||||
std::vector<std::array<float, 3>> &jacobian,
|
||||
std::vector<std::array<std::array<float, 3>, 3>> *hessians) {
|
||||
const size_t m = anchors.size();
|
||||
residuals.resize(m);
|
||||
jacobian.resize(m);
|
||||
if (hessians) {
|
||||
hessians->assign(m, {});
|
||||
}
|
||||
|
||||
float cost = 0.0F;
|
||||
for (size_t i = 0; i < m; ++i) {
|
||||
Point diff = pos - anchors[i];
|
||||
float len = norm(diff);
|
||||
if (len < 1e-6F) {
|
||||
len = 1e-6F;
|
||||
}
|
||||
const float invLen = 1.0F / len;
|
||||
const float invLen3 = invLen * invLen * invLen;
|
||||
|
||||
residuals[i] = len - lengths[i];
|
||||
jacobian[i] = {diff[0] * invLen, diff[1] * invLen, diff[2] * invLen};
|
||||
|
||||
if (hessians) {
|
||||
auto &H = (*hessians)[i];
|
||||
for (size_t r = 0; r < 3; ++r) {
|
||||
for (size_t c = 0; c < 3; ++c) {
|
||||
const float id = (r == c) ? invLen : 0.0F;
|
||||
H[r][c] = id - diff[r] * diff[c] * invLen3;
|
||||
}
|
||||
}
|
||||
}
|
||||
cost += 0.5F * residuals[i] * residuals[i];
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
static bool solveNormalSystem(const float JTJ[3][3], const float rhs[3], Point &delta) {
|
||||
FixedMatrix<float, 3, 4> system{};
|
||||
for (size_t r = 0; r < 3; ++r) {
|
||||
for (size_t c = 0; c < 3; ++c) {
|
||||
system(r, c) = JTJ[r][c];
|
||||
}
|
||||
system(r, 3) = rhs[r];
|
||||
}
|
||||
if (!system.GaussJordan(3, 4)) {
|
||||
return false;
|
||||
}
|
||||
delta = {system(0, 3), system(1, 3), system(2, 3)};
|
||||
return true;
|
||||
}
|
||||
|
||||
static void accumulateJtJandGrad(const std::vector<std::array<float, 3>> &J, const std::vector<float> &residuals,
|
||||
float JTJ[3][3], float grad[3]) {
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
grad[i] = 0.0F;
|
||||
for (size_t j = 0; j < 3; ++j) {
|
||||
JTJ[i][j] = 0.0F;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < J.size(); ++i) {
|
||||
grad[0] += J[i][0] * residuals[i];
|
||||
grad[1] += J[i][1] * residuals[i];
|
||||
grad[2] += J[i][2] * residuals[i];
|
||||
|
||||
JTJ[0][0] += J[i][0] * J[i][0];
|
||||
JTJ[0][1] += J[i][0] * J[i][1];
|
||||
JTJ[0][2] += J[i][0] * J[i][2];
|
||||
JTJ[1][0] += J[i][1] * J[i][0];
|
||||
JTJ[1][1] += J[i][1] * J[i][1];
|
||||
JTJ[1][2] += J[i][1] * J[i][2];
|
||||
JTJ[2][0] += J[i][2] * J[i][0];
|
||||
JTJ[2][1] += J[i][2] * J[i][1];
|
||||
JTJ[2][2] += J[i][2] * J[i][2];
|
||||
}
|
||||
}
|
||||
|
||||
static SolverResult solveHalley(const std::vector<Point> &anchors, const std::vector<float> &lengths, Point initial,
|
||||
float eta, float tol, size_t maxIters) {
|
||||
SolverResult result{};
|
||||
result.pos = initial;
|
||||
|
||||
for (size_t iter = 0; iter < maxIters; ++iter) {
|
||||
std::vector<float> residuals;
|
||||
std::vector<std::array<float, 3>> J;
|
||||
std::vector<std::array<std::array<float, 3>, 3>> H;
|
||||
result.cost = residualsAndDerivatives(anchors, lengths, result.pos, residuals, J, &H);
|
||||
|
||||
float JTJ[3][3];
|
||||
float grad[3];
|
||||
accumulateJtJandGrad(J, residuals, JTJ, grad);
|
||||
JTJ[0][0] += eta;
|
||||
JTJ[1][1] += eta;
|
||||
JTJ[2][2] += eta;
|
||||
|
||||
Point deltaLm{};
|
||||
float rhs1[3] = {-grad[0], -grad[1], -grad[2]};
|
||||
if (!solveNormalSystem(JTJ, rhs1, deltaLm)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Build Hbar rows = delta^T * H_i
|
||||
std::vector<std::array<float, 3>> Hbar(J.size());
|
||||
for (size_t i = 0; i < J.size(); ++i) {
|
||||
Hbar[i][0] = deltaLm[0] * H[i][0][0] + deltaLm[1] * H[i][1][0] + deltaLm[2] * H[i][2][0];
|
||||
Hbar[i][1] = deltaLm[0] * H[i][0][1] + deltaLm[1] * H[i][1][1] + deltaLm[2] * H[i][2][1];
|
||||
Hbar[i][2] = deltaLm[0] * H[i][0][2] + deltaLm[1] * H[i][1][2] + deltaLm[2] * H[i][2][2];
|
||||
}
|
||||
|
||||
std::vector<std::array<float, 3>> Jbar(J.size());
|
||||
for (size_t i = 0; i < J.size(); ++i) {
|
||||
Jbar[i][0] = J[i][0] + 0.5F * Hbar[i][0];
|
||||
Jbar[i][1] = J[i][1] + 0.5F * Hbar[i][1];
|
||||
Jbar[i][2] = J[i][2] + 0.5F * Hbar[i][2];
|
||||
}
|
||||
|
||||
float JTJ2[3][3];
|
||||
float grad2[3];
|
||||
accumulateJtJandGrad(Jbar, residuals, JTJ2, grad2);
|
||||
JTJ2[0][0] += eta;
|
||||
JTJ2[1][1] += eta;
|
||||
JTJ2[2][2] += eta;
|
||||
|
||||
Point delta{};
|
||||
float rhs2[3] = {-grad2[0], -grad2[1], -grad2[2]};
|
||||
if (!solveNormalSystem(JTJ2, rhs2, delta)) {
|
||||
break;
|
||||
}
|
||||
|
||||
++result.iterations;
|
||||
result.pos = result.pos + delta;
|
||||
if (norm(delta) < tol) {
|
||||
result.converged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh cost at the final pose
|
||||
std::vector<float> residuals;
|
||||
std::vector<std::array<float, 3>> Jtmp;
|
||||
result.cost = residualsAndDerivatives(anchors, lengths, result.pos, residuals, Jtmp, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
static SolverResult solveHybrid(const std::vector<Point> &anchors, const std::vector<float> &lengths, Point initial,
|
||||
float eta, float tol, size_t halleyIters, size_t maxIters) {
|
||||
SolverResult result{};
|
||||
result.pos = initial;
|
||||
|
||||
size_t iter = 0;
|
||||
for (; iter < halleyIters && iter < maxIters; ++iter) {
|
||||
std::vector<float> residuals;
|
||||
std::vector<std::array<float, 3>> J;
|
||||
std::vector<std::array<std::array<float, 3>, 3>> H;
|
||||
result.cost = residualsAndDerivatives(anchors, lengths, result.pos, residuals, J, &H);
|
||||
|
||||
float JTJ[3][3];
|
||||
float grad[3];
|
||||
accumulateJtJandGrad(J, residuals, JTJ, grad);
|
||||
JTJ[0][0] += eta;
|
||||
JTJ[1][1] += eta;
|
||||
JTJ[2][2] += eta;
|
||||
|
||||
Point deltaLm{};
|
||||
float rhs1[3] = {-grad[0], -grad[1], -grad[2]};
|
||||
if (!solveNormalSystem(JTJ, rhs1, deltaLm)) {
|
||||
break;
|
||||
}
|
||||
|
||||
std::vector<std::array<float, 3>> Hbar(J.size());
|
||||
for (size_t i = 0; i < J.size(); ++i) {
|
||||
Hbar[i][0] = deltaLm[0] * H[i][0][0] + deltaLm[1] * H[i][1][0] + deltaLm[2] * H[i][2][0];
|
||||
Hbar[i][1] = deltaLm[0] * H[i][0][1] + deltaLm[1] * H[i][1][1] + deltaLm[2] * H[i][2][1];
|
||||
Hbar[i][2] = deltaLm[0] * H[i][0][2] + deltaLm[1] * H[i][1][2] + deltaLm[2] * H[i][2][2];
|
||||
}
|
||||
|
||||
std::vector<std::array<float, 3>> Jbar(J.size());
|
||||
for (size_t i = 0; i < J.size(); ++i) {
|
||||
Jbar[i][0] = J[i][0] + 0.5F * Hbar[i][0];
|
||||
Jbar[i][1] = J[i][1] + 0.5F * Hbar[i][1];
|
||||
Jbar[i][2] = J[i][2] + 0.5F * Hbar[i][2];
|
||||
}
|
||||
|
||||
float JTJ2[3][3];
|
||||
float grad2[3];
|
||||
accumulateJtJandGrad(Jbar, residuals, JTJ2, grad2);
|
||||
JTJ2[0][0] += eta;
|
||||
JTJ2[1][1] += eta;
|
||||
JTJ2[2][2] += eta;
|
||||
|
||||
Point delta{};
|
||||
float rhs2[3] = {-grad2[0], -grad2[1], -grad2[2]};
|
||||
if (!solveNormalSystem(JTJ2, rhs2, delta)) {
|
||||
break;
|
||||
}
|
||||
|
||||
result.pos = result.pos + delta;
|
||||
result.iterations = iter + 1;
|
||||
if (norm(delta) < tol) {
|
||||
result.converged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (; iter < maxIters && !result.converged; ++iter) {
|
||||
std::vector<float> residuals;
|
||||
std::vector<std::array<float, 3>> J;
|
||||
result.cost = residualsAndDerivatives(anchors, lengths, result.pos, residuals, J, nullptr);
|
||||
|
||||
float JTJ[3][3];
|
||||
float grad[3];
|
||||
accumulateJtJandGrad(J, residuals, JTJ, grad);
|
||||
JTJ[0][0] += eta;
|
||||
JTJ[1][1] += eta;
|
||||
JTJ[2][2] += eta;
|
||||
|
||||
Point delta{};
|
||||
float rhs3[3] = {-grad[0], -grad[1], -grad[2]};
|
||||
if (!solveNormalSystem(JTJ, rhs3, delta)) {
|
||||
break;
|
||||
}
|
||||
|
||||
result.pos = result.pos + delta;
|
||||
result.iterations = iter + 1;
|
||||
if (norm(delta) < tol) {
|
||||
result.converged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<float> residuals;
|
||||
std::vector<std::array<float, 3>> Jtmp;
|
||||
result.cost = residualsAndDerivatives(anchors, lengths, result.pos, residuals, Jtmp, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
static SolverResult solveLm(const std::vector<Point> &anchors, const std::vector<float> &lengths, Point initial,
|
||||
float eta, float tol, size_t maxIters) {
|
||||
SolverResult result{};
|
||||
result.pos = initial;
|
||||
|
||||
for (size_t iter = 0; iter < maxIters; ++iter) {
|
||||
std::vector<float> residuals;
|
||||
std::vector<std::array<float, 3>> J;
|
||||
result.cost = residualsAndDerivatives(anchors, lengths, result.pos, residuals, J, nullptr);
|
||||
|
||||
float JTJ[3][3];
|
||||
float grad[3];
|
||||
accumulateJtJandGrad(J, residuals, JTJ, grad);
|
||||
JTJ[0][0] += eta;
|
||||
JTJ[1][1] += eta;
|
||||
JTJ[2][2] += eta;
|
||||
|
||||
Point delta{};
|
||||
float rhs[3] = {-grad[0], -grad[1], -grad[2]};
|
||||
if (!solveNormalSystem(JTJ, rhs, delta)) {
|
||||
break;
|
||||
}
|
||||
|
||||
result.pos = result.pos + delta;
|
||||
result.iterations = iter + 1;
|
||||
if (norm(delta) < tol) {
|
||||
result.converged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<float> residuals;
|
||||
std::vector<std::array<float, 3>> Jtmp;
|
||||
result.cost = residualsAndDerivatives(anchors, lengths, result.pos, residuals, Jtmp, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::vector<float> motorPosToLengths(const Flex &flex, const std::array<float, HANGPRINTER_MAX_ANCHORS> &motorPos,
|
||||
const std::array<float, HANGPRINTER_MAX_ANCHORS> &origins, size_t numAnchors) {
|
||||
std::vector<float> lengths(numAnchors, 0.0F);
|
||||
for (size_t i = 0; i < numAnchors; ++i) {
|
||||
const float steps = motorPos[i] * g_stepsPerDegree;
|
||||
lengths[i] = flex.MotorPosToLinePos(steps, i) + origins[i];
|
||||
}
|
||||
return lengths;
|
||||
}
|
||||
|
||||
#ifndef RUN_DATASET_CLI
|
||||
int main() {
|
||||
constexpr size_t numAnchors = 5;
|
||||
Flex const flex = makeFlex(numAnchors);
|
||||
auto const origins = originLengths(numAnchors);
|
||||
|
||||
// Dataset from motorstepstocartesiantest.cpp ("With flex max 120 target 20")
|
||||
std::vector<std::array<float, numAnchors>> motorPoss = {
|
||||
{-369.47366890F, -375.18362935F, 318.27641438F, 323.88876891F, 1076.68163402F},
|
||||
{-5980.29607895F, 12630.56774248F, 12288.67350302F, -6506.18962476F, -13348.06053879F},
|
||||
{-2353.64278337F, 15870.99892165F, 15755.46225500F, -2522.71380922F, -27477.49741579F},
|
||||
{1433.28912224F, 10685.68516553F, 1454.31086905F, -10542.99803343F, 1813.47411829F},
|
||||
{3112.53568603F, 11779.51141393F, 3231.55807349F, -7609.55533435F, -17364.20990461F},
|
||||
{7221.24317502F, 14331.47424095F, 6657.95387927F, -1853.21287105F, -36135.10874008F},
|
||||
{10106.78583366F, 10693.29200030F, -7583.66231627F, -8505.26876850F, 6010.84493879F},
|
||||
{11680.14400927F, 12421.57492733F, -5209.71780789F, -6326.70127134F, -14780.55685279F},
|
||||
{16309.54520647F, 16482.81831770F, -1424.01387322F, -1674.11174073F, -29909.99659944F},
|
||||
{-10145.44532568F, 1094.96136691F, 10156.51947369F, 1434.73615456F, 3572.60726310F},
|
||||
{-7640.99960502F, 3134.81886277F, 11567.99443696F, 2933.32488052F, -16735.05779004F},
|
||||
{-2825.34894707F, 7163.91339055F, 14266.90144144F, 5840.37464568F, -33865.11200386F},
|
||||
{-7448.08057312F, 10796.70751776F, 10151.74389637F, -8459.78905687F, 3271.18757879F},
|
||||
{2211.41905092F, 2111.20882241F, 858.18022603F, 961.42598207F, -17727.66189890F},
|
||||
{6585.49993026F, 5349.29768666F, 5599.61645498F, 6829.22955353F, -40179.35611831F},
|
||||
{9827.26906637F, 973.41612678F, -9847.89764725F, 1374.65365736F, 4088.32777321F},
|
||||
{11672.37320821F, 3419.76976053F, -7745.30493425F, 2691.62201517F, -16638.39998295F},
|
||||
{13421.03929287F, 6834.73758758F, -2414.14469240F, 5523.60605573F, -33907.52745615F},
|
||||
{-8153.62357389F, -7386.54442994F, 10370.98726659F, 9875.86705528F, 3214.03835550F},
|
||||
{-6347.85480184F, -5493.48884529F, 12625.31736324F, 12063.42984255F, -14568.06462464F},
|
||||
{-2585.49492187F, -1676.70121477F, 15851.52670557F, 15223.11520330F, -28367.04177068F},
|
||||
{730.23171944F, -9759.54189457F, 1580.93148691F, 9745.76583762F, 3967.14372473F},
|
||||
{2429.55959648F, -7123.34974121F, 3539.66195357F, 11159.52316296F, -17372.69974680F},
|
||||
{6079.30436810F, -2972.78187516F, 7172.81870678F, 14578.78537233F, -33851.97153806F},
|
||||
{11195.81863308F, -7791.69855043F, -8587.42819506F, 10696.72883673F, 3279.60983059F},
|
||||
{12162.75651477F, -6552.47720614F, -6177.61954587F, 12406.22670936F, -12538.57963324F},
|
||||
{14653.37178962F, -2366.53557957F, -1021.48237225F, 15599.48126071F, -29623.47054342F},
|
||||
};
|
||||
|
||||
std::vector<Point> expectedPoss = {
|
||||
{17.9255679F, -17.6352632F, -27.497151F},
|
||||
{-523.885148F, -501.061599F, 507.741532F},
|
||||
{-538.35251F, -530.255594F, 953.040004F},
|
||||
{-545.189816F, -0.55803779F, 26.4689901F},
|
||||
{-520.999273F, -3.27341154F, 537.019049F},
|
||||
{-470.799477F, 16.5498517F, 1047.17018F},
|
||||
{-505.362595F, 467.529134F, -42.5453256F},
|
||||
{-513.234032F, 464.122399F, 533.480869F},
|
||||
{-538.29312F, 526.060302F, 1030.39159F},
|
||||
{8.98405788F, -520.642383F, -26.6148823F},
|
||||
{-5.52678502F, -514.840431F, 517.628213F},
|
||||
{-38.6000122F, -492.617793F, 991.936222F},
|
||||
{-507.629503F, -465.97604F, 31.7537695F},
|
||||
{-30.5601452F, 35.9665477F, 458.719776F},
|
||||
{43.2898928F, 28.8400594F, 1046.72968F},
|
||||
{10.5874156F, 504.407891F, -44.2588518F},
|
||||
{-19.9804722F, 520.41744F, 517.004705F},
|
||||
{-37.9958866F, 454.266612F, 975.222737F},
|
||||
{455.930483F, -487.688259F, 26.0515823F},
|
||||
{482.712486F, -520.125685F, 535.481389F},
|
||||
{495.517745F, -539.35609F, 965.228753F},
|
||||
{500.096373F, -22.437457F, -42.0139801F},
|
||||
{490.657689F, -30.4215669F, 527.319817F},
|
||||
{506.742907F, -31.9689121F, 998.360926F},
|
||||
{490.590662F, 523.118645F, 41.4092948F},
|
||||
{517.848381F, 501.639033F, 482.878157F},
|
||||
{525.399857F, 459.863258F, 981.665044F},
|
||||
};
|
||||
|
||||
float totalErrHalley = 0.0F;
|
||||
float totalErrHybrid = 0.0F;
|
||||
float totalErrLm = 0.0F;
|
||||
|
||||
std::cout << "idx, halley_err(mm), hybrid_err(mm), lm_err(mm), halley_it, hybrid_it, lm_it\n";
|
||||
Point seed{0.0F, 0.0F, 0.0F};
|
||||
for (size_t i = 0; i < motorPoss.size(); ++i) {
|
||||
auto lengths = motorPosToLengths(flex, motorPoss[i], origins, numAnchors);
|
||||
std::vector<Point> anchorVec;
|
||||
anchorVec.reserve(numAnchors);
|
||||
for (size_t k = 0; k < numAnchors; ++k) {
|
||||
anchorVec.push_back(fiveAnchors[k]);
|
||||
}
|
||||
|
||||
SolverResult halley = solveHalley(anchorVec, lengths, seed, 1e-3F, 1e-3F, 20);
|
||||
SolverResult hybrid = solveHybrid(anchorVec, lengths, seed, 1e-3F, 1e-3F, 3, 30);
|
||||
SolverResult lm = solveLm(anchorVec, lengths, seed, 1e-3F, 1e-3F, 30);
|
||||
|
||||
Point halleyErr = expectedPoss[i] - halley.pos;
|
||||
Point hybridErr = expectedPoss[i] - hybrid.pos;
|
||||
Point lmErr = expectedPoss[i] - lm.pos;
|
||||
float halleyNorm = norm(halleyErr);
|
||||
float hybridNorm = norm(hybridErr);
|
||||
float lmNorm = norm(lmErr);
|
||||
totalErrHalley += halleyNorm;
|
||||
totalErrHybrid += hybridNorm;
|
||||
totalErrLm += lmNorm;
|
||||
|
||||
std::cout << i << ", " << halleyNorm << ", " << hybridNorm << ", " << lmNorm << ", " << halley.iterations << ", "
|
||||
<< hybrid.iterations << ", " << lm.iterations << '\n';
|
||||
|
||||
// Warm start from previous pose to mirror controller behaviour
|
||||
seed = halley.pos;
|
||||
}
|
||||
|
||||
const float n = static_cast<float>(motorPoss.size());
|
||||
std::cout << "Mean error (Halley): " << (totalErrHalley / n) << " mm\n";
|
||||
std::cout << "Mean error (Hybrid Halley->LM): " << (totalErrHybrid / n) << " mm\n";
|
||||
std::cout << "Mean error (LM baseline): " << (totalErrLm / n) << " mm\n";
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int main() {
|
||||
std::ios::sync_with_stdio(false);
|
||||
std::string line;
|
||||
while (std::getline(std::cin, line)) {
|
||||
if (line.empty()) {
|
||||
continue;
|
||||
}
|
||||
if (line.rfind("CFG", 0) == 0) {
|
||||
parseConfigLine(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::istringstream iss(line);
|
||||
size_t numAnchors = 0;
|
||||
int useFlexInt = 1;
|
||||
if (!(iss >> numAnchors >> useFlexInt)) {
|
||||
std::cout << "fail 0 0 0 0 0 0\n";
|
||||
continue;
|
||||
}
|
||||
if (numAnchors == 0 || numAnchors > HANGPRINTER_MAX_ANCHORS) {
|
||||
std::cout << "fail 0 0 0 0 0 0\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
std::array<float, HANGPRINTER_MAX_ANCHORS> motorPos{};
|
||||
motorPos.fill(0.0F);
|
||||
for (size_t i{0}; i < numAnchors; ++i) {
|
||||
if (!(iss >> motorPos[i])) {
|
||||
std::cout << "fail 0 0 0 0 0 0\n";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Point> anchors(numAnchors);
|
||||
for (size_t i{0}; i < numAnchors; ++i) {
|
||||
if (!(iss >> anchors[i][0] >> anchors[i][1] >> anchors[i][2])) {
|
||||
std::cout << "fail 0 0 0 0 0 0\n";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
setActiveAnchors(anchors);
|
||||
|
||||
Flex const flex = makeFlex(numAnchors);
|
||||
auto const origins = originLengths(numAnchors);
|
||||
auto lengths = motorPosToLengths(flex, motorPos, origins, numAnchors);
|
||||
std::vector<Point> anchorVec = anchors;
|
||||
|
||||
Point seed{0.0F, 0.0F, 0.0F};
|
||||
auto const start = std::chrono::steady_clock::now();
|
||||
SolverResult hybrid = solveHybrid(anchorVec, lengths, seed, 1e-3F, 1e-3F, 3, 30);
|
||||
auto const end = std::chrono::steady_clock::now();
|
||||
double const ms = std::chrono::duration<double, std::milli>(end - start).count();
|
||||
|
||||
std::cout << (hybrid.converged ? "ok" : "fail") << ' ' << hybrid.pos[0] << ' ' << hybrid.pos[1] << ' '
|
||||
<< hybrid.pos[2] << ' ' << hybrid.iterations << ' ' << hybrid.cost << ' ' << ms << '\n';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue