Class UnderlayDwfDefinition
Represents a DWF underlay definition.
Implements
System.ICloneable
System.IComparable
System.IComparable<TableObject>
System.IEquatable<TableObject>
Inherited Members
System.Object.Equals(System.Object, System.Object)
System.Object.GetType()
System.Object.MemberwiseClone()
System.Object.ReferenceEquals(System.Object, System.Object)
Namespace: netDxf.Objects
Assembly: CADability.dll
Syntax
public class UnderlayDwfDefinition : UnderlayDefinition, IHasXData, ICloneable, IComparable, IComparable<TableObject>, IEquatable<TableObject>
Constructors
| Improve this Doc View SourceUnderlayDwfDefinition(String)
Initializes a new instance of the UnderlayDwfDefinition
class.
Declaration
public UnderlayDwfDefinition(string file)
Parameters
| Type | Name | Description |
|---|---|---|
| System.String | file | Underlay file name with full or relative path. |
UnderlayDwfDefinition(String, String)
Initializes a new instance of the UnderlayDwfDefinition
class.
Declaration
public UnderlayDwfDefinition(string name, string file)
Parameters
| Type | Name | Description |
|---|---|---|
| System.String | name | Underlay definition name. |
| System.String | file | Underlay file name with full or relative path. |
Properties
| Improve this Doc View SourceOwner
Gets the owner of the actual underlay DWF definition.
Declaration
public UnderlayDwfDefinitions Owner { get; }
Property Value
| Type | Description |
|---|---|
| UnderlayDwfDefinitions |
Methods
| Improve this Doc View SourceClone()
Creates a new UnderlayDwfDefinition that is a copy of the current instance.
Declaration
public override object Clone()
Returns
| Type | Description |
|---|---|
| System.Object | A new UnderlayDwfDefinition that is a copy of this instance. |
Overrides
| Improve this Doc View SourceClone(String)
Creates a new UnderlayDwfDefinition that is a copy of the current instance.
Declaration
public override TableObject Clone(string newName)
Parameters
| Type | Name | Description |
|---|---|---|
| System.String | newName | UnderlayDwfDefinition name of the copy. |
Returns
| Type | Description |
|---|---|
| TableObject | A new UnderlayDwfDefinition that is a copy of this instance. |
Overrides
Implements
System.ICloneable
System.IComparable
System.IComparable<T>
System.IEquatable<T>


Programming
Coursera Data Science Specialization
I am currrently working on the Capstone Project for this specialization. Here are some projects from later courses (using R and Shiny):
Capstone Project: Practical Machine Learning: Developing Data Products: Reproducible Research:Django Tutorial Projects
Dev Bootcamp Phase 3
For our final project, I worked on the team that put together a dating site for web developers:
Dev Bootcamp Phase 0
Mathematics
In my dissertation, I am trying to develop a simplicial model for various link homology theories (e.g. Khovanov homology). This is where I will post anything related to my research.
Here is an outline, written by my advisor Louis Kauffman, of the project I was engaged in.
Simplicial Homotopy Theory, Link Homology, and Khovanov Homology


