问:
Control system in Matlab with RSA encryption
I want to implement an encrypted controller in Matlab using RSA. I am trying to replicate what is written in this scheme from 'Cyber-Security Enhancement of Networked Control Systems Using Homomorphic Encryption' written by Kiminao Kogiso and Takahiro Fujita:

The input of the controller has to be the output of the plant, and the input of the plant has to be the output of the controller. I think the problem happens when I try to decrypt, but I am not sure.

I am using the state space representation of a system and the following code:

```<code>A_p = [9.9998*(10)^-1 1.9700*(10)^-2; -1.970*(10)^-2 9.7025*(10)^-1];
B_p = [9.9900*(10)^-5; 9.8508*(10)^-3];
C_p = [1 0];
D_p = 0;

X0 = [1;0]; %initial conditions for the plant

t = [0:0.01:5];  %sampling time

u = ones(1,length(t));        %encrypted input
y_p = zeros(1, length(t));    %output of the plant
x_p = zeros(2, length(t));    %state of the plant
x_c = zeros(2, length(t));    %state of the controller

x_p(:, 1) = X0;               %assign the initial values to the satet of the
                              %plant

%parameters of the controller

A_c = [1 0.0063; 0 0.3678];
B_c = [0; 0.0063];
C_c = [10 -99.90];
D_c = 3;

end_t = length(t);

N = 94399927;    % N=p*q
e = 11;          %public key
d = 85800451;    %private key

%encrypted parameters for the controller

A_enc = mod(A_c.^e, N);
B_enc = mod(B_c.^e, N);
C_enc = mod(C_c.^e, N);
D_enc = mod(D_c.^e, N);

xc_enc = zeros(2,length(t));   %x_c encrypted
y_enc = zeros(1,length(t));    %y_c encrypted

u_dec = ones(1, length(t));    %u decripted

y_quant = zeros(1, length(t));

for ind=1:end_t-1

    %plant

    x_p(:, ind+1) = A_p*x_p(: ,ind) + B_p*u_dec(ind);
    y_p(ind) = C_p*x_p(: ,ind);

    %encryption of x_c and y_p

    y_quant(ind) = round(y_p(ind));  %quantization

    y_enc(ind) = modpow(y_quant(ind), e, N);

    %controller with encrypted parameter
    x_c(:, ind+1) = A_enc*x_c(:, ind) - B_enc*y_enc(ind);
    u(ind+1) = C_enc*x_c(:, ind) - D_enc*y_enc(ind);

    %decrypting u
    u_dec(ind+1) = modpow(u(ind+1),d,N);

    function result = modpow(base,exp,m)
   result = 1;
   while (exp > 0)
      if bitand(exp,1) > 0
         result = mod((result * base),m);
      end
      exp = bitshift(exp,-1);
      base = mod(base^2,m);
   end
end

end

figure
plot(t,y_enc);

figure
plot(t,u);
</code>```

Can somebody help me? Thank's in advance.

EDIT:

sorry, I had to delete some pictures because I can't post all of them because I don't have enough reputation.

Now I am just trying to simply encrypt the output of the plant and then encrypt it before it enters in the controller, and then I encrypt the output of the controller and before it enters in the plant I decrypt it. The idea is the following:

The problem is that if I don't use encryption the outputs I get when I plot

hold on
  plot(t, y_p, 'r')
  figure
  plot(t, u_dec)

are

but when i use encryption, the outputs are

my code is:

```<code>A_p = [9.9998*(10)^-1 1.9700*(10)^-2; -1.970*(10)^-2 9.7025*(10)^-1];
B_p = [9.9900*(10)^-5; 9.8508*(10)^-3];
C_p = [1 0];
D_p = 0;

X0 = [1;0];

t = [0:0.01:5];

u = zeros(1,length(t));
y_p = zeros(1, length(t));
x_p = zeros(2, length(t));
x_c = zeros(2, length(t));

x_p(:, 1) = X0;

A_c = [1 0.0063; 0 0.3678];
B_c = [0; 0.0063];
C_c = [10 -99.90];
D_c = 3;

end_t = length(t);

N = 94399927;
e = 11;
d = 85800451;
xc_enc = zeros(2,length(t));
y_enc = zeros(1,length(t));

u_dec = ones(1, length(t));

xc_dec = zeros(2, length(t));

x_dec = zeros(2,length(t));
y_dec = zeros(1, length(t));

u_enc = zeros(1,length(t));

y_quant = zeros(1, length(t));

u_quant = zeros(1, length(t));

for ind=1:end_t-1

     x_p(:, ind+1) = A_p*x_p(: ,ind) + B_p*u_dec(ind);
     y_p(ind) = C_p*x_p(: ,ind);

     y_quant(ind) = round(y_p(ind));

     y_enc(ind) = modpow(y_quant(ind),e,N);

     y_dec(ind) = modpow(y_enc(ind),d,N);

     x_c(:, ind+1) = A_c*x_c(:, ind) - B_c*y_dec(ind);
     u(ind+1) = C_c*x_c(:, ind) - D_c*y_dec(ind);

     u_quant(ind+1) = round(u(ind+1));        %quantization of u(ind+1)

     u_enc(ind+1) = modpow(u_quant(ind+1),e,N);
     u_dec(ind+1) = modpow(u_enc(ind+1),d,N);

     disp(u(ind +1) + " " + u_dec(ind+1))

end

hold on
plot(t, y_p, 'r')
figure
plot(t, u_dec)

function result = modpow(base,exp,m)
   result = 1;
   while (exp > 0)
      if bitand(exp,1) > 0
         result = mod((result * base),m);
      end
      exp = bitshift(exp,-1);
      base = mod(base^2,m);
   end
end

function y = powermod_matrix(a,z,n)
% This function calculates y = a^z mod n
 %If a is a matrix, it calculates a(j,k)^z mod for every element in a
[ax,ay]=size(a);

% If a is negative, put it back to between 0 and n-1
a=mod(a,n);

% Take care of any cases where the exponent is negative
if (z<0)
   z=-z;
   for j=1:ax
      for k=1:ay
         a(j,k)=invmodn(a(j,k),n);
      end
   end
end

for j=1:ax
for k=1:ay
  x=1;
  a1=a(j,k);
  z1=z;
  while (z1 ~= 0)
     while (mod(z1,2) ==0)
        z1=(z1/2);
        a1=mod((a1*a1), n);
     end  %end while
     z1=z1-1;
     x=x*a1;
     x=mod(x,n);
  end
  y(j,k)=x;
end %end for k
end %end for j
end
</code>```

Shouldn't I get almost the same result as the ones without encryption? I think that something is wrong with the input u and how I initialize and increment it, but I don' t know how to fix this. Can somebody help me? Thank's in advance.

EDIT:

moreover, if i add the following line of code:

```<code>disp(y_p(ind) + " " + y_dec(ind))
</code>```

i can see that y_p and y_dec, which should be the same, are different at each iteration.

EDIT:

the problem is that even if i add a quantization ,and so i get integers, i get the same output.

In addition, if i add the following line of code:

```<code>disp(u(ind +1) + " " + u_dec(ind+1))
</code>```

after the decryption of u_enc, so after u_dec, i get :

so u(ind+1) and u_dec(ind+1) are different numbers. And another fact that leaves me confused is that if i  quantize u(ind+1), this result doesn't become an integer.

EDIT:

I think that the problem of this is that u(ind+1) becomes a negative number and too big. Infact, if i for example try to do:

```<code>x = -19495615862231.37;

z = round(x);

x_enc = modpow(x,11,94399927);

x_dec = modpow(x_enc,85800451,94399927)
</code>```

as result, after the decryption i get 31779346, and not the original number. I think modpow calculates the modular exponential for large numbers, but it looks like it has a limit.

答:
:EDIT:

Your numbers must be <s>integers</s> POSITIVE INTEGERS. (link)

This is probably the root of the trouble you're having. Interesting that the paper didn't mention anything about this. I'm not sure how they arrived at the encrypted control parameters but, as I mentioned below, it's not my field so I haven't "digested" the paper. In any event, RSA encryption doesn't work with non-integer or negative integer numbers so you can't pass fractional numbers back and forth and you can't pass negative numbers back and forth.

I've removed the original answer here, but it's in the edit history if anyone is curious.

Consider the following example. I used much smaller numbers to reduce my own search times, and I'm sure there are better ways of finding these numbers but, as I mentioned previously, crypto is not my field. Here's some checks:

```<code>p = 7
q = 11
N = p*q
lambda = lcm(p-1,q-1)
e = 17
d = 1;
while true
    if(mod(d*e,lambda)==1)
        break;
    else
        d = d+1;
    end
end

>>d

d =

    23
</code>```

So now I've got e = 17, d = 23, and N = 77. Now, check that it works:

```<code>>> modpow(29,e,N)

ans =

    50

>> modpow(50,d,N)

ans =

    29
</code>```

Okay, seems to work fine. Now, try it with a negative number, then see if there's a positive number that gives the same encrypted result:

```<code>i=1;
while true
    if(modpow(i,e,N)==modpow(-3,e,N))
        break;
    else
        i=i+1;
    end
end

>>i

i =

    74
</code>```

Try it again, with a different negative number:

```<code>i=1;
while true
    if(modpow(i,e,N)==modpow(-29,e,N))
        break;
    else
        i=i+1;
    end
end

>>i

i =

    48
</code>```

So, as you can see, a negative integer can wind up giving you the same encryption result as (a different) positive integer.

Since N is always positive (because p and q are prime and thus positive), Matlab documentation states that the modulus operation will always return a positive result. This again confirms that modpow of some negative number, with N>0, will always result in some positive result which could be duplicated by a positive number.

It also means that modpow(~, d, N) will never return a negative number.

Solution

As I mentioned at the top, I'm surprised this wasn't mentioned in the paper you linked, but my approach would be to bias your numbers by some "sufficiently large" positive number and un-bias them before use. Also, since decimal numbers can't be used, you could "inflate" your numbers by multiplying by some scale factor before rounding, then "deflate" the numbers before use by dividing by the same scale factor. Consider the following edits to your code (the powermod_matrix function wasn't being used, so I removed it for brevity):

