答:
I'll assume you're talking about a 3D vector here. Can you just generalize normalize() like that? Is it that common (i've never seen it so if it is, then news to me). Otherwise, obvious compass wrap issues apply to each of the X and Y components. Why not call them roll and/or pitch and/or yaw? (mixing 3D and 2D nomenclature confuses the question).

My 2D normalize looks something like this;

```<code>int Pilot_QuickestTurnTo(int hdgNow, int hdgNew)
{
    hdgNow = Pilot_Hdg360(hdgNow);
    hdgNew = Pilot_Hdg360(hdgNew);
    if (hdgNow < hdgNew)
        hdgNow += 360;
    int left = hdgNow - hdgNew;
        return (left < 181 ? -left : 360 - left);
}
</code>```

If it is indeed a quad, I assume your X and Y components are really YAW, Altitude ( (X, Y) & Z). You'll need to handle the YAW(X, Y) in 2D, and simply drop or gain altitude for Z (and again that's why I suspect normalize is more than you have it as).

Title: Guiding a Quadrotor Towards a Target

Body:
I am working on a quadrotor.  I know its position -- $a$, where I would like to go -- target position $b$, and from that I calculate a vector $c$ -- a unit vector that will take me to my target:

```<code>c = b - a
c = normalize(c)
</code>```

Since a quadrotor can move in any direction without rotation, what I have tried to do is

rotate $c$ by the robots yaw angle

split it into its $x, y$ components

pass them to the robot as roll and pitch angles.

The problem is that if the yaw is 0° ±5 then this works, but if the yaw is near +90 or -90 it fails and steers to wrong directions. My question is am I missing something obvious here?

Body:
I'll assume you're talking about a 3D vector here. Can you just generalize normalize() like that? Is it that common (i've never seen it so if it is, then news to me). Otherwise, obvious compass wrap issues apply to each of the X and Y components. Why not call them roll and/or pitch and/or yaw? (mixing 3D and 2D nomenclature confuses the question).

My 2D normalize looks something like this;

int Pilot_QuickestTurnTo(int hdgNow, int hdgNew)
{
    hdgNow = Pilot_Hdg360(hdgNow);
    hdgNew = Pilot_Hdg360(hdgNew);
    if (hdgNow < hdgNew)
        hdgNow += 360;
    int left = hdgNow - hdgNew;
        return (left < 181 ? -left : 360 - left);
}

If it is indeed a quad, I assume your X and Y components are really YAW, Altitude ( (X, Y) & Z). You'll need to handle the YAW(X, Y) in 2D, and simply drop or gain altitude for Z (and again that's why I suspect normalize is more than you have it as).


问:
Assuming I have the angle with respect to two beacons, and know the distance between them, can I localize myself?
Let's assume I have the following situation, and need to find (x,y).

Is it possible? There does not appear to be more than one solution to the system, but my trigonometry is a bit rusty.

I feel like I need one more distance.

答:
If we assume that the origin of the reference frame is the left beacon, then it holds:

$$
\begin{cases} \tan\theta_1=\frac{x}{y} \\
\tan\theta_2=\frac{d-x}{y} \end{cases}.
$$

We finally derive the following relations:

$$
\begin{cases} x=\frac{d\cdot\tan\theta_1}{\tan\theta_1+\tan\theta_2} \\
y=\frac{d}{\tan\theta_1+\tan\theta_2} \end{cases}.
$$

ContentLicense: CC BY-SA 3.0


答:
Octopus's answer assumes you only know D and θ₁ + θ₂.  If that's all you know, then many points are possible solutions.

However, your diagram shows θ₁, θ₂ separately, as if they are true headings to the beacons.  If that is so, and if you know the (x,y) locations of the beacons, then it is possible to solve for your unknown location.

Suppose B₁=(x₁,y₁) and B₂=(x₂,y₂) are the locations of the two beacons, and B₀=(x₀,y₀) is the unknown location.  Equations of the lines B₀B₁ and B₀B₂ are x-x₁=(y-y₁)tanθ₁ and x-x₂=(y-y₂)tanθ₂, respectively, supposing your headings are relative to the y-axis.  At point B₀ we have x₀-xᵢ=(y₀-yᵢ)tanθᵢ so x₀ = (y₀-y₁)tanθ₁-x₁ =  (y₀-y₂)tanθ₂-x₂ giving y₀(tanθ₁-tanθ₂) = y₁tanθ₁-y₂tanθ₂+x₁-x₂ whence y₀ = (y₁tanθ₁-y₂tanθ₂+x₁-x₂)/(tanθ₁-tanθ₂).  Then back-substitute to get x₀.

Title: Assuming I have the angle with respect to two beacons, and know the distance between them, can I localize myself?

Body:
Let's assume I have the following situation, and need to find (x,y).

Is it possible? There does not appear to be more than one solution to the system, but my trigonometry is a bit rusty.

I feel like I need one more distance.


问:
How can I make a quadcopter avoid obstacles using infrared?
I have a quadcopter built, and I need to be able to make it to autonomously follow a route and avoid obstacles where possible.

My general plan is to have an array of sensors on a pre-defined "front". The quadcopter will only go forward. Generally I'd like to make  it so that if the sensors pointing at a higher angle detect something getting closer as the bot moves forward, the quadcopter will stop, descend until the distance to that detected object decreases, and then continues forward. Similarly, I'd like the opposite event to happen if the sensors pointing at a lower angle detect something getting closer to the quadcopter.

I'm thinking of having something like 9 small infrared distance detectors (pointing up, forward, down || left, forward, right), basically a 3x3 matrix.

Would anyone have any ideas of the feasibility of this? I'd like to use a raspberry pi, but it will probably also need an additional board to read in the values from its sensors. In addition, I have no idea which sensors to use, or if infrared can even work. Any suggestions are more than welcome.

I was also thinking about ultrasonic sensors, but having 9 of them could get cluttered, and I'd worry about their short range when a crash means death for the quadcopter. I also fear they would cause interference with each other.

答: Ultrasonic sensors will in my experience give you better range and accuracy than infrared, unless specifically dealing with many smooth, or sound dampening surfaces. You can poll them one at a time in order to not cause interference, and use some that use I2C (like these), then you could directly attach them to the raspberry pi to poll the values. What flight controller are you using? for most you could simply send direction data over the GPIO. </p>


问:
Strategies for managing power on electrical systems for mobile robots
What are some good strategies to follow while designing power supply for electrical systems on mobile robots?

Such robots typically comprise of systems with

microprocessor, microcontroller, DSP, etc units and boards along with immediate peripherals

Motor control

Analog Sensors(proximity, audio, voltage, etc)

Digital Sensors (Vision, IMU, and other exotica)

Radio comm circuits (Wifi, Bluetooth, Zigbee, etc)

Other things more specific to the purpose of the robot being designed.

Are there unified approaches/architectural rules to designing power systems which can manage clean power supply to all these various units which may be distributed across boards, without issues of interference, common ground, etc? Furthermore, also including aspects of redundancy, failure management, and other such 'power management/monitoring' features?

well explained examples of some such existing power systems on robots would make for excellent answers.

答:
Although it depends on the vehicle mission, these are also worth thinking about power-architecture (not implementation):

If your robot has a payload (that is not used for moving or controlling the robot), try to have a separate power source for the payload.

Isolate the motors, through a separate battery if required. So that even if the motors die, your camera or other systems would still be able to function.

If you will send the robot out of eye sight make sure you have at least some beacon to later find it when the batteries die out. Today, I heard that an RC model got lost (power outage or some other fatal error). If it had a beacon, it could have been saved.


答:
+1 Ugo's answer.  To show the process a bit more:

We have two ways to calculate $y$:

$$
y = \frac{x}{\tan{\theta_1}} = \frac{d-x}{\tan{\theta_2}}
$$

So we can use this equality (ignoring $y$ completely for the moment) to solve for $x$.  We start by cross multiplying:

$$
\begin{align}
x \tan{\theta_2} & = (d - x) \tan{\theta_1} \\
x \tan{\theta_2} & = d \tan{\theta_1} - x \tan{\theta_1} \\
x \tan{\theta_1} + x \tan{\theta_2} & =  d \tan{\theta_1} \\
x (\tan{\theta_1} + \tan{\theta_2}) & =  d \tan{\theta_1} \\
x & = \frac{d \tan{\theta_1}}{\tan{\theta_1} + \tan{\theta_2}}
\end{align}
$$

And since we know that $y = \frac{x}{\tan{\theta_1}}$ we plug in the equation we have for $x$ (which conveniently cancels the $\tan{\theta_1}$ term) to get:

$$
y = \frac{d}{\tan{\theta_1} + \tan{\theta_2}}
$$


问:
how to implement and code inner and outer PD controllers for quadrotor for position tracking
The quadrotor system is  multi-ODEs equations. The linearized model is usually used especially for position tracking, therefore one can determine the desired x-y positions based on the roll and pitch angles. As a result,  one nested loop which has inner and outer controllers is needed for controlling the quadrotor. For implementation, do I have to put while-loop inside ode45 for the inner attitude controller? I'm asking this because I've read in a paper that the inner attitude controller must run faster (i.e. 1kHz) than the position controller (i.e. 100-200 Hz). In my code, both loops run at 1kHz, therefore inside ode45 there is no while-loop. Is this correct for position tracking? If not, do I have to insert while-loop inside ode45 for running the inner loop? Could you please suggest me a pseudocode for position tracking?

To be more thorough, the dynamics equations of the nonlinear model of the quadrotor is provided  here, if we assume the small angles, the model is reduced to the following equations

$$
\begin{align}
\ddot{x}      &= \frac{U_{1}}{m} ( \theta \cos\psi + \phi \sin\psi) \\
\ddot{y}      &= \frac{U_{1}}{m} ( \theta \sin\psi - \phi \cos\psi) \\
\ddot{z}      &= \frac{U_{1}}{m} - g   \\
\ddot{\phi}   &= \frac{l}{I_{x}} U_{2} \\
\ddot{\theta} &= \frac{l}{I_{y}} U_{3} \\
\ddot{\psi}   &= \frac{1}{I_{z}} U_{4} \\
\end{align}
$$

The aforementioned equations are linear. For position tracking, we need to control $x,y,$ and $z$, therefore we choose the desired roll and pitch (i.e. $\phi^{d} \ \text{and} \ \theta^{d}$)

$$
\begin{align}
\ddot{x}^{d} &= \frac{U_{1}}{m} ( \theta^{d} \cos\psi + \phi^{d} \sin\psi) \\
\ddot{y}^{d} &= \frac{U_{1}}{m} ( \theta^{d} \sin\psi - \phi^{d} \cos\psi) \\
\end{align}
$$