Algorithms for Walking, Running, Swimming, Flying, and Manipulation
© Russ Tedrake, 2023
Last modified .
How to cite these notes, use annotations, and give feedback.
Note: These are working notes used for a course being taught at MIT. They will be updated throughout the Spring 2023 semester. Lecture videos are available on YouTube.
| Previous Chapter | Table of contents | Next Chapter |
While solving the dynamic programming problem for continuous systems is very hard in general, there are a few very important special cases where the solutions are very accessible. Most of these involve variants on the case of linear dynamics and quadratic cost. The simplest case, called the linear quadratic regulator (LQR), is formulated as stabilizing a time-invariant linear system to the origin.
The linear quadratic regulator is likely the most important and influential result in optimal control theory to date. In this chapter we will derive the basic algorithm and a variety of useful extensions.
Consider a linear time-invariant system in state-space form, $$\dot{\bx} = {\bf A}\bx + \bB\bu,$$ with the infinite-horizon cost function given by $$J = \int_0^\infty \left[ \bx^T {\bf Q} \bx + \bu^T {\bf R} \bu \right] dt, \quad {\bf Q} = {\bf Q}^T \succeq {\bf 0}, {\bf R} = {\bf R}^T \succ 0.$$ Our goal is to find the optimal cost-to-go function $J^*(\bx)$ which satisfies the HJB: $$\forall \bx, \quad 0 = \min_\bu \left[ \bx^T {\bf Q} \bx + \bu^T {\bf R} \bu + \pd{J^*}{\bx} \left( {\bf A}\bx + \bB\bu \right) \right].$$
There is one important step here -- it is well known that for this problem the optimal cost-to-go function is quadratic. This is easy to verify. Let us choose the form: $$J^*(\bx) = \bx^T {\bf S} \bx, \quad {\bf S} = {\bf S}^T \succeq 0.$$ The gradient of this function is $$\pd{J^*}{\bx} = 2 \bx^T {\bf S}.$$
Since we have guaranteed, by construction, that the terms inside the $\min$ are quadratic and convex (because ${\bf R} \succ 0$), we can take the minimum explicitly by finding the solution where the gradient of those terms vanishes: $$\pd{}{\bu} = 2\bu^T {\bf R} + 2 \bx^T {\bf S} \bB = 0.$$ This yields the optimal policy $$\bu^* = \pi^*(\bx) = - {\bf R}^{-1} \bB^T {\bf S} \bx = - \bK \bx.$$
Inserting this back into the HJB and simplifying yields $$0 = \bx^T
\left[ {\bf Q} - {\bf S B R}^{-1}\bB^T{\bf S} + 2{\bf SA} \right]\bx.$$ All
of the terms here are symmetric except for the $2{\bf SA}$, but since
$\bx^T{\bf SA}\bx = \bx^T{\bf A}^T{\bf S}\bx$, we can write $$0 = \bx^T
\left[ {\bf Q} - {\bf S B R}^{-1}\bB^T{\bf S} + {\bf SA} + {\bf A}^T{\bf S}
\right]\bx.$$ and since this condition must hold for all $\bx$, it is
sufficient to consider the matrix equation $$0 = {\bf S} {\bf A} + {\bf A}^T
{\bf S} - {\bf S} \bB {\bf R}^{-1} \bB^T {\bf S} + {\bf Q}.$$ This extremely
important equation is a version of the algebraic Riccati equation.
Note that it is quadratic in ${\bf S}$, making its solution non-trivial, but
it is well known that the equation has a single positive-definite solution
if and only if the system is controllable and there are good numerical
methods for finding that solution, even in high-dimensional problems. Both
the optimal policy and optimal cost-to-go function are available from
(K,S) =
LinearQuadraticRegulator(A,B,Q,R)
.
If the appearance of the quadratic form of the cost-to-go seemed mysterious, consider that the solution to the linear system $\dot\bx = (\bA - \bB\bK)\bx$ takes the form $\bx(t) = e^{(\bA-\bB\bK)t}\bx(0)$, and try inserting this back into the integral cost function. You'll see that the cost takes the form $J=\bx^T(0) {\bf S} \bx(0)$.
It is worth examining the form of the optimal policy more closely. Since the value function represents cost-to-go, it would be sensible to move down this landscape as quickly as possible. Indeed, $-{\bf S}\bx$ is in the direction of steepest descent of the value function. However, not all directions are possible to achieve in state-space. $-\bB^T {\bf S} \bx$ represents precisely the projection of the steepest descent onto the control space, and is the steepest descent achievable with the control inputs $\bu$. Finally, the pre-scaling by the matrix ${\bf R}^{-1}$ biases the direction of descent to account for relative weightings that we have placed on the different control inputs. Note that although this interpretation is straight-forward, the slope that we are descending (in the value function, ${\bf S}$) is a complicated function of the dynamics and cost.
Now we can use LQR to reproduce our HJB example from the previous chapter:
import numpy as np
from pydrake.all import LinearQuadraticRegulator
# Define the double integrator's state space matrices.
A = np.array([[0, 1], [0, 0]])
B = np.array([[0], [1]])
Q = np.eye(2)
R = np.eye(1)
(K, S) = LinearQuadraticRegulator(A, B, Q, R)
print("K = " + str(K))
print("S = " + str(S))
As in the hand-derived example, our numerical solution returns $${\bf K} = [ 1, \sqrt{3} ], \qquad{\bf S} = \begin{bmatrix} \sqrt{3} & 1 \\ 1 & \sqrt{3} \end{bmatrix}.$$
LQR is extremely relevant to us even though our primary interest is in nonlinear dynamics, because it can provide a local approximation of the optimal control solution for the nonlinear system. Given the nonlinear system $\dot{\bx} = f(\bx,\bu)$, and a stabilizable operating point, $(\bx_0,\bu_0)$, with $f(\bx_0,\bu_0) = 0.$ We can define a relative coordinate system $$\bar\bx = \bx - \bx_0, \quad \bar\bu = \bu - \bu_0,$$ and observe that $$\dot{\bar\bx} = \dot{\bx} = f(\bx,\bu),$$ which we can approximate with a first-order Taylor expansion to $$\dot{\bar\bx} \approx f(\bx_0,\bu_0) + \pd{f(\bx_0,\bu_0)}{\bx} (\bx - \bx_0) + \pd{f(\bx_0,\bu_0)}{\bu} (\bu - \bu_0) = {\bf A}\bar{\bx} + \bB\bar\bu.$$
Similarly, we can define a quadratic cost function in the error coordinates, or take a (positive-definite) second-order approximation of a nonlinear cost function about the operating point (linear and constant terms in the cost function can be easily incorporated into the derivation by parameterizing a full quadratic form for $J^*$, as seen in the Linear Quadratic Tracking derivation below).
The resulting controller takes the form $\bar\bu^* = -{\bf K}\bar\bx$
or $$\bu^* = \bu_0 - {\bf K} (\bx - \bx_0).$$ For convenience,
controller =
LinearQuadraticRegulator(system, context, Q, R)
on most dynamical
systems (including block diagrams built up of many subsystems); it will
perform the linearization for you.
LQR provides a very satisfying solution to the canonical "balancing" problem that we've already described for a number of model systems. Here is the notebook with those examples, again:
I find it very compelling that the same derivation (and effectively identical code) can stabilize such a diversity of systems!
Recall that the cost-to-go for finite-horizon problems is time-dependent, and therefore the HJB sufficiency condition requires an additional term for $\pd{J^*}{t}$. $$ \forall \bx, \forall t\in[t_0,t_f],\quad 0 = \min_\bu \left[ \ell(\bx,\bu) + \pd{J^*}{\bx}f(\bx,\bu) + \pd{J^*}{t} \right]. $$
Consider systems governed by an LTI state-space equation of the form $$\dot{\bx} = {\bf A}\bx + \bB\bu,$$ and a finite-horizon cost function, $J = h(\bx(t_f)) + \int_0^{t_f} \ell(\bx(t), \bu(t)) dt,$ with \begin{gather*} h(\bx) = \bx^T {\bf Q}_f \bx,\quad {\bf Q}_f = {\bf Q}_f^T \succeq {\bf 0} \\ \ell(\bx,\bu) = \bx^T {\bf Q} \bx + \bu^T {\bf R} \bu, \quad {\bf Q} = {\bf Q}^T \succeq 0, {\bf R}={\bf R}^T \succ 0 \end{gather*} Writing the HJB, we have $$ 0 = \min_\bu \left[\bx^T {\bf Q} \bx + \bu^T {\bf R}\bu + \pd{J^*}{\bx} \left({\bf A} \bx + \bB \bu \right) + \pd{J^*}{t} \right]. $$ Due to the positive definite quadratic form on $\bu$, we can find the minimum by setting the gradient to zero: \begin{gather*} \pd{}{\bu} = 2 \bu^T {\bf R} + \pd{J^*}{\bx} \bB = 0 \\ \bu^* = \pi^*(\bx,t) = - \frac{1}{2}{\bf R}^{-1} \bB^T \pd{J^*}{\bx}^T \end{gather*} In order to proceed, we need to investigate a particular form for the cost-to-go function, $J^*(\bx,t)$. Let's try a solution of the form: $$J^*(\bx,t) = \bx^T {\bf S}(t) \bx, \quad {\bf S}(t) = {\bf S}^T(t)\succ {\bf 0}.$$ In this case we have $$\pd{J^*}{\bx} = 2 \bx^T {\bf S}(t), \quad \pd{J*}{t} = \bx^T \dot{\bf S}(t) \bx,$$ and therefore \begin{gather*} \bu^* = \pi^*(\bx,t) = - {\bf R}^{-1} \bB^T {\bf S}(t) \bx \\ 0 = \bx^T \left[ {\bf Q} - {\bf S}(t) \bB {\bf R}^{-1} \bB^T {\bf S}(t) + {\bf S}(t) {\bf A} + {\bf A}^T {\bf S}(t) + \dot{\bf S}(t) \right] \bx.\end{gather*} Therefore, ${\bf S}(t)$ must satisfy the condition (known as the continuous-time differential Riccati equation): $$-\dot{\bf S}(t) = {\bf S}(t) {\bf A} + {\bf A}^T {\bf S}(t) - {\bf S}(t) \bB {\bf R}^{-1} \bB^T {\bf S}(t) + {\bf Q},$$ and the terminal condition $${\bf S}(t_f) = {\bf Q}_f.$$ Since we were able to satisfy the HJB with the minimizing policy, we have met the sufficiency condition, and have found the optimal policy and optimal cost-to-go function.
Note that the infinite-horizon LQR solution described in the prequel is exactly the steady-state solution of this equation, defined by $\dot{\bf S}(t) = 0$. Indeed, for controllable systems this equation is stable (backwards in time), and as expected the finite-horizon solution converges on the infinite-horizon solution as the horizon time limits to infinity.
The solution ${\bf S}(t)$ will be the result of numerical integration. On weakly controllable systems (like the perching airplane), I've found that even error-controlled integration can lead to crippling numerical artifacts such as the loss of symmetry or positive definiteness. For a more robust numerical solution, we can instead integrate a factorization of ${\bf S}$ that ensures these properties are maintained. Taking ${\bf S}(t) = {\bf P}(t){\bf P}^T(t)$, and again using the fact that $\bx^T{\bf P}\dot{\bf P}^T\bx = \bx^T\dot{\bf P}{\bf P}^T \bx$, we can write the "square-root form" of the Riccati differential equation: $$-\dot{\bf P}(t) = \bA^T {\bf P}(t) - \frac{1}{2}{\bf S}(t)\bB{\bf R}^{-1}\bB^T{\bf P}(t) + \frac{1}{2}{\bf Q}{\bf P}^{-T}(t), \quad {\bf P}(t_f) = {\bf Q}_f^\frac{1}{2}.$$ This form does require that ${\bf P}(t)$ is invertible, which in turn requires that ${\bf Q}_f \succ 0.$
The derivation above holds even if the dynamics are given by $$\dot{\bx} = {\bf A}(t)\bx + {\bf B(t)}\bu.$$ Similarly, the cost functions ${\bf Q}$ and ${\bf R}$ can also be time-varying. This is quite surprising, as the class of time-varying linear systems is a quite general class of systems. It requires essentially no assumptions on how the time-dependence enters, except perhaps that if ${\bf A}$ or $\bB$ is discontinuous in time then one would have to use the proper techniques to accurately integrate the differential equation.
One of the most powerful applications of time-varying LQR involves linearizing around a nominal trajectory of a nonlinear system and using LQR to provide a trajectory controller. This will tie in very nicely with the algorithms we develop in the chapter on trajectory optimization.
Let us assume that we have a nominal trajectory, $\bx_0(t), \bu_0(t)$ defined for $t \in [t_1, t_2]$. Similar to the time-invariant analysis, we begin by defining a local coordinate system relative to the trajectory: $$\bar\bx(t) = \bx(t) - \bx_0(t), \quad \bar\bu(t) = \bu(t) - \bu_0(t).$$ Now we have $$\dot{\bar\bx} = \dot{\bx} - \dot{\bx}_0 = f(\bx,\bu) - f(\bx_0, \bu_0),$$ which we can again approximate with a first-order Taylor expansion to $$\dot{\bar\bx} \approx f(\bx_0,\bu_0) + \pd{f(\bx_0,\bu_0)}{\bx} (\bx - \bx_0) + \pd{f(\bx_0,\bu_0)}{\bu} (\bu - \bu_0) - f(\bx_0,\bu_0) = {\bf A}(t)\bar{\bx} + \bB(t)\bar\bu.$$ This is very similar to using LQR to stabilize a fixed-point, but with some important differences. First, the linearization is time-varying. Second, our linearization is valid for any state along a feasible trajectory (not just fixed-points), because the coordinate system is moving along with the trajectory.
Similarly, we can define a quadratic cost function in the error coordinates, or take a (positive-definite) second-order approximation of a nonlinear cost function along the trajectory (linear and constant terms in the cost function can be easily incorporated into the derivation by parameterizing a full quadratic form for $J^*$, as seen in the Linear Quadratic Tracking derivation below).
The resulting controller takes the form $\bar\bu^* = -{\bf
K}(t)\bar\bx$ or $$\bu^* = \bu_0(t) - {\bf K}(t) (\bx - \bx_0(t)).$$
FiniteHorizonLinearQuadraticRegulator
method; if you pass it a nonlinear systems it will perform the
linearization in the proper coordinates for you using automatic
differentiation.
Remember that stability is a statement about what happens as time goes to infinity. In order to talk about stabilizing a trajectory, the trajectory must be defined for all $t \in [t_1, \infty)$. This can be accomplished by considering a finite-time trajectory which terminates at a stabilizable fixed-point at a time $t_2 \ge t_1$, and remains at the fixed point for $t \ge t_2$. In this case, the finite-horizon Riccati equation is initialized with the infinite-horizon LQR solution: $S(t_2) = S_\infty$, and solved backwards in time from $t_2$ to $t_1$ for the remainder of the trajectory. And now we can say that we have stabilized the trajectory!
For completeness, we consider a slightly more general form of the linear quadratic regulator. The standard LQR derivation attempts to drive the system to zero. Consider now the problem: \begin{gather*} \dot{\bx} = {\bf A}\bx + \bB\bu \\ h(\bx) = (\bx - \bx_d(t_f))^T {\bf Q}_f (\bx - \bx_d(t_f)), \quad {\bf Q}_f = {\bf Q}_f^T \succeq 0 \\ \ell(\bx,\bu,t) = (\bx - \bx_d(t))^T {\bf Q} (\bx - \bx_d(t)) + (\bu - \bu_d(t))^T {\bf R} (\bu - \bu_d(t)),\\ {\bf Q} = {\bf Q}^T \succeq 0, {\bf R}={\bf R}^T \succ 0 \end{gather*} Now, guess a solution \begin{gather*} J^*(\bx,t) = \bx^T {\bf S}_{xx}(t) \bx + 2\bx^T {\bf s}_x(t) + s_0(t), \quad {\bf S}_{xx}(t) = {\bf S}_{xx}^T(t)\succ {\bf 0}. \end{gather*} In this case, we have $$\pd{J^*}{\bx} = 2 \bx^T {\bf S}_{xx}(t) + 2{\bf s}_{x}^T(t),\quad \pd{J^*}{t} = \bx^T \dot{\bf S}_{xx}(t) \bx + 2\bx^T \dot{\bf s}_x(t) + \dot{s}_0(t).$$ Using the HJB, $$ 0 = \min_\bu \left[(\bx - \bx_d(t))^T {\bf Q} (\bx - \bx_d(t)) + (\bu - \bu_d(t))^T {\bf R} (\bu - \bu_d(t)) + \pd{J^*}{\bx} \left({\bf A} \bx + \bB \bu \right) + \pd{J^*}{t} \right], $$ we have \begin{gather*} \pd{}{\bu} = 2 (\bu - \bu_d(t))^T{\bf R} + (2\bx^T{\bf S}_{xx}(t) + 2{\bf s}_x^T(t))\bB = 0,\\ \bu^*(t) = \bu_d(t) - {\bf R}^{-1} \bB^T\left[{\bf S}_{xx}(t)\bx + {\bf s}_x(t)\right] \end{gather*} The HJB can be satisfied by integrating backwards \begin{align*} -\dot{\bf S}_{xx}(t) =& {\bf Q} - {\bf S}_{xx}(t) \bB {\bf R}^{-1} {\bf B}^T {\bf S}_{xx}(t) + {\bf S}_{xx}(t) {\bf A} + {\bf A}^T {\bf S}_{xx}(t)\\ -\dot{\bf s}_x(t) =& - {\bf Q} \bx_d(t) + \left[{\bf A}^T - {\bf S}_{xx} \bB {\bf R}^{-1} \bB^T \right]{\bf s}_x(t) + {\bf S}_{xx}(t) \bB \bu_d(t)\\ -\dot{s}_0(t) =& \bx_d(t)^T {\bf Q} \bx_d(t) - {\bf s}_x^T(t) \bB {\bf R}^{-1} \bB^T {\bf s}_x(t) + 2{\bf s}_x(t)^T \bB \bu_d(t), \end{align*} from the final conditions \begin{align*} {\bf S}_{xx}(t_f) =& {\bf Q}_f\\ {\bf s}_{x}(t_f) =& -{\bf Q}_f \bx_d(t_f) \\ s_0(t_f) =& \bx_d^T(t_f) {\bf Q}_f \bx_d(t_f). \end{align*} Notice that the solution for ${\bf S}_{xx}$ is the same as the simpler LQR derivation, and is symmetric (as we assumed). Note also that $s_0(t)$ has no effect on control (even indirectly), and so can often be ignored.
A quick observation about the quadratic form, which might be helpful in debugging. We know that $J(\bx,t)$ must be uniformly positive. This is true iff ${\bf S}_{xx}\succ 0$ and $s_0 > {\bf s}_x^T {\bf S}_{xx}^{-1} {\bf s}_x$, which comes from evaluating the function at $\bx_{min}(t)$ defined by $\left[ \pd{J^*(\bx,t)}{\bx} \right]_{\bx=\bx_{min}(t)} = 0$.
The finite-horizon LQR formulation can be used to impose a strict final boundary value condition by setting an infinite ${\bf Q}_f$. However, integrating the Riccati equation backwards from an infinite initial condition isn't very practical. To get around this, let us consider solving for ${\bf P}(t) = {\bf S}(t)^{-1}$. Using the matrix relation $\frac{d {\bf S}^{-1}}{dt} = - {\bf S}^{-1} \frac{d {\bf S}}{dt} {\bf S}^{-1}$, we have: $$-\dot{\bf P}(t) = - {\bf P}(t){\bf Q P}(t) + {\bf B R}^{-1} \bB - {\bf A P}(t) - {\bf P}(t){\bf A}^T,$$ with the final conditions $${\bf P}(t_f) = 0.$$ This Riccati equation can be integrated backwards in time for a solution.
It is very interesting, and powerful, to note that, if one chooses
${\bf Q} = 0$, therefore imposing no position cost on the trajectory
before time $T$, then this inverse Riccati equation becomes a linear ODE
which can be solved explicitly.
Essentially all of the results above have a natural correlate for discrete-time systems. What's more, the discrete time versions tend to be simpler to think about in the model-predictive control (MPC) setting that we'll be discussing below and in the next chapters.
Consider the discrete time dynamics: $$\bx[n+1] = {\bf A}\bx[n] + {\bf
B}\bu[n],$$ and we wish to minimize $$\min \sum_{n=0}^{N-1} \bx^T[n] {\bf
Q} \bx[n] + \bu^T[n] {\bf R} \bu[n], \qquad {\bf Q} = {\bf Q}^T \succeq 0,
{\bf R} = {\bf R}^T \succ 0.$$ The cost-to-go is given by $$J(\bx,n-1) =
\min_\bu \bx^T {\bf Q} \bx + \bu^T {\bf R} \bu + J({\bf A}\bx + {\bf
B}\bu, n).$$ If we once again take $$J(\bx,n) = \bx^T {\bf S[n]} \bx,
\quad {\bf S}[n] = {\bf S}^T[n] \succ 0,$$ then we have $$\bu^*[n] = -{\bf
K[n]}\bx[n] = -({\bf R} + {\bf B}^T {\bf S}[n] {\bf B})^{-1} {\bf B}^T
{\bf S}[n] {\bf A} \bx[n],$$ yielding $${\bf S}[n-1] = {\bf Q} + {\bf
A}^T{\bf S}[n]{\bf A} - ({\bf A}^T{\bf S}[n]{\bf B})({\bf R} + {\bf B}^T
{\bf S}[n] {\bf B})^{-1} ({\bf B}^T {\bf S}[n]{\bf A}), \quad {\bf S}[N]
= 0,$$ which is the famous Riccati difference equation. The
infinite-horizon LQR solution is given by the (positive-definite)
fixed-point of this equation: $${\bf S} = {\bf Q} + {\bf A}^T{\bf S}{\bf
A} - ({\bf A}^T{\bf S}{\bf B})({\bf R} + {\bf B}^T {\bf S} {\bf B})^{-1}
({\bf B}^T {\bf S}{\bf A}).$$ Like in the continuous time case, this
equation is so important that we have special numerical recipes for
solving this discrete-time algebraic Riccati equation (DARE). LinearQuadraticRegulator
method on a system that
has only discrete state and a single periodic time step.
You can explore the relationship between the discrete-time and continuous-time formulations in this notebook:
In reinforcement learning, it is popular to consider the
infinite-horizon "discounted" cost: $\min \sum_{n=0}^\infty \gamma^n
(\bx^T[n]{\bf Q}\bx[n] + \bu^T[n]{\bf R}\bu[n]).$ The optimal controller
is $$\bu^* = -\gamma(\bR + \gamma \bB^T {\bf S} \bB)^{-1} \bB^T {\bf S}
\bA \bx.$$ and the corresponding Riccati equation is $${\bf S} = {\bf Q} +
\gamma {\bf A}^T{\bf S}{\bf A} - \gamma^2({\bf A}^T{\bf S}{\bf B})({\bf
R} + \gamma {\bf B}^T {\bf S} {\bf B})^{-1} ({\bf B}^T {\bf S}{\bf A}),$$
whose solution can be found using
DiscreteAlgebraicRiccatiEquation
$(\sqrt{\gamma} {\bf A},
{\bf B}, {\bf Q}, \frac{1}{\gamma} {\bf R}).$
In the dynamic programming chapter, we developed general purpose tools for approximating value functions with function approximators. I think it is particularly illustrative to see how these work out for LQR. Let's consider the discrete-time, infinite-horizon, discounted case.
For LQR, we know that the optimal value function will take a quadratic form, $\bx^T {\bf S}\bx.$ Although it is quadratic in $\bx$, this form is linear in the parameters, ${\bf S}$. We can leverage some of the special tools for fitted value iteration with a linear function approximator.
I've included two versions of the value iteration update in the notebook -- one that samples over both $\bx$ and $\bu$, and one that samples only over $\bx$ and uses the LQR policy (given the current estimated cost-to-go) to determine $\bu$. The difference is not subtle when $\gamma \rightarrow 1$. Take a look!
We must remember that there are multiple solutions to the Riccati equation -- the solution to the LQR problem is the (unique) positive definite solution. But there are non-positive definite solutions, too, which lead to unstable controllers -- these solutions do achieve zero Bellman residual. Every solution to the Riccati equation is a fixed point of the (fitted) value iteration update, but only the positive-definite solution is a stable fixed point of the algorithm.
To see this, write $\hat{J}(\bx) = \bx^{T} ({\bf S}^* + {\bf \Delta})\bx$, where ${\bf S}^*$ is any solution to the Riccati equation, and ${\bf \Delta}$ is a small deviation matrix. If we write the error dynamics through the fitted value iteration update, we can see that $${\bf \Delta}_{i+1} = (\bA - \bB\bK_i)^T {\bf \Delta}_i (\bA - \bB \bK_i),$$ where ${\bf K}_i$ is the optimal controller given ${\bf S}_i = {\bf S}^* + {\bf \Delta}_i \approx \bK^*.$ This error converges to zero if and only if $(\bA - \bB\bK^*)$ is stable, which is only if ${\bf S}^* \succ 0$.
Go ahead and try many different initial ${\bf S}$ in the code to verify it for yourself.
A natural extension for linear optimal control is the consideration of strict constraints on the inputs or state trajectory. Most common are linear inequality constraints, such as $\forall n, |\bu[n]| \le 1$ or $\forall n, \bx[n] \ge -2$ (any linear constraints of the form ${\bf Cx} + {\bf Du} \le {\bf e}$ can be solved with the same tools). Much is known about the solution to this problem in the discrete-time case, but it's computation is signficantly harder than the unconstrained case. Almost always, we give up on solving for the best control policy in closed form, and instead solve for the optimal control trajectory $\bu[\cdot]$ from a particular initial condition $\bx[0]$ over some finite horizon. Fortunately, this problem is a convex optimization and we can often solve it quickly and reliably enough to solve it at every time step, effectively turning a motion planning algorithm into a feedback controller; this idea is famously known as model-predictive control (MPC). We will provide the details in the trajectory optimization chapter.
We do actually understand what the optimal policy of the
inequality-constrained LQR problem looks like, thanks to work on
"explicit MPC"
One important case that does have closed-form solutions is LQR with linear equality constraints. This is particularly relevant in the case of stabilizing robots with kinematic constraints such as a closed kinematic chain, which appears in four-bar linkages or even for the linearization of a biped robot with two feet on the ground.
Our formulation is as follows: in addition to the linear dynamics (in continuous time or discrete time), we have a linear equality constraint of the form ${\bf F}\bx = 0,$ with ${\bf F} \in \Re^{(n-d) \times n}.$ Form a matrix ${\bf P} \in \Re^{d \times n}$ that forms an orthonormal basis for the nullspace of ${\bf F},$ such that $${\bf PP}^T = {\bf I}^{d \times d}, \quad {\bf PF}^T = {\bf 0}^{d \times (n-d)}.$$ Then for any $\bx$ we can write $\bx = {\bf P}^T \by + {\bf F}^T \bz,$ form some $\by \in \Re^d$ and $\bz \in \Re^{n-d}.$ However, as the result of the constraints we know that ${\bf F}\bx = \bz = 0.$ Instead of stabilizing $\bx$ via LQR, we will stabilize $\by$, using the projected cost and dynamics given by $$\bA_\by = {\bf P}\bA_\bx{\bf P}^T, \qquad \bB_\by = {\bf P}\bB_\bx, \qquad \bQ_\by = {\bf P}\bQ_\bx{\bf P}^T$$ where $\bA_\bx,\bB_\bx,$ and $\bQ_\bx$ are the matrices from the full coordinates model. I've chosen to write it this way because it is the same in both discrete and continuous time. The resulting cost-to-go is given by ${\bf S}_\bx = {\bf P}^T{\bf S}_y{\bf P}$ and the controller is given by $\bK_\bx = \bK_\by {\bf P},$ and the where $\bK_y, {\bf S}_y$ are the solutions to the reduced LQR problem in $\by.$
More generally, for a nonlinear system with nonlinear equality
constraints, we would linearize both the system dynamics and the
constraint, and then apply the derivation above.
A nice example of this is the task of balancing a Segway in the $x-z$
plane. In 3D, one could either consider the nonholonomic wheels of the
Segway, or turn it into a Ballbot. For the
purposes of simulation, one can simply construct the ground, the ball,
and the bot with appropriate collision geometry, and drop it into
MultibodyPlant
. The frictional contact between the ball
and the ground generates the expected dynamics.
Designing the LQR controller is another story. We will use a
PlanarJoint
for the floating base, giving us 4 degrees of
freedom: $[x, z, \theta_{ball}, \theta_{bot-ball}].$ If we linearize
this model and call LQR, the LQR call will fail because the system
is not controllable in the full coordinates. The first reason is
easy to see: there is nothing that the actuators can do to change $z$,
the vertical position of the ball. Perhaps the more subtle reason is
that there is a (holonomic) constraint from the ball rolling without
slip on the ground: $x = -r \theta_{ball},$ where $r$ is
the radius of the ball.
I will use one small implementation "trick". In my code, rather than
deal with finding the resting penetration of the ball, I decided to
remove the vertical degree of freedom completely, and used a prismatic
joint for $x$ and a revolute joint for $\theta_{ball}$ instead of the
PlanarJoint
for the floating base. I configured it so that
the ball was sufficiently in penetration that the normal forces from
the ground were substantial enough that the friction cone could support
the horizontal frictional forces I needed to roll. This effectively
implements the $z$ constraint by construction (completely removing that
degree of freedom).
To use LQR, we will write the constraints $x = -r\theta_{ball}$ and
the implied $\dot{x} = -r\dot\theta_{ball}$ as $${\bf Fx} =
\begin{bmatrix}1 & r & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & r & 0
\end{bmatrix} \bx = 0$$ The nullspace matrix ${\bf P}$ can be obtained
numerically, but here it was simple enough to get from inspection,
$${\bf P} = \begin{bmatrix} \frac{r}{\sqrt{1+r^2}} &
-\frac{1}{\sqrt{1+r^2}} & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 \\ 0 &
0 & 0 & \frac{r}{\sqrt{1+r^2}} & -\frac{1}{\sqrt{1+r^2}} & 0 \\ 0 & 0 &
0 & 0 & 0 & 1 \end{bmatrix}.$$ We can obtain the matrices $\bA_x \in
\Re^{6 \times 6}, \bB_x \in \Re^{6 \times 1}$ by linearizing the
MultibodyPlant
dynamics. Then we will call LQR with the
projected matrices. Note that the we will use the discrete-time
dynamics mode of the MultibodyPlant
(by passing in a
non-zero time_step
to the constructor), because
discrete-time dynamics engine contains our most advanced and robust
algorithms for simulating contact.
Importantly, although we design the LQR controller using the reduced model, we can run this controller directly on the original model.
Consider a linear system given by the state-space equations, $${\bf
E}\dot\bx = \bA\bx + \bB\bu,$$ where ${\bf E}$ may or may not be
invertible. We consider this model to be in "implicit form", and will
discuss much more about the use of implicit forms, and their strong
connections to mechanical systems, in
the next chapter. Under stabilizability and detectability
conditions
One can also design the LQR gains using linear matrix inequalities (LMIs). I will defer the derivation til we cover the policy gradient view of LQR, because the LMI formulation is based on a change of variables from the basic policy evaluation criterion. If you want to look ahead, you can find that formulation here.
Solving the algebraic Riccati equation is still the preferred way of computing the LQR solution. But it is helpful to know that one could also compute it with convex optimization. In addition to deepening our understanding, this can be useful for generalizing the basic LQR solution (e.g. for robust stabilization) or to solve for the LQR gains jointly as part of a bigger optimization.
We can also obtain the solution to the discrete-time finite-horizon
(including the time-varying or tracking variants) LQR problem using
optimization -- in this case it actually reduces to a simple
least-squares problem. The presentation in this section can be viewed as
a simple implementation of the Youla
parameterization (sometimes called "Q-parameterization") from
controls. Small variations on the formulation here play an important
role in the minimax variants of LQR (which optimize a worst-case
performance), which we will discuss in the robust control chapter (e.g.
First, let us appreciate that the default parameterization is not convex. Given \begin{gather*} \min \sum_{n=0}^{N-1} \bx^T[n] {\bf Q} \bx[n] + \bu^T[n] {\bf R} \bu[n], \qquad {\bf Q} = {\bf Q}^T \succeq 0, {\bf R} = {\bf R}^T \succ 0 \\ \subjto \quad \bx[n+1] = {\bf A} \bx[n] + {\bf B}\bu[n], \\ \bx[0] = \bx_0 \end{gather*} if we wish to search over controllers of the form $$\bu[n] = {\bf K}_n \bx[n],$$ then we have \begin{align*}\bx[1] &= {\bf A}\bx_0 + {\bf B}{\bf K}_0\bx_0, \\ \bx[2] &= {\bf A}({\bf A} + {\bf BK}_0)\bx_0 + {\bf BK}_1({\bf A} + {\bf BK}_0)\bx_0 \\ \bx[n] &= \left( \prod_{i=0}^{n-1} ({\bf A} + {\bf BK}_i) \right) \bx_0 \end{align*} As you can see, the $\bx[n]$ terms in the cost function include our decision variables multiplied together -- resulting in a non-convex objective. The trick is to re-parameterize the decision variables, and write the feedback in the form: $$\bu[n] = \tilde{\bf K}_n \bx_0,$$ leading to \begin{align*}\bx[1] &= {\bf A}\bx_0 + {\bf B}\tilde{\bf K}_0\bx_0, \\ \bx[2] &= {\bf A}({\bf A} + {\bf B}\tilde{\bf K}_0)\bx_0 + {\bf B}\tilde{\bf K}_1 \bx_0 \\ \bx[n] &= \left( {\bf A}^n + \sum_{i=0}^{n-1}{\bf A}^{n-i-1}{\bf B}\tilde{\bf K}_{i} \right) \bx_0 \end{align*} Now all of the decision variables, $\tilde{\bf K}_i$, appear linearly in the solution to $\bx[n]$ and therefore (convex) quadratically in the objective.
We still have an objective function that depends on $\bx_0$, but we would like to find the optimal $\tilde{\bf K}_i$ for all $\bx_0$. To achieve this let us evaluate the optimality conditions of this least squares problem, starting by taking the gradient of the objective with respect to $\tilde{\bf K}_i$, which is: $$\bx_0 \bx_0^T \left( \tilde{\bf K}_i^T \left({\bf R} + \sum_{m=i+1}^{N-1} {\bf B}^T ({\bf A}^{m-i-1})^T {\bf Q A}^{m-i-1} {\bf B}\right) + \sum_{m=i+1}^{N-1} ({\bf A}^m)^T {\bf Q A}^{m-i-1} {\bf B}\right).$$ We can satisfy this optimality condition for all $\bx_0$ by solving the linear matrix equation: $$\tilde{\bf K}_i^T \left({\bf R} + \sum_{m=i+1}^{N-1} {\bf B}^T ({\bf A}^{m-i-1})^T {\bf Q A}^{m-i-1} {\bf B}\right) + \sum_{m=i+1}^{N-1} ({\bf A}^m)^T {\bf Q A}^{m-i-1} {\bf B} = 0.$$ We can always solve for $\tilde{\bf K}_i$ since it's multiplied by a (symmetric) positive definite matrix (it is the sum of a positive definite matrix and many positive semi-definite matrices), which is always invertible.
If you need to recover the original ${\bf K}_i$ parameters, you can extract them recursively with \begin{align*} \tilde{\bf K}_0 &= {\bf K}_0, \\ \tilde{\bf K}_n &= {\bf K}_n \prod_{i=0}^{n-1} ({\bf A} + {\bf BK}_i), \qquad 0 < n \le N-1. \end{align*} But often this is not actually necessary. In some applications it's enough to know the performance cost under LQR control, or to handle the response to disturbances explicitly with the disturbance-based feedback (which I've already promised for the robust control chapter). After all, the problem formulation that we've written here, which makes no mention of disturbances, assumes the model is perfect and the controls $\tilde{\bf K}_n \bx_0$ are just as suitable for deployment as ${\bf K}_n\bx[n]$.
"System-Level Synthesis" (SLS) is the name for an important and
slightly different approach, where one optimizes the closed-loop
response directly
Once again, the algorithms presented here are not as efficient as
solving the Riccati equation if we only want the solution to the simple
case, but they become very powerful if we want to combine the LQR
synthesis with other objectives/constraints. For instance, if we want to
add some sparsity constraints (e.g. enforcing that some elements of
$\tilde{\bf K}_i$ are zero), then we could solve the quadratic
optimization subject to linear equality constraints
When we are designing LQR controllers based on a linearization (around some operating state or trajectory) of a nonlinear system, then it is interesting to ask: how does the LQR solution change as you change the nominal point (or trajectory)? If the nonlinear dynamics are smooth, does the solution also change smoothly?
The answer is yes -- the Riccati solution does change smoothly, and
its local variation can be obtained with a little bit of work by taking
Taylor approximation of the $\bA$ and $\bB$ matrices
To help you get a little more familiar with Drake, the exercise in will step you through the process of building a Drake Diagram, and designing an LQR controller for it. Systems and Diagrams are the way we write modular code describing dynamical systems, and implementing an algorithm like LQR against the System abstraction becomes very powerful.
For completeness, I've included here the derivation for continuous-time finite-horizon LQR with all of the bells and whistles.
Consider an time-varying affine (approximation of a) continuous-time dynamical system in state-space form: $$\dot{\bx} = {\bf A}(t)\bx + {\bf B}(t)\bu + {\bf c}(t),$$ and a running cost function in the general quadratic form: \begin{gather*} \ell(t, \bx,\bu) = \begin{bmatrix} \bx \\ 1 \end{bmatrix}^T {\bf Q}(t) \begin{bmatrix} \bx \\ 1 \end{bmatrix} + \begin{bmatrix} \bu \\ 1 \end{bmatrix}^T {\bf R}(t) \begin{bmatrix} \bu \\ 1 \end{bmatrix} + 2\bx^T{\bf N}(t)\bu, \\ \forall t\in[t_0, t_f], \quad \bQ(t) = \begin{bmatrix} \bQ_{xx}(t) & \bq_x(t) \\ \bq_x^T(t) & q_0(t) \end{bmatrix}, \bQ_{xx}(t) \succeq 0, \quad \bR(t) = \begin{bmatrix} \bR_{uu}(t) & {\bf r}_u(t) \\ {\bf r}_u^T(t) & r_0(t) \end{bmatrix}, \bR_{uu}(t) \succ 0.\end{gather*} Observe that our LQR "optimal tracking" derivation fits in this form, as we can always write $$(\bx - \bx_d(t))^T \bQ_t (\bx - \bx_d(t)) + (\bu - \bu_d(t))^T \bR_t (\bu - \bu_d(t)) + 2 (\bx - \bx_d(t))^T {\bf N}_t (\bu - \bu_d(t)),$$ by taking \begin{gather*} \bQ_{xx} = \bQ_t,\quad \bq_x = -\bQ_t \bx_d - {\bf N}_t\bu_d, \quad q_0 = \bx_d^T \bQ_t \bx_d + 2 \bx_d^T {\bf N}_t \bu_d, \\ \bR_{uu} = \bR_t, \quad {\bf r}_u = -\bR_t \bu_d - {\bf N}_t^T \bx_d, \quad r_0 = \bu_d^T \bR_t \bu_d, \quad {\bf N} = {\bf N}_t.\end{gather*} Of course, we can also add a quadratic final cost with $\bQ_f$. Let's search for a positive quadratic, time-varying cost-to-go function of the form: \begin{gather*} J(t, \bx)=\begin{bmatrix} \bx \\ 1 \end{bmatrix}^T {\bf S}(t) \begin{bmatrix} \bx \\ 1 \end{bmatrix}, \quad {\bf S}(t) = \begin{bmatrix} {\bf S}_{xx}(t) & {\bf s}_x(t) \\ {\bf s}_x^T(t) & s_0(t) \end{bmatrix}, {\bf S}_{xx}(t) \succ 0, \\ \frac{\partial J}{\partial \bx} = 2\bx^T{\bf S}_{xx} + 2{\bf s}_x^T, \quad \frac{\partial J}{\partial t} = \begin{bmatrix} \bx \\ 1 \end{bmatrix}^T\dot{\bf S} \begin{bmatrix} \bx \\ 1 \end{bmatrix}. \end{gather*} Writing out the HJB: \begin{gather*} \min_\bu \left[\ell(\bx,\bu) + \frac{\partial J}{\partial \bx} \left[{\bf A}(t)\bx + {\bf B}(t)\bu + {\bf c}(t) \right] + \frac{\partial J}{\partial t} \right] = 0, \end{gather*} we can find the minimizing $\bu$ with \begin{gather*} \frac{\partial}{\partial \bu} = 2\bu^T{\bf R}_{uu} + 2{\bf r}_u^T + 2\bx^T{\bf N} + (2\bx^T{\bf S}_{xx} + 2{\bf s}_x^T){\bf B} = 0 \\ \bu^* = -{\bf R}_{uu}^{-1} \begin{bmatrix} {\bf N} + {\bf S}_{xx} \bB \\ {\bf r}^T_{u} + {\bf s}^T_{x}\bB \end{bmatrix}^T \begin{bmatrix} \bx \\ 1 \end{bmatrix} = -{\bf K}(t) \begin{bmatrix} \bx \\ 1 \end{bmatrix} = -{\bf K}_x(t) \bx - {\bf k}_0(t). \end{gather*} Inserting this back into the HJB gives us the updated Riccati differential equation. Since this must hold for all $\bx$, we can collect the quadratic, linear, and offset terms and set them each individually equal to zero, yielding: \begin{align*} -\dot{\bf S}_{xx} =& \bQ_{xx} - ({\bf N} + {\bf S}_{xx} \bB){\bf R}_{uu}^{-1}({\bf N} + {\bf S}_{xx} \bB)^T + {\bf S}_{xx}{\bf A} + {\bf A}^T{\bf S}_{xx}, \\ -\dot{\bf s}_x =& \bq_x - ({\bf N} + {\bf S}_{xx} \bB){\bf R}_{uu}^{-1} ({\bf r}_u + \bB^T {\bf s}_x ) + {\bf A}^T{\bf s}_x + {\bf S}_{xx}{\bf c}, \\ -\dot{s}_0 =& q_0 + r_0 - ({\bf r}_u + \bB^T {\bf s}_x)^T{\bf R}_{uu}^{-1} ({\bf r}_u + \bB^T {\bf s}_x) + 2{\bf s}_x^T {\bf c}, \end{align*} with the final conditions ${\bf S}(t_f) = {\bf Q}_f.$
In the discrete-time version, we have...
Phew! Numerical solutions to these equations can be obtained by
calling the FiniteHorizonLinearQuadraticRegulator
methods in
| Previous Chapter | Table of contents | Next Chapter |