```<code>scaleFactor = 1000; % <-- New
biasValue = 100; % <-- New

A_p = [9.9998*(10)^-1 1.9700*(10)^-2; -1.970*(10)^-2 9.7025*(10)^-1];
B_p = [9.9900*(10)^-5; 9.8508*(10)^-3];
C_p = [1 0];
D_p = 0;

X0 = [1;0];

t = [0:0.01:5];

u = zeros(1,length(t));
y_p = zeros(1, length(t));
x_p = zeros(2, length(t));
x_c = zeros(2, length(t));

x_p(:, 1) = X0;

A_c = [1 0.0063; 0 0.3678];
B_c = [0; 0.0063];
C_c = [10 -99.90];
D_c = 3;

end_t = length(t);

N = 94399927;
e = 11;
d = 85800451;
xc_enc = zeros(2,length(t));
y_enc = zeros(1,length(t));

u_dec = ones(1, length(t));

xc_dec = zeros(2, length(t));

x_dec = zeros(2,length(t));
y_dec = zeros(1, length(t));

u_enc = zeros(1,length(t));

y_quant = zeros(1, length(t));

u_quant = zeros(1, length(t));

for ind=1:end_t-1

     x_p(:, ind+1) = A_p*x_p(: ,ind) + B_p*u_dec(ind);
     y_p(ind) = C_p*x_p(: ,ind);

     %y_quant(ind) = round(y_p(ind));
     y_quant(ind) = round(scaleFactor*(y_p(ind) + biasValue)); % <-- New

     y_enc(ind) = modpow(y_quant(ind),e,N);

     y_dec(ind) = modpow(y_enc(ind),d,N);

     y_dec(ind) = y_dec(ind)/scaleFactor - biasValue; % <-- New

     x_c(:, ind+1) = A_c*x_c(:, ind) - B_c*y_dec(ind);
     u(ind+1) = C_c*x_c(:, ind) - D_c*y_dec(ind);

     %u_quant(ind+1) = round(u(ind+1));        %quantization of u(ind+1)
     u_quant(ind+1) = round(scaleFactor*(u(ind+1) + biasValue)); % <-- New

     u_enc(ind+1) = modpow(u_quant(ind+1),e,N);
     u_dec(ind+1) = modpow(u_enc(ind+1),d,N);

     u_dec(ind+1) = u_dec(ind+1)/scaleFactor - biasValue; % <-- New

     disp(u(ind +1) + " " + u_dec(ind+1))

end

hold on
plot(t, y_p, 'r')
figure
plot(t, u_dec)

function result = modpow(base,exp,m)
   result = 1;
   while (exp > 0)
      if bitand(exp,1) > 0
         result = mod((result * base),m);
      end
      exp = bitshift(exp,-1);
      base = mod(base^2,m);
   end
end
</code>```

I commented all the lines (six of them) with % <-- New to highlight the changes; again all I did was shift your values by +100 (biasValue) and then multiply by 1000 (scaleFactor) before rounding, and then doing the inverse after decrypting. Seems like that's got your controller working!

Body:
:EDIT:

Your numbers must be <s>integers</s> POSITIVE INTEGERS. (link)

This is probably the root of the trouble you're having. Interesting that the paper didn't mention anything about this. I'm not sure how they arrived at the encrypted control parameters but, as I mentioned below, it's not my field so I haven't "digested" the paper. In any event, RSA encryption doesn't work with non-integer or negative integer numbers so you can't pass fractional numbers back and forth and you can't pass negative numbers back and forth.

I've removed the original answer here, but it's in the edit history if anyone is curious.

Consider the following example. I used much smaller numbers to reduce my own search times, and I'm sure there are better ways of finding these numbers but, as I mentioned previously, crypto is not my field. Here's some checks:

p = 7
q = 11
N = p*q
lambda = lcm(p-1,q-1)
e = 17
d = 1;
while true
    if(mod(d*e,lambda)==1)
        break;
    else
        d = d+1;
    end
end

>>d

d =

    23

So now I've got e = 17, d = 23, and N = 77. Now, check that it works:

>> modpow(29,e,N)

ans =

    50

>> modpow(50,d,N)

ans =

    29

Okay, seems to work fine. Now, try it with a negative number, then see if there's a positive number that gives the same encrypted result:

i=1;
while true
    if(modpow(i,e,N)==modpow(-3,e,N))
        break;
    else
        i=i+1;
    end
end

>>i

i =

    74

Try it again, with a different negative number:

i=1;
while true
    if(modpow(i,e,N)==modpow(-29,e,N))
        break;
    else
        i=i+1;
    end
end

>>i

i =

    48

So, as you can see, a negative integer can wind up giving you the same encryption result as (a different) positive integer.

Since N is always positive (because p and q are prime and thus positive), Matlab documentation states that the modulus operation will always return a positive result. This again confirms that modpow of some negative number, with N>0, will always result in some positive result which could be duplicated by a positive number.

It also means that modpow(~, d, N) will never return a negative number.

Solution

As I mentioned at the top, I'm surprised this wasn't mentioned in the paper you linked, but my approach would be to bias your numbers by some "sufficiently large" positive number and un-bias them before use. Also, since decimal numbers can't be used, you could "inflate" your numbers by multiplying by some scale factor before rounding, then "deflate" the numbers before use by dividing by the same scale factor. Consider the following edits to your code (the powermod_matrix function wasn't being used, so I removed it for brevity):

scaleFactor = 1000; % <-- New
biasValue = 100; % <-- New

A_p = [9.9998*(10)^-1 1.9700*(10)^-2; -1.970*(10)^-2 9.7025*(10)^-1];
B_p = [9.9900*(10)^-5; 9.8508*(10)^-3];
C_p = [1 0];
D_p = 0;

X0 = [1;0];

t = [0:0.01:5];

u = zeros(1,length(t));
y_p = zeros(1, length(t));
x_p = zeros(2, length(t));
x_c = zeros(2, length(t));

x_p(:, 1) = X0;

A_c = [1 0.0063; 0 0.3678];
B_c = [0; 0.0063];
C_c = [10 -99.90];
D_c = 3;

end_t = length(t);

N = 94399927;
e = 11;
d = 85800451;
xc_enc = zeros(2,length(t));
y_enc = zeros(1,length(t));

u_dec = ones(1, length(t));

xc_dec = zeros(2, length(t));

x_dec = zeros(2,length(t));
y_dec = zeros(1, length(t));

u_enc = zeros(1,length(t));

y_quant = zeros(1, length(t));

u_quant = zeros(1, length(t));

for ind=1:end_t-1

     x_p(:, ind+1) = A_p*x_p(: ,ind) + B_p*u_dec(ind);
     y_p(ind) = C_p*x_p(: ,ind);

     %y_quant(ind) = round(y_p(ind));
     y_quant(ind) = round(scaleFactor*(y_p(ind) + biasValue)); % <-- New

     y_enc(ind) = modpow(y_quant(ind),e,N);

     y_dec(ind) = modpow(y_enc(ind),d,N);

     y_dec(ind) = y_dec(ind)/scaleFactor - biasValue; % <-- New

     x_c(:, ind+1) = A_c*x_c(:, ind) - B_c*y_dec(ind);
     u(ind+1) = C_c*x_c(:, ind) - D_c*y_dec(ind);

     %u_quant(ind+1) = round(u(ind+1));        %quantization of u(ind+1)
     u_quant(ind+1) = round(scaleFactor*(u(ind+1) + biasValue)); % <-- New

     u_enc(ind+1) = modpow(u_quant(ind+1),e,N);
     u_dec(ind+1) = modpow(u_enc(ind+1),d,N);

     u_dec(ind+1) = u_dec(ind+1)/scaleFactor - biasValue; % <-- New

     disp(u(ind +1) + " " + u_dec(ind+1))

end

hold on
plot(t, y_p, 'r')
figure
plot(t, u_dec)

function result = modpow(base,exp,m)
   result = 1;
   while (exp > 0)
      if bitand(exp,1) > 0
         result = mod((result * base),m);
      end
      exp = bitshift(exp,-1);
      base = mod(base^2,m);
   end
end

I commented all the lines (six of them) with % <-- New to highlight the changes; again all I did was shift your values by +100 (biasValue) and then multiply by 1000 (scaleFactor) before rounding, and then doing the inverse after decrypting. Seems like that's got your controller working!


问:
How to cope with an optical window limitation on 2D LiDAR?
I have a very small and cheap robot and I wanted to mount a 2D LiDAR on a bottom of it (3cm above the ground). It seems to be great as during the mapping the lidar will detect even small elevations from the ground.

But what happens when a chair will be in front of this LiDAR? I guess it will see only its legs due to a limited optical window (as it is 2D).
How can I cope with that? So my robot will not try to go under the chair.

This is the LiDAR: LINK

答:
The answer by @nathangeorge1 is valid for the case of not hitting the legs of the chair.

However, you are faced with limited sensor input. This is the case for most robots, even people need to turn their heads to see what is behind them. Either you need to mount more sensors or you may actuate the lidar. You can see an example of an actuated lidar on the PR2 robot platform under its chin in this video.

You could also use a depth camera like the Realsense cameras from Intel or the Structure cameras from Occipital. These cameras will give you a limited field-of-view compared to the LIDAR, but will provide depth information also above the robot.

A cheaper solution is to use ultrasonic sensors. Mounting them pointing upwards will give the robot a sense of obstacles above it. Alternatively the IR based range finders from Sharp, models GP2Y0xxxxxxx, does almost the same job.

ContentLicense: CC BY-SA 4.0


问:
Is pose estimation using images necessary in visual-inertial SLAM
In visual SLAM, pose estimation is performed between two adjacent frames or keyframes using feature detection and pose estitmation from corresponding features.

However in visual-inertial SLAM, pose information can be calculated from acceleroemeter and gyro. Is visual information still used to estimation poses?
I have read several papers about SLAM, but authors don't mention this explicitly.

Edit:

From the link:

Full 3D Pose (Scale, Rotation and Translation) Estimation using Gyro and Acceleromter sensors fusion

Pose estimation from IMU sensor is incorrect due to bias. Then IMU sensor will not help in typical situation, but only in the situation where few textures are found and feature matching won't work?

答: The typical way of doing visual-inertial SLAM is to create a short accumulated trajectory from IMU and correcting it by visual observation. The pose estimation by the images wouldn't be performed but implicitly affect during the joint optimization.</p>


问:
Smooth servo movement for a crawling robot
I made a small crawler robot a little while ago that had two legs with two degrees of freedom each, so 4 RC servos total. While I was programming the movement of the legs I noticed that they moved rather stiffly. It makes sense that the RC servo's internal controller would have a very quick response to position commands, but I wanted my crawler to move in a way that seems a little more smooth and life-like.

My solution was create a cubic function of time that describes the path of the servos, and then set their position in small time increments, resulting in more smooth motion. Essentially what I did was solve for the $a_i$ coefficients in a cubic equation using the time interval, starting and ending position of the servo, and starting and ending rates the servo should move (which is just the derivative of the position):

Solve for $a_0$, $a_1$, $a_2$, and $a_3$:

$$ position(t) = a_0 + a_1t + a_2t^2 + a_3t^3 $$
$$ rate(t) = position'(t) = a_1 + 2a_2t + 3a_3t^2 $$

Given: $position(0)$, $position(t_f)$, $rate(0)$, $rate(t_f)$

I set the rate of the servo between a pair of movements to be zero if the movements were in opposite directions, and positive or negative if the movements were both in the positive or negative direction, respectively.