Therefore, the closed form for the desired angles can be obtained as follows

$$
\begin{bmatrix}
\phi_{d} \\
\theta_{d}
\end{bmatrix}
=
\begin{bmatrix}
\sin\psi & \cos\psi \\
-\cos\psi & \sin\psi
\end{bmatrix}^{-1}
\left( \frac{m}{U_{1}}\right)
\begin{bmatrix}
\ddot{x}^{d} \\
\ddot{y}^{d}
\end{bmatrix}
$$

My desired trajectory is shown below

The results are

And the actual trajectory vs the desired one is

My code for this experiment is

```<code>%%
%######################( Position Controller )%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

clear all;
clc;

dt = 0.001;
 t = 0;

% initial values of the system
 x = 0;
dx = 0;
 y = 0;
dy = 0;
 z = 0;
dz = 0;

   Phi = 0;
  dPhi = 0;
 Theta = 0;
dTheta = 0;
   Psi = pi/3;
  dPsi = 0;

%System Parameters:
m  = 0.75;      % mass (Kg)
L  = 0.25;      % arm length (m)
Jx = 0.019688; % inertia seen at the rotation axis. (Kg.m^2)
Jy = 0.019688; % inertia seen at the rotation axis. (Kg.m^2)
Jz = 0.039380; % inertia seen at the rotation axis. (Kg.m^2)
g  = 9.81;      % acceleration due to gravity m/s^2

errorSumX = 0;
errorSumY = 0;
errorSumZ = 0;

errorSumPhi   = 0;
errorSumTheta = 0;

pose = load('xyTrajectory.txt');

DesiredX = pose(:,1);
DesiredY = pose(:,2);
DesiredZ = pose(:,3);

dDesiredX = 0;
dDesiredY = 0;
dDesiredZ = 0;

DesiredXpre = 0;
DesiredYpre = 0;
DesiredZpre = 0;

dDesiredPhi = 0;
dDesiredTheta = 0;
DesiredPhipre = 0;
DesiredThetapre = 0;

for i = 1:6000

   % torque input
   %&&&&&&&&&&&&( Ux )&&&&&&&&&&&&&&&&&&
   Kpx = 50; Kdx = 8; Kix = 0;
   Ux = Kpx*( DesiredX(i) - x  ) + Kdx*( dDesiredX - dx ) + Kix*errorSumX;

   errorSumX = errorSumX + ( DesiredX(i) - x );

     dDesiredX = ( DesiredX(i) - DesiredXpre ) / dt;
   DesiredXpre = DesiredX(i);

   %&&&&&&&&&&&&( Uy )&&&&&&&&&&&&&&&&&&
   Kpy = 100; Kdy = 10; Kiy = 0;
   Uy = Kpy*( DesiredY(i) - y  ) + Kdy*( dDesiredY - dy ) + Kiy*errorSumY;

   errorSumY = errorSumY + ( DesiredY(i) - y );

     dDesiredY = ( DesiredY(i) - DesiredYpre ) / dt;
   DesiredYpre = DesiredY(i);

   %&&&&&&&&&&&&( U1 )&&&&&&&&&&&&&&&&&&
   Kpz = 100; Kdz = 20; Kiz = 0;
   U1 = Kpz*( DesiredZ(i) - z ) + Kdz*( dDesiredZ - dz ) + Kiz*errorSumZ;

   errorSumZ = errorSumZ + ( DesiredZ(i) - z );

      dDesiredZ = ( DesiredZ(i) - DesiredZpre ) / dt;
   DesiredZpre = DesiredZ(i);

   %#######################################################################
   %#######################################################################
   %#######################################################################
   % Desired Phi and Theta
   R = [  sin(Psi),cos(Psi);
         -cos(Psi),sin(Psi)];

   DAngles = R\( (m/U1)*[Ux; Uy]);

   %Wrap angles
   DesiredPhi   = wrapToPi( DAngles(1) ) /2;
   DesiredTheta = wrapToPi( DAngles(2) );

   %&&&&&&&&&&&&( U2 )&&&&&&&&&&&&&&&&&&
   KpP = 100; KdP = 10; KiP = 0;
   U2 = KpP*( DesiredPhi - Phi ) + KdP*( dDesiredPhi - dPhi )  + KiP*errorSumPhi;

   errorSumPhi = errorSumPhi + ( DesiredPhi - Phi );

     dDesiredPhi = ( DesiredPhi - DesiredPhipre ) / dt;
   DesiredPhipre = DesiredPhi;

   %--------------------------------------
   %&&&&&&&&&&&&( U3 )&&&&&&&&&&&&&&&&&&

   KpT = 100; KdT = 10; KiT = 0;
   U3 = KpT*( DesiredTheta - Theta ) + KdP*( dDesiredTheta - dTheta ) + KiT*errorSumTheta;

    errorSumTheta = errorSumTheta + ( DesiredTheta - Theta );

     dDesiredTheta = ( DesiredTheta - DesiredThetapre ) / dt;
   DesiredThetapre = DesiredTheta;

   %--------------------------------------
   %&&&&&&&&&&&&( U4 )&&&&&&&&&&&&&&&&&&
   KpS = 80; KdS = 20.0; KiS = 0.08;
   U4 = KpS*( 0 - Psi ) + KdS*( 0 - dPsi );

   %###################( ODE Equations of Quadrotor )###################
   %===================( X )=====================
   ddx = (U1/m)*( Theta*cos(Psi) + Phi*sin(Psi) );

    dx = dx + ddx*dt;
     x =  x +  dx*dt;
   %===================( Y )=====================
   ddy = (U1/m)*( Theta*sin(Psi) - Phi*cos(Psi) );

    dy = dy + ddy*dt;
     y =  y +  dy*dt;

   %===================( Z )=====================
   ddz = (U1/m) - g;

    dz = dz + ddz*dt;
     z =  z +  dz*dt;

   %===================( Phi )=====================
   ddPhi = ( L/Jx )*U2;

    dPhi = dPhi + ddPhi*dt;
     Phi =  Phi +  dPhi*dt;

   %===================( Theta )=====================
   ddTheta =  ( L/Jy )*U3;

    dTheta =  dTheta + ddTheta*dt;
     Theta =   Theta +  dTheta*dt;

   %===================( Psi )=====================
   ddPsi =  (1/Jz)*U4;

    dPsi = dPsi + ddPsi*dt;
     Psi =  Psi +  dPsi*dt;

   %store the erro
     ErrorX(i)   = ( x - DesiredX(i) );
     ErrorY(i)   = ( y - DesiredY(i) );
     ErrorZ(i)   = ( z - DesiredZ(i) );
%    ErrorPhi(i)   = ( Phi - pi/4 );
%    ErrorTheta(i) = ( Theta - pi/4 );
     ErrorPsi(i)   = ( Psi - 0 );

   X(i) = x;
   Y(i) = y;
   Z(i) = z;

   T(i) = t;

%    drawnow
%    plot3(DesiredX, DesiredY, DesiredZ, 'r')
%    hold on
%    plot3(X, Y, Z, 'b')
   t = t + dt;

end

Figure1 = figure(1);
set(Figure1,'defaulttextinterpreter','latex');
%set(Figure1,'units','normalized','outerposition',[0 0 1 1]);

subplot(2,2,1)
plot(T, ErrorX, 'LineWidth', 2)
title('Error in $x$-axis Position (m)')
xlabel('time (sec)')
ylabel('$x_{d}(t) - x(t)$', 'LineWidth', 2)

subplot(2,2,2)
plot(T, ErrorY, 'LineWidth', 2)
title('Error in $y$-axis Position (m)')
xlabel('time (sec)')
ylabel('$y_{d}(t) - y(t)$', 'LineWidth', 2)

subplot(2,2,3)
plot(T, ErrorZ, 'LineWidth', 2)
title('Error in $z$-axis Position (m)')
xlabel('time (sec)')
ylabel('$z_{d} - z(t)$', 'LineWidth', 2)

subplot(2,2,4)
plot(T, ErrorPsi, 'LineWidth', 2)
title('Error in $\psi$ (m)')
xlabel('time (sec)')
ylabel('$\psi_{d} - \psi(t)$','FontSize',12);
grid on

Figure2 = figure(2);
set(Figure2,'units','normalized','outerposition',[0 0 1 1]);

figure(2)
plot3(X,Y,Z, 'b')
grid on

hold on
plot3(DesiredX, DesiredY, DesiredZ, 'r')

pos = get(Figure2,'Position');
set(Figure2,'PaperPositionMode','Auto','PaperUnits','Inches','PaperSize',[pos(3),pos(4)]);
print(Figure2,'output2','-dpdf','-r0');

legend('actual', 'desired')
</code>```

The code of the desired trajectory is

```<code>clear all; clc;

fileID = fopen('xyTrajectory.txt','w');

 angle = -pi; radius = 5; z = 0; t = 0;

for i = 1:6000
    if ( z < 2 )
        z = z + 0.1;
        x = 0;
        y = 0;
    end
    if  ( z >= 2 )
        angle = angle + 0.1;
        angle = wrapToPi(angle);
        x = radius * cos(angle);
        y = radius * sin(angle);
        z = 2;
    end

    X(i) = x;
    Y(i) = y;
    Z(i) = z;

    fprintf(fileID,'%f \t %f \t %f\n',x, y, z); end

fclose(fileID); plot3(X,Y,Z) grid on
</code>```

答:
Your pseudocode for PD like this:

```<code>Kp Kd
erroSum=errorSum+(desired-actual);
ddesired=(desired-predesired)/dt;
desiredpre=desired;
PD= Kp*(desired-actual)+Kd*(ddesired-dactual)
</code>```

Try to apply this:

```<code>previosuerror=0
Kp Kd
error=(desired-actual); //for angles use atan2(sin(desired),cos(actual)) neglect sign
derivative=(previouserror-error)/dt;
previouserror=error;
P=Kp*error;
D=Kd*derivative;
PD=P+D;
</code>```

Reference: first 3 module of https://class.coursera.org/conrob-001

Body:
Your pseudocode for PD like this:

Kp Kd
erroSum=errorSum+(desired-actual);
ddesired=(desired-predesired)/dt;
desiredpre=desired;
PD= Kp*(desired-actual)+Kd*(ddesired-dactual)

Try to apply this:

previosuerror=0
Kp Kd
error=(desired-actual); //for angles use atan2(sin(desired),cos(actual)) neglect sign
derivative=(previouserror-error)/dt;
previouserror=error;
P=Kp*error;
D=Kd*derivative;
PD=P+D;

Reference: first 3 module of https://class.coursera.org/conrob-001