You can use d-on-model-initialize to execute an expression when there the mustache of d-model does not exist.


Parcel Sending Details:
{{request.req.serviceProvider.journeyDate}}: {{request.req.currentCity}}-{{request.req.deliveryCity}}-{{request.req.status}}
Parcel Description :
Parcel Dimensions :
Pick up location :
Delivery location :
Personal Details :
Provider Address :
Personal Details :
Receiver Address :
{{mapAddress}}
Parcel Sending Details:
{{request.req.serviceProvider.journeyDate}}-{{request.req.currentCity}}-{{request.req.deliveryCity}}
{{request.req.currentCity}}-{{request.req.deliveryCity}}-Unassigned
Parcel Description :
Parcel Dimensions :
Pick up location :
Delivery location :
Personal Details :
Receiver Address :
No Parcel Requests.


There are mainly 5 parts:
The process of using the web starts with the user, me, opening a web browser. When I command the browser to do something, I am effectively sending a signal over the internet ("the world's largest computer network"). HTTP, an applications protocol that stands for hypertext transfer protocol, takes the signals and gives them to servers that host the content I want to access. These servers are computers that are optimized for sitting in a room and hosting content. The servers then send information back along the chain of command (through HTTP through the internet through my browser) back to me, the user.
HTML is the main type of document on the web that glues the internet together. This type of document contains:
There are two varieties of elements: inline and block. Inline elements flow along with text content while block elements form an invisible paragraph box for its content.
HTML documents, as we have learned them so far, are governed by two languages:
The HTML for a webpage is converted by whatever DevTools you are using into a tree-like structure. This visual representation is called the document object model, or DOM. The CSS controls how everything looks on the webpage, i.e., the colour, the padding, etc.
Everything is a box. Well, mostly. Remember the inline vs. block question in Lesson 1? These boxes are blocks and contain separate sections of content, which can be defined using </div> tags. They show up in the tree-like structure as a series of nested boxes. How do we make these boxes different sizes? Using classes in conjunction with these </div> tags!
The two key tools we learned to create/review structured documents were:


We encountered 2 errors while trying to process this form:
title must be provided
An interesting passage or quote extracted from the article.
ruby, rails, forms, internets, remarkability
section must be provided


The OEM team have been discussing the v9 low-write mode, and trying to decide how best to protect SD cards from fatigue and early failure.
To put this in perspective, a v9 standard installation with 7 or 8 feeds produces a SD card data 'write' figure of about 9kB/s, whilst if 'low-write' mode is activated with default settings this drops to less than 6kB/s. By stopping Redis, emoncms & apache logging, plus increasing the write buffer to 600 seconds (instead of 60) the SD card data 'write' figure drops dramatically down to about 500 B/s.
In the previous version of emoncms, the low-write version made further changes to protect the SD card, by not only switching off the logs, redirecting other less intrusive logs to a tmpfs (held in RAM), and also further partitioned the SD card putting the operating system in 'read only'.
Advantages to applying the same protection in v9 are that it provides the best possible option to long term protect SD cards from fatigue and unexpected power failure corruption, and has been proven to work well in the previous version.
However, the downside is that it would add significantly to the build guide and introduce opportunities for mistakes to be made during installation, or deter people due to the added complexities. Also, especially now as IoT expands, people are using complementary software such as node-red, Mosquitto, MQTTwarn etc, alongside emoncms, and just question how they would co-exist in a read only environment.
We would value your thoughts on this please.
Paul
Re: Low-write mode - your thoughts please
I abandoned low-write long ago in favour of a HDD solution with the extra flexibility that brings, I also use the MySQL engine for all my feeds, again for the extra facilities that allows. I have experienced a number of SD card corruption events but only 1 whilst using a HDD based Emoncms which was due to a power outage that incidentally also took out 2 windows PCs and their HDDs.
Re: Low-write mode - your thoughts please
Another HDD user. Never had an SD card corruption but then I've always used an HDD.
Of course it's a bit more expensive as a solution both in terms of hardware and power requirements but for me a theoretically more stable solution. I say theoretically because I've just switched from an old pi with rfm12 to a pi2 with rfm69 and it's much flakier. While we were away recently the system just stopped receiving data from my emonTX. It was still receiving data from an esp8266 via WiFi though. And I've noticed that if I reboot the router that the pi doesn't reconnect. So will have to track down what's going on. I'm on V9 rc2 and its not a power issue as I have purchased a recommended USB hub.
Re: Low-write mode - your thoughts please
I switched to an HD when my first SD card died (after only 3 months). I use a Toshiba 320GB 2.5 inch drive that draws 0.8W at idle, 2.5W max at spin up, and 1.5W during r/w ops. (drive is powered from a hub) I run it 24/7 and it's been rock solid for almost 3 years. As Paul mentioned in a post a couple of years ago (if memory serves!), one of the added bennies is a file server to store stuff on.
Re: Low-write mode - your thoughts please
I think that we are all agreed that running emoncms on a HDD is the best solution, but we still have to cater for users who wish to run emoncms on a SD card in low-write mode.
I'm trying to establish the pros & cons of making the OS read only, and balancing the obvious benefits against the points described in the first post above.
When power is unexpectedly removed we know that disk corruption occurs only when the OS is writing to the disk, so if we can reduce disk writing to a absolute minimum, is there then any need to make it read only? If nothing is being written, would there be any benefits?
It could be considered 'belt & braces' but I'm trying to balance that against the points made in my first post.
Paul
Re: Low-write mode - your thoughts please
so if we can reduce disk writing to a absolute minimum, is there then any need to make it read only?
There might be. Unless we know for certain there are no writes to the drive, i.e. we're in r/o mode, the OS will make occasional writes to take care of routine things like file and dir atime, inode table maintenance, etc. Granted, the frequency of those writes will likely be quite low, but the chance for data corruption still exists. Reads and writes from/to the drive can be monitored with: cat /proc/diskstats. Here's how the 11 columns break down.
It could be considered 'belt & braces'
Nothing wrong with that. Given some users have systems located in remote, or distant locations, erring on the safe side would be the prudent thing to do.
node-red, Mosquitto, MQTTwarn etc, alongside emoncms, and just question how they would co-exist in a read only environment.
It would seem the current method of switching from r/o to r/w, and back, would be the easiest solution, provided those apps can exist in a read-only environment once configured.
Re: Low-write mode - your thoughts please
I agree with most of that Bill, but it still leaves the two main issue which I raised; the added complexity for users building the system (creating partitions etc), and compatibility with other software. And trying to 'balance' those two issues against creating a 'belt & braces' stable system.
I was hoping to find a compromise by leaving the system in RW and taking disk writes to an absolute minimum by directing the /var/log & /tmp to tmpfs, so any log/housekeeping writes are held in RAM, but I'm struggling with the Ext4 jbd2 journal, which every few seconds writes a chunk of about 7kB to disk.
I'm in the process of trying to disable the root journal using the tune2fs 'has_journal' function, and am almost there.
If this could be achieved, I believe that the 'balance' would shift towards leaving the OS in RW.
Paul
Re: Low-write mode - your thoughts please
Hi Paul,
Here's some insight on running ext4 with a minimum of idle disk writes:
unix.stackexchange.com/questions/96517/minimizing-idle-writes-on-a-file-system
fenidik.blogspot.com/2010/03/ext4-disable-journal.html
All else failing, you could use ext2.
Re: Low-write mode - your thoughts please
Cheers Bill, I've now disabled the journal which has made a big difference.
The only other thing I've got writing to disk, albeit every 15 - 30 seconds or so is;
The command is apache2 -k start, which writes about 3 kB. Stopping apache does stop the disk writes.
If I follow the PID id number, it points to /usr/lib/apache2/mpm-prefork/apache2
Any ideas?
Paul
Re: Low-write mode - your thoughts please
Would a compromise of recommending a USB flash key a storage help? The benefits of an externally exchangeable data-store, no writes to the internal OS SD card and cheap as chips to procure and to replace and maybe recommend keeping the old one as a data backup?
Re: Low-write mode - your thoughts please
Thanks Peter, however the data writes aren't that much of an issue, as we can control that by increasing the feed write time in emoncms. It's the disk writes from the OS, apache, redis etc. that we need to control.
Paul
Re: Low-write mode - your thoughts please
Thanks Paul for starting this thread. Both Glyn and I use SD cards for all our logging Im happy now with their reliability and the added benefit of a cheaper and neater install, plus small reduction in power consumption is nice.
On the subject of filesystem types, the ext2 filesystem with a blocksize of 1024 bytes rather than 4096 bytes is currently used on the SD cards for the data partition. I wrote this note at the time:
https://github.com/emoncms/emoncms/blob/low-write/docs/install.md
"We create here an ext2 filesystem with a blocksize of 1024 bytes instead of the default 4096 bytes. A lower block size results in significant write load reduction when using an application like emoncms that only makes small but frequent and across many files updates to disk. Ext2 is choosen because it supports multiple linux user ownership options which are needed for the mysql data folder. Ext2 is non-journaling which reduces the write load a little although it may make data recovery harder vs Ext4, The data disk size is small however and the downtime from running fsck is perhaps less critical."
The write load investigation I did here compared a 512 byte block vFAT filesystem with a 4096 byte block ext4 system. https://github.com/openenergymonitor/documentation/blob/master/BuildingB.... The ext4 filesystem had a write load of around 8x the vFAT load. Every 4 byte datapoint write results in two blocks of write load one block for the inode and one for the data. A 512 byte block filesystem results in 1024 bytes per update where the data size to be updated is less than 512 bytes (even if its 4 bytes). A 4096 byte block filesystem results in 8192 bytes being written even if the update is only 4 bytes.
Buffering brings the data size to be written to disk closer to the block size. But even 10 minutes of 10s data (per feed file) is only 240 bytes, ~23% of 1024, 5.8% of 4096. So using the smaller block size can still provide a large contribution to reducing write load.
Im quite keen to err on the safe side in terms of keeping a read-only image for the operating system but I am open to the fully writable partition option if we feel the benefits are marginal.
Re: Low-write mode - your thoughts please
I also use the low write SD card version and also like the read only file system.
Even if the card does have bad blocks, the file system will still boot and the system recovered.
I replicate the data into a cloud backup, so if the card goes bad, I swap it and restore (not happened yet).
I also like there are no moving parts - although SSD's are very cheap now.
Re: Low-write mode - your thoughts please
Trystan, I thought SDs have 4KB erase block size, meaning if you use 1KB size it will write a SD block 4 times in worst case, where it would only need to write one if partition block size is correct.
Then I saw this link https://wiki.linaro.org/WorkingGroups/KernelArchived/Projects/FlashCardS... that says block size can be different for different memories sizes and brands. Many diferences now a day.
Also check: https://wiki.gentoo.org/wiki/SDCard
Dont forget partition should be aligned to SD blocks boundaries.
Re: Low-write mode - your thoughts please
If I follow the PID id number, it points to /usr/lib/apache2/mpm-prefork/apache2
Any ideas?
Paul,
I'm still looking to see if there's a way to redirect those writes to a tmpfs mounted directory.
Re: Low-write mode - your thoughts please
Thankyou Chaveiro, I was not aware of that. I will have a good read of the articles, it sounds like I was mistaken.
Re: Low-write mode - your thoughts please
I've done a video update so that you can see the amount of data that emoncms in low-write mode actually writes to disk.
It's a standard v9 installation with the following changes which are very easy to implement;
The filesystem is still in RW, which allows companion software to run (although this should be discouraged), and also from a user perspective, there is no requirement to shrink/create volumes, etc during installation - keeping it simple.
Of the frequency that data that is written to disk, you would be very unlucky to have a power failure at that precise time, and cause a disk corruption, also the amount of data written is unlikely to cause disk fatigue.
Paul
Re: Low-write mode - your thoughts please
The command is apache2 -k start, which writes about 3 kB. Stopping apache does stop the disk writes.
The only thing I have been able to find about the -k switch says:
"The -k option is used to run Apache as a service on Windows and takes a command as an argument."
(I got curious as to why -k wasn't listed as an option on the Apache man page)
Re: Low-write mode - your thoughts please
Thanks Bill, I suppose this raises another question, presumably apache is writing this data for a reason, if so, and the OS is mounted RO, what is the detrimental effect of not being able to write it?
Paul
Re: Low-write mode - your thoughts please
I run the EMONPI image on a Pi2 alongside Openhab and appreciate the reliability the mainly read only file system brings as well as the ability to pull the SD card and switch to another in the rare event I'm trying something out. I've kept away from adding a hard disk as I don't want to add in an extra enclosure or layer of complication. I run a 32GB Sandisk Extreme SSD with plenty of free space as I'm relying on wear leveling to keep my 42 feeds alive for many months to come.
Having a large portion of the OS read only has meant everything came back OK after a couple of unexpected power cuts. Unfortunately a combination of largely overhead power lines, big trees and large storms makes my installation vulnerable to sudden power loss, and I'd rather not spend the morning after frantically googling to see whether it can be brought back to life by swapping the card into one of my Windows Machines
Re: Low-write mode - your thoughts please
Hi Kevin, you may recall that historically, 'emoncms' had a number of variants, which over the past 6 months has distilled to a single version, with options in the 'settings' to change the way emoncms functions; low-write/full write, MQTT, etc. but all variants now start with a standard install, which can be changed at a later time.
For example; as a new starter to emoncms, you install v9 emoncms with the low-write option (as the OS is on a SD card), but later buy a USB HDD and change to full-write, add MQTT, Node-red, maybe a blog, media server, etc. you are able to upgrade/degrade without making major changes. Other advantages are that one version is much easier to maintain, develop & support, and combining functionality is more energy efficient.
There will always be disk-writes to the SD card, as the emoncms data needs to be stored, but what is the difference between a filesystem that does not write data to disk, and a system which is RO?
In my example in the post above, there are some disk writes, but compared with a standard install, they are minute, so maybe it's worth the compromise to have just one system which is easy to install (not everyone has the same competence!), have options to add other software, and be free to upgrade/downgrade at will.
This is just my personal opinion, T & G will have the final say, but good to hear that RO works for you.
Paul.
Re: Low-write mode - your thoughts please
Thanks Bill, I suppose this raises another question, presumably apache is writing this data for a reason, if so, and the OS is mounted RO, what is the detrimental effect of not being able to write it?
Turns out the -k switch is valid under Linux. Took me awhile to find the answer.
Now to try and determine the answer to the question above.
Re: Low-write mode - your thoughts please
Paul,
Thanks for the reply, having one single branch that is then modified based upon usage makes sense.
Most operating systems have a RW file system which at the least should be checked after an outage, and is vulnerable to corruption by incomplete writes as the power goes down or the system crashes. As I understand it mounting the OS partition RO means no checks are necessary after a problem as nothing could have changed or become corrupted by incomplete writes to the card / disk. I'm not sure how often you get corruption from power loss or just generally from things going wrong with a Pi, but on mine with V8.5 V Low Write the powers gone unexpectedly about 4 times so far with no problems that I know of. This is a great result for a computer, but also the expected behaviour of a domestic appliance.
My suggestion is a system similar to the shipped image? with a RO OS Partition, the option to put all logging in RAM or perhaps on a memory stick, and a general RW area for programs that need it. I'm assuming the logs auto limit their sizes?
Modern file systems are way better than the file allocation tables of old, but an unexpected power cut can cause bad problems regardless of whether a SD Card is used or a hard disk. Indeed I recently had a loose SSD power cable in my desktop that killed Windows 10 beyond what it could recover from.
Having delayed, consolidated disk writes is a great idea for both SD card longevity and performance, as long as it doesn't leave anything partially written and that the system can work with all the data whether written or not.
Problems arise when someone needs to install software that insists on having RW access to the whole file system so perhaps a script can be provided to permanently switch between modes?
Getting Openhab to work involved giving it a separate partition mounted in /home/pi that it can play in, even though the bits it writes to are very small now I've managed to get it to log to the temp directory.
Just my 10 penneth - hope its useful!
Kevin
Re: Low-write mode - your thoughts please
I'd suggest starting from a different point - who is the target audience.
If the EmonPi is aimed at the wider population that just want something that works, then a minimal install image that prolongs the SD card life is the prime driver. However it is then configured (perhaps minimal local logging - use emoncms.org) this then comes with a warning that the life of the card cannot be guaranteed in any other configuration. I'd suggest this is not a Raspbian image but an absolute minimum (keeps size of card low as well).
If you want to provide for the more 'hobbyist' client then a more complicated instruction set should not be an issue (they will be happy to ask questions). The majority of these hobbyists may be using a HDD already so the effort in supporting a low write SD image may not be the best use of scarce resources. I note that the install instruction now have a set of instructions to move an SD card setup to an HDD which is really great (not tried it though).
Personally, I use one Pi for lots of different things and moved to a HDD a while ago (after a card failure). I have just done a new minimal install (direct to HDD) from the raspbian-ua-netinst on github and then installed emoncms and emonhub. I'll be moving the other stuff across soon.
I think it is partly a decision on where the overall product line is being aimed at.
$0.01 worth.
Brian
Re: Low-write mode - your thoughts please
@borpin123 - who is the target audience?
This is foremost in my mind, and of course not all users have the same competence/confidence, therefore we need to structure the installation process to be achievable for the wider majority. Having just read sheppy's post (above yours) it's clear that he is fairly knowledgeable and confident about creating/resizing partitions, even adding yet another partition for other software, but many users would find it difficult to do, or be put off by the size of the guide.
I'm not enthusiastic about creating a second (more complicated) guide, as that would deprive the less competent users of those features, and also make support more difficult as we would then have 2 quite different systems.
Paul
Re: Low-write mode - your thoughts please
Hi Paul,
Not suggesting different systems as such, just that the starting points are different. The ready to go is just that. A simple system, pre-installed, that is not designed to be fiddled with, but for it to just work and be reliable. It (should) provide a web interface for configuration and adding modules etc. No specialist knowledge needed. It may even not immediately provide for any local logging but assume that emoncms.org will be used.
If the user subsequently wants more, as with any Linux system, the world is your oyster and TIMTOWTDI. The trick then is to get good clear coherent documentation to support this desire. Unfortunately, as is usually the way, the documentation is lagging.
The current basic install instructions are very good. I did not try a low-write system but I'm hoping if I had, that would have worked well as well. The bit perhaps that is missing is explaining to a new user, the different configurations they may want and why they may want them up front.
I have then fallen over a lack of clear instruction on converting inputs to suitable feeds and (now) how to install modules.
I think the premise of a single system is right and, as long as it remains possible, the other types of install can be done by those with some knowledge or ready to learn.
Cheers, Brian
Re: Low-write mode - your thoughts please
Hi guys,
Thanks a lot for lots of good opinions on this topic. I've been enjoying reading over past few days
borpin123 has hit the nail on the head thinking about the target user. My feeling is to be on the cautious side and make the SD card image we ship with the emonPi as bulletproof as possible. Yes, it will be trickier to setup but once up and running, it should result in a more stable resilient setup. We are now well into our 2nd 1K PCS production run of emonPi'. Many of these users just use the unit 'as is' therefore won't be inconvenienced by the hassles of running a RO file system.
We have started building and testing a new SD card image, I've posted the latest feature set list there so that this thread doesn't go too much off topic (http://openenergymonitor.org/emon/node/11407). As my post on the build thread mentions, we are considering having nodeRED and openHAB pre-installed and configured with a skeleton setup to pull in data from emonhub MQTT. IMO, the read-only file system is even more important when adding other services as it's a safety net against the possibility of a service going to town on file writes behind the scenes without us realising and reducing the life of an SD card.
We are keen to have a standardised installation procedure across the ready-to-go SD card and install guides with the idea that it will be easier to maintain as most systems will be generally running the same thing. We are open to a non read-only OS if there was broad support, but feel that it's probably better to err on the side of a cautious, read only approach.
Re: Low-write mode - your thoughts please
Trystan,
I think you are right for the EmonPi (KISS principle), but a RW OS is needed. You could assume that these will all be HDD based and produce an HDD image like you did before. Having said that, I used the rasbian-ua-install (which I suspect is much the same as the Minibian) partly as it would install directly onto a HDD and a 256Mb Micro SD and followed the emoncms install instructions without any great hassle.
What I do need to work out is how to install modules :)
Key I think is maintaining the documentation and helping folks upgrade (take them with you). for instance, you mention Emonhub MQTT; is that different to the older emonhub?
I'm looking forward to playing with node-red and openhab though I'm not yet clear in my mind how they interact.
Cheers. Brian
Re: Low-write mode - your thoughts please
Hi Chaps,
I've only just noticed this thread, sorry for reviving a zombie!
This problem was fixed years ago by others, I dug all the info up nearly four years ago for My Little Server (tm) :)
Some background - I run an Asus EEE 701 (the original netbook) as my server at home (cheap, low power usage, enough horsepower), it only has 4GB of SSD/Flash for the OS which wasn't big enough. Wanting to use it without spinning disks 24/7, I used the SD card slot to extend the storage. Clearly this would have the same issues as the RaspPi, hence my investigation into minimising writes to SD card. My server runs home automation software which writes to the SD card every 60 secs for it's main log, and several times every 5-10 secs for many other logs. It also runs a full mail server, webmail, Apache, FTP, NFS/Samba shares, weather station software (SQL db) and all the logging that goes with them. So this solution really works and has done for nearly four years on the same 8GB Sandisk SD card.
Basically the OS (Ubuntu Server - similar to Debian used on the Pi) was installed on the 4GB internal flash on the EEE, then the /OPT and /VAR where moved to the SD card - This is of course different to the Pi's situation but the principle is the same. My notes from the install are a bit chaotic but here goes...
1) Aligning the SD Card
SD cards aren't like harddrives, SD cards erase/write 128KB blocks of storage at a time, which means even if one byte of data in a block changes, the whole block is erased and rewritten. If the file systems blocks are mis-aligned to the SD card hardware blocks, that one byte change to the FS block will actually erase/rewrite two SD blocks, slowing everything by a factor of two and also causing twice the wear on the SD card. Not optimal.
sudo fdisk -u -l /dev/sda
Will show you something like -
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 7813119 3905536 83 Linux
That start block is 2048 and is a multiple of 128, so it's aligned with the SD hardware block, which is correct.
Start blocks like 63 are common but anything not a multiple of 128 is mis-aligned and must be fixed before moving on. DD the partition off the SD card, FDISK the SD card to move the partition to the correct boundary and DD the patition back.
2) Add noatime and commit on your FSTAB / mount.
This makes the OS not track read access (modified date/time) to files and buffers the writes to the card for longer.
edit /etc/fstab
UUID=your_uuid / ext4 defaults,noatime,errors=remount-ro,commit=180 0 1
3) You can set up a RAMdrive to hold temp files - depends on your free RAM
# mount a RAM disk in FSTAB
tmpfs /tmp tmpfs defaults,noatime,size=128M 0 0
There are many examples which use nosuid,nodev,noexec,mode=1777 but I found this caused problems with APT updates. YMMV.
4) Tune the system for SSD usage
Now to the real magic. These settings basically turn down the OS's urge to swap stuff out of RAM to SD swap space (if you have some), turn on laptop mode to minimise disk writes and then really tune the 'dirty write' settings.
These settings control flushing unwritten data in RAM back to permanent storage. Normally this is about every 4 seconds. These settings crank that up to three minutes.  Meaning that normally the blocks should be pretty full actually minimising rewrites of the same block as well as writing them less often.
Now I admit this can cause issues in the event of a power cut, in theory you could lose three mins of data, statistically more like 90 seconds. BUT is that really an issue? How many power cuts do you *really* get? In reality it will more likely lessen data corruption as power is far less likely to go out *during* a write.
edit /etc/sysctl.conf
# specific tuning for flash drive
vm.swappiness = 0
vm.laptop_mode = 0
vm.dirty_writeback_centisecs = 18000
vm.dirty_expire_centisecs = 18000
vm.dirty_ratio = 10
vm.dirty_background_ratio = 1
5a) Change the kernel I/O scheduler
I see from various places then everyone seems to use the DEADLINE elevator on the Pi, for the workload of my server (which would seem similar to the EmonPi) NOOP didn't cause any slower I/O but did reduce CPU workload. Given the small CPU on the Pi, this would seem a better fit.
edit /boot/cmdline.txt and change
elevator=deadline to elevator=noop
After a reboot - check it has stuck
cat /sys/block/sda/queue/scheduler
5b) For some machines grub editing doesn't seem to work properly, in that case try this -
edit /etc/rc.local
echo noop > /sys/block/sda/queue/scheduler
Put this line before the exit 0
After a reboot - check it has stuck
cat /sys/block/sda/queue/scheduler
All these setting overlap to some extent, but have been working for a long time.
Sorry for the epic post - hope it helps,
V.
Re: Low-write mode - your thoughts please
How many power cuts do you *really* get?
Hi Mark,
Here in rural Oklahoma, USA, the power can be very flaky. I've seen it go off-line 3 times in the span of an hour. I've lived here for three years, and have yet to see a stretch of more than a few months without power loss. There's a few posts on the forum from users in rural UK that have made similar comments about power that's not very reliable.
edit /etc/default/grub
The Pi doesn't use the Grub bootloader. The I/O scheduler is specified in /boot/cmdline.txt
I see from various places then everyone seems to use the DEADLINE elevator on the Pi
Regarding the I/O scheduler, this post says Noop is appropriate only for true SSDs, and that Deadline incorporates the elevator algorithm which groups spatially near disk accesses when possible.
Regards,
Bill
Re: Low-write mode - your thoughts please
Hi Bill,
OK you got me! :) I'm thinking primarily of the UK, we get power cuts but very rarely.
That said, the rest of it still stands, there will still probably be less chance of FS corruption during a power cut. Have you had any SD card corruption from your frequent power outs?
As to grub, I stand corrected, I don't use a Pi for EmonCMS, so I've not done this stuff on a Pi. I've updated the post above to keep it accurate and in one place.
I read about Deadline at the time, I'm not sure it makes that much difference in my use case (or EmonCMS on a Pi using the same set up). The writes are so infrequent that the lower CPU usage was more important to me. That said, perhaps if the only thing running on the Pi is EmonCMS and you have the CPU headroom, the tradeoff in SD longevity is worth the CPU usage?
V
Re: Low-write mode - your thoughts please
Have you had any SD card corruption from your frequent power outs?
I switched to a USB HDD about two years ago. (My 8GB SD card died after ~3 months) So far, the ext4 filesystem has been able to recover from power hits via the journal.
Good info in your post, nonetheless.
Re: Low-write mode - your thoughts please
Thanks Vster, lots of interesting stuff there. I'll review our image build with your notes in mind
Re: Low-write mode - your thoughts please
Hi Vster:
Taking a look at your point 1.) :
sudo fdisk returns:
and:
As the /boot partition starts at 16 am I correct that this is not aligned, as it's not a multiple? How can I correct this? Will this need to be done on the same SD card at we indeed to ship with? Will this vary between SD cards?
Point 2.) & 3.)
Yup, we already mount with noatime
Yes we mount /var/log to tmpfs using: nodev,nosuid,size=30M,mode=1777. We have not had any problems with this. I notice you use tmpfs /tmp tmpfs defaults,noatime,size=128M 0 0
The fstab is as follows :
Point 4.)
I think I will leave this one out. The emonPi could be unplugged / lose power at any moment. Even though we recommend users to shut down properly, I'm not sure how often this happens in practice! We also ship to many countries where power is not always the best quality and blackouts are common. Even in the UK (in rural N.Wales) we get power cuts often in the winter months.
Point 5a.)
Elevator
Changing elevator from deadline to noop sounds like a good idea. Also recommended in this article:
https://fiasko-nw.net/~thomas/projects/rpi/writeless.html.en.
I made the change then checked using
pi@emonpi:~/emonpi$ cat /sys/block/mmcblk0/queue/scheduler
[noop] deadline cfq
therefore no rc.local edit is required
Copies if fstab, rc.local and cmdline.txt are in the emonPi git repo: https://github.com/openenergymonitor/emonpi
Re: Low-write mode - your thoughts please
Glyn,
Here's another system logging option. busybox-syslogd puts the system logs in a circular ram buffer. (the size is configurable) Log contents are read via the logread command. (part of the package) Here's a synopsis:
With a circular buffer, there's no "out of ram" issue. Log rotation is built in.
Re: Low-write mode - your thoughts please
Thanks Bill, that looks interesting. However I'm happy with logrotate at the moment
Re: Low-write mode - your thoughts please
Hi Trystan,
1) You are correct in that the logical/physical blocks are mis-aligned and therefore causing twice the wear on the SD card.
I'm a Linux guy so I'd use DD and Fdisk to move the partitions data off the SD to HD, redo the partitions then move the data back. But it's probably easier just to use GPARTED, it's part of the Ubuntu desktop (which I think you use) or can be booted off CD and used as a live OS. GPARTED is graphical tool to create/move/delete partitions around. Move the P3 up a bit, then P2, then P1. Leaving P1 aligned on say 2048, will correct the issue.
I assume you just copy a file image to the SD cards that you ship? If that's the case just create a new image from the updated SD card (it will just have a bit of wasted space at the beginning but otherwise be identical).
No, it won't matter between SD cards, only the length/size matters (some SD cards are slightly smaller/larger than others for a given size), as this image os only 3.6GB that's not an issue.
2/3) Interesting, it may be an Ubuntu vs Debian thing. There is a commit= line in there you may have missed.
4) I understand your concern, but this is the real magic. It cuts writes by orders of magnitude. As I mentioned, I suspect it may actually prevent corruption by minimising writes, because as well as writing less often (once every three mins) it writes once instead of say 100 times (one block of 100 rows, rather than 100 blocks of one row). It may be worth running a few tests, yanking the power out and seeing which gets corrupted first with/without the patch. I've been running it for nearly four years and never suffered any loss of data/corruption, there have been several hard power downs due to electrical work/bad coding/bad wiring.
5) Interesting page, I've taken NTP logging off my server too. He also use the dirty.write fixes. May be worth reaching out to him to get his experience of running it on a Pi?
Re: Low-write mode - your thoughts please
Thanks for your help,. It was easy to use gparted to align the partition. There was an align to cylinder option. Also added commit=180 to fstab
Re: Low-write mode - your thoughts please
Hi Trystan,
The commit=300 will help, but it's only doing half the job. Commit specifies a maximum write commit timeframe that the OS uses, programs can still call fsync to flush the file buffers, sidestepping the OS commit timeframe. More importantly I forgot to mention (sorry!) commit only works for EXT4 partitions, if you're storing data in the third EXT2 partition, the commit parameter will be ignored.
I can't think of a way to test the benefit of the just using the commit (without the dirty.writes) other than to plug in USB hard drive, move the OS to it, and then watch the HDD LED, it should only flash every three mins in normal use (I suspect). Or perhaps someone who is using a HDD can add the commit temporarily to test it?
Hope that helps.
Re: Low-write mode - your thoughts please
It was easy to use gparted to align the partition. There was an align to cylinder option. Also added commit=180 to fstab
Hi Glyn,
Did you use align to cylinder, or align to MiB?
Re: Low-write mode - your thoughts please
@Vster Ah, we do use ext2 for our data partition therefore, commit will have no effect.
@Bill I used "align to cylinder" option in Gparted. Is this correct?
Re: Low-write mode - your thoughts please
I used "align to cylinder" option in Gparted. Is this correct?
Unfortunately, no. You want the MiB option.
Re: Low-write mode - your thoughts please
Ah, ok. I've done some reading up on the Gparted manual and your totally correct. However looking at the effect of the alignment operation:
Before
After
The first partition now starts at 4096, since this is a multiple of 128 am I correct in thinking that this is now aligned to the SD card 128KB blocks?