This worked pretty well, but this solution is limited in a few ways. For one, it's difficult to decide what exactly the rates between movements that go in the same direction should be. I used the average of the slopes ahead and behind of a particular position between movements, but it isn't clear to me that is optimal. Second of all, cubic curves could take the servo to a position outside of the range of the positions at the beginning and end of a movement, which may be undesirable. For example, at some point during the time interval, the curve could cause the servo to go beyond the second position, or below the first position. Thirdly, curve generation here does not consider the maximum rate that the servo can turn, so a curve may have the servo move at a speed that is unrealistic. With that, a minor concern is that the maximum turning rate depends on the response of servo's internal controller, and may change depending on the size of the position interval.

Neglecting that last concern, these issues may be solved by increasing the degree of the polynomial and adding constraints to solve for the coefficients, but I'm now starting to wonder...

Is there a better way than this to make servo movement smooth and seem more life-like?

答:
Motion Profile Generation

In the past, I've used a motion profile generator to solve this problem. To use it you would need the desired target position (set point), maximum velocity, and acceleration values that are associated with your motors. It works by integrating a trapezoidal velocity curve in order to get a smooth position profile. An S-curve can be used if the motion has to be even smoother.
Reference to article explaining Motion profiling.

Set Point Pre-filtering

Aside from the motion profiling route, you can try simply low pass filtering the command to the servos. This type of setpoint filtering will slow your response down but it will also smooth it out and it's easy to implement. The cut-off frequency will have to be chosen so that it supports the bandwidth of your system (so it does not filter out desired motion).
Simple Low-pass filter implementation in C

ContentLicense: CC BY-SA 3.0


问:
Is it possible to run multiple loops at the same time? (Arduino)
I've got a code where I have a motor running back and forth and buttons connected to a scanner, when I press the buttons it causes the motor to stop  and over rides it. I would like them to run parallel to each other so the codes don't interrupt each other.

Here is my code

```<code>#include <AccelStepper.h>

// Define some steppers and the pins they will use

AccelStepper stepper1(AccelStepper::FULL2WIRE, 2, 3);

const int buttonPin = 4;
const int button2Pin = 14;
const int pulseopto1 = 9;
const int startScan = 11;

int buttonState = 0;
long previousMillis = 0;
long interval = 5;

void setup()
{
    pinMode(buttonPin, INPUT);
    pinMode(button2Pin, INPUT);
    pinMode(pulseopto1, OUTPUT);
    pinMode(startScan, OUTPUT);
    stepper1.setMaxSpeed(40000.0);
    stepper1.setAcceleration(100000.0);
    stepper1.moveTo(25000);
}

void loop()
{
    buttonState = digitalRead(buttonPin);

    if (buttonState == LOW)
    {
        digitalWrite(startScan, HIGH);
    }
    else (buttonState == HIGH);
    {
        digitalWrite(startScan, LOW);
    }

    {
        buttonState = digitalRead(button2Pin);

        if (buttonState == LOW)
        {
            // turn LED on:
            digitalWrite(pulseopto1, HIGH);
            delay(5);
            digitalWrite(pulseopto1, LOW);
            delay(5);
        }
        else
        {
            // turn LED off:
            digitalWrite(pulseopto1, LOW);
        }
    }

    // Change direction at the limits
    if (stepper1.distanceToGo() == 0)
    {
        stepper1.moveTo(-stepper1.currentPosition());
    }

    stepper1.run();
}
</code>```

答:
I have been looking for the same thing and I messed around in the IDLE and found has you put a space next to the first code or the code that you want to do two actions with and type the code.

Example:

```<code>Void loop
{
  Serial.print("Hello");
  Serial.print("World");
}
</code>```

And put the semi-colons where I place it on the code.

Body:
I have been looking for the same thing and I messed around in the IDLE and found has you put a space next to the first code or the code that you want to do two actions with and type the code.

Example:

Void loop
{
  Serial.print("Hello");
  Serial.print("World");
}

And put the semi-colons where I place it on the code.


问:
Why do we need to design controllers (feedback) for controlling a quadrotor?
For example if I want to make my quadrotor hover at a particular height, can't this be achieved by using an altitude sensor, and to correct it's position due to disturbances, can't we just write some if conditions such that depending on certain ranges of the IMU certain motors will increase or decrease it's speed and bring it back to the original position. Hence what is the use of designing controllers for a quadrotor using pid/lqr/h-infinity etc?</p>

答:
using [a] sensor and to correct it's position due to disturbances

Anything that corrects an action by means of sensors is a controller.

depending on certain ranges of the IMU certain motors will increase or decrease it's speed

This sounds a 'stepwise control with deadband' controller.

You can do this - the controller on my lathe is stepwise with deadband as it's easy and sometimes it works well enough where the system dynamics allow it - there's enough inertia in the lathe that we don't need anything very complicated. Generally linear control and PID give better results where the system has to respond to rapidly changing loads. It's unlikely that a quadcopter will be as forgiving as a chunk of rotating iron.


答:
can't it be achieved by using an altitude sensor

Feeding the sensor data back to motors = feedback control. So you're actually answering your own question. So I'm leaning more on that you're questioning the control techniques like PID, etc.

If you just had some if's everywhere in the code instead of a continuously modulated control loop, short answer, it wouldn't be accurate, it wouldn't be efficient, it wouldn't be practical, it wouldn't be straightforward to implement.

I suggest you read a bit about Theory of Control Systems even before going through the answers here but I'll answer your questions briefly. Controllers can help with the following:

Improving steady state accuracy by decreasing the steady state errors.

As the steady state accuracy improves, the stability also improves.

Reducing the offsets produced in the system.

Maximum overshoot of the system can be controlled using controllers.

Reducing the noise signals produced in the system.

Slow response of the over damped system can be made faster with the help of these controllers.

Title: Why do we need to design controllers (feedback) for controlling a quadrotor?

Body: For example if I want to make my quadrotor hover at a particular height, can't this be achieved by using an altitude sensor, and to correct it's position due to disturbances, can't we just write some if conditions such that depending on certain ranges of the IMU certain motors will increase or decrease it's speed and bring it back to the original position. Hence what is the use of designing controllers for a quadrotor using pid/lqr/h-infinity etc?</p>


问:
Forward Kinematics Frame Simulation in MATLAB
I've worked out the T matrix of the tip (position and orientation) with respect to the base frame of a 6 DoF robot for 2 seconds at 1kHz.

So the size of the total T matrix is 4*4*1000.

How can I animate it with MATLAB? Just simple simulation showing the tip frame movement. Like this (not necessary showing the position in numbers):

from here

Thanks.

答:
suppose you calculate the positions of your joints $p_i, i=1\ldots6$ using your homogeneous matrices.

The best solution in my experience is to plot the initial configuration e.g. like this:

```<code>// calc p for time t=0
f=figure(1);
plot3([0, p_1(1)], [0, p_1(2)], [0, p_1(3)]);
hold on;
plot3([p_1(1), p_2(1)], [p_1(2), p_2(2)], [p_1(3), p_2(3)])
.... // for all links
</code>```

the thing is now, if you want to have a smooth animation, it is a bad idea to call the plot command each time because it needs some time.
The better solution is to update the coordinates of your figure.

```<code>// in a for loop i=1:length of you time vector
// calc p for time t=i*deltaT
set(f.Children(x), 'XData', [p_1(1), p_2(1)], 'YData', [p_1(2), p_2(2)], 'ZData', [p_1(3), p_2(3)])
</code>```

where you have to figure out the correct child of you figure handle f, you can just hop trough the structure of f to find the right children.

Body:
suppose you calculate the positions of your joints $p_i, i=1\ldots6$ using your homogeneous matrices.

The best solution in my experience is to plot the initial configuration e.g. like this:

// calc p for time t=0
f=figure(1);
plot3([0, p_1(1)], [0, p_1(2)], [0, p_1(3)]);
hold on;
plot3([p_1(1), p_2(1)], [p_1(2), p_2(2)], [p_1(3), p_2(3)])
.... // for all links

the thing is now, if you want to have a smooth animation, it is a bad idea to call the plot command each time because it needs some time.
The better solution is to update the coordinates of your figure.

// in a for loop i=1:length of you time vector
// calc p for time t=i*deltaT
set(f.Children(x), 'XData', [p_1(1), p_2(1)], 'YData', [p_1(2), p_2(2)], 'ZData', [p_1(3), p_2(3)])

where you have to figure out the correct child of you figure handle f, you can just hop trough the structure of f to find the right children.


问:
System Requirements for Gazebo
According to this document from Gazebo's (Beginner:Overview) online web site, for the installation of Gazebo version 7.0 on Ubuntu OS, these are the following System Requirements:

A dedicated GPU (Nvidia cards tend to work well in Ubuntu)

A CPU that is at least an Intel I5, or equivalent.

At least 500MB of free disk space,

Ubuntu Trusty or later installed.

Then, I would like the following questions to clarify some doubts that I have:

How much of RAM memory is needed for good performance?

Has anyone already tested Gazebo with Intel HD Graphics?

答:
I'm using Gazebo everyday on my i7 ultrabook; and at home, on i3-7100 desktop. They both have Nvidia GPUs. But fortunately, Gazebo doesn't depend on the GPU. It mostly works on the CPU side. Most Gazebo plugins are built for CPU by default, AFAIK there is only GPU plugin for laser sensor, for 7.0. But I suggest using GPU for better desktop experience while Gazebo is handling your simulation on your powerful CPU.

So answer to your question is;

RAM usage depends on your environment; gazebo plugins that you use/write, world file, also models and their amounts and details.

It works with Intel HD Graphics. Tried lots of times. But also depends on your environment, and your CPU.

You just need an average processor to run it, and a processor that is above the average can give you a better performance. I'm running PX4 flight simulator with Gazebo on my;

i3-7100 desktop (3.90 GHz, 2 cores, 4 threads, GTX1060) and Real Time Factor is mostly about 0.97

But on my i7-4710MQ laptop (2.50 GHz, 4 cores, 8 threads, GTX960M), R.T.F. is mostly about 0.70, rarely goes crazy, down to 0.45 or something.

Multi-monitor with Intel HD (for example my Intel® HD Graphics 4600 on i7) is already bad and almost impossible to simulate stuff. But on single laptop monitor, gazebo works normal with Intel HD graphics but don't expect it to work well if your processor is also old.

On multi-monitor setup, with GPU accelerated environment, gazebo works better.

Title: System Requirements for Gazebo


问:
Sensor fusion - Kalman for two identical position sensors
I require a little help in the implementation of my filter. I am currently working with two Leapmotion devices for the physiological study of hand vibrations. For this we call each of the devices "L leader" and "L support". I have problems with the C matrix, which is responsible for modeling the operation of the sensors. In my case, Leapmotion devices deliver data on position (x, y, z) and of course with this it is possible to detach the speed and use it in the filter, leaving L leader (Px, Py, Pz, Vx, Vy, Vz) and L support (Px, Py, Pz, Vx, Vy, Vz). This would then be as follows for the merger?

What data should be put in Xk*?