问:
Odometry vs Dead-reckoning
In terms of robotics, what are the differences between odometry and dead-reckoning?

I read that odometry uses wheel sensors to estimate position, and dead-reckoning also uses wheel sensors, but "heading sensors" as well. Can someone please elaborate on this point for me?

答: Dead-reckoning systems are based on estimating position relative to sensors. These sensors can be accelerometers, gyroscopes, whell encoders, infrared sensors, cameras etc. which have to placed on body of robot. So we can calculate displacement or coordinates. Odometry is a sub topic of dead-reckoning and based on wheel displacement calculations. </p>

Title: Odometry vs Dead-reckoning


问:
Least squares map joining
There is a lot of background here, scroll to the bottom for the question

I am trying out the map joining algorithm described in How Far is SLAM From a Linear Least Squares Problem; specifically, formula (36).  The code I have written seems to always take the values of the second map for landmark positions.  My question is, am I understanding the text correctly or am I making some sort of error. I'll try to explain the formulas as I understand them and show how my code implements that.  I'm trying to do the simple case of joining just two local maps.

From the paper (36) says joining two local maps is finding the a state vector $X_{join,rel}$ that minimizes:

$$
\sum_{j=1}^{k}(\hat{X_j^L} - H_{j,rel}(X_{join,rel}))^T(P_j^L)^{-1}(\hat{X_j^L} - H_{j,rel}(X_{join,rel}))
$$

Expanded for two local maps $\hat{X_1^L}$ and $\hat{X_2^L}$ I have:

$$
(\hat{X_1^L} - H_{j,rel}(X_{join,rel}))^T(P_1^L)^{-1}(\hat{X_1^L} - H_{j,rel}(X_{join,rel})) + (\hat{X_2^L} - H_{j,rel}(X_{join,rel}))^T(P_2^L)^{-1}(\hat{X_2^L} - H_{j,rel}(X_{join,rel}))
$$

As I understand it, a submap can be viewed as an integrated observation for a global map, so $P^L_j$ is noise associated with the submap (as opposed to being the process noise in the EKF I used to make the submap, which may or may not be different).

The vector $X_{join,rel}$ is the pose from the first map, the pose from the second map and the union of the landmarks in both maps.

The function $H_{j,rel}$ is:

$$
\begin{bmatrix} X_{r_{je}}^{r_{(j-1)e}}\\
                 \phi_{r_{je}}^{r_{(j-1)e}}\\
                 R(\phi_{r_{(j-1)e}}^{r_{m_{j1}e}})
                        (X^{r_{m_{j1}e}}_{f_{j1}} -
                         X^{r_{m_{j1}e}}_{r_{(j-1)e}})\\.\\.\\.\\
                 R(\phi_{r_{(j-1)e}}^{r_{m_{jl}e}})
                        (X^{r_{m_{jl}e}}_{f_{jl}} -
                         X^{r_{m_{jl}e}}_{r_{(j-1)e}})\\
                         X_{f_{j(l+1)}}^{r_{j-1e}}\\
                         .\\.\\.\\
                         X_{f_{jn}}^{r_{j-1e}}
\end{bmatrix}
$$

I'm not convinced that my assessment below is correct:

The first two elements are the robot's pose in the reference frame of the previous map.  For example, for map 1, the pose will be in initial frame at $t_0$; for map 2, it will be in the frame of map 1.

The next group of elements are those common to map 1 and map 2, which are transformed into map 1's reference frame.

The final rows are the features unique to map 2, in the frame of the first map.

My matlab implementation is as follows:

```<code>function [G, fval, output, exitflag] = join_maps(m1, m2)
    x = [m2(1:3);m2];
    [G,fval,exitflag,output] = fminunc(@(x) fitness(x, m1, m2), x, options);
end

function G = fitness(X, m1, m2)
    m1_f = m1(6:3:end);
    m2_f = m2(6:3:end);
    common = intersect(m1_f, m2_f);
    P = eye(size(m1, 1)) * .002;
    r = X(1:2);
    a = X(3);
    X_join = (m1 - H(X, common));
    Y_join = (m2 - H(X, common));
    G = (X_join' * inv(P) * X_join) + (Y_join' * inv(P) * Y_join);
end

function H_j = H(X, com)
    a0 = X(3);
    H_j = zeros(size(X(4:end)));
    H_j(1:3) = X(4:6);
    Y = X(1:2);
    len = length(X(7:end));
    for i = 7:3:len
        id = X(i + 2);
        if find(com == id)
            H_j(i:i+1) = R(a0) * (X(i:i+1) - Y);
            H_j(i+2) = id;
        else  % new lmk
            H_j(i:i+2) = X(i:i+2);
        end
    end
end

function A = R(a)
    A = [cos(a) -sin(a);
         sin(a)  cos(a)];
end
</code>```

I am using the optimization toolbox to find the minimum of the fitness function described above.  The fitness function itself is pretty straightforward I think.  The function H returns the vector H described above.

The result is:
When I run join_maps on the two vectors

```<code>map_1 = [3.7054;1.0577;-1.9404; %robot x, y, angle
      2.5305;-1.0739;81.0000]; % landmark x, y, id
map_2 = [3.7054;1.0577;-1.9404;
         2.3402;-1.1463;81.0000]; % note the slightly different x,y

[G,fv,output,exitflag] = join_maps(map_1, map_2)
</code>```

The output is:

```<code>Warning: Gradient must be provided for trust-region algorithm;
  using line-search algorithm instead.
> In fminunc at 341
  In join_maps at 7

Local minimum found.

Optimization completed because the size of the gradient is less than
the default value of the function tolerance.

<stopping criteria details>

Local minimum possible.

fminunc stopped because it cannot decrease the objective function
along the current search direction.

<stopping criteria details>

G =
      3.7054
      1.0577
     -1.9404
      3.7054
      1.0577
     -1.9404
      2.3402
     -1.1463
      81.0000

 fv =
     1.3136e+07
  output =
     iterations: 1
      funcCount: 520
       stepsize: 1.0491e-16
  firstorderopt: 1.6200e+05
      algorithm: 'medium-scale: Quasi-Newton line search'
        message: [1x362 char]
  exitflag =
   5
</code>```

The question:

My program gives map 2 is the minimum of the map joining function.  It seems like the minimum should be somewhere between map 1 and map 2.  I'm pretty sure the problem is with the matrix H.  What am I doing wrong?

答:
This seems to work correctly and is a much simpler solution:

```<code>function [X, FVAL, EXITFLAG, OUTPUT, GRAD] = join_maps(m1, m2)
    p = [m1(1:3);m2(1:3)];
    x1 = [p;m1(4:end)];
    x2 = [p;m2(4:end)];
    guess_0 = zeros(size(x1,1),1);
    q = @(x)x'*eye(length(x))*x;
    fit = @(x)q(x1-x)+q(x2-x);
    [X,FVAL,EXITFLAG,OUTPUT,GRAD] = fminunc(fit ,guess_0);
end
</code>```

I've changed the output to better match the description for fminunc.

The output with map_1 and map_2 is

```<code>X =
 3.7054
 1.0577
-1.9404
 3.7054
 1.0577
-1.9404
 2.4353
-1.1101
 81.0000
</code>```

In this case, there is no need to call H(X), because the first two poses are identical, so the two maps share the same frame of reference.  The function H just transforms the state estimate into the frame of reference of the submap.

Title: Least squares map joining

Body:
This seems to work correctly and is a much simpler solution:

function [X, FVAL, EXITFLAG, OUTPUT, GRAD] = join_maps(m1, m2)
    p = [m1(1:3);m2(1:3)];
    x1 = [p;m1(4:end)];
    x2 = [p;m2(4:end)];
    guess_0 = zeros(size(x1,1),1);
    q = @(x)x'*eye(length(x))*x;
    fit = @(x)q(x1-x)+q(x2-x);
    [X,FVAL,EXITFLAG,OUTPUT,GRAD] = fminunc(fit ,guess_0);
end

I've changed the output to better match the description for fminunc.

The output with map_1 and map_2 is

X =
 3.7054
 1.0577
-1.9404
 3.7054
 1.0577
-1.9404
 2.4353
-1.1101
 81.0000

In this case, there is no need to call H(X), because the first two poses are identical, so the two maps share the same frame of reference.  The function H just transforms the state estimate into the frame of reference of the submap.