Plugin Information |
|---|
View Recipe on the plugin site for more information. |
This plugin enables the community to share fragments of Jenkins configurations (such as jobs, views, plugins, and so on) with others through the mechanism similar to the plugin update center.
Such recipes provide a great starting point for users to get up to speed, and it simplifies the transfer of knowledge from one Jenkins instance to another.
Workflow
The basic workflow is as follows:
- Joe exports a recipe
- from the export UI, he chooses to publish it to the community (jenkins-ci.org account is necessary)
- The recipe gets uploaded to the repository
- The recipe gets published to the update center
- Alice will be able to install this recipe from her Jenkins through the import UI
Since a recipe file is a plain old XML file, it can be also shared by other means, and the import wizard allows you to upload such recipes through a form submission.
Screenshots
These features are accessible from the "Manage Jenkins" page:
The export screen allows you to add the contents of the recipe and choose where to submit the recipe:
The import screen allows you to select from the community contributed recipes (or upload)
The recipe contains information about plugins used in the recipe, and the first step in the import process is to install missing plugins and update old ones.
Then the details of the recipe import process will appear. You can make some customizations in this stage:
Changelog
Version 1.2 (Jun 3, 2014)
- Implemented a proper import/export of views
Version 1.1 (Nov 22, 2013)
- Allow an existing job to be updated (JENKINS-20727)
- Fixed broken icon
Version 1.0 (Dec 31, 2012)
- Initial version
Attachments:
plugin-check.png (image/png)
wizard.png (image/png)
export.png (image/png)
select-recipe.png (image/png)