How do I model matrix C?

Should the H matrix be a 6x6 identity matrix?

Thanks for read, excuse my bad english.

答:
The matrix $C$ usually is denoted the output matrix of your system.
So e.g. if you are interested in the 3 positions $x,y,z$ your matrix would look like
$ C=\begin{bmatrix} 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 \end{bmatrix}$

The matrix $H$ on the other hand, is the matrix describing uncertainties in your system (which could also be measurement noise) and has the dimension $3\times r$ for the case of a 3-dimensional output. $r$ is the dimension of your assumed uncertainty (could be 6 for the noise of your $2\times3$ dimensional sensors). In practice, it is feasible to assume the uncertainties are not affecting each other, in this case the matrix $H$ simplifies to a diagonal matrix.


问:
Does a vehicle with defferential gear still move straight?
I am in the concept phase of a driving robot. The two wheels on the front axle will be powered, while the rear will be dragged along. The rear is also responsible for steering but this has noting to do with my question.

Since the robot is required to make relatively sharp turns at high speed. Therefore I have two options to compensate the different speeds on both sides. On the one hand, a differential gear in the front axle could be used. It would be powered by one motor then. On the other hand, I could simply use two motors directly powering each a front wheel. This way I could simulate the differentiation in software.

I'd like to go for the first approach, using the hardware differential. But I have the one concern with it. Would a robot vehicle with differential gear still move straight, without explicit steering applied?

My imagination is that, with those wheels not being solidly connected, the robot would move in random curves which I'd have to compensate with a lot of steering then. I know that for real cars, differential gears are standard and do their work, but now I am talking about a small robot measuring about 6 inches.

答:
If I understand your question, you are asking whether a vehicle balancing on two wheels (or two wheels and one caster) will be able to move straight, or at least predictably, if both wheels were driven from the same motor and used a differential.

The answer is yes, but only if you have a way to equalize the forces of friction affecting each wheel.  For example, by applying a brake individually to each wheel, you could alter the balance of force between the left and right.  It would be crude, but certainly possible to control the steering in this way.  In fact, many tractors use independent left and right brake pedals to accomplish this.

Without actively braking (or some other method), your intuition is correct: the amount of rotation of each wheel would depend on an unpredictable set of forces, and the robot would make seemingly random turns.


问:
Encoder values for PID control
I'm working on a two-wheeled robot and I'm trying to implement a PID control for the motors. But I have a problem, all sources I found online said I have to calculate the error with my encoder values.

For the robot I'm programming I got 2 functions. One that gets the absolute encoder values and one that gets the speed in ticks/s.

The sources I found didn't specify if I use absolute encoder values or the speed encoder values. I tried both already but it didn't work out too well, so I would like to know if some already have some experience with a motor PID control using the encoders.

This is my PID code I wanted to use:

```<code>e_func_r = v_des-v_act_r;

r_mot_r = r_old_r
    + (1/K_P)*(e_func_r-e_old_r)
    + K_I*(e_func_r+e_old_r)/2
    + K_D*(e_func_r-2*e_old_r+e_old2_r);

if(r_mot_r >= 100)
{
    r_mot_r = 100;
}
if(r_mot_r <= -100)
{
    r_mot_r = 100;
}

r_old_r  = r_mot_r;
e_old2_r = e_old_r;
e_old_r  = e_func_r;
</code>```

答:
The "PID code" you have is not a PID controller. At all. You should have error terms defined as:

```<code>error = setpoint - feedback; // Setpoint and feedback should be in the same units.
deltaTime = TimeSinceLastCall(); // Platform/language specific.

proportionalError = error;
integralError = integralError + error*deltaTime;
derivativeError = (error-prevError)/deltaTime;
prevError = error;

controlSignal = (kP*proportionalError) + (kI*integralError) + (kD*derivativeError);
</code>```

That's a PID controller. I'm not going to go through the code that you posted point-by-point because it's very wrong, to the point that I can't understand how it was intended to work, so I don't really have a rebuttal or explanation to try to help point out where it went wrong. If you want a PID controller, use the error terms as I provided above.

Also, with the original code, the motor control signal is always accumulating. It shouldn't do this, it should instead just be the output of the PID controller. You have:

```<code>r_mot_r = r_old_r + <controller output>
</code>```

when it should just be

```<code>r_mot_r = <controller output>
</code>```

as in:

```<code>r_mot_r = controlSignal
</code>```

where controlSignal is the term I defined in the block of code at the top of this post.

I'll point out that two-wheeled vehicles are non-holonomic platforms, which means you can't just position the actuators (wheels) independently and arrive at a given position and orientation. Going forward 10 blocks and then turning left is not the same as turning left and then going forward 10 blocks! You are going to find that your robot will never go straight without having some kind of absolute position feedback. Wheel encoder feedback is okay for (very) short term, but you will experience drift.

Title: Encoder values for PID control

Body:
The "PID code" you have is not a PID controller. At all. You should have error terms defined as:

error = setpoint - feedback; // Setpoint and feedback should be in the same units.
deltaTime = TimeSinceLastCall(); // Platform/language specific.

proportionalError = error;
integralError = integralError + error*deltaTime;
derivativeError = (error-prevError)/deltaTime;
prevError = error;

controlSignal = (kP*proportionalError) + (kI*integralError) + (kD*derivativeError);

That's a PID controller. I'm not going to go through the code that you posted point-by-point because it's very wrong, to the point that I can't understand how it was intended to work, so I don't really have a rebuttal or explanation to try to help point out where it went wrong. If you want a PID controller, use the error terms as I provided above.

Also, with the original code, the motor control signal is always accumulating. It shouldn't do this, it should instead just be the output of the PID controller. You have:

r_mot_r = r_old_r + <controller output>

when it should just be

r_mot_r = <controller output>

as in:

r_mot_r = controlSignal

where controlSignal is the term I defined in the block of code at the top of this post.

I'll point out that two-wheeled vehicles are non-holonomic platforms, which means you can't just position the actuators (wheels) independently and arrive at a given position and orientation. Going forward 10 blocks and then turning left is not the same as turning left and then going forward 10 blocks! You are going to find that your robot will never go straight without having some kind of absolute position feedback. Wheel encoder feedback is okay for (very) short term, but you will experience drift.


问:
Can I program my roomba to run essentially all day (except for charging, of course)?
I'm an artist with basically no programming background. I need to make my roombas (3 of them) move around a gallery space throughout the day and night (the gallery will be visible from street view 24 hours a day). The show will last about 4 months, so I was wondering if there's a way to automatically schedule such a thing using the Create 2. (The customer service rep said there's a regular model with an app control, but it sounds like someone would have to manually re-set the roomba every time it's done charging). The roombas do not have to be good at cleaning, or anything other than moving, so if there's also a way to minimize the workload of the machine to maximize it's lifespan, I'd be curious if that's possible as well. Thanks so much for your help, roomba programmers! </p>

答:
If I understand you right, you want to achieve that three roombas clean 24 hours a day, just making a break if they need to recharge and then continue.
The Create 2 is a roomba robot that is similar to the 600-series, but some article says it can not clean, which is good as this saves the energy that would be needed to drive the vaccum and brush motors. This also extremly reduces the noise!

Unfortunately, roombas are only able to be schedule for cleaning once a day just using the normal user interface. This means the robot will move around and "clean" until it thinks its enough for the room size it detects or it's battery is nearly depleated and then move back its charging station. For a large hall this typically means the robot should clean until it's battery is empty. For my 500-series roomba the battery lasts for about 1,5 hours. If not really cleaning, the battery might last much longer! However, the battery discharges even the robot isn't moving or cleaning, since the electronics (control board) draw a noticable amount of energy. This means, the roomba would stop its work for this day and continue cleaning the next day. If you have three of them you can schedule one of them to clean at 0:00am, 8:00am and 4:00pm. But, that's surely not enough.

To make them all clean again as soon as it recharged, you need to influence the devices in one or the other way. Means: You need additional hardware or a person who does it manually. If you know someone who has access to some electronics and can do microcontroller programming (e.g. arduino) stuff well you can use the open interface of the roomba. There is some serial port to control the roomba and to get information from it.
If you don't want to control the robot, but just need to restart cleaning its quite easy:
* build a serial connection to the roomba (5V-Arduino prefered)

send a "START" and "SAFE MODE" command to the robot to be able to observe its state

check if it is placed on a charging station. If not: "STOP" and sleep some minutes and repeat.

if its on a charging station and finished recharging -> start "MAX" cleaning mode

observe the battery status, if it's getting too low: -> activate "Docking mode"