答:
Deduced reckoning is figuring out where you are after starting from a known position, by using your speed, direction and time.  (It's effectively integration of velocity, if you want the calculus/mathematical version).

At sea you would know your direction from a compass, speed by any one of various means, and important complications like the wind speed and direction would be estimated.

Odometry is really just doing the same thing on the ground, instead of at sea.  Instead you count your "footsteps" as an estimate of your walking speed.  A wheeled vehicle would instead count wheel revolutions, that's equivalent to counting footsteps.

Odometry isn't very accurate on its own as wheel slippage, carpet "springiness" and uneven floors can affect accuracy.  A separate heading sensor can help with accurate headings at least, though.

For an old (1996!) but detailed account of odometry, I like Borenstein's "Where am I" technical report, which has a lot of outdated information but a still-good description of odometry and its inaccuracies.  It's linked from this page:
http://www-personal.umich.edu/~johannb/mypapers.htm
(Beware it's quite a large download.)

Title: Odometry vs Dead-reckoning

Body:
In terms of robotics, what are the differences between odometry and dead-reckoning?

I read that odometry uses wheel sensors to estimate position, and dead-reckoning also uses wheel sensors, but "heading sensors" as well. Can someone please elaborate on this point for me?


问:
Linear Motion Control for quadrotor (clarification)
I've posted a question regarding this matter that I couldn't solve. I'm reading this paper, the authors state

Linear $x$ and $y$ Motion Control: From the mathematical model one can see
  that the motion through the axes $x$ and $y$ depends on $U_{1}$. In fact $U_{1}$ is
  the total thrust vector oriented to obtain the desired linear motion.
  If we consider $U_{x}$ and $U_{y}$ the orientations of $U_{1}$ responsible for the
  motion through x and y axis respectively, we can then extract from
  formula (18) the roll and pitch angles necessary to compute the
  controls $U_{x}$ and $U_{y}$ ensuring the Lyapunov function to be negative
  semi-definite ( see Fig. 2).

The paper is very clear except in the linear motion control. They didn't explicitly state the equations for extracting the angles. The confusing part is when they say

we can then extract from
  formula (18) the roll and pitch angles necessary to compute the
  controls $U_{x}$ and $U_{y}$

where formula (18) is

$$
U_{x} = \frac{m}{U_{1}} (\cos\phi \sin\theta \cos\psi + \sin\phi \sin\psi) \\
U_{y} = \frac{m}{U_{1}} (\cos\phi \sin\theta \sin\psi - \cos\phi \cos\psi) \\
$$

It seems to me that the roll and pitch angles depend on $U_{x}$ and $U_{y}$, therefore we compute the roll and pitch angles based on the $U_{x}$ and $U_{y}$ to control the linear motion.

答:
I reckon that the equations you raised in your previous post, in the assumption of small angles, already give us the intuition that $U_1$ is used to keep the height $z$ as desired, so that what is left to us to control the linear displacement $x$ and $y$ of the quadcopter is the roll $\phi$ and pitch $\theta$.

Therefore, your last equation to find out the desired $\phi_d$ and $\theta_d$ as function of linear acceleration $\ddot{\hat{x}}_d$ and $\ddot{\hat{y}}_d$ is correct.

Of course, then, you'll impose some tracking behavior such as the one I've seen in your script that relates the linear acceleration with the displacement error, something like the well known impedance control law: $\ddot{\hat{x}}_d=K_p\left(x_d-x\right)+K_d\dot{x}$. Note how $\ddot{\hat{x}}_d \neq \frac{d^2x_d}{dt^2}$.

In this case it is evident how you don't employ the yaw $\psi$ for the linear displacement: it's simply kept constant. It is usually used for more complicated maneuvers indeed.

If the small angle assumption does no longer hold, then you're forced to rely on the Eq.(6) described in the paper you cited, which still doesn't change too much the story.

I don't know how familiar you're with Simulink, but it'd be much easier to simulate this system by means of it.


问:
Help with ultrasonic sensors on obstacles avoiding robot
Well, I will start directly in my problem. I'm working on a project and I only have 10 days left.
The idea is simple, a wheeled robot with 3 ultrasonic sensors to avoid obstacles.
I've developed a code and it's working fine.
I'm using: Arduino Uno, L293D driver for the 2 dc motors, 3 HC-SR04 ultrasonic sensors and the Newping library.

I've made some kind of a shield where I soldered common points for gnd and 5V in order to connect the L293 ic and the sensors pins easily. The problem is that the ultrasonic sensors only functioned once in the expected behavior! After that they were always sending the zero result and sometimes a number is showed when i disconnect the sensor!
Is it a power problem? I'm using the usb cable to power the arduino and the sensors (motors are powered using 2 Li-po batteries)
kindly provide me with guidance

答: You can convert Line follower PID robot to obstacle avoiding robot. At page 18 write new 3 sensor values instead of 5 line sensors (i assume that you can reduce number sensor and convert follower to avoider)</p>


答:
You may have misread (or else your book misrepresented) the definition odometry; it is not a direct measurement of position, just distance travelled.  Odometry may say that you travelled a mile, but whether you ended up a mile away or right back where you started will depend on other aspects of your movement.

By combining odometry with other measurements, the process of estimating your position -- "dead reckoning" -- becomes more accurate.

Title: Odometry vs Dead-reckoning


问:
What algorithm can I use for constructing a map of an explored area using a number of ultrasound sensors?
Ultrasound sensors are incredibly cheap these days which makes them a popular choice for many hobbyist robotic applications, and I'd like to use a bunch of them (say 10) around a robot with an algorithm to build a rough map of an area (as the robot explores it.) I'm not interested in dealing with moving objects at this stage, just pinpointing stationary ones, and I'll be using GPS for location. I realise that other components such as a laser scanner would produce much more accurate results, however such devices are also astronomically more expensive.

Does an algorithm exist for this purpose?

答:
The algorithms are essentially the same regardless of what sensors you are using.

The real issue, which Chris touched upon, is that SLAM is hard even with very good sensors.

I would consider GPS, wheel odometry, and an IMU to be necessary to even attempt slam with ultrasound.

If you are just looking for cheap localization I recommend taking a look at vision/kinect based slam as well.  Both webcams and the kinect are very cheap and visual slam has come a long way.

The kinect is pretty much the holy grail in terms of sensor performance/cost as long as you are indoors.

Here is an example of a kinect on a robot plus a lot of math: http://www.youtube.com/watch?v=9Y4RQVpp-BY


问:
making a robot that knows your location
I've just made a radio frequency remote control using PIC microcontroller and I want to do something useful with it. I am thinking of a robot that gets things for you while you are at bed but here comes the question: How am I going to have the PIC determine the location of the remote control calling for it? It can't really be done using a GPS module because it will all be in the house.

What options do I have?

答:
It sounds like you want to find an RF transmitter using the robot that receives the signal, which is difficult to do with the degree of accuracy that you would probably need.  The strength of a signal (whether optical, auditory, or RF) in a real-world environment varies due to interference.

Not only that, you'd have to assume that the robot could move directly toward the signal at all times.

The most robotics-oriented way to do this would be to have the transmitter report its position, then have the robot navigate to that position.  This requires both the transmitter and the robot to be able to measure their position.  Features such as the ability to move through rooms of a house or avoid obstacles would require additional time and energy to implement.

Title: making a robot that knows your location


答:
This is a little trick with the HC-SR04s.
Power it on, so its in the broken state.

Flick the wire mesh piece.

The reason might be it doesn't reset itself. These components might be cheap clones and not the real ones, and some of the clones have this problem. Then when you flick it, it resets the depressed component.

More info here:
http://forum.arduino.cc/index.php?topic=55119.0

Title: Help with ultrasonic sensors on obstacles avoiding robot

Body:
Well, I will start directly in my problem. I'm working on a project and I only have 10 days left.
The idea is simple, a wheeled robot with 3 ultrasonic sensors to avoid obstacles.
I've developed a code and it's working fine.
I'm using: Arduino Uno, L293D driver for the 2 dc motors, 3 HC-SR04 ultrasonic sensors and the Newping library.

I've made some kind of a shield where I soldered common points for gnd and 5V in order to connect the L293 ic and the sensors pins easily. The problem is that the ultrasonic sensors only functioned once in the expected behavior! After that they were always sending the zero result and sometimes a number is showed when i disconnect the sensor!
Is it a power problem? I'm using the usb cable to power the arduino and the sensors (motors are powered using 2 Li-po batteries)
kindly provide me with guidance


答:
You asked for examples of existing robots. I once built a 6 wheeled rover robot with the following components:
 - 2 homemade paperclip touch sensors
 - 2 Arduino Unos
 - a 3.3V digital compass
 - a 5V radio transmitter
 - 6 Vex Motor Controller 29's
 - 6 DC motors, Stall current @ 2 amps, 6V

To avoid using complicated electrical stuff (no messing with capacitors or linear voltage regulators), we had 2 batteries, 1 for the "brain", 1 for the body.

The 6 DC motors were powered by a LIPO battery, 5000mAh 7.4V 20C 2cell. The Vex Motor Controller 29's have 3 wires, 1 for data, and Vcc and Ground. It basically converts the motor into a servo. So we had the data wires from the motor controllers go to the Arduino PWM ports (11, 10, 9, 6, 5, 3), and the Vcc's go to the positive terminal of the LIPO, and the negatives to the common ground.

The Arduino Unos, compass, and radio transmitter were powered by 4 AA batteries. The 4 AA batteries fed into the master Arduino, then distributed out to everything else via the 3.3V, 5V, and Vin ports (Arduino Uno has built in 3.3V and 5V linear regulators). So the 3.3V went to the compass, the 5V went to the radio beacon, the Vin went to the slave Arduino.

2 separate batteries is simple. There is no need to worry about back EMF from motors, no need for capacitors or adding voltage regulators.

Title: Strategies for managing power on electrical systems for mobile robots

Body:
What are some good strategies to follow while designing power supply for electrical systems on mobile robots?

Such robots typically comprise of systems with

microprocessor, microcontroller, DSP, etc units and boards along with immediate peripherals

Motor control

Analog Sensors(proximity, audio, voltage, etc)

Digital Sensors (Vision, IMU, and other exotica)

Radio comm circuits (Wifi, Bluetooth, Zigbee, etc)

Other things more specific to the purpose of the robot being designed.

Are there unified approaches/architectural rules to designing power systems which can manage clean power supply to all these various units which may be distributed across boards, without issues of interference, common ground, etc? Furthermore, also including aspects of redundancy, failure management, and other such 'power management/monitoring' features?

well explained examples of some such existing power systems on robots would make for excellent answers.


答:
Robotics is usually a business of various trade-offs, so there is no ultimate solution for power management, as every robot is different. For example, separate battery for motors mentioned by others sometimes may be a good solution, but sometimes cannot be used due to size/weight constraints. There are however some general tips there can be utilized in many designs:

Never use same power source for electronics and motors/servos. Even if your motors are 5V, use separate voltage regulator for electronics, and separate power for motors.

Do not use linear regulators for driving servos/motors. Use DC/DC converters instead. Motors can draw huge amounts of current. Linear regulators usually have poor efficiency, so much of a power will go to a waste in form of heat dissipated on a regulator.

Keep high-current circuits away from other electronics, especially from analog ones.

Consider using hardware or/and software filters if you want reliable and precise ADC readings.

Use capacitors! They are your biggest friends when it comes to fighting interference. As a rule of thumb, you can assume that each IC should have at least one 100n capacitor between each VCC and GND pins pair.

If you many boards distributed all around your robot, consider adding a separate voltage regulator for each board. It will cut out any interference acquired by power cables.

Check out dedicated power management ICs. They can be really clever, signalling power failures, protecting your circuits from reverse polarity, over and under voltage and many, many more.


问:
Dispensing precise quantities of liquid and powder
I've been toying around with the idea of automating the process of testing aquarium water for certain chemicals. Very briefly, salt water aquariums (reefs, specifically) require almost-daily testing for 3-4 chemicals (calcium, alkalinity, ammonia, phosphate). This is typically done by hand, using various kits. There are two main types

you combine several powders with a fixed amount of aquarium water, and then compare the color the mixture turns with a chart

you combine several liquids together with the aquarium water, and then add another liquid until the mixture turns a color. you then record how much of the final liquid you had to add for the color change to occur (titration).

Both methods are straightforward, but tedious. To maintain an aquarium well, you really do need daily readings of all of those metrics, which easily adds up to 30 minutes+ daily.

So - I'd like to be able to automate the process. The biggest question is, how do I reliably dispense the materials needed? We're talking in gram and milliliter UoM here. The kits come with plastic syringes and spoons of correct volume for the powders. I need a way to measure out and dispense both of these, and a way to queue up several days worth (refilling daily defeats the purpose).

Any ideas?

Edit this is different from How to measure and dispense a finite amount of powder or liquid because of the units of measure involved. I need to be able to reliably dispense ~ 1g +/- 5% of a powder, or 1ml +/- 5% of liquid.

答:
So here's a system commmonly used in portioning substances, but I don't know what it's called for you to look it up (sorry). I've included two pictures, one for reference for us to call things by the same name, and another for displaying principle of operation.

A portioner is a disc or other shape that has a hole. The hole is sized to contain the correct quantity of the substance you are trying to portion. Think of it like a measuring spoon.

The portioner goes into a portioner housing, which allows a hopper to attach. It also allows the material contained in the portioner to be released. The hopper allows you to hold as much stock as you would like. One sample, a day, a week - the size of the hopper is up to you.

As far as operation, the disc is configured with its hole aligned towards the hopper. When you want the required quantity of material, you just move the disc to align its hole with the outlet of the portioner housing. The material contained in the hole of the disc falls out.

Note that I've drawn this as a vertical-rotating system, but you could just as easily have a horizontal-translating system. This would look like a cigar cutter.

:EDIT:

To be clear, this setup works with any units of measure. It's as big or as small as you need it to be.


问:
Good method for building a pan and tilt controller?
Have you ever seen one those video games that has headset/goggles you stand in and look around the virtual scene with? I'm building one of those, and I'm trying to design a simple controller. I need the output of the controller to emulate a mouse input. So if you look to the left, it's as if you were moving the mouse to the left. Supposing I use optical encoders, the pan and tilt will need to be in separate locations (a couple of inches apart). It seems that many mouse hacks online have the components very close together.

Do you think it's possible to have one of the encoders some distance away from the controller chip? For OEM purposes, is there a good mouse controller chip that will output USB protocol mouse movements that I could buy in bulk?

Many thanks for any suggestions. Cheers

答:
Probably not the answer you want, but IMU boards have gotten so cheap and easy I'm not sure if going the mouse encoder route is worth the trouble.  I fly FPV quads, and I have the parts for pan and tilt, although not installed yet. The head tracking is built into the goggles (ie no added costs).

I also installed a MultiWii Flight control board this morning and was watching real time signals show roll/pitch/yaw(heading) with the option to add full gps. The board costs less than \$20. It would be pretty easy to install that on a hat, and add a Bluetooth option (another \$8) for easy robust wireless pan and tilt tracking. You would need to do some sort of HUI device driver though, I do not know of anything already existing. Then again, if you are doing all your own software you could access the bluetooth stream directly and avoid needing a driver.


答:
If you know the first location, you can use a laser mouse.

{URL redacted}

Title: making a robot that knows your location

Body:
I've just made a radio frequency remote control using PIC microcontroller and I want to do something useful with it. I am thinking of a robot that gets things for you while you are at bed but here comes the question: How am I going to have the PIC determine the location of the remote control calling for it? It can't really be done using a GPS module because it will all be in the house.

What options do I have?


问:
How can i make a compact soft robot
I want to make a compact (actuators motors and sensors are all in one) soft robot. Actuators can be pneumatic or dielectric. I need suggestions about manufacturating. I'm open to new ideas.</p>

答:
I think dielectric mechanism like piezo are suitable for compact designs.
These might be usefull
http://en.wikipedia.org/wiki/Piezoelectric_motor

https://www.google.com/patents/US4812698

Title: How can i make a compact soft robot


问:
Vacuum Lifter: Moving Playing Cards
I'd like to buy a small Vacuum Lifter so that I can move playing cards around with robotics. But my "google-fu" is failing me. I don't really know what search terms to look for... or what webpages to look to find this kind of component.

In essence, I want an electronic version of a Vacuum Pen.

I don't really know where to search for this kind of component. I've found pneumatic valves and other complicated machinery... but ideally I'd want a self-contained electronic vacuum pen. Since I'm only planning to move playing cards around.

Anyone have an idea where to look for something like this? Thanks.

答:
Vacuum gripper - I think. Perhaps something like the lynxmotion version, which generates the vacuum with a motorised syringe:
http://www.lynxmotion.com/p-788-vacuum-gripper-kit.aspx

Alternatively - a flat electrostatic gripper can be used for paper handling but it involves a high voltage on one side of a plate, covered by a thin plastic sheet.  A bit of research would be needed to get one working though:
http://mechatronics.org/r&d/rob/eag/electroadhesion.pdf

Title: Vacuum Lifter: Moving Playing Cards


问:
How can computer vision distinguish one object being contained by another vs being on top of it?
How do we know that an object is contained inside another object or is just lying on top of it?

Lets take an example of a cup-plate-spoon. The cup is lying on top of the plate. But the spoon is inside the cup. How do we distinguish between the 2 situations? What are the criteria to decide whether A is contained inside B or just lying above B?

I am trying to solve it using kinect.

答:
The problem is much easier, when you want solve this for specific object categories like cup-plate-spoon instead of any generic pair of objects. Also in my opinion there degeneracies as mentioned by DaemonMaker is not going to happen in this case since we have depth image instead of just a 2D image.

When you know the objects in scene and you have a depth image, it is possible to estimate the full 3D orientation (pose) of each of those objects. If the objects in question are rigid, some sort of ICP may be enough in getting this pose. For harder scenarios where the object is non-rigid (humans) or you don't know the exact specific model of the object (say tea cup vs coffee cup), you should refer to some computer-vision/Kinect literature.

Once you have the 3D poses of the objects, answering object-object 3D positional queries will be easier.


问:
Position estimation from photo fingerprinting
i want to make 3d position and position change estimation from photos taken from flying robot. I need suggestions for fast photo matching. </p>

答:
What you're looking for is called an optical flow system: a camera that by recognizing the movement of patterns can estimate the movement of the camera target relative to the camera.  You can implement your own optical flow algorithm through the use of OpenCV, a popular computer vision library.

However, it's more likely that you'll want to use existing sensors with SoCs for optical flow built in, such as those found in optical mice. An example commonly used with quadcopters is this ADNS3080 breakout board, or this one from 3DRobotics.  Good luck!


答:
This 12V vaccum pump from Sparkfun may be of interest to you: link.

In order to drive this pump you could either:

Use an HBridge motor driver for both forwards and reverse variable speed control.  This would allow you to release your playing cards with some force, but it may not be necessary.

If you think you could get away with just stopping the pump to let go of a card, you could simply use a Mosfet to variably control the pump with only a sucking ability and no blowing.

If you don't expect to require variable speed control, you could use a relay to very simply open and close a 12V circuit with the motor.

Good luck.

Title: Vacuum Lifter: Moving Playing Cards

Body:
I'd like to buy a small Vacuum Lifter so that I can move playing cards around with robotics. But my "google-fu" is failing me. I don't really know what search terms to look for... or what webpages to look to find this kind of component.

In essence, I want an electronic version of a Vacuum Pen.

I don't really know where to search for this kind of component. I've found pneumatic valves and other complicated machinery... but ideally I'd want a self-contained electronic vacuum pen. Since I'm only planning to move playing cards around.

Anyone have an idea where to look for something like this? Thanks.


问:
Detect polyethylene
First of all, I am in high school[to tell you that I am a newbie and lack knowledge]

What I want to achieve for now is a thing that can differentiate between poly bags[polyethylene] and other stuffs. Or a thing that could detect polyethylene.

I have to built a robot and therefore we have only a few method accessible.

Anyway any knowledge or suggestion or external links provided by you, about this topic would be welcomed by me.

答: You might be able to do something with hyperspectral imaging.</p>

Title: Detect polyethylene


问:
How can I make a motion tracking camera?
I'm looking into CCTV, and am interested in minimising costs by having a motion tracking camera cover an area that would otherwise utilise multiple cameras.

There is already something like this on the market manufactured by a company called NightWatcher (I think).  However, it does not track, it merely senses using 3 PIR's and points the camera in 1 of 3 positions. Ping ponging between them if the subject is between sensors.

I like the idea of this, but not the drawbacks, and was wondering if there was anything I could do with an arduino or similar to achieve a better result.

I stumbled across this, but am not entirely sure about it. Also this is for outside application, and that thread is for indoor (if that makes a difference).

https://robotics.stackexchange.com/a/1397/9751

Edit...

Just in case I have mislead you, I want to have a unit where sensors detect movement and then a camera to face that position.

答:
Basically you need to solve 3 different problems:

Find the right camera setup and recording strategy
I'm not an expert in this field so I won't say anything to this

Second get the information about a person on the camera. Basically to follow a person in the picture you have to know that there is a person in the picture. So you need something like a machine vision (Let computer decide whether there is a person or not). If you know there is a person you can get there position in the picture easily

The last problem is that you need a motor which moves the camera around. For this application a simple hobby servo motor is sufficient. The motor needs a small controller and some "strategy" how the motor let the camera follow the person.

My first approach to this problems would use a raspberry pi because of two reasons:

It provides the ability to control small servo motors

It can perform simple machine vision tasks

The raspberry is able to use the opencv library easily and there tons of projects how to do people recognition with opencv on the internet.

At the end of the day you will get a pixel value from the recognition algorithm. This value will tell you, that there is a person in the picture and where.
You just need to rotate the camera so far that the person is in the center of your image. This is pretty simple done by using a proprtional controller.

The first problem I see, which you will encounter with this implementation is how the camera will behave when there are 2 or more people in the field of view. But there you can find a solution, too.


问:
2Nm small motor
Currently designing a spherical wrist, I want to manipulate a 300gr payload.
the design has a 200mm span, so I'm guessing at a 1.1Nm (considering the weight of structure & motors).

I've looked at Maxon, Faulhaber, but can't find any motor+gearbox+encoder under a 100gr.
Any suggestion ?

答:
Use a servomotor like some Dynamixal, the MX 28AR meets your listed requirements pretty good.
More then 2Nm torque with 77g weight.

There are other models from dynamixal or other suppliers.

Title: 2Nm small motor


答:
You can do all this with the right software, no sensors required (or the sensors could be other cameras).

The technique you're looking for is known as Frame Differencing - it basically means taking a frame of camera footage and using it as a masking filter on the next frame, this reveals the pixels which have changed in the current frame, these are usually pixels representing observed objects which have moved.

This gives you motion detection and can be done with fairly low resolution 'sensor' cameras, which then tell your main high resolution camera which way to face.

The 'ping-pong' effect would be mitigated by always having the motion target in the center of the main camera's view and only using the interpreted data from the sensor cameras to calculate the object's position.

Title: How can I make a motion tracking camera?

Body:
I'm looking into CCTV, and am interested in minimising costs by having a motion tracking camera cover an area that would otherwise utilise multiple cameras.

There is already something like this on the market manufactured by a company called NightWatcher (I think).  However, it does not track, it merely senses using 3 PIR's and points the camera in 1 of 3 positions. Ping ponging between them if the subject is between sensors.

I like the idea of this, but not the drawbacks, and was wondering if there was anything I could do with an arduino or similar to achieve a better result.

I stumbled across this, but am not entirely sure about it. Also this is for outside application, and that thread is for indoor (if that makes a difference).

https://robotics.stackexchange.com/a/1397/9751

Edit...

Just in case I have mislead you, I want to have a unit where sensors detect movement and then a camera to face that position.


答:
First

I would like to caution your choice of motor torque. I don't know how you generated the drawing of your wrist, but CAD packages like Inventor or Solidworks can easily generate masses and moments of inertia if you select the correct material.

For looking solely at holding torque, the torque required to not move, you need a torque that supports the load's weight at the distance from the joint to the center of mass of the load as well as the arm's weight between the joint and the load (and associated motors, gearboxes, etc.) at the distance from the joint to the center of mass of the arm.

$$
\tau_{holding} = x_{center.of.mass_{load}} (m_{load} g) + x_{center.of.mass_{arm}} (m_{arm} g)
$$

where $\tau_{holding}$ is the holding torque, in Nm, $x$ is the distance from the joint axis to the respective center of mass, in meters, $m$ is the mass of the respective component, in kg, and $g$ is the gravitational constant; $9.81 m/s^2$.

The accelerating torque, or torque required to move your part, depends on the moment of inertia. If you're not actuating at the center of mass of both the arm and the load (you're not; you can't!) then you need the parallel axis theorem to find the moment of inertia at the joint.

$$
I_{end.effector} = I_{load} + m_{load} x^2_{center.of.mass_{load}} + I_{arm} + m_{arm} x^2_{center.of.mass_{arm}}
$$

where inertias $I$ are in $kg-m^2$, and again, $m$ is in kg and $x$ is in meters. :EDIT: When I say end effector here, I'm referring to the everything after the wrist joint, up to and including the load. When I talk about the "arm" in this context, I mean all of the robot after the wrist joint, excluding the load. The center of mass of the 'arm' is the center of mass of the linkage(s) between the wrist joint and the load. :\EDIT:

The torque required to accelerate the load is then given by:

$$
\tau_{accelerating} = I_{end.effector} \alpha_{desired}
$$

where torque $\tau$ is in Nm and angular acceleration $\alpha$ is in $rad/s$.

If you don't care about a particular acceleration you can rearrange the above equation to determine what your acceleration will be, given a particular moment of inertia and motor torque:

$$
\alpha_{achievable} = \frac{\tau_{motor}}{I_{end.effector}}
$$

If your end effector (the robot arm between the wrist and the load) had no moment of inertia through its center of mass (it was just a point mass), the moment of inertia through the wrist joint would reduce to $mx^2$. This is also true of the load. However, because it and the load are both real objects, they will have size, which also implies they will have a nonzero moment of inertia through their centers of mass.

All of this is to say, if you don't account for moments of inertia, you may find that your wrist is incapable of accelerating your load. If it can't accelerate, it won't be able to position well if at all.

Second

I would like to caution your choice of units. 'gr' is the symbol for grain, which is a unit of mass, like gram, but one grain is equal to approximately 0.065 grams. If you mean gram, 'g' is the (SI) symbol you should use. If you would like to avoid confusion between the gram symbol and the gravitational constant, you should use kilograms instead 'kg'.

Most equations are predicated on SI base units, which means kilograms and meters, not grams and millimeters. If you would like to express precision to the millimeter or gram level, use trailing zeros as trailing zeros after a decimal are considered significant figures.

Third

To your question, I would suggest using servomotors for positioning unless you need to have positive feedback that you have reached your destination or unless you're trying to do some form of external PID control on the joint.

Note that all servos run on some sort of internal PID control with internal position feedback. You don't get access to their position encoder (potentiometer, typically), but they DO run closed-loop and can be expected to reach the position you've requested provided they have sufficient torque, see the First note above.

If you DO need position feedback (CNC quality control or something else), you could search Digikey for encoders to get exactly what you need or you could search for 'rotary encoders' online. I have experience with rotary encoders for larger applications, but at a glance the miniature offerings from Nemicon and US Digital look nice.

If you are looking specifically for a gearbox and motor (search: gearmotor), then Pololu has some nice miniature offerings.

As a final note, I'm not affiliated with any of the companies I've linked to. I have offered them as examples of what you may be interested in and what they're called; sometimes the hardest part of finding something is figuring out what to put into the search box.

Title: 2Nm small motor

Body:
Currently designing a spherical wrist, I want to manipulate a 300gr payload.
the design has a 200mm span, so I'm guessing at a 1.1Nm (considering the weight of structure & motors).

I've looked at Maxon, Faulhaber, but can't find any motor+gearbox+encoder under a 100gr.
Any suggestion ?


问:
Sporadic sensing rates for hc-sr04 ultrasonic distance sensor
Been working on a robot recently which uses ultrasonic sensors for an integral part of the navigation.
While testing the sensors I noticed a strange behaviour, the sensors seem to frequently stop functioning and bring the entire Arduino Mega I'm working with to a stop. The strange part is that these stops seem to be entirely random, on some occasions the sensor will read values consistently (at maybe 20 vals per second) for 10+ seconds, then all of a sudden the sensor will slow to reading only 2-3 values per second with stalls between.

I have tested several sensors and different codes for pinging distances yet the problem has persisted.

This leads me to believe the issue is with the arduino mega itself, but I am unsure how to verify this. Any advice?
Thanks in advance!

PS: other pins on the Mega seem to be working fine, i.e. analog pins for IR reflectance sensors and PWM pins for driving 2 DC motors.

答:
You said, "on some occasions the sensor will read values consistently (at maybe 20 vals per second)".

20 values per second is 20Hz. This means that you are polling every 50ms. In the datasheet linked in the other response, it says,

"we suggest to use over 60ms measurement cycle, in order to prevent trigger signal to the echo signal"

In the operation discussion it says the your 10$\mu$s pulse starts the "sonic burst", after which the sensor raises the echo bit. You are watching for that echo bit to return to zero; time raised determines distance. What it appears that you are doing is polling the sensor too frequently. The trigger signal causes another sonic burst, which raises the echo pulse a second time. This could overlap the first pulse, resulting in a signal that stays high.

Your "maybe 20 vals per second" could also be the reason for your intermittent issue; if you're not using a dedicated timer (interrupt) to initiate the polling, then you're at the mercy of whatever other logic you have running on the microcontroller.

You could (good solution) use an interrupt to trigger the polling and to measure the signal length, or you could (bad solution) add some meaningless math calculations in your code in an attempt to increase the time between sensor function calls. Bad solution is bad, but it could be handy to help troubleshoot. You're looking for a value of about 10Hz; 15Hz is right on the border of instability for the sensor. Of course, if you could reliably count on polling to go off at a precise interval cough interrupt cough then borderline cases are very manageable.


问:
C++ Robust Model Fitting Library
Often when I need to perform model fitting I find myself looking for a decent C++ library to do this. There is the RANSAC implementation in MRPT, but I was wondering if there are alternatives available.

To give an example for the type of problems I would like to solve: For a set $A$ of (approx 500) 3D point pairs $(a, b)$ I would like to find the Isometry transform $T$, which maps the points onto each other so that $|(a - Tb)| < \epsilon$. I would like to get the largest subset of $A$ for a given $\epsilon$. Alternatively I guess I could have the subset size fixed and ask for the lowest $\epsilon$.

答:
PCL has a nice C++ templated RANSAC library which can solve your problem.

If you feel, PCL is too big of a dependency, then using umeyama function in Eigen's geometry module is probably the easiest way towards a working solution for your problem.

Title: C++ Robust Model Fitting Library


问:
How to control a dc motor
I have 2 of these 12v motors and a 12v battery
http://www.enigmaindustries.com/Motors/Bosch_EV_Warrior.htm

I would like to know what the best solution for controlling this motor with an Arduino Uno would be.
Does the motor controller need to have a maximum current of 100A?

I though of a 100A transistor connected to the pwm pin of arduino, and then, control the motor with pwm.

Is voltage regulator better than pwm?

答:
Yes, as this motor is rated for 100amps stall at 12V you should probably be using a motor controller capable of supplying that amount of current.  Regarding how to drive the motor, the following may be of use:

A voltage regulator cannot be used to drive a motor.  What it does is convert a certain voltage to another voltage, for example 5v to 12v.  It does not provide variable speed control.

A transistor rated for 100amps at 12V would be sufficient to drive one of these motors, however you would only have one direction of control (for example, turning clockwise but not counterclockwise).  This may be OK for your application, it also may not be.  You could easily hook up the transistor to a PWM pin of your Arduino for control.

If you want dual directional control of your motor, you will need a DC brushed motor driver, or HBridge.

Good luck with your project.  Just a note, if you don't have very much experience I don't recommend messing with such high currents: issues with unsafe wiring due to lack of experience could be very dangerous and expensive.  I'd recommend starting smaller and working upwards.

Title: How to control a dc motor


问:
make hc-sr04 receive from another one
I have 3 ultrasonic Sensor (HC-SR04), i want to use one of them as transmitter, and the other as receiver, i want to let the first one send ultra Sonic waves and the other receive these waves from the same transmitter.

how can i do that ?

i tried to send trigger for each ultrasonic and connect them on different pins on PIC, but its now work.

its something like this project but using HC-SR04

答: The sensor have trig and echo pins. Simular to your video, you can do that as pen is transmiter and others are receiver. Send from trigger pen (dont listen from echo)and count signals from transciver inputs(dont send any signal from trig). </p>

Title: make hc-sr04 receive from another one


问:
How to transfer signed integers with libusb?
Folks at programmers stack exchange asked me ask here:

I want to communicate with an arduino and sent integers it. I code this program in C++. I initialy used bulk_transfer(), but it sends only char data.

This in the API reference for libusb:
http://libusb.org/static/api-1.0/group__syncio.html

Here is the prototype of bulk_transfer()

int     libusb_bulk_transfer (struct libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *data, int length, int *transferred, unsigned int timeout)

As you can see, data is an unsigned char pointer, that is, a pointer to a buffer containing length unsigned chars. I can successfully transcieve strings. How do I transfer integers with sign?

Currently I am thinking about a system in which the arduino asks for the digit by sending a character and my program sends the number as reply followed by the sign, which is requested next. Is this solution viable? Or should I transfer the integer as a string? Is there a better way?

答:
What you are looking for is called serialization. Serialization is the process of creating a string (a serial stream of data) (not necessarily NUL-terminated) from arbitrary data.

The issue serialization addresses is the fact that the same data are represented in different computers differently. For example, take this struct:

```<code>struct A
{
    unsigned int x;
    unsigned long y;
};

struct A a = { 0x12345678, 0x1020304050607080LLU };
</code>```

This would be laid out in memory in a 32-bit little-endian CPU like this:

```<code>lowest address           highest address
       +--+--+--+--+--+--+--+--+
       |78|56|34|12|80|70|60|50|
       +--+--+--+--+--+--+--+--+
        \____ ____/ \____ ____/
             V           V
             x           y
</code>```

On a 32-bit big-endian CPU like this:

```<code>lowest address           highest address
       +--+--+--+--+--+--+--+--+
       |12|34|56|78|50|60|70|80|
       +--+--+--+--+--+--+--+--+
        \____ ____/ \____ _____/
             V           V
             x           y
</code>```

On a 64-bit little-endian CPU like this:

```<code>lowest address                    highest address
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|78|56|34|12|??|??|??|??|80|70|60|50|40|30|20|10|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 \____ ____/ \____ ____/ \__________ __________/
      V           V                 V
      x         padding             y
</code>```

On a 16-bit big-endian microcontroller like this:

```<code>lowest address           highest address
       +--+--+--+--+--+--+--+--+
       |56|78|??|??|50|60|70|80|
       +--+--+--+--+--+--+--+--+
        \_ _/ \_ _/ \____ ____/
          V     V        V
          x  padding     y
</code>```

In the above, ?? means irrelevant values where the compiler has introduced padding to align long. The values given to a.x and a.y are intentionally too large to fit in some architectures just so that in this example you could identify what byte belongs to what.

Now the issue is that if you simply give the byte-representation of this struct from one computer to another, for example by simply transmitting over the network, the other computer is not guaranteed to see the same data. Imagine if in the example above, the 64-bit computer sends the representation to the 16-bit microcontroller, the x value would have the wrong byte order, and y value would be garbage taken from the padding in the original struct. If the 16-bit microcontroller sends the representation to the 64-bit computer, the x value would be half garbage, and the y value would be read outside the actual buffer sent, which is anything that happens to be there, such as your password.

Now that you understand the problem, you need to learn how to serialize your data.  If you are interfacing with a system where serialization is already in place, of course you need to follow its rules.  However, if you are designing your system, you are free to do it however you like!  First, it's a good idea to define a fixed size for your data.  For example, in the example above, we could have defined struct A like this:

```<code>struct A
{
    uint32_t x;
    uint64_t y;
};
</code>```

Doing this, now you know that x for example is always going to need 4 bytes to transfer, and you should expect to extract 4 bytes on the other side to reconstruct x.  Note that, you still can't send the memory representation of this struct from one computer to another because both the paddings could be different and the byte order.

Next, you need to think about in which order you want to send the bytes. Let's say you want to send them in big-endian. You may also need to think about floating point numbers. How are you going to represent them? One possibility is to send them as two numbers: what comes before the . and what comes after it. How would you handle sign? This all depends on your application.

So, let's serialize struct A with the assumption that it is going to be presented in big-endian. The code is very simple, you simply put the bytes in the order you define in a string and send it:

```<code>size_t serialize_struct_A(struct A *data, unsigned char *buf, size_t buf_len)
{
    size_t len = 0;

    /* we need 12 bytes for struct A, so buffer should have enough size */
    if (buf_len < 12)
        return 0;

    /* you can either be lazy and specify each byte */
    buf[len++] = data->x >> 24 & 0xFF;
    buf[len++] = data->x >> 16 & 0xFF;
    buf[len++] = data->x >> 8 & 0xFF;
    buf[len++] = data->x & 0xFF;

    /* or calculate simple formulas to do it in a loop */
    for (int i = 56; i >= 0; i -= 8)
        buf[len++] = data->y >> i & 0xFF;

    /* len should be 12 now! */
    return len;
}
</code>```

Now we know for sure that buf contains the following regardless of the CPU architecture:

```<code>lowest address                    highest address
+--+--+--+--+--+--+--+--+--+--+--+--+
|12|34|56|78|10|20|30|40|50|60|70|80|
+--+--+--+--+--+--+--+--+--+--+--+--+
 \____ ____/ \__________ __________/
      V                 V
      x                 y
</code>```

We could transfer this, e.g., with libusb like this:

```<code>unsigned char a_serialized[12];

size_t len = serialize_struct_A(&a, a_serialized, sizeof a_serialized);
if (len == 0)
    { /* error, my buffer was too small */ }

int ret = libusb_bulk_transfer(dev, endpoint, a_serialized, len, &transferred, timeout);
if (ret != 0)
    { /* error */ }
</code>```

On the other side, when you receive the buffer, you can deserialize it. Again, the code is simple:

```<code>int deserialize_struct_A(struct A *result, unsigned char *buf, size_t buf_len)
{
    size_t cur = 0;

    /* we need 12 bytes for struct A, so we should have received this much */
    if (buf_len < 12)
        return -1;

    *result = (struct A){0};

    /* again, either the lazy way */
    result->x |= buf[cur++] << 24;
    result->x |= buf[cur++] << 16;
    result->x |= buf[cur++] << 8;
    result->x |= buf[cur++];

    /* or the compact way */
    for (int i = 56; i >= 0; i -= 8)
        result->y |= buf[cur++] << i;

    return 0;
}
</code>```

So far, we dealt with unsigned numbers. How would you handle signed numbers? 2's complement representation is quite ubiquitous, so one could think of sending the signed number as if it were unsigned, relying on the fact that the sender and the receiver both use 2's complement representation.  If you cannot rely on this, there are a variety of things one could do.  One simple way would be to use an extra byte for the sign:

```<code>lowest address           highest address
       +--+--+--+--+--+--+--+--+
       |78|56|34|12|80|70|60|50|
       +--+--+--+--+--+--+--+--+
        \____ ____/ \____ ____/
             V           V
             x           y
</code>```0

There are a variety of optimizations that are possible.  For example, if you are sure that the architectures on both end are big-endian and therefore the memory layout for integers are identical, you could just transfer the memory representation, for example:

```<code>lowest address           highest address
       +--+--+--+--+--+--+--+--+
       |78|56|34|12|80|70|60|50|
       +--+--+--+--+--+--+--+--+
        \____ ____/ \____ ____/
             V           V
             x           y
</code>```1

Another optimization could be the following.  If you have multiple signed integers that you want to send with the method above, you could use one bit for the sign instead of one byte, then pack all those sign bits together in one or more bytes that are not necessarily placed directly before the number.  Or, if you are sure that a 4-byte number is always between 0x7FFFFFFF and -0x7FFFFFFF, you can use the most significant bit to store the sign with the rest of the bits showing the absolute value of the integer (this is called a sign and value method of representation for signed integers).

Bottom line is that you need to be able to lay out your numbers byte by byte and be able to recover them on the other side of the communication. How you do that entirely depends on yourself.

Note: the code snippets above are not tested!

Body:
What you are looking for is called serialization. Serialization is the process of creating a string (a serial stream of data) (not necessarily NUL-terminated) from arbitrary data.

The issue serialization addresses is the fact that the same data are represented in different computers differently. For example, take this struct:

struct A
{
    unsigned int x;
    unsigned long y;
};

struct A a = { 0x12345678, 0x1020304050607080LLU };

This would be laid out in memory in a 32-bit little-endian CPU like this:

lowest address           highest address
       +--+--+--+--+--+--+--+--+
       |78|56|34|12|80|70|60|50|
       +--+--+--+--+--+--+--+--+
        \____ ____/ \____ ____/
             V           V
             x           y

On a 32-bit big-endian CPU like this:

lowest address           highest address
       +--+--+--+--+--+--+--+--+
       |12|34|56|78|50|60|70|80|
       +--+--+--+--+--+--+--+--+
        \____ ____/ \____ _____/
             V           V
             x           y

On a 64-bit little-endian CPU like this:

lowest address                    highest address
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|78|56|34|12|??|??|??|??|80|70|60|50|40|30|20|10|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 \____ ____/ \____ ____/ \__________ __________/
      V           V                 V
      x         padding             y

On a 16-bit big-endian microcontroller like this:

lowest address           highest address
       +--+--+--+--+--+--+--+--+
       |56|78|??|??|50|60|70|80|
       +--+--+--+--+--+--+--+--+
        \_ _/ \_ _/ \____ ____/
          V     V        V
          x  padding     y

In the above, ?? means irrelevant values where the compiler has introduced padding to align long. The values given to a.x and a.y are intentionally too large to fit in some architectures just so that in this example you could identify what byte belongs to what.

Now the issue is that if you simply give the byte-representation of this struct from one computer to another, for example by simply transmitting over the network, the other computer is not guaranteed to see the same data. Imagine if in the example above, the 64-bit computer sends the representation to the 16-bit microcontroller, the x value would have the wrong byte order, and y value would be garbage taken from the padding in the original struct. If the 16-bit microcontroller sends the representation to the 64-bit computer, the x value would be half garbage, and the y value would be read outside the actual buffer sent, which is anything that happens to be there, such as your password.

Now that you understand the problem, you need to learn how to serialize your data.  If you are interfacing with a system where serialization is already in place, of course you need to follow its rules.  However, if you are designing your system, you are free to do it however you like!  First, it's a good idea to define a fixed size for your data.  For example, in the example above, we could have defined struct A like this:

struct A
{
    uint32_t x;
    uint64_t y;
};

Doing this, now you know that x for example is always going to need 4 bytes to transfer, and you should expect to extract 4 bytes on the other side to reconstruct x.  Note that, you still can't send the memory representation of this struct from one computer to another because both the paddings could be different and the byte order.

Next, you need to think about in which order you want to send the bytes. Let's say you want to send them in big-endian. You may also need to think about floating point numbers. How are you going to represent them? One possibility is to send them as two numbers: what comes before the . and what comes after it. How would you handle sign? This all depends on your application.

So, let's serialize struct A with the assumption that it is going to be presented in big-endian. The code is very simple, you simply put the bytes in the order you define in a string and send it:

size_t serialize_struct_A(struct A *data, unsigned char *buf, size_t buf_len)
{
    size_t len = 0;

    /* we need 12 bytes for struct A, so buffer should have enough size */
    if (buf_len < 12)
        return 0;

    /* you can either be lazy and specify each byte */
    buf[len++] = data->x >> 24 & 0xFF;
    buf[len++] = data->x >> 16 & 0xFF;
    buf[len++] = data->x >> 8 & 0xFF;
    buf[len++] = data->x & 0xFF;

    /* or calculate simple formulas to do it in a loop */
    for (int i = 56; i >= 0; i -= 8)
        buf[len++] = data->y >> i & 0xFF;

    /* len should be 12 now! */
    return len;
}

Now we know for sure that buf contains the following regardless of the CPU architecture:

lowest address                    highest address
+--+--+--+--+--+--+--+--+--+--+--+--+
|12|34|56|78|10|20|30|40|50|60|70|80|
+--+--+--+--+--+--+--+--+--+--+--+--+
 \____ ____/ \__________ __________/
      V                 V
      x                 y

We could transfer this, e.g., with libusb like this:

unsigned char a_serialized[12];

size_t len = serialize_struct_A(&a, a_serialized, sizeof a_serialized);
if (len == 0)
    { /* error, my buffer was too small */ }

int ret = libusb_bulk_transfer(dev, endpoint, a_serialized, len, &transferred, timeout);
if (ret != 0)
    { /* error */ }

On the other side, when you receive the buffer, you can deserialize it. Again, the code is simple:

int deserialize_struct_A(struct A *result, unsigned char *buf, size_t buf_len)
{
    size_t cur = 0;

    /* we need 12 bytes for struct A, so we should have received this much */
    if (buf_len < 12)
        return -1;

    *result = (struct A){0};

    /* again, either the lazy way */
    result->x |= buf[cur++] << 24;
    result->x |= buf[cur++] << 16;
    result->x |= buf[cur++] << 8;
    result->x |= buf[cur++];

    /* or the compact way */
    for (int i = 56; i >= 0; i -= 8)
        result->y |= buf[cur++] << i;

    return 0;
}

So far, we dealt with unsigned numbers. How would you handle signed numbers? 2's complement representation is quite ubiquitous, so one could think of sending the signed number as if it were unsigned, relying on the fact that the sender and the receiver both use 2's complement representation.  If you cannot rely on this, there are a variety of things one could do.  One simple way would be to use an extra byte for the sign:

size_t serialize_int32_t(int32_t data, unsigned char *buf, size_t buf_len)
{
    size_t len = 0;

    /* we need 5 bytes for int32_t, so buffer should have enough size */
    if (buf_len < 5)
        return 0;

    if (data < 0)
    {
        buf[len++] = 1;
        data = -data;
    }
    else
        buf[len++] = 0;

    buf[len++] = data >> 24 & 0xFF;
    buf[len++] = data >> 16 & 0xFF;
    buf[len++] = data >> 8 & 0xFF;
    buf[len++] = data & 0xFF;

    /* len should be 5 now! */
    return len;
}

int deserialize_int32_t(int32_t *result, unsigned char *buf, size_t buf_len)
{
    size_t cur = 0;
    int sign;

    /* we need 5 bytes for int32_t, so we should have received this much */
    if (buf_len < 5)
        return -1;

    *result = 0;

    /* again, either the lazy way */
    sign = buf[cur++];
    *result |= buf[cur++] << 24;
    *result |= buf[cur++] << 16;
    *result |= buf[cur++] << 8;
    *result |= buf[cur++];

    if (sign)
        *result = -*result;

    return 0;
}

There are a variety of optimizations that are possible.  For example, if you are sure that the architectures on both end are big-endian and therefore the memory layout for integers are identical, you could just transfer the memory representation, for example:

 /* serialize */
 *(uint32_t *)(buf + len) = data->x;
 len += 4;

 /* deserialize */
 data->x = *(uint32_t *)(buf + len);
 len += 4;

Another optimization could be the following.  If you have multiple signed integers that you want to send with the method above, you could use one bit for the sign instead of one byte, then pack all those sign bits together in one or more bytes that are not necessarily placed directly before the number.  Or, if you are sure that a 4-byte number is always between 0x7FFFFFFF and -0x7FFFFFFF, you can use the most significant bit to store the sign with the rest of the bits showing the absolute value of the integer (this is called a sign and value method of representation for signed integers).

Bottom line is that you need to be able to lay out your numbers byte by byte and be able to recover them on the other side of the communication. How you do that entirely depends on yourself.

Note: the code snippets above are not tested!


问:
Why do my ESCs stop working?
I'm new to robotics and this is my first time building a quadcopter.  I'm unable to work out why I keep losing ESCs.

Most recently in testing, I've managed to calibrate all 4 ESCs and accurately control the speed of all 4 motors.  But after neatly securing them to the frame, 1 motor didn't work.  I recalibrated the ESCs again and, when running them again, the motor still didn't work.  However, the other 3 motors continued to run at first, but also suddenly just stopped altogether.

Research suggested that ESCs have a cut-off voltage, indicating that my battery might be too flat, so I immediately looked to recharging it. To my surprise, the (still very new) battery appeared to have bulged out, indicating that it had been damaged.

Further research suggested that the size of the battery I was using is insufficient for the amount of current drawn by the motors.  So, without any PWM applied, I reconnected a new fully charged battery in the hope of listening for any beeps to diagnose, and one ESC immediately coughed up a huge puff of smoke.

Before all of this happened, I only managed to get 2 of the ESCs to run their motors.  Despite several attempts at tweaking PWM signals and calibrating them, I ended up replacing the other 2.

Unless there's some obvious reason for my ESCs to keep dying on me, I can only assume that these specific ESCs are badly made and I should ask for my money back.

These are the components I'm using:

Raspberry Pi 2 Model B

Adafruit 16-Channel 12-bit PWM/Servo Driver - I2C interface - PCA9685

RCTimer Mini ESC 40A OPTO BLHeli Firmware (Oneshot125, Support 2-6S)

RCTimer 2208-8 2600kV Outrunner Brushless Motor

Gens ace 2200mAh 11.1V 25C 3S1P Lipo Battery Pack

The Raspberry Pi is powered through its micro USB interface by a 5V Step-Up Voltage Regulator connected to a 5000mAh 3.7V LiPo battery.  The PWM Controller is powered to its Vcc pin by the GPIO1 (3.3V) pin from the Raspberry Pi, that also happens to power other sensors.

At the time (when all 4 motors worked), I was able to accurately control them at either 50Hz or 400Hz with 1-2 millisecond duty cycles.

答:
I use those RCtimer ESCs and they have always worked great for me, generally thease (and most) ESCs will be looking for 50Hz pwm with a period between 1-2ms, though generally you will not damage them by altering the pwm output. I would recommended cutting the 5v supply on each ESC as they can act funny and even damage themselves  when they are all tied to each other.

Your battery should be fine, I would recommended being careful when using it in a bench setup to monitor it's voltage never letting it drop below 3.0v/cell under load (i.e. 9v) and never below 3.2v unloaded per cell (i.e. 9.6v)

To troubleshoot I would connect the motors one at a time to a known working ESC then connect the ESCs one at a time to a known working motor to see if they work, and then one at a time connect known working ESC motor pairs to be sure they work, then add the pairs one at a time to see if it stops working at a certain number of ESC/motor connections

Title: Why do my ESCs stop working?


问:
Help with ultrasonic sensors on obstacles avoiding robot
Well, I will start directly in my problem. I'm working on a project and I only have 10 days left.
The idea is simple, a wheeled robot with 3 ultrasonic sensors to avoid obstacles.
I've developed a code and it's working fine.
I'm using: Arduino Uno, L293D driver for the 2 dc motors, 3 HC-SR04 ultrasonic sensors and the Newping library.

I've made some kind of a shield where I soldered common points for gnd and 5V in order to connect the L293 ic and the sensors pins easily. The problem is that the ultrasonic sensors only functioned once in the expected behavior! After that they were always sending the zero result and sometimes a number is showed when i disconnect the sensor!
Is it a power problem? I'm using the usb cable to power the arduino and the sensors (motors are powered using 2 Li-po batteries)
kindly provide me with guidance

答: Well.. It was a power issue! I'm using one of the arduino replicas and the 5v pins is only outputting 4.5v instead of 5. The problem was solved by providing an external power source. I don't find it cool to power robots externally but this is the only way in my case.</p>


问:
Arduino depth sensor
I'm looking for an arduino compatible depth sensor NOT for water. What I need is a sensor very similar to an Xbox kinect (but much smaller) that will tell me what is in front of the sensor and also the shape of the object. For example, if I place a cylindrical water bottle in front of the sensor I would like to be able to figure out how far away the bottle is and also the shape of the object (in 2d, I don't need to know whether it is actually a cylinder only the general shape). The sensor only needs to be accurate at most 1 meter away. Does this exist and if so where can I purchase one. If it does not exist wholly what pieces do I need to buy to put it together? Thanks.</p>

答: Arduino or other microcontrollers is not enough for image or video processing. So you can try it with scanners (like LIDAR) or sensor arrays like this link. The link contains only 4 sensors but you can increase the number of sensor for increase measuring angle( angle of HC SR04 is 15 degree)

Title: Arduino depth sensor


问:
Driving a non-circular timing belt
I'd like to create a camera slider similar to this one.

The only part I'm not sure on is how to setup the camera drive.  It looks like I can buy a similar timing belt here, but I'm not sure how to set up the servo to drive the slider.  Particularly how to keep the belt in contact with the drive pulley.

My fabrication skills are very limited so I need a simple or out of the box solution.

答:
As can be seen in the following two photos from pages 1 and 3 of David Hunt's article mentioned in question, the timing belt forms a U-bend as it passes the motor's drive pulley.   Sets of bearings support the back of the belt on each side of the drive pulley.  It looks like the centerline of the drive pulley is in line with the rest of the belt.  A deeper U than is shown probably would be a good idea.

As is clear from descriptions and the circuits shown on page 3 of David Hunt's article, the drive motor is an ordinary DC motor operated open-loop rather than being operated as a servo motor.  For example, the description says “Sending a pulse of 12v for 150ms to the motor drives the dolly about 3mm”.  To move the platform 10 inches, one would pulse the motor 80 times.  If you sent one 150 ms pulse every 45 seconds, the platform would move about 10 inches in an hour.

Edit re “Is there any advantages to using the "DC open loop motor" vs a servo?” :  Generally, using a plain DC motor or gearmotor will be less expensive than using a servomotor.  Servomotors typically have an encoder built in or attached on (see pictures at tigertek.com or orientalmotor.com, for example) and typically are driven by servoamplifiers.  (Hobby or RC servos can be controlled without using a separate servoamplifier.)

If high-speed or high-accuracy positioning are required, a servo probably would be a better choice than a non-servoed motor.  But otherwise, using a plain motor or gearmotor costs less and leaves you with more latitude for choice.

Regarding stepper motors vs servomotors or plain DC motors, (1) stepper motors will cost more per watt of power output, (2) stepper motors generally rotate slower, (3) stepper motors typically need more-complex driving sequences.

Title: Driving a non-circular timing belt