4 December 2003
Disease Outbreak Reported
As of 2 December 2003, the Ministry of Health, Mali has reported a total number of 1 149 cases, including 78 deaths in the Koulikoro, Segou and Mopti regions ( see previous report).
Médecins sans Frontières and Médecins du Monde are providing technical assistance and supplies. In collaboration with the Ministry of Health, the WHO Global Task Force on Cholera Control is sending an intervention team and cholera kits .


ANALYZE THIS **½ (out of four) -a review by Bill Chambers<EMAIL_ADDRESS>)
(Visit Film Freak Central!: http://filmfreakcentral.net Bring your own beer.)
starring Robert DeNiro, Billy Crystal, Lisa Kudrow, Chazz Palminteri screenplay by Peter Tolan, Harold Ramis, and Ken Lonergan directed by Harold Ramis
Robert DeNiro is not a comedian. He used this to his advantage, in what is arguably his best performance, as Rupert Pupkin in The King of Comedy. In Scorsese's 1982 media-age satire, which becomes more relevant with each passing year, Pupkin is a struggling comic obsessed with talk show host Jerry Langford (a self-parodying Jerry Lewis) and the thought of appearing on his program. Pupkin's routines, however, are painfully unfunny-and he is blithely unaware of his own mediocrity. That his jokes don't sound like they were written to bomb (they're liked warmed over Henny Youngman one-liners that a Catskills veteran could elicit a chuckle or two from) is because of DeNiro's desperate delivery; the actor has awful timing in his bones.
As Paul Vitti, the head of a mafia family in Analyze This, DeNiro sends up his Goodfellas and Casino characters mostly by playing it straight: when plunked into veritable comedy, we realize just how goofy the whole mobster attitude can be. Vitti is having anxiety attacks over his station in life and an upcoming meeting with the heads of all the families. He seeks counsel from Dr. Ben Sobol (Crystal, redeeming himself in this post-City Slickers 2/Forget Paris/Father's Day/My Giant era), a psychiatrist engaged to be married to reporter Laura (Kudrow). Vitti, who is the movie equivalent of John Gotti, panics Ben at first. Ben loosens up and agrees to help after he realizes they share common neuroses over their fathers, but Vitti's request that he be "cured" in two weeks naturally puts a wrench in Ben's nuptials.
Analyze This takes more intelligent potshots at the gangster sub-genre than, say, last year's Mafia!, but it doesn't attempt to mimic the baroque visuals of The Godfather films or Once Upon A Time In America. (One reason I so adore Mel Brooks' hilarious Young Frankenstein is that it actually looks and feels like a Universal horror picture.) Stuart Dryburgh's cinematography is full of missed opportunities-Vitti's world should appear tantalizing, elegant, and slightly foreboding to Ben. Even the Italian restaurant used in a sequence that pays homage to the original Godfather looks like as generic as the pizza parlour on TV's "Everybody Loves Raymond."
The film's screenplay has similar problems. The concept is so good, so utterly "pitch-able," that someone else got there first: the film bears remarkable resemblance to HBO's weekly smash "The Sopranos." Unlike that show, Analyze This makes the mistake of anchoring its whole story on an amusing but thin premise. It lacks meat on its bones: that's why the film is half over before Dr. Sobol officially agrees to take on his special patient; that's why there are not one but two wedding sequences, both involving Ben and Laura (!); that's why Chazz Palminteri's role consists mainly of shouting "I'm gonna get that son of a bitch Vitti!" every few scenes. (He's a crashing bore (er, boor)-Palminteri (Hurlyburly) is a good actor in dire need of new schtick.) The movie really falls apart in its final third, because it has relied on up to that point the surprisingly excellent chemistry between Crystal and DeNiro to carry it through, and the climax has Crystal flying solo in a flat and endless impersonation gag. Academy Awards aside, Crystal is always funnier playing off an able co-star.
(Aside: the relationship between Crystal and his intelligent son sadly remains mostly unexplored at the expense of plot; Kudrow, alas, is also wasted in the "girlfriend" role she's too damn good for these days.)
Yet I'll remember Analyze This as being a fun movie because of DeNiro and Crystal's rapport. Crystal, who truly gives zingers their zing, is granted genuinely witty comebacks to DeNiro's numerous threats. (One can practically hear the ba-bum-ch! drumbeat after his one-liners.) Surprisingly, they both begin the film playing caricatures but end up flesh and blood protagonists. The film also features outstanding supporting work from Joe Viterelli as Vitti's right hand man Jelly. Lastly, though the script has its flaws, it's at least as profane as the genuine mob movie article-"Larry Sanders" refugee Tolan surely must have been the one who liberally peppered Analyze This with "fucks." Hearing DeNiro use the word is old hat, but hearing Crystal repeat the word is a scream.
-February, 1999
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


--- permalink: /404.html layout: default-minus-hero ---
Looks like we can't find that page. If you reached this page by typing in a URL, make sure that you spelled it correctly. If you reached this page by clicking on a link, contact us at {% email<EMAIL_ADDRESS>%} so we can fix the link!


Please enter the URL:
How does it work?
Simply paste the URL of a playlist into the textfield.
Create .pls file
Download
Want to know more about the .pls File format?


{% extends "layout.html" %} {% block page_title %} Allocation statements - manage your education and skills funding - GOV.UK {% endblock %} {% block content %} Casterbridge Local Authority (UKPRN: 12345678) View your sub-services Sign out Home Choose allocation statements to view Choose a statement type Your 19+ allocation statements Results updated, now showing 1 to 28 of 28 allocation statements Your 19+ allocation statements {% endif %} {% if nothingToView %} {% else %} Filter by type Filter by type 16 to 18 traineeships (1) 19 to 24 traineeships (1) Advanced learner loans (1) Apprenticeship carry-in (1) ESFA funded adult education budget (2) Non levy apprenticeship funding (1) Filter by year Filter by year 2022 to 2023 (6) 2021 to 2022 (1) {% if noFilterResults %} No results found. Use the filters to refine your search again. {% else %} ESFA funded adult education budget grant for 2022 to 2023 (version 1) 4 March 2023 version 1 Updated £849,742 ESFA funded adult education budget contract for services for 2022 to 2023 (version 1) 3 March 2023 version 1 Updated £2,395,872 16 to 18 traineeships for 2022 to 2023 (version 1) 1 March 2023 version 1 £192,916 19 to 24 traineeships (2020 procurement) for 2022 to 2023 (version 1) 1 March 2023 version 1 £205,266 Advanced learner loans for 2022 to 2023 1 July 2023 version 1 £5,500 Apprenticeship carry-in for 2022 to 2023 1 July 2023 version 1 £1,100 Non-levy apprenticeship for 2021 to 2022 1 March 2022 version 1 £1,187,538 Showing 1 to 7 of 7 allocation statements Back to top ... ... {% endif %} {% endif %} {% endblock %}
No results found. Use the filters to refine your search again.
...


Heat can basically do everything, it can move from one place to another, increase energyand even get atoms excited. Heat is energy. When a system is increase by heat, it really means that the increase of the amount of energy in that system. Thermodynamics is related to heat. When you talk about thermodynamics, you are talking about the measure of energy moving in and out of a system.
Heat is the energy transferred from one object to another because of the different in temperature. Heat can be flow immediately from hot to cold. Specific Heat capacity of water determines the energy needed to heat it.


--- layout: post title: Keep Looking To Improve published: 1 category: ---
I have to admit that I don't follow Football news. However, this story caught my eye. When Nigel Atkins was terminated as manager at Southampton, he lefthis players with a positive message on the dressing-room wall before he cleared out his office.
These nuggets of advice could be used by agile coaches too! I particularly like "Keep Looking to Improve" as it encourages us to keep our eyes and minds open to doing better than we are now. While at the same time having confidence in our ability to do the right thing.


We propose how a developing country like Sri Lanka can benefit from privacy-enabled machine learning techniques such as Federated Learning to detect road conditions using crowd-sourced data collection and proposed the idea of implementing a Digital Twin for the national road system in Sri Lanka. Developing countries such as Sri Lanka are far behind in implementing smart road systems and smart cities compared to the developed countries. The proposed work discussed in this paper matches the UN Sustainable Development Goal (SDG) 9: "Build Resilient Infrastructure, Promote Inclusive and Sustainable Industrialization and Foster Innovation". Our proposed work discusses how the government and private sector vehicles that conduct routine trips to collect crowd-sourced data using smartphone devices to identify the road conditions and detect where the potholes, surface unevenness (roughness), and other major distresses are located on the roads. We explore Mobile Edge Computing (MEC) techniques that can bring machine learning intelligence closer to the edge devices where produced data is stored and show how the applications of Federated Learning can be made to detect and improve road conditions. During the second phase of this study, we plan to implement a Digital Twin for the road system in Sri Lanka. We intend to use data provided by both Dedicated and Non-Dedicated systems in the proposed Digital Twin for the road system. As of writing this paper, and best to our knowledge, there is no Digital Twin system implemented for roads and other infrastructure systems in Sri Lanka. The proposed Digital Twin will be one of the first implementations of such systems in Sri Lanka. Lessons learned from this pilot project will benefit other developing countries who wish to follow the same path and make a data-driven decisions. Additionally, our intended work can be used as a blueprint for those countries planning to implement such systems..
This paper was presented during ACM SIGKDD 2021 International Conference on Knowledge Discovery & Data Mining Workshop: Data-driven Humanitarian Mapping: Harnessing Human-Machine Intelligence for High-Stake Public Policy and Resiliency Planning, August 15th, 2021
ACM SIGKDD 2021 International Conference on Knowledge Discovery & Data Mining Workshop: Data-driven Humanitarian Mapping: Harnessing Human-Machine Intelligence for High-Stake Public Policy and Resiliency PlanningThis is a short video presenented during the KDD 2021 Humanitarian Mapping Workshop symposium.


com.anji.imaging
contains utility classes to handle image processing.
There is some support for JMagick () that is not fully tested, but mostly it employs
javax.imagio.*
and java.awt.*
classes.com.anji.imaging.Identifier
,
com.anji.imaging.EvaluateImageIdentifier
, and
IdentifyImageFitnessFunction
provide a framework for evaluating agents'
abilities successfully to identify images as containing certain features.


According to the definition of B-Tree, there are lower and upper bounds on the number of keys a node can have. These bounds are represented using the minimum degree t, where .
• Except the root node, all other nodes should have minimum keys.
• Every internal node except the root will have minimum of t children.
• In a nonempty tree, the root node must have minimum one key.
• Every node can have maximum keys.
• Every internal node can have maximum of 2t children.
If the degree of t is 1, the minimum number of nodes will be 0 and the B-tree will be an empty tree. A nonempty B - tree should contain at least one key, thus making degree.
Hence the minimum degree of and the minimum degree of is not allowed.
The following is the given B-tree:
According to property 5 B-tree
a. Every node other than root must have at least keys.
b. Every node may contain at most keys.
c. And t ≥ 2
Finding value of t :
• Every node in the given tree has 2 keys or 3 keys.
• Therefore, least number of keys, t-1 ≤ 2 and maximum number of keys, 2t-1 ≥ 3
i.e. t ≤ 2 +1 and 2t ≥ 3+1
t ≤ 3 and 2t ≥ 4
t ≤ 3 and t ≥ 2
• From the above two in equations, 2 ≤ t ≤ 3
• So, the value of t cannot exceed 3 as some nodes have only 2 keys.
Therefore, the given tree is a legal B-tree, for t =2 or 3.
Since minimum degree, t = 2,
• Every node except the root in the B-tree must have at least 1 key (i.e. t-1).
• Every node can have at most 3 keys (i.e. 2t-1).
• That is, a node may have 1 key or 2 keys or 3 keys.
All legal B-trees that represent {1, 2, 3, 4, 5} and satisfy the above conditions are shown below:
i)
ii)
iii)
iv)
Supposed condition:
If the black node assimilates the red children and incorporates its own black children at that place in the Red Black Tree, then a new data structure is formed.
Red Black Tree is a special type of tree in which each node contains an extra bit for the storage of the color of that node. Every node in the Red Black Tree contains five fields p for parent, left for left child, right for right child, key for data value and color for color of the node.
The properties of Red Black Tree are as follows:
1. In this tree each and every node is either painted with red color or painted with black color.
2. The root node of the Red Black tree is always black. (This rule is not right in every condition. Since the root can always be changed from red to black, but not true for the change of color from black to red always)
3. All leaf nodes (NIL) are painted in black color.
4. For each red node its children are always black.
In the Red Black Tree each path from a node to its leaf contains equal number of black nodes.
Fig: Red Black Tree
B-Tree is a tree data structure in which each node can have at least two children and special attributes, that is, it stores the number of keys currently in node with the keys themselves. It also contains a boolean field which to confirm that if a node is internal node or the leaf node.
Fig: B-Tree
As the root node in a Red Black tree is black, we can say that if a black node would absorb its red children and incorporate them with its black children, we would get a new data structure.
This data structure would be a generalized version of Binary search tree, a tree with features similar to B Tree. It is because if all the black nodes would absorb its red children and make their children as its own, then the red black tree’s height will reduce and there will be many nodes in a single level. As per the definitions of B-Tree, this description suits well.
Hence, in a Red Black Tree, if the black node absorbs its red children and incorporate its own children in that place, then the new formed data structure will be the B-Tree.