if docked, execute "STOP" command (else it won't recharge!)

repeat steps

To optimize you might already restart the cleaning at 80-90% of battery charge, as the last 10-20% of recharging take much longer.

The programming itself isn't too hard, but you need:
1. a microcontroller (e.g. Arduino)
2. someone who is able to do the electronics (connections to the robot), if you can't do it yourself
3. someone to do simple (arduino-)programming stuff (mainly serial port communication)

If you would send me a video of the installation, I would do the programming for you. But, I assume that I cannot come over and modify the roomba for you to install an arduino to it. Nor can I upload the software to your arduino. So it makes more sense if you would find someone nearby who can do it. Give them a link to the open interface spec, which tells them basically how to connect an arduino and how to execute commands via serial port commands.


问:
PID Tuning. Does Setpoint Affect Gain for Tuning
So I understand that a heuristic way of determining values for PID would be to use the Ziegler method, having zero I and D and then adjusting P until you have oscillations. Wouldn't the setpoint change what the P gain should be to oscillate? So if setpoint is very far off you might be coming into the oscillation region with a larger rate of change and would need a larger P to have it oscillate back, whereas with a setpoint relatively close you wouldn't need as much.

Would you simply tune to what is more likely being close or being far from the setpoint when control begins?

答:
You are correct; this is the biggest disadvantage of a PID controller. Oscillation will happen as a result of system inertia, but there's no way to "inform" the PID controller as to how much inertia it should expect.

Another factor would be actuator saturation. A cruise control system that would floor a gas pedal trying to get from 0 to 25 would also floor the gas pedal trying to get from 0 to 100; so in that instance there's not going to be too much difference regarding the initial transient.

Generally speaking, the best approach if you don't know the process is simply to tune for the anticipated scenario. I've seen brute force methods try to swap control gains depending on the scenario at hand, if you expected distinctly different operating conditions (like startup, normal operation, and shutdown).

If you know the process but don't want to get into more complex controls then you can try to estimate the required control signal given current conditions. This is known as "feed-forward" control, and leaves your PID controller to make up the difference between the result of your feed-forward controller and the actual system output. This is very common in industrial controls, especially motor speed/torque control. You input rotor inertia, load inertia, etc., along with the motor parameters and can generally ballpark the current required to achieve a specific speed profile. The PID controller then just makes up the difference.

Finally, if you know the process and are willing to get more in-depth, model-based control would be the approach. Techniques like state feedback controls exist that allow you to take a model of your system and use that model to define the controller.


问:
Wind force impact on torque mechanical arm
I've got an arm attached to a shaft. The arms dimensions are 40x5 inches the arm weights about 10 lbs.

If I have a wind acting on the side of the arm, how would I translate the wind force into torque on the shaft?

To give some more information, I'm rotating the arm using a stepper motor, and I would like to know how to size the motor depending environmental conditions.

What should my formula look like in order to arrive a required oz-in of torque given my requirements being:

I need to be able to accelerate the arm from 0 to 12 rpm in 1.5 seconds

The wind speed can be as high as 30 mph

Using the formula P = .00256 x 30^2 i find the wind pressure per square foot being 2.304

Using the formula F = A x P x Cd for calculating force, I get 1.389 x 2.304 x 2 = 6.4

So I know that the wind force on my arm is 6.4 lbs. But now how do I translate this to torque on my arm?

Source: http://k7nv.com/notebook/topics/windload.html

答:
If you assume that the wind force you calculated is distributed evenly about the arm (reasonable assumption) then the torque about the shaft is the distance to the center of the arm (20 in) multiplied by the force in oz.

So

Torque = Force in ounces * Distance = (6.4 lb) * (16 oz / 1 lb) * (20 in) =  2048 oz. in.


问:
Management of asynchronous commands
I am working on a robotics project with C++ (drawing signs on board), on CRS CataLyst5 arm.

I have faced a problem:

I have many methods move in different directions, goToLocalizations, etc, but the problem is that when I run many of them in main without Sleep() function between each function they does not run properly. I think that the first one needs time (the time of robot movement) but when I put Sleep(10000) between them (I guessed that 10 seconds are enough for the movement) all is ok. This is very ineffective and slow solution. Would you like to give me some solutions to avoid the use of Sleep ?

答:
Since you mention that you are using a CRS Catalyst 5 arm, I assume that you are using the CRS ActiveRobot ActiveX control.

A quick look through this ActiveRobot Tutorial suggests that all robot commands are asynchronous, so when you command the gripper to open (using Robot.GripperOpen in VB) you then have to wait for the move to finish (using Robot.GripperFinish in VB).

Similarly it looks like you need to wait for a Robot.MoveStraight to complete with a Robot.Finish etc.

Replace all of your sleep calls with the relevant wait commands and you will get rid of all of the unwanted dead time. Similarly if you wait for one move to finish before starting a subsequent move, you may prevent moves conflicting with eact other, confusing the control system.

Title: Management of asynchronous commands


问:
Can GPS modules work inside plastic enclosures?
I'm going to be embarking on an autonomous robot project and I was going to be using GPS to navigate to waypoints (I'm aware of the margin of error when it comes to localization with GPD but I live in a lovely area with many open fields).

I was going to use Adafruit's Ultimate GPS Breakout board with my RaspberryPi, and I was wondering how I should protect or mount the GPS to protect it from the elements. Do all GPS units need to be face up and unobstructed (ex. wood or plastic) in order to work? If so, how can I still protect a GPS unit from the outdoors?

答:
Yes, it works fine in a plastic (or wood) case. I've used the PA6H GPS from Adafruit in a Hammond 1553B plastic case with no issues.

Mostly what you want to avoid is any sort of conductor that might block a signal. This includes copper and iron.


问:
Preventing leaks in motor shafts for underwater bots
Whenever building an aquatic bot, we always have to take care to prevent leakages, for obvious reasons. Now, holes for wires can be made watertight easily--but what about motors? We can easily seal the casing in place (and fill in any holes in the casing), but the part where the axle meets the casing is still left unprotected.

Water leaking into the motor is still quite bad. I doubt there's any way to seal up this area properly, since any solid seal will not let the axle move, and any liquid seal (or something like grease) will rub off eventually.

I was thinking of putting a second casing around the motor, maybe with a custom rubber orifice for the shaft. Something like (forgive the bad drawing, not used to GIMP):

This would probably stop leakage, but would reduce the torque/rpm significantly via friction.

So, how does one prevent water from leaking into a motor without significantly affecting the motor's performance?

(To clarify, I don't want to buy a special underwater motor, I'd prefer a way to make my own motors watertight)

答:
Simple DC motors installed in my Underwater Robot are still running (with a little more noise), from an year, without ANY seal.

The voltage of 12V is not so much, so even if the power terminals are dipped in water,  water will not conduct much current through itself, unless it is salty.

As the current flows through the path of least possible resistance, most of the current will still be going through the motor windings, however presence of water causes Rusting which will damage the brushes of the motor and hence more noise and friction.


问:
How to manage interrupts on an AVR?
I have a number of interrupt service routines on an AVR. These include interrupts for USART serial communication, timers, and SPI communication.

For all of these, I use circular queues (using a start and end pointer, without boundary checking).

Some problems start to occur if the AVR starts to get overloaded. The circular queues will lose chunks of data. To solve this, I can reduce the load on the AVR (for example, by skipping some cycles in the timer). However, this is a manual process, where it is reduced if the AVR appears to have problems. This is partly because I do want relatively consistent timer periods.

However, even at 70% average processor load, the queues can fill up randomly by chance.

In case of spurious overloading at times, how can I make this more adaptive to avoid queue overflows?

答:
I can't answer specifically for the AVR, but I can offer some more general advice.

Low level

I think you are going to have to prioritise. Look at what you can afford to throw away and what you can afford to process when your system starts to get overloaded. Also, profile your usage to see what data you have coming in when.

For instance, if you have a higher level retry protocol on your serial comms, then when you are overloaded perhaps you could drop incoming serial bytes, leaving it to the retry mechanism to catch up when the CPU has the time.

If you can do this then you are going to want to fail early. When your serial buffer is full, there is no point reading the data from the uart, writing it into your buffer, overwriting existing data - that's just wasting cycles which could be used elsewhere (you are going to have to throw away the partial serial stream anyway). When you experience a serial buffer overrun, just clear the uart without reading it, leave the buffer in it's old state and return, letting the CPU get on with things it can complete successfully.

Alternatively, you could disable interrupts entirely for low priority events.

Profiling your usage can also be very valuable. Lets say you have four 16 byte buffers where one is constantly going into an overrun condition because you are sending 36 byte packets to it, but where the other 3 never have more than 5 or 6 bytes in them at once. In this case it is worth rewriting your buffer code to allow different sized buffers. That way you could allocate 8 bytes each to three streams and 40 bytes for the final stream.

High level

You need to analyse why your buffers randomly fill up by chance. Are you trying to do too much with the data in one go? Could you split that processing up and do several shorter processes rather than one long process.

For instance, if your interrupts normally take up 70% of your CPU and another routine takes up 20% on average, but only needs 10% some of the time and runs out of CPU at others, then breaking up that processing into more predictable, repeatable blocks could be worthwhile, even if it takes more processing power power overall.

Also, if you don't have a higher level retry mechanism, consider implementing one, this would enable low level prioritisation which might otherwise not be possible.

Finally, learn how to optimise for your hardware. Again, profiling can help here. If your ISRs are taking up a significant proportion of your CPU time, every cycle you save is a cycle you can use elsewhere. Don't blindly 'optimise' everywhere, chose your battles.

Profiling will tell you where in your code is most critical so you can put your efforts where it will count (See Is micro-optimisation important when coding?).

Title: How to manage interrupts on an AVR?


问:
Programming Robots with JavaScript
As somebody who is spending the majority of his time programming in JavaScript, what's the best route to get into small-robotics without needing to deviate too much from my current language focus?

Are there any project kits or tools that make use of the JavaScript language that might make the field more approachable for developers like myself? I would even be interested in virtual environments where all code is executed in a simulation.

答:
Programming the AR.Drone 2.0 with Javascript is super fun. Here's an example that makes a drone take off, move around, do a flip, then land, all using the node-ar-drone library:

```<code>var arDrone = require('ar-drone');
var client = arDrone.createClient();

client.takeoff();

client
  .after(5000, function() {
    this.clockwise(0.5);
  })
  .after(3000, function() {
    this.animate('flipLeft', 15);
  })
  .after(1000, function() {
    this.stop();
    this.land();
  });
</code>```

The blog post NodeBots - the Rise of JS Robotics talks about advantages javascript has for robotics, specifically the natural way that real world objects and actions can be modeled as chainable, evented processes.  The example code above to animate a drone looks very similar to using jQuery to animate an HTML element:

```<code>$("#foo")
  .slideUp(300)
  .delay(800)
  .fadeIn(400);
</code>```

Title: Programming Robots with JavaScript

Body:
Programming the AR.Drone 2.0 with Javascript is super fun. Here's an example that makes a drone take off, move around, do a flip, then land, all using the node-ar-drone library:

var arDrone = require('ar-drone');
var client = arDrone.createClient();

client.takeoff();

client
  .after(5000, function() {
    this.clockwise(0.5);
  })
  .after(3000, function() {
    this.animate('flipLeft', 15);
  })
  .after(1000, function() {
    this.stop();
    this.land();
  });

The blog post NodeBots - the Rise of JS Robotics talks about advantages javascript has for robotics, specifically the natural way that real world objects and actions can be modeled as chainable, evented processes.  The example code above to animate a drone looks very similar to using jQuery to animate an HTML element:

$("#foo")
  .slideUp(300)
  .delay(800)
  .fadeIn(400);


问:
ArduIMU noisy output in Quadrotor
We are using ArduIMU (V3) as our Quadrotor's inertial measurement unit. (we have a separate board to control all motors, not with ArduIMU itself).

Now we have a problem with ArduIMU's sensors output. When we put our quadrotor steady on the ground with motors on, instead of getting 0 degree in roll and pitch we have a noisy output something like the image below( -6 to 6 degree error ):

delta_t = 0.2s

We are sure that this isn't a mechanical problem, because we checked the mechanical joints and everything.

I should mention that with motors off everything is going well. Also we checked that if we vibrate the device slowly on yaw axis or any other axis, it still shows the noisy output.

We are using DCM filter inside ArduIMU, also we tested with Kalman filter but no difference.

We also tested FRI low-pass filter, results is good but there is about 3 seconds delay in the output.

We also checked that if we separate the ArduImu's power from our circuit, it still no difference.

What's the problem with ArduIMU and how we can get rid off this noisy output ?

Update:
We think that the problem with our PID controller is because of these noises ... Is this a true assumption ? We can't tune our PID parameters ( using Ziegler–Nichols method ) when we have noisy data. We tested Ziegler–Nichols method when we have low rate noises and we successfully tuned our PID but when noise appears we are unable to tune PIDs. Is there anyway for us for tuning our PID in such situation ? Is this problem is because of the noises or the PID itself can get rid of them ?

答:
We build a new version and its now available for download:

http://code.google.com/p/ardu-imu/downloads/detail?name=arduimu_vD....

The problem completely gone in this version. Read comments in arduimu_vd.ino for more info.

Title: ArduIMU noisy output in Quadrotor


问:
classify if two adjacent surfaces belong to same object
I have a box (cuboid) lying on floor or table. So there are 6 surfaces of the box and 1 surface of the floor. If I take each pair of surface such that the surfaces are "adjacent" to each other, I get two kind of pairings:

1) two surfaces of the box: the surface normals of the surfaces diverge from each other.

2) 1 surface of the box + surface of the floor : the surface normals converge and intersect at an angle of 90 degrees. ( 8o to 100 degrees, if we want to add some tolerance).

I want to distinguish these two cases by representing through a function? What function can distinguish between these two situations?

In both cases, the the normalized dot product of the surface normals is 0, since the angle b/w them is 90 degrees. So this is not the right solution...

答:
It actually makes sense that the dot product in both cases is the same (zero) because the dot product of two vectors does not consider the vectors' origins.  Or in other words the math for the dot product places the two vectors at the same origin. In this sense there is no way to distinguish converging or diverging vectors.

I think what you need to do is to consider a midpoint for your surfaces as well as their normals and then you should have a convergence or a divergence. Or try taking a dot product of one surface's normal with the other surface's position or vice versa. You will probably find that positive vs negative numbers in this regard will get the answer you seek.

Or maybe you can use the delta position from one to the other against a normal. See the following sketch.

By delta position I mean P1-P2. I hope the diagram helps to clarify. I've drawn two cases: case #1 on the left and case #2 on the right. Calculate the dot product of the two blue vectors or the two red vectors. So, for example:

```<code>answer = dot( N[blue], P[red]-P[blue] )
</code>```

These vectors won't be perpendicular, but the answer will tell you if the one surface is in front of the other or behind it. For case #1 the dot products will be positive. For case #2 the dot products will be negative.  In fact, this method will tell you if any two arbitrarily positioned surfaces that meet at a common edge are convex or concave (divergent or convergent). They don't have to be perpendicular.

Body:
It actually makes sense that the dot product in both cases is the same (zero) because the dot product of two vectors does not consider the vectors' origins.  Or in other words the math for the dot product places the two vectors at the same origin. In this sense there is no way to distinguish converging or diverging vectors.

I think what you need to do is to consider a midpoint for your surfaces as well as their normals and then you should have a convergence or a divergence. Or try taking a dot product of one surface's normal with the other surface's position or vice versa. You will probably find that positive vs negative numbers in this regard will get the answer you seek.

Or maybe you can use the delta position from one to the other against a normal. See the following sketch.

By delta position I mean P1-P2. I hope the diagram helps to clarify. I've drawn two cases: case #1 on the left and case #2 on the right. Calculate the dot product of the two blue vectors or the two red vectors. So, for example:

answer = dot( N[blue], P[red]-P[blue] )

These vectors won't be perpendicular, but the answer will tell you if the one surface is in front of the other or behind it. For case #1 the dot products will be positive. For case #2 the dot products will be negative.  In fact, this method will tell you if any two arbitrarily positioned surfaces that meet at a common edge are convex or concave (divergent or convergent). They don't have to be perpendicular.


问:
Do 6 motors require 6 individually-assigned batteries?
For the Dagu Wild Thumper 6 Wheeled platform, or any multiple motor system, do I really need 1 battery for each motor? Or should I just buy 2 for either side of the platform. In addition, for larger motors like the ones on this platform, how do I deal with the power generated from a coasting motor?

I want to jump into the deep end with robotics, as I already hold all the programming skills, and I realize a platform of this magnitude may be a difficult endeavor.

Recommended motor voltage is 2 – 7.5 Volts, so should one use two 22 Volt batteries for the left and right side, or six 7.5 volt batteries?

答:
I'm not familiar with that platform.  But in general, no, you do not need separate batteries for each motor.

Also in general, if you need 2-7.5V for each motor, then you probably want one honkin' big battery that puts out 7.5V or slightly more.  You could use a 12V battery and take care with your drive commands to never give the motors over 7.5V.

Only if you need to do something odd like connecting the motors in series would you need more voltage.


答:
There are a variety of GPS units available that use plastic cases to protect against the elements, and they are all plastic.

For example, these Garmin units.

It sounds like you're really asking about what enclosure materials will keep the weather out but let the signal in.  For this, you just need to make sure that you aren't using a conductive shield:

the conductor used as a shield has to be thicker than the "skin depth" of the metal at the frequencies you're trying to block out. [...] 1 micron is enough in practice.

This shielding could be in the form of a metal, a paint, or even a fabric.  So, your enclosure can be anything that does not have a lining made with one of these materials.  Unpainted plastic is a good option.

Title: Can GPS modules work inside plastic enclosures?

Body:
I'm going to be embarking on an autonomous robot project and I was going to be using GPS to navigate to waypoints (I'm aware of the margin of error when it comes to localization with GPD but I live in a lovely area with many open fields).

I was going to use Adafruit's Ultimate GPS Breakout board with my RaspberryPi, and I was wondering how I should protect or mount the GPS to protect it from the elements. Do all GPS units need to be face up and unobstructed (ex. wood or plastic) in order to work? If so, how can I still protect a GPS unit from the outdoors?


问:
Help with PID "units" in a quadcopter control system
I'm in the process of writing my own simple quadcopter controller for experimental use, and I'm having trouble getting my head around how to convert from the degrees which my PID controller demands to an appropriate 1k-2k range for PWM output. For example, take the roll axis on a '+' configured 'copter (pseudo-code):

```<code>setpoint = scaleToRange(receiver.rollValue, -30, 30); //scale the command (1000-2000) to between -30 and 30 degrees, as that's the maximum roll permitted.
demandedRoll = rollPID.calculate(setpoint, imu.currentRoll, PID_params);

/// the part I'm having trouble with

motorLeft_command = receiver.throttle - rollPWM;
motorRight_command = receiver.throttle + rollPWM;
</code>```

How do I take the roll demanded by my PID controller and convert it to a value useful to the motors, that is to say, where does rollPWM come from? My first instinct is to use a simple linear relationship, i.e.:

```<code>rollPWM = scaleToRange(demandedRoll, MinValue=receiver.throttle/2, MaxValue=2000-receiver.throttle);
//don't let it go beyond 50% of throttle on low end, and the ESC's max on the high end.
</code>```

However this seems far too simplistic to work.

Or should I be doing more calculations before everything goes through PID control? Any help would be great.

答:
Wrapping your head around unit conversions in controllers is a pretty common problem, so don't think you're alone.

If you're implementing your PID controller using floating point math, then you really don't have to worry: the gains that you assign for the proportional, integral, and derivative action will take care of the differing ranges for the inputs and outputs.

If you're implementing your PID controller using integer math or fixed-point math, then you don't have to worry for the reasons you're worrying.  Instead, you have to worry about keeping the calculations in the right range so that you neither lose precision nor overflow any calculations.

As an example for a floating-point calculation, a plausible proportional gain would be 500 output counts per degree of input error.  In floating point, you'd just assign 500.0 to the proportional gain.

So have fun.  Don't forget the integrator anti-windup.


问:
What good robotics software platforms / operating systems are available?
My company will soon be starting a brand new robotics project, and we are still trying to decide whether we should design and code a robotics software platform from scratch, or if there are any good existing ones.

It would be very useful if there was a software platform which was commonly used among both academics and industry so that our robotic system was generally compatible with others, and so that people were already familiar with it.

We would like the software platform to be able to:

Integrate new robotic hardware components easily.

Already contain a wide array of useful data processing and visualisation tools

Make efficient use of computing hardware

答:
My preferred platform is ROS. However, there is another strong contender from... dare I say it... Microsoft. It is called Robotics Developer Studio (RDS). Begin your search here: http://www.microsoft.com/robotics/ </p>

<p>They have many videos of impressive applications. To me, the largest benefit is the built-in support for Kinect via Microsoft's Kinect SDK. Technically, the one which ROS uses from OpenNI has the same capabilities but it seems comforting to know the SDK which RDS uses is written by the same company which produced the hardware. </p>

Body:
My preferred platform is ROS. However, there is another strong contender from... dare I say it... Microsoft. It is called Robotics Developer Studio (RDS). Begin your search here: http://www.microsoft.com/robotics/

They have many videos of impressive applications. To me, the largest benefit is the built-in support for Kinect via Microsoft's Kinect SDK. Technically, the one which ROS uses from OpenNI has the same capabilities but it seems comforting to know the SDK which RDS uses is written by the same company which produced the hardware.


问:
What rail material is best used for linear bearings?
For the 3d printer RepRap Prusa there are several rails (smooth rods) that guide the printer head on the different axises. The printer head uses several linear bearings to glide along the rails.

There isn't any specification on what kind of material would be best suited for this purpose with the linear bearings. My first assumption would be for stainless steel because it won't corrode (rust) on the surface, but I'm not sure if this is true for all printers (whether they are 3D printers or not) as a different material may allow the linear bearings to glide more easily. Aluminum would have been my second choice but I have the same reservations of which grade would be least resistant.

This resource has some limited information but does not help with which would be best suited for this particular application.

What material is best suited for this purpose?

答:
For ball bearings, you almost always want to use the hardest, smoothest material you can find. Stainless steel would do nicely. Aluminium will be far too soft, and will simply be worn down the the steel ball bearings.

Plastic bearings like these Drylin from Igus can use aluminium rails:


答:
Tim Wescot is one of the most experienced experts ever in this forum especially in the PID controllers field.

I recommend you to read his brilliant article here.

We used discrete PID for our quadrotor control system. We are building a quadrotor right now and tested both continuous PID controller(What you are usually find in wikipedia or web searches) and discrete PID controller, and for quadrotor systems which has a digitized system, we find discrete PID far better than continuous one.