--- layout: post authors: ["Raniere Silva"] title: "Software Carpentry at Brazilian Open Science Conference" date: 2014-08-23 time: "15:00:00" tags: ["Opinion", "Latin America"] ---
Last week, Raniere Silva and Alex Viana attended at Brazilian Open Science Conference where they ran a Git course for Software Carpentry and Alex gave a talk about Software Carpentry (like the one that Damien Irving gave at PyCon Australia). Our workshop was a great time and from the feedbacks every student like it. One of the students said:
Very didactic, the instructors showed much care, dedication and attention with the students.and another one
Very good, from the basic to complex in a easy way.
This course was different from most all of previous Git lesson taught by
Software Carpentry instructors because (1) we used Git GUI instead of the
command line and (2) we teach git fetch
and git
merge
instead of git pull
.
Related with the use of Git GUI we choose it because we won't have time
to teach the shell lessons and all students hadn't an programmer background. I
was a little afraid that the GUI will be difficult for students to follow but
this didn't happen. About teach git fetch
and git merge
we do that as one
experiment to get data from one of our internal discussion and look like that
students didn't problem with that.
Most all the students complain about the short time for the lesson although we had three hours of class. In my opinion this complaints was due, in part, because of the fact that we start the lesson half one hour later since students are later and we need to end it on the scheduled time.
Other complains raised by the students was: have more exercises and explore the doors opened by this tool. I and Alex will try to address this in the others workshops here in Brazil and will be happy to get suggestions on how to do that.


Heat face the 76ers, seek 6th straight victory
by Associated PressMiami Heat (11-3, second in the Eastern Conference) vs. Philadelphia 76ers (10-5, fifth in the Eastern Conference)
Philadelphia; Saturday, 7 p.m. EST
Miami comes into a matchup against Philadelphia as winners of five games in a row.
Philadelphia finished 51-31 overall and 31-21 in Eastern Conference games in the 2018-19 season. The 76ers averaged 7.4 steals, 5.3 blocks and 14.9 turnovers per game last season.
Miami finished 39-43 overall and 20-21 on the road a season ago. The Heat averaged 24.3 assists per game on 39.6 made field goals last season.
The matchup Saturday is the first meeting of the season between the two teams.
76ers Injuries: Josh Richardson: day to day (hip).
Heat Injuries: Justise Winslow: out (concussion), KZ Okpala: out (left achilles strain), Derrick Jones Jr.: out (hip).
___
The Associated Press created this story using technology provided by Data Skrive and data from Sportradar.