In this method, you should use 2 separate PID for each motor, but PID gains is equal except Kp of one of them should be -Kp of another one. Here is the sample code( in C# ):

```<code>    class PIDController
    {
        float[] _u = new float[3];
        float[] _e = new float[3];
        float[] _ef = new float[3];
        float _Tf;

        float _Kp;
        float _Ti;
        float _Td;
        float _h; //delta_t
        float MaxValue; // min value for motors output
        float MinValue; // max value for motors output
        float _Alfa; //mostly 0.1
        public PIDController(float SamplingPeriod,float Alfa)
        {
            _Alfa = Alfa;
            _h = SamplingPeriod;
            MinValue = 0;
            MaxValue = 100;

        }
        public void SetCoefficient(float Kp,float Ti,float Td)
        {
            _Kp = Kp;
            _Ti = Ti;
            _Td = Td;
        }
        public void SetRenge(float Min,float Max)
        {
            MinValue = Min;
            MaxValue = Max;
        }

        public float GetOutputSignal(float y, float r)
        {

            _Tf = _Alfa * _Td;
            float a = _h / (_Tf + _h);
            _u[1] = _u[0];
            _ef[2] = _ef[1];
            _ef[1] = _ef[0];
            _e[2] = _e[1];
            _e[1] = _e[0];
            _e[0] = r - y;
            _ef[0] = (1 - a) * _ef[1] + a * _e[0];
            if ((_Ti != 0) && (_h > 0))
                _u[0] = _u[1] + _Kp * (_e[0] - _e[1]) + (_Kp * _h / _Ti) * _e[0] + ((_Kp * _Td) / _h) * (_ef[0] - 2 * _ef[1] + _ef[2]);
            else
                _u[0] = 0;
            //System.Diagnostics.Debug.WriteLine(string.Format("y = {0} , r = {1} , e = {2} u={3}",y,r,_e[0],_u[0]));
            //System.Diagnostics.Debug.WriteLine(string.Format("Ti = {0} , Td = {1} , Kp = {2}", _Ti, _Td, _Kp));
            //System.Diagnostics.Debug.WriteLine("");
            if ((_u[0] > MaxValue) || (_u[0] < MinValue))
            {
                if (_u[0] > MaxValue) { _u[0] = MaxValue; };
                if (_u[0] < MinValue) { _u[0] = MinValue; };
            }

            return _u[0];
        }

    }
</code>```

Test it, you will find this solution far better than continious one. We also used genetic algorithm for auto-tuning this PID. I should mention this type of PID controller won't work without an integral gain. I also should mention that, we didn't currently fully tune our quadrotor, but we got far far better results than continuous one.

Here is the mathematical explanation of this method for more info.

Title: Help with PID "units" in a quadcopter control system

Body:
I'm in the process of writing my own simple quadcopter controller for experimental use, and I'm having trouble getting my head around how to convert from the degrees which my PID controller demands to an appropriate 1k-2k range for PWM output. For example, take the roll axis on a '+' configured 'copter (pseudo-code):

```<code>setpoint = scaleToRange(receiver.rollValue, -30, 30); //scale the command (1000-2000) to between -30 and 30 degrees, as that's the maximum roll permitted.
demandedRoll = rollPID.calculate(setpoint, imu.currentRoll, PID_params);

/// the part I'm having trouble with

motorLeft_command = receiver.throttle - rollPWM;
motorRight_command = receiver.throttle + rollPWM;
</code>```

How do I take the roll demanded by my PID controller and convert it to a value useful to the motors, that is to say, where does rollPWM come from? My first instinct is to use a simple linear relationship, i.e.:

```<code>rollPWM = scaleToRange(demandedRoll, MinValue=receiver.throttle/2, MaxValue=2000-receiver.throttle);
//don't let it go beyond 50% of throttle on low end, and the ESC's max on the high end.
</code>```

However this seems far too simplistic to work.

Or should I be doing more calculations before everything goes through PID control? Any help would be great.

Body:
Tim Wescot is one of the most experienced experts ever in this forum especially in the PID controllers field.

I recommend you to read his brilliant article here.

We used discrete PID for our quadrotor control system. We are building a quadrotor right now and tested both continuous PID controller(What you are usually find in wikipedia or web searches) and discrete PID controller, and for quadrotor systems which has a digitized system, we find discrete PID far better than continuous one.

In this method, you should use 2 separate PID for each motor, but PID gains is equal except Kp of one of them should be -Kp of another one. Here is the sample code( in C# ):

    class PIDController
    {
        float[] _u = new float[3];
        float[] _e = new float[3];
        float[] _ef = new float[3];
        float _Tf;

        float _Kp;
        float _Ti;
        float _Td;
        float _h; //delta_t
        float MaxValue; // min value for motors output
        float MinValue; // max value for motors output
        float _Alfa; //mostly 0.1
        public PIDController(float SamplingPeriod,float Alfa)
        {
            _Alfa = Alfa;
            _h = SamplingPeriod;
            MinValue = 0;
            MaxValue = 100;

        }
        public void SetCoefficient(float Kp,float Ti,float Td)
        {
            _Kp = Kp;
            _Ti = Ti;
            _Td = Td;
        }
        public void SetRenge(float Min,float Max)
        {
            MinValue = Min;
            MaxValue = Max;
        }

        public float GetOutputSignal(float y, float r)
        {

            _Tf = _Alfa * _Td;
            float a = _h / (_Tf + _h);
            _u[1] = _u[0];
            _ef[2] = _ef[1];
            _ef[1] = _ef[0];
            _e[2] = _e[1];
            _e[1] = _e[0];
            _e[0] = r - y;
            _ef[0] = (1 - a) * _ef[1] + a * _e[0];
            if ((_Ti != 0) && (_h > 0))
                _u[0] = _u[1] + _Kp * (_e[0] - _e[1]) + (_Kp * _h / _Ti) * _e[0] + ((_Kp * _Td) / _h) * (_ef[0] - 2 * _ef[1] + _ef[2]);
            else
                _u[0] = 0;
            //System.Diagnostics.Debug.WriteLine(string.Format("y = {0} , r = {1} , e = {2} u={3}",y,r,_e[0],_u[0]));
            //System.Diagnostics.Debug.WriteLine(string.Format("Ti = {0} , Td = {1} , Kp = {2}", _Ti, _Td, _Kp));
            //System.Diagnostics.Debug.WriteLine("");
            if ((_u[0] > MaxValue) || (_u[0] < MinValue))
            {
                if (_u[0] > MaxValue) { _u[0] = MaxValue; };
                if (_u[0] < MinValue) { _u[0] = MinValue; };
            }

            return _u[0];
        }

    }

Test it, you will find this solution far better than continious one. We also used genetic algorithm for auto-tuning this PID. I should mention this type of PID controller won't work without an integral gain. I also should mention that, we didn't currently fully tune our quadrotor, but we got far far better results than continuous one.

Here is the mathematical explanation of this method for more info.


问:
MPU-6050 + Arduino nano - Logic converter or not?
I bought this MPU-6050: link

According to the manufacture site, the sensor logic level is 3.3V (though the ebay page says Power supply :3-5v)

Should I use a 4 channel Bi-Directional Logic Level Converter (like this one) for the SDA, SCL, INT channels? or can I connect it directly to my arduino nano?

I saw some places that says I should use it with a logic level converter and some who say it's ok without it. (I guess it depends on the sensor board, so please take a look, link above)

Current Setup:

```<code>SDA <-> LLC <-> A4
SCL <-> LLC <-> A5
INT <-> LLC <-> D2
VCC <- LLC <- 5V (arduino)
GND <- LLC <- GND (arduino)
</code>```

I still don't have the parts so I can't test it, and I'm probably going to use Jeff Rowberg library to communicate with the sensor (I2C)

答:
According to the link you provided, you can use 5V or 3.3V directly on the sensor (it already have a voltage regulator). Since the arduino is able to send 3.3V or 5V you can use both of them directly without any level converter.
You can see on the video here that you don't need anything

I got a GY-80 with the same kind of features and I use it directly on my arduino nano without any level converter.
Their is also a whole arduino playground on how to use this sensor.


问:
Smooth servo movement for a crawling robot
I made a small crawler robot a little while ago that had two legs with two degrees of freedom each, so 4 RC servos total. While I was programming the movement of the legs I noticed that they moved rather stiffly. It makes sense that the RC servo's internal controller would have a very quick response to position commands, but I wanted my crawler to move in a way that seems a little more smooth and life-like.

My solution was create a cubic function of time that describes the path of the servos, and then set their position in small time increments, resulting in more smooth motion. Essentially what I did was solve for the $a_i$ coefficients in a cubic equation using the time interval, starting and ending position of the servo, and starting and ending rates the servo should move (which is just the derivative of the position):

Solve for $a_0$, $a_1$, $a_2$, and $a_3$:

$$ position(t) = a_0 + a_1t + a_2t^2 + a_3t^3 $$
$$ rate(t) = position'(t) = a_1 + 2a_2t + 3a_3t^2 $$

Given: $position(0)$, $position(t_f)$, $rate(0)$, $rate(t_f)$

I set the rate of the servo between a pair of movements to be zero if the movements were in opposite directions, and positive or negative if the movements were both in the positive or negative direction, respectively.

This worked pretty well, but this solution is limited in a few ways. For one, it's difficult to decide what exactly the rates between movements that go in the same direction should be. I used the average of the slopes ahead and behind of a particular position between movements, but it isn't clear to me that is optimal. Second of all, cubic curves could take the servo to a position outside of the range of the positions at the beginning and end of a movement, which may be undesirable. For example, at some point during the time interval, the curve could cause the servo to go beyond the second position, or below the first position. Thirdly, curve generation here does not consider the maximum rate that the servo can turn, so a curve may have the servo move at a speed that is unrealistic. With that, a minor concern is that the maximum turning rate depends on the response of servo's internal controller, and may change depending on the size of the position interval.

Neglecting that last concern, these issues may be solved by increasing the degree of the polynomial and adding constraints to solve for the coefficients, but I'm now starting to wonder...

Is there a better way than this to make servo movement smooth and seem more life-like?

答:
I think the question refers to this sort of device: RC servo

Those usually aren't very high performance so they're not going to be able to track a generated motion profile very well.  Most commercial motor control systems use an S curve for a point to point move (see @ddevaz's answer) which do a piece-wise profile where each segment uses a different equation.  Your problem is going to be that in order for your motor to track the generated profile you're probably going to have a very "slow" profile.  Otherwise the profile you try and command the device to follow is going to have a large position error vs. the actual position of the device.

Ideally you'll want some sort of feedback you can look at while you are executing the motion so you can see how well the device is tracking the command.  From a more practical perspective, if you want significantly better motion you may need different motors and different motor control.


问:
Build an WiFi IP camera with webcam
I have a USB webcam and a WiFi module which it can convert Serial data to WiFi and vice versa.

The question is can I simply convert the data coming from the webcam to serial with a USB to Serial IC (like FT232R ) and then hand it over to my WiFi Module?

Update:

The WiFi module DataSheet is here

答:
I think you're asking whether you can use a USB-to-serial adapter to enable you to connect a USB webcam to a serial-to-wifi converter.  The answer to that is no, unfortunately.

USB defines a hardware interface and a communications protocol.  Your webcam driver communicates with the physical webcam by sending image data over USB, and your USB-to-serial adapter sends RS232 data over USB.  The video stream and the RS232 stream are not compatible.  (And even if your webcam somehow sent data over RS232, USB devices communicate with the operating system, not each other.)

What you are looking for is a bridge -- a way to send USB data over wifi.  There are other consumer products which perform this function, e.g. this one or this one.

Title: Build an WiFi IP camera with webcam


问:
What are good strategies for tuning PID loops?
Tuning controller gains can be difficult, what general strategies work well to get a stable system that converges to the right solution?

答:
Sebastian Thrun presented a simple algorithm for tuning PID in his "How to Program a Robotic Car" class. It's called "twiddle", he describes it here.

Twiddle is very prone to finding local minima--this means that you could come up with a set of three constants that are okay, but not optimal for the situation. The problem of tuning PID constants is a subset of a more general search problem to find certain parameters to maximize utility (in this case, minimizing error of the PID algorithm). You can look into other general solutions to this problem, like hill-climbing, simulated annealing, genetic algorithms, etc. that might end up finding more optimal solutions.


问:
What is the difference between a Robot and a Machine?
What is the difference between a Robot and a Machine? At what point does a machine begin to be called a robot?

Is it at a certain level of complexity? Is it when it has software etc?.

For instance: A desktop printer has mechanics, electronics and firmware but it is not considered a robot (or is it). A Roomba has the same stuff but we call it a robot. So what is the difference.

I have always believed that a robot is a robot when it takes input from it's environment and uses it to make decisions on how to affect it's environment; i.e. a robot has a feedback loop.

答:
In the industrial world, robots have a clear definition to differentiate them from other industrial machines:

Industrial robot as defined by ISO 8373:

An automatically controlled, reprogrammable, multipurpose manipulator programmable in three or more axes, which may be either fixed in place or mobile for use in industrial automation applications.

Reprogrammable: whose programmed motions or auxiliary functions may be changed without physical alterations;

Multipurpose: capable of being adapted to a different application with physical alterations;

Physical alterations: alteration of the mechanical structure or control system except for changes of programming cassettes, ROMs, etc.

Axis: direction used to specify the robot motion in a linear or rotary mode

The important words in this definition are "reprogrammable" and "multipurpose."

For example, let's think about a welding operation that takes place in a car factory.  This operation could be done with a custom machine that lowers welding elements into place at the appropriate place on the car.  Or we could install a robot arm, put a welder on the end of the arm, and teach (program) it where to weld.  When a new model of car comes along, we can teach it the new weld points.  If we no longer need the welding operation, we can move the robot somewhere else, put a new tool on the end of the arm, and teach it to paint or to screw in a bolt.

In a larger context, people have different ideas about what is a robot and what is not.  But "multipurpose" and "reprogrammable" are still key ideas.  If you can't easily re-purpose your machine to do something completely different by reprogramming (and perhaps making minimal hardware "tool" changes), it's not a robot.


问:
Approach to using PID to get a differential robot driving straight
Consider a differential drive robot that has two motorized wheels with an encoder attached to each for feedback. Supposed there is a function for each DC motor that takes a float from -1 to 1 and sets the PWM signals to provide a proportional amount of power to that motor. Unfortunately, not all motors are created equal, so sending each motor the same PWM signal makes the robot veer left or right. I'm trying to think about how to drive the robot straight using the encoders attached to each motor as input to a PID loop.

Here's how I would do it: I would take the difference between the left and right encoders, bound the error between some range, normalize it to be from [-1, 1], and then map it to the motor powers 0 to 1. So if I and D were zero, and we get an error of 1 (so the left motor has turned much more than the right motor), then left motor would be set to 0, and the right motor set to 1 (causing a hard left).

Are there any issues with this? What is a better approach?

答:
Are there any issues with this?

The main issue with this is that while your proposed solution will instantaneously correct for a mismatch between the performance of the motors, it will not correct for accumulated error, let alone more complex errors in position such as Abbe error (see later).

What is a better approach?

There are several things you can do, depending on what your tolerance for errors are and how much effort you want to put into correcting them.

The first step would be to set up a pair of PID loops, one for each wheel, giving them both the same demand position. As I suggested in my answer to a similar question, if you keep both wheels within a very tight error bound of where you ask them to be, then it will take some time to accumulate enough of an error to cause noticeable veer.

It will also be much easier to tune two nominally independent Motor level PID loops than to tune a single complex, interdependent combined system. To stand any change of the higher level control working you really need each motor to behave as similarly as possible to the other motor for as much of the time as possible, and that really requires separate servo loops.

There are a number of further complications however, and it depends what accuracy you need and how much effort you are prepared to go to to correct for them as to which solution you go for. It may be that Dead Reckoning is sufficient, or you may need to add Relative or Absolute position determination to your robot.

One problem is that even if your left and right wheels both move 1000 encoder counts, you may still end up in a different position on two different runs.

For example, say you have a maximum following error of 10 encoder counts, and your motors are running at a speed of say 10 encoder counts per PID loop iteration. Your left motor might move 5,10,10,10...10,5 while your right motor might have a profile of 4,11,10,10...10,5 and even that slight difference in acceleration at the start of the move could cause the robot to set off in slightly the wrong direction. Not only that but the further you move in that direction, the greater the error will become in absolute terms. This is what we are talking about when we talk of Abbe error, and without a complex kinematic model or some sort of external reference, you are never going to be able to correct for it.

For more information, see my answer to a similar but not quite duplicate question: How can I use the Arduino PID library to drive a robot in a straight line?
and my answer to the also related Line Follower optimization


问:
What is the difference between RC motors for cars and helicopters?
I am working on a robot with focus on speed. At the moment I am looking for a suitable motor but it would help if I understood the difference between the various options.

To provide some background, I have not worked with RC model components before, but I think this is the only place for me to find the components needed for my robot, such as the motor.

I have already figured out how much power the motor needs to accelerate my robot as desired, taking energy conversion efficiency and tractional resistance into account. It's about 170 watts, depending on the final weight.

To limit my search further, I need to decide on either using a RC car motor or a RC helicopter motor now, but I don't understand the difference between these options.

Focussing on brushless motors (if that matters), what are the differences between RC car and RC helicopter motors? What needs to be taken into account when choosing between them?

答:
I think the term you're looking for is outrunner (vs inrunner):

This type of motor spins its outer shell around its windings

[...]

Outrunners spin much slower than their inrunner counterparts with their more traditional layout (though still considerably faster than ferrite motors) while producing far more torque. This makes an outrunner an excellent choice for directly driving electric aircraft propellers since they eliminate the extra weight, complexity, inefficiency and noise of a gearbox.

Inrunners (which are what most people think of when they think of a DC motor) are high-RPM motors with low torque, which usually require some kind of mechanical transmission to be practical.

Quadcopters and other aerial vehicles tend to use outrunners, while R/C cars tend to use inrunners.


问:
How can I control a fast (200Hz) realtime system with a slow (30Hz) system?
We are currently designing a mobile robot + mounted arm with multiple controlled degrees of freedom and sensors.

I am considering an architecture in two parts:

A set of realtime controllers (either Raspeberry Pis running an RTOS such as Xenomai or bare metal microcontrollers) to control the arm motors and encoders.  Let us call these machines RTx, with x=1,2,3… depending on the number of microcontrollers.  This control loop will run at 200Hz.

A powerful vanilla linux machine running ROS to compute SLAM, mocap, and execute high-level logic (decide the robot’s task and compute the motors' desired position and speed).  This control loop will run at 30Hz.

I know my framework needs to be scalable to account for more motors, more sensors, more PCs (eg. for external mocap).

My main problem is to decide how to have the different RTx communicate with PC1. I have looked at papers related to robots architecture (e.g. HRP2), most often they describe the high level control architecture but I have yet to find information on how to have the low level communicate with the high level and in a scalable way. Did I miss something?

In order to connect the fast RT machines ensuring the motor control with PC1, I have considered TCP/IP, CAN and UART:

TCP/IP: not deterministic but easy to put in place. Is non determinism a real issue (as it will only be used at at slow speed 30Hz anyways)?

CAN: slow, very reliable, targeted to cars ( have seen there are some exemples using CAN with robots but it looked exotic)

UART: if I had only had one RT machine for motor control I would have considered UART but I guess this port does not scale well with many RTx
Is TCP/IP really a no go because of its non-deterministic characteristics? It is so easy to use…

At the moment no solution really seems obvious to me. And as I can find no serious robot example using a specific reliable and scalable solution, I do not feel confident to make a choice.

Does anyone have a clear view on this point or literature to point to?  Are there typical or mainstream communication solutions used on robots?

答:
I would say any application where a large number of communications nodes are required (sensors or actuators) would benefit from being implemented as a system bus (in contrast to point to point links such as UART or Ethernet), due to wiring complexity, determinism and modularity.

Any control system requires a high degree of determinism, which high bandwidth channels (such as Ethernet) are usually poor at (especially when used with a general purpose OS which introduces large amounts of scheduling jitter, see the following link for a discussion on scheduling determinism). Application processors (such as the ARM11 of the Raspberry Pi) is also probably a poor fit for real-time systems (due to effects such as interrupt latency, and instruction pipe-lining). See the following digikey discussion comparing real-time behavior of a ARM application core vs a microcontroller.

It's a shame the availability of integrated CAN isn't as widespread as UART (RS-485) or I2C (yet), because I think it really simplifies the problem of distributed sensing and actuation. And while the usual 1 Mbps may seem slow, it's usually more than enough after refresh rates of all bus members are calculated (and the transmission rate can always be increased, depending on bus length, impedance and whether your transceivers will allow it). There's also brilliant simulation software available, that basically guarantees worst case response times (for instance RealTime-at-work has a free CAN bus analyser called RTaW-Sim). And finally, it would seem the availability of MEMS sensors with integrated CAN is rather poor.

Another example where actuators are configured as a bus (or ring), is Dynamixels AX and MX series, where each motor is daisy chained to the next via a UART link. This greatly simplifies system design if you have a large amount of actuators.

But, to get back to the actual question, I think if you describe your system as real-time set points, instead of commands (eg rather continuously broadcast a motor angle than instructing a command such as goto angle), it simplifies the coupling between the 200 Hz and 30 Hz loop.


答:
Ian is absolutely right.  I've been in the RC hobby for years.  Your drivetrain/gearing is going to be your biggest factor into deciding inrunner vs. outrunner.  You must also consider your power source and figure out it's voltage and max current output and be sure it has enough capacity (typically measured in milliamp/hours).

To make things easier, I'd recommend buying a brushless SYSTEM so you don't have to worry when buying a separate ESC (electronic speed controller) and having it not be a good match for your motor choice.

Brushless motors are faster than you might think.  They can easily make RC cars go 50+ MPH.  You don't want to have something so fast you can't control it.  All said, I'd go with a properly powered and geared inrunner because I believe the large RPM range will allow greater control.  I've NEVER seen a radio controlled land vehicle use an outrunner brushless setup in all my years.  Good luck!

Title: What is the difference between RC motors for cars and helicopters?

Body:
I am working on a robot with focus on speed. At the moment I am looking for a suitable motor but it would help if I understood the difference between the various options.

To provide some background, I have not worked with RC model components before, but I think this is the only place for me to find the components needed for my robot, such as the motor.

I have already figured out how much power the motor needs to accelerate my robot as desired, taking energy conversion efficiency and tractional resistance into account. It's about 170 watts, depending on the final weight.

To limit my search further, I need to decide on either using a RC car motor or a RC helicopter motor now, but I don't understand the difference between these options.

Focussing on brushless motors (if that matters), what are the differences between RC car and RC helicopter motors? What needs to be taken into account when choosing between them?