问:
Shape Memory Alloy wire for robot gripper arm actuation: How to vary grip pressure?
For a robotic gripper arm we are designing for factory floor use on very small components, we propose to use electrically activated Shape Memory Alloy (SMA) wire harnesses for actuation.

The device being designed is akin to Pick & Place machines used for circuit assembly, but moves over an aircraft-hanger sized work surface on wheels. It manipulates irregular shaped and porous objects between 0.5 cu.cm and 8 cu.cm each - hence the traditional vacuum P&P mechanism does not appeal. Also, individual objects in the assembly line have varying hardness and weights.

Our design constraints are:

Ensuring minimal to zero vibration and sound

Using minimal volume within the mechanism (batteries are at the wheelbase, providing stability, so their weight is not a concern)

Fine variation of gripper pressure

We believe SMA meets the first two constraints well, but need some guidance on achieving constraint 3, i.e. different levels of pressure of the gripper controlled electronically.

My questions:

Can PWM of a current above the activation threshold (320 mA for 0.005 inch Flexinol HT) provide variable, repeatable actuation force?

Would we need pressure sensors on each fingertip and a closed loop control for grip, or can the gripper be calibrated periodically and maintain repeatable force?

Is there any well-documented precedent or study we should be referring to?

答:
Have a look at the paper Technical Characteristics of Flexinol Actuator Wires.

What you'll want to do is devise a structure that leverages the available contraction of the nitinol wire to achieve the desired stroke and force for your application. The paper give a couple of example structures:

The percentage of contraction of nitinol is related to it's temperature. However, the relationship is non-linear and differs between the heating phase and the cooling phase. These differences will need to be taken into account.

In the article precision flexinol position control using arduino the author describes how to use the properties of nitinol so that the wire can act as it's own feedback sensor:

Flexinol, also known as Muscle Wire, is a strong, lightweight wire
  made from Nitinol that can be made to contract when conducting
  electricity. In this article I'll present an approach to precision
  control of this effect based on controlling the voltage in the
  Flexinol circuit. In addition, taking advantage of the fact that the
  resistance of Flexinol drops predictably as it contracts, the
  mechanism described here uses the wire itself as a sensor in a
  feedback control loop. Some advantages of eliminating the need for a
  separate sensor are reduced parts count and reduced mechanical
  complexity.

So by using PWM to vary the voltage across the wire and using an ADC to read that voltage drop, you can design closed loop control of the percentage of contraction of the nitinol wire. Then, using an appropriate mechanical structure, you can translate that contraction into the desired stroke and force needed for your application.


问:
Why must I loop 127 times for a "7-bit" address in this example?
I am learning about I2C on the Arduino. I was looking at a sample program to scan for I2C devices and saw this:

```<code>// This sketch tests the standard 7-bit addresses
// from 0 to 127. Devices with higher bit address
// might not be seen properly.
</code>```

With the following code.

```<code>    for(address = 0; address <= 127; address++ )
      {
        // The i2c_scanner uses the return value of
        // the Write.endTransmisstion to see if
        // a device did acknowledge to the address.
        Wire.beginTransmission(address);
        error = Wire.endTransmission();

        if (error == 0)
        {
          Serial.print("I2C device found at address 0x");
          if (address<16)
            Serial.print("0");
          Serial.print(address,HEX);
          Serial.println(" !");
    }
}
</code>```

As far as I understand it, a bit is just 1.  So, why how do 7 bits loop from 0 - 127?

答:
As mentioned above 7-bits means possibility of 128 slave devices attached to the same i2c bus.

This loop is run 128 times(0-127) to determine how many slaves are present on the bus by asking them to respond(via ack) and prints whenever a device presence is detected.

ContentLicense: CC BY-SA 3.0


问:
What is the wheel base distance of the create2?
What is the wheel base distance that should be used for the create2 to calculate angle? I have seen 230.8mm in code samples but the manual seems to indicate 235.0 mm.</p>

答: The OI Spec indicates a wheel base distance of 235.00mm. The wheels are 15.2mm wide, so 230.8mm would be the distance between the inward-facing sides of the wheels. Kinematics should be measured from the centers of wheels, so the 230.8mm figure is probably incorrect (unless there is something else accounting for the discrepancy in the code or the Roomba's mechanics).</p>

ContentLicense: CC BY-SA 4.0


问:
All-in-one GNSS localization solution (hardware+software)
Is there something like an all-in-one satellite based localization solution that would contain both hardware and software to do GNSS localization for robotics? I mean a package that would also contain an IMU, would fuse it with GPS and filter the result accordingly and then provide a software API to query for location/speed etc.

I am interested rather in some affordable solution but is there some professional hardware too?

I am trying to implement this for my mobile robot and I realize that a smartphone-grade GPS (Samsung J5) gives me better preliminary results than an u-blox eval board (this NEO-M8T with integrated antenna and ground plane) - I wonder why, I guess Android may fuse the IMU and have better readings even with worse antenna?

答: I have used both KVH CNS-5000 and the Xsens MTi-G-710 that do what you are asking. Both these products provide on-board sensor fusion. The CNS-5000 uses an EKF and I am not sure about the Xsens. They both cost in excess of $4k. I am unaware of any less costly solutions that integrate both the GNSS and IMU. </p>


问:
Low latency control from a laptop
Lets say that I needed to send sensor readings in increments of 100 bytes from a micro controller to a laptop with sub 2 ms latencies in real time (the data needs to be processed and acted upon immediately (to control a robot)). What interfaces would one use?

FTDI usb-serial converters aren't an option because they introduce 5-10 ms latencies both ways. PCI cards are an option though.

答:
Off the shelf expresscard or cardbus cards for rs422/485 will do 921Kbit/sec which, depending on the protocol you use and its overhead, should get you more than 100Bytes of data in less than 2ms.

Considering the ease at which you can use RS422 with a microcontroller this is the first thing to try. You can even forgo a protocol and use the raw communications during development to get up and running quickly (though for robustness, a protocol that can handle errors and comms start and stop will be wanted).

Ethercat is the other option, which can use a standard ethernet card, (if you are lucky your laptop will use a compatible chipset), but you will need to add an Ethercat chip and ethernet phy on the microcontroller side. Additionally, Ethercat uses a robust but complicated communication protocol so it can take some time to learn. The benefit of doing so is that you have fast communications designed for realtime control.

Title: Low latency control from a laptop


问:
How to apply A bang-bang signal of amplitude 1 N and 1 s width as an input force to reproduce certain results in Matlab?
I working on dynamic modeling and simulation of a mechanical system (overhead crane), after I obtained the equation of motion, in the form: $$ M(q)\ddot{q}+C(q,\dot{q})\dot{q}+G(q)=Q $$

All the matrices are know inertia, $ M(q)$, Coriolis-Centrifugal matrix $ C(q,\dot{q})$, and gravity $ G(q)$ as functions of the generalized coordinates $q$, and their derivatives $\dot{q}$.

I want to solve for $q$, using Matlab ODE (in m-file), I got the response for some initial conditions and zero input, but, I want to find the response, for the aforementioned control signal (A bang-bang signal of amplitude 1 N and 1 s width), I'm trying to regenerate some results from the literature, and what the authors of that work said, regrading the input signal is the following: "A bang-bang signal of amplitude 1 N and 1 s width is used as an input force, applied at the cart of the gantry crane. A bang-bang force has a positive (acceleration) and negative (deceleration) period allowing the cart to, initially, accelerate and then decelerate and eventually stop at a target location." I didn't grasp what do they mean by bang-bang signal, I know in Matlab we could have step input, impulse, ...etc. But bang-bang signal, I'm not familiar with. According to this site and this bang bang is a controller rather.

Could anyone suggest to me how to figure out this issue and implement this input signal? preferably in m-file.

The code I'm using is given bellows, two parts:

```<code>function xdot = AlFagera(t,x,spec)
% xdot = zeros(8,1);
xdot = zeros(12,1); % to include the input torque

% % Crane Specifications
mp = spec(1);
mc = spec(2);
mr = spec(3);
L = spec(4);
J = spec(5);

g = 9.80;               % accelatrion of gravity (m/s^)

% % matix equations
M11 = mr+mc+mp; M12 = 0; M13 = mp*L*cos(x(3))*sin(x(4)); M14 = mp*L*sin(x(3))*cos(x(4));
M21 = 0; M22 = mp+mc; M23 = mp*L*cos(x(3))*cos(x(4)); M24 = -mp*L*sin(x(3))*sin(x(4));
M31  = M13; M32 = M23; M33 = mp*L^2+J; M34 = 0;
M41 = M14; M42 = M24; M43 = 0; M44 = mp*L^2*(sin(x(3)))^2+J;
M = [M11 M12 M13 M14; M21 M22 M23 M24; M31 M32 M33 M34; M41 M42 M43 M44];

C11 = 0; C12 = 0; C13 = -mp*L*sin(x(3))*sin(x(4))*x(7)+mp*L*cos(x(3))*cos(x(4))*x(8);
C14 = mp*L*cos(x(3))*cos(x(4))*x(7)-mp*L*sin(x(3))*sin(x(4))*x(8);
C21 = 0; C22 = 0; C23 = -mp*L*sin(x(3))*cos(x(4))*x(7)-mp*L*cos(x(3))*sin(x(4))*x(8);
C24 = -mp*L*cos(x(3))*sin(x(4))*x(7)-mp*L*sin(x(3))*cos(x(4))*x(8);
C31 = 0; C32 = 0; C33 = 0; C34 = -mp*L^2*sin(x(3))*cos(x(3))*x(8);
C41 = 0; C42 = 0; C43 = -C34; C44 = mp*L^2*sin(x(3))*cos(x(4))*x(7);

C = [C11 C12 C13 C14; C21 C22 C23 C24; C31 C32 C33 C34; C41 C42 C43 C44];
Cf = C*[x(5); x(6); x(7); x(8)];

G = [0; 0; mp*g*L*sin(x(3)); 0];

fx = 0;

if t >=1 && t<=2
fy = 1.*square(t*pi*2);
else fy = 0;
end

F =[fx; fy; 0; 0];     % input torque vector,

xdot(1:4,1)= x(5:8);
xdot(5:8,1)= M\(F-G-Cf);
xdot(9:12,1) = F;
</code>```

And:

```<code>clear all; close all; clc;

t0 = 0;tf = 20;

x0 = [0.12 0.5 0 0, 0 0 0 0,0 0 0 0];  % initional conditions

% % spectifications
Mp = [0.1 0.5 1];      % variable mass for the payload
figure
plotStyle = {'b-','k','r'};
for i = 1:3
mp = Mp(i);
mc = 1.06; mr = 6.4;           % each mass in kg
L = 0.7; J = 0.005;            % m, kg-m^2 respe.
spec = [mp mc mr L J];
% % Call the the function
[t,x] = ode45(@(t,x)AlFagera(t,x,spec),[t0 :0.001: tf],x0);

legendInfo{i} = ['mp=',num2str(Mp(i)),'kg'];

fx = diff(x(:,9))./diff(t);
fy = diff(x(:,10))./diff(t);
tt=0:(t(end)/(length(fx)-1)):t(end); % this time vector

% to plot the cart positions in x and y direcitons
subplot(1,2,1)
plot(t,x(:,1),plotStyle{i})
axis([0 20 0 0.18]);
grid
xlabel('time (s)');
ylabel('cart position in x direction (m)');
hold on
legend(legendInfo,'Location','northeast')

subplot(1,2,2)
plot(t,x(:,2),plotStyle{i})
axis([0 20 0 1.1]);
grid
xlabel('time (s)');
ylabel('cart position in y direction (m)');
hold on
legend(legendInfo,'Location','northeast')

end

% to plot the input torque, (bagn-bang signal), just one sample
figure
plot(tt,fy)
grid
set(gca,'XTick',[0:20])
xlabel('time (s)');
ylabel('input signal, f_y (N)');
</code>```

Furthermore, the results I'm getting and what I supposed to get are shown:

Major difficulties, initial conditions are not clearly stated in the paper, the input force direction, is only in y (which it should be), or it has different direction. I appreciate any help.

the paper I'm trying to recreate is:
  R. M. T. Raja Ismail, M. A. Ahmad, M. S. Ramli, and F. R. M. Rashidi, “Nonlinear Dynamic Modelling and Analysis of a 3-D Overhead Gantry Crane System with System Parameters Variation.,” International Journal of Simulation–Systems, Science & Technology, vol. 11, no. 2, 2010.
  http://ijssst.info/Vol-11/No-2/paper2.pdf

答:
The 'bang' refers to a step transition. Bang-Bang means that one applies maximum positive effort, then maximum negative effort, with step transitions in between.

Technically we starting at 0 velocity and returning to 0 velocity so it should be bang-bang-bang control; but it sounds strange to say that.

For theoretical analysis involving bang-bang inputs, I would use the dirac delta. I don't use matlab that much but it looks like they have it for symbolic analysis and numerical analysis. It sounds like you already know this though.


答:
This is how I would go about simulating a nonlinear ODE in Matlab. As I mentioned in a (now-deleted) comment on your question, I typically work with linear ODE's in my line of work, which means that I usually use the (awesome) functions in the Control System Toolbox.

Now, I'll start by saying that you haven't given any definitions of what the matrices are in your equation, so I can't give you a concrete example of how to solve your specific example. If you update your question to give numbers for everything then I can modify this answer to solve your problem. That said, you give:

$$
M(q)\ddot{q}+C(q,\dot{q})\dot{q}+G(q)=Q
$$

First I would say that this can be re-written as:

$$
\ddot{q} = \frac{1}{M(q)}\left(Q-C(q,\dot{q})\dot{q} -G(q)\right) \\
$$

So, for an example for you, I chose an RLC circuit, which takes the form:

$$
\begin{array}
.\dot{I} = \frac{1}{L}\left(V_{\mbox{in}} - V_C - IR\right) \\
\dot{V} = \frac{1}{C}I
\end{array}
$$

Typically your input signal would be a smooth function of time. Here you're looking for a bang-bang signal, which is akin to a light switch. At some time, the input signal goes from nothing immediately to some value, then later from that value immediately back to nothing.

So, where typically you would use an interpolate command to get values defined sample time increments, here you don't want those commands interpolated. You don't want a ramp, you want the signal to immediately shift.

So this question really is two parts:

How do I pass parameters to an ODE45 (or 23 or whatever else) function in Matlab, and

How do I define a step change in an input signal for an ODE45 function?

The answers are (examples to follow)

Define your ODE function as a function in its own script, such that the first line of the script is something like function [dq] = AlFageraODE(t,x,parameter1,parameter2,...,parameterN). Then, when you want to solve the ODE, call Matlab's built-in ODE solver as follows: [t,y] = ode45(@AlFageraODE,[t0,t1],[y0,y1],[ ],parameter1,parameter2,...,parameterN);. The square brackets in bold there need to be included because that is where you can pass specific options to the ODE solver. If you don't want to pass anything specific and are okay with the default settings, you still need to put something, so put an empty array - this is done with an empty array []. After that you can put in parameters that will be passed to your custom function.

To get a true step function, you need to split the simulation into three distinct sets - before the step, during the step, and after the step. Anything else will result in the need to interpolate the input command. The last entry in the outputs will be the initial conditions for the next segment of the simulation.

Below, I've written the custom ODE function, and then below that is the script used to solve the custom ODE. Note that the R, L, and C values are set in the calling script, not in the custom ODE. This is because those values are passed in to the custom ODE, along with what the applied voltage should be during that particular segment.

The examples:

The custom ODE function (again, this simulates an RLC circuit, but you can modify it for any custom ODE needing parameters passed in.)

.

```<code>function dx = RoboticsODE(t,x,Vin,R,L,C)
dx = zeros(2,1);

I = x(1);
V = x(2);

di_dt = (1/L)*(Vin - V - I*R);
dv_dt = (1/C)*I;

dx(1) = di_dt;
dx(2) = dv_dt;
</code>```

The script that solves that ODE for a bang-bang signal.

.

```<code>%% Clear/close everything
clear;
close all;
clc;

%% Simulation Configuration
v0 = 0;             % Initial *output* voltage
i0 = 0;             % Initial circuit current
C = 47*(1/1000);    % Capacitance, F
R = 0.1;            % Resistance, Ohm
L = 22*(1/1000);    % Inductance, H

appliedVoltages = [0,1,0]; % The applied voltages at t0, bangOn, bangOff
tStart = 0;         % t0
bangStart = 1;      % bangOn time
bangWidth = 1;      % bangOff time = bangOn time + bangWindow
endWindow = 5;      % endWindow is how long to "watch" the simulation after
                    %   the bang-bang signal goes "off".

%% Output Initialization
outputTime = zeros(0,1);
outputVoltage = zeros(0,1);
outputCurrent = zeros(0,1);
inputVoltage = zeros(0,1);

%% Dependent Configuration
currentValues = [i0;v0];
samplePoints = cumsum([tStart,bangStart,bangWidth,endWindow]);
% A note on the above - I use the cumulative sum (cumsum) because I defined
% each point as the number of seconds *after* the previous event. If you
% defined absolute time points then you'd just use those time points
% directly with no cumulative sum.
nSegments = numel(samplePoints)-1;

%% Simulation
for currentSegment = 1:nSegments
    % Setup the simulation by getting the current time window and "intial"
    % conditions.
    Vt = appliedVoltages(currentSegment);
    t0 = samplePoints(currentSegment);
    t1 = samplePoints(currentSegment+1);
    sampleTime = [t0;t1];

    % Run the simulation by solving the ODE for this particular segment.
    [intermediateTime,intermediateOutput] = ...
        ode45(@RoboticsODE,sampleTime,currentValues,[],Vt,R,L,C);

    % Assign outputs
    nOutputPoints = numel(intermediateTime);
    outputTime(end+1:end+nOutputPoints) = intermediateTime;
    outputCurrent(end+1:end+nOutputPoints) = intermediateOutput(:,1);
    outputVoltage(end+1:end+nOutputPoints) = intermediateOutput(:,2);
    inputVoltage(end+1:end+nOutputPoints) = Vt*ones(nOutputPoints,1);

    % Setup the next simulation by setting the "initial" conditions for
    % that simulation equal to the ending conditions for the current
    % simulation.
    currentValues(1) = outputCurrent(end);
    currentValues(2) = outputVoltage(end);
end

%% Output Plot
plot(outputTime,inputVoltage);
hold on;
plot(outputTime,outputVoltage);
title('RLC Circuit with Step Input to ODE45');
xlabel('Time (s)');
ylabel('Voltage (V)');
legend('Input Voltage','Output Voltage');
</code>```

The plot of the output.

Finally, as I mentioned, if you would be willing to give concrete numbers for your equation then I could tailor this to solve your particular problem. As it stands, I can't provide any solution to a symbolic nonlinear ODE so this example is the best I can give you.

:EDIT:

I've got the problem solved for you. The code is attached below. I'll say this, though: It's important, for a step input (bang-bang, etc.) to segment the ODE solver process, as I described above. This is because Matlab tries to optimize solving the ODE and may not take process time in exactly the way you would expect.

The segmenting method is again, as described above, where you split the solving process at every discontinuity. The initial conditions for the following step is equal to the ending conditions of the current step.

The images below are the solutions I got with the segmented method and the "all-in-one" method. The all-in-one is the way you had it setup, where the force function was determined by an if statement in the ODE function. Because Matlab chooses the sample time increments, the positive and negative segments aren't guaranteed to have exactly the same number of samples. I think this is the reason for the drift in the output of the all-in-one solution.

I found several problems with your method. When I corrected them, I got a plot that looked (to me) to exactly duplicate the plots from the paper you linked.

The biggest problem - fx and fy should be the same.

Also a problem, the pulse width should be 1s. You used a square wave of period 1s, meaning that there was a 0.5s "positive" and 0.5s "negative" signal. I halved the frequency and got the proper 1s signal width.

Your initial conditions for x and y were not zero. They are zero in the paper, so I set them to zero in the simulation to replicate the figures in the paper.

Here's the code! First, the ODE script:

.

```<code>function varDot = AlFagera(t,var,spec,F)
% In general, I did a lot of cleanup with this function to make things
% easier for me to read.

%% Misc Declarations
% varDot = zeros(8,1);
varDot = zeros(12,1); % to include the input torque
g = 9.80;               % Acceleration of gravity (m/s^2)

%% Define Forces if Undefined
% If the segmentSolution is being used, then the force is supplied to the
% function. If it's not being used (the "all-in-one" solution), then the
% force is determined by the simulation time.
if isempty(F)
    if t >=1 && t<=3
        fy = -1.*sign(sin(t*pi));
    else
        fy = 0;
    end
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % I'll highlight this, because I think this was the key problem     %
    % you were having. The force for fx and fy should be the same. You  %
    % had fx = 0 for all cases.                                         %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %fx = 0;
    fx = fy;
    F = [fx;fy;0;0];
end
%% Crane Specifications
mp = spec(1);
mc = spec(2);
mr = spec(3);
L = spec(4);
J = spec(5);

%% Breakout the Input Variable
x        = var(1);
y        = var(2);
theta    = var(3);
phi      = var(4);

xDot     = var(5);
yDot     = var(6);
thetaDot = var(7);
phiDot   = var(8);

%% Repackage the Inputs into Useful Form
q = [...
    x; ...
    y; ...
    theta; ...
    phi];

qDot = [...
    xDot; ...
    yDot; ...
    thetaDot; ...
    phiDot];

%% Simplified expressions for (extensive) use later
mpL  = mp*L;
cosT = cos(theta);
sinT = sin(theta);
cosP = cos(phi);
sinP = sin(phi);

%% Matrix Expressions
M = [...
    mr+mc+mp      , 0              , mpL*cosT*sinP , mpL*sinT*cosP; ...
    0             , mp+mc          , mpL*cosT*cosP , -mpL*sinT*sinP; ...
    mpL*cosT*sinP , mpL*cosT*cosP  , mpL*L+J       , 0; ...
    mpL*sinT*cosP , -mpL*sinT*sinP , 0             , mp*(L*sinT)^2+J];
C = [...
    0 , 0 , -mpL*sinT*sinP*thetaDot+mpL*cosT*cosP*phiDot , mpL*cosT*cosP*thetaDot-mpL*sinT*sinP*phiDot; ...
    0 , 0 , -mpL*sinT*cosP*thetaDot-mpL*cosT*sinP*phiDot , -mpL*cosT*sinP*thetaDot-mpL*sinT*cosP*phiDot; ...
    0 , 0 , 0                                            , -mpL*L*sinT*cosT*phiDot; ...
    0 , 0 , mpL*L*sinT*cosT*phiDot                       , mpL*L*sinT*cosT*thetaDot];
G = [...
    0; ...
    0; ...
    mpL*g*sinT; ....
    0];

%% Assign Outputs
qDdot = M\(-C*qDot-G+F);
varDot = [...
    qDot; ...
    qDdot; ...
    F];
</code>```

Then, the script that solves the ODE:

.

```<code>clear all;
close all;
clc;

% Compare the all-in-one method of solving the problem with the segmented
% method of solving the problem by setting the variable below equal to
% "true" or "false".
segmentSolution = true;

t0 = 0;tf = 20;

% Your initial conditions here for x- and y-positions were not zero, so I
% set them to zero to reproduce Figure 2 and Figure 3 in the paper you
% linked.
% Also - you don't ever use the last 4 values of this except as a way to
% output the force. This isn't used in the segmentSolution because there
% the input force is supplied to the function.

x0 = [0 0 0 0, 0 0 0 0,0 0 0 0];  % Initial Conditions

%% Specifications
Mp = [0.1 0.5 1];      % Variable mass for the payload
figure
plotStyle = {'b-','k','r'};

%% SegmentSolution Settings
fx = [0,1,-1,0];
fy = [0,1,-1,0];
tStart = 0;
tOn = 1;
bangWidth = 1;
tEndWindow = 17;
sampleTime = cumsum([tStart,tOn,bangWidth,bangWidth,tEndWindow]);
nSegments = numel(sampleTime)-1;
%% Simulation
for i = 1:3
    mp = Mp(i);
    mc = 1.06; mr = 6.4;           % each mass in kg
    L = 0.7; J = 0.005;            % m, kg-m^2 respe.
    spec = [mp mc mr L J];
    %% Call the the function
    initialConditions = x0;

    if segmentSolution
        t = zeros(0,1);
        x = zeros(0,numel(x0));
        outputFx = zeros(0,1);
        outputFy = zeros(0,1);
        for currentSegment = 1:nSegments
            inputForce = [fx(currentSegment),fy(currentSegment),0,0].';
            t0 = sampleTime(currentSegment);
            t1 = sampleTime(currentSegment+1);
            [intermediateT,intermediateX] = ode45(@AlFagera,[t0 :0.001: t1],initialConditions,[],spec,inputForce);
            nOutputSamples = numel(intermediateT);
            index1 = size(t,1)+1;
            index2 = size(t,1)+nOutputSamples;
            t(index1:index2) = intermediateT;
            x(index1:index2,:) = intermediateX;
            initialConditions = x(end,:).';
            outputFx(index1:index2) = inputForce(1)*ones(nOutputSamples,1);
            outputFy(index1:index2) = inputForce(2)*ones(nOutputSamples,1);
        end
        tt = t;
    else
        inputForce = []; % Leave this empty for the all-in-one solver.
                         % There's a check in the code to setup the force
                         % when it's not defined.
        [t,x] = ode45(@AlFagera,[t0:0.001:tf],initialConditions,[],spec,inputForce);
        outputFx = diff(x(:,9))./diff(t);
        outputFy = diff(x(:,10))./diff(t);
        tt=0:(t(end)/(length(outputFx)-1)):t(end);
    end
    legendInfo{i} = ['mp=',num2str(Mp(i)),'kg'];

    %fx = diff(x(:,9))./diff(t);
    %fy = diff(x(:,10))./diff(t);
    %tt=0:(t(end)/(length(fx)-1)):t(end); % this time vector

    % to plot the cart positions in x and y direcitons
    subplot(1,2,1)
    plot(t,x(:,1),plotStyle{i})
    axis([0 20 0 0.18]);
    grid
    xlabel('time (s)');
    ylabel('cart position in x direction (m)');
    hold on
    legend(legendInfo,'Location','northeast')

    subplot(1,2,2)
    plot(t,x(:,2),plotStyle{i})
    axis([0 20 0 1.1]);
    grid
    xlabel('time (s)');
    ylabel('cart position in y direction (m)');
    hold on
    legend(legendInfo,'Location','northeast')
end

% to plot the input torque, (bang-bang signal), just one sample
figure
plot(tt,outputFy);
grid
set(gca,'XTick',[0:20])
xlabel('time (s)');
ylabel('input signal, f_y (N)');
</code>```

I took the liberty of cleaning up the code in the ODE function, I hope you don't mind.

So, to summarize, the solution to your problem is:

Pass inputs to the ODE function (such as parameters and applied forces), and

Segment the ODE solution at each discontinuity.

Title: How to apply A bang-bang signal of amplitude 1 N and 1 s width as an input force to reproduce certain results in Matlab?

Body:
I working on dynamic modeling and simulation of a mechanical system (overhead crane), after I obtained the equation of motion, in the form: $$ M(q)\ddot{q}+C(q,\dot{q})\dot{q}+G(q)=Q $$

All the matrices are know inertia, $ M(q)$, Coriolis-Centrifugal matrix $ C(q,\dot{q})$, and gravity $ G(q)$ as functions of the generalized coordinates $q$, and their derivatives $\dot{q}$.

I want to solve for $q$, using Matlab ODE (in m-file), I got the response for some initial conditions and zero input, but, I want to find the response, for the aforementioned control signal (A bang-bang signal of amplitude 1 N and 1 s width), I'm trying to regenerate some results from the literature, and what the authors of that work said, regrading the input signal is the following: "A bang-bang signal of amplitude 1 N and 1 s width is used as an input force, applied at the cart of the gantry crane. A bang-bang force has a positive (acceleration) and negative (deceleration) period allowing the cart to, initially, accelerate and then decelerate and eventually stop at a target location." I didn't grasp what do they mean by bang-bang signal, I know in Matlab we could have step input, impulse, ...etc. But bang-bang signal, I'm not familiar with. According to this site and this bang bang is a controller rather.

Could anyone suggest to me how to figure out this issue and implement this input signal? preferably in m-file.

The code I'm using is given bellows, two parts:

```<code>function xdot = AlFagera(t,x,spec)
% xdot = zeros(8,1);
xdot = zeros(12,1); % to include the input torque

% % Crane Specifications
mp = spec(1);
mc = spec(2);
mr = spec(3);
L = spec(4);
J = spec(5);

g = 9.80;               % accelatrion of gravity (m/s^)

% % matix equations
M11 = mr+mc+mp; M12 = 0; M13 = mp*L*cos(x(3))*sin(x(4)); M14 = mp*L*sin(x(3))*cos(x(4));
M21 = 0; M22 = mp+mc; M23 = mp*L*cos(x(3))*cos(x(4)); M24 = -mp*L*sin(x(3))*sin(x(4));
M31  = M13; M32 = M23; M33 = mp*L^2+J; M34 = 0;
M41 = M14; M42 = M24; M43 = 0; M44 = mp*L^2*(sin(x(3)))^2+J;
M = [M11 M12 M13 M14; M21 M22 M23 M24; M31 M32 M33 M34; M41 M42 M43 M44];

C11 = 0; C12 = 0; C13 = -mp*L*sin(x(3))*sin(x(4))*x(7)+mp*L*cos(x(3))*cos(x(4))*x(8);
C14 = mp*L*cos(x(3))*cos(x(4))*x(7)-mp*L*sin(x(3))*sin(x(4))*x(8);
C21 = 0; C22 = 0; C23 = -mp*L*sin(x(3))*cos(x(4))*x(7)-mp*L*cos(x(3))*sin(x(4))*x(8);
C24 = -mp*L*cos(x(3))*sin(x(4))*x(7)-mp*L*sin(x(3))*cos(x(4))*x(8);
C31 = 0; C32 = 0; C33 = 0; C34 = -mp*L^2*sin(x(3))*cos(x(3))*x(8);
C41 = 0; C42 = 0; C43 = -C34; C44 = mp*L^2*sin(x(3))*cos(x(4))*x(7);

C = [C11 C12 C13 C14; C21 C22 C23 C24; C31 C32 C33 C34; C41 C42 C43 C44];
Cf = C*[x(5); x(6); x(7); x(8)];

G = [0; 0; mp*g*L*sin(x(3)); 0];

fx = 0;

if t >=1 && t<=2
fy = 1.*square(t*pi*2);
else fy = 0;
end

F =[fx; fy; 0; 0];     % input torque vector,

xdot(1:4,1)= x(5:8);
xdot(5:8,1)= M\(F-G-Cf);
xdot(9:12,1) = F;
</code>```

And:

```<code>clear all; close all; clc;

t0 = 0;tf = 20;

x0 = [0.12 0.5 0 0, 0 0 0 0,0 0 0 0];  % initional conditions

% % spectifications
Mp = [0.1 0.5 1];      % variable mass for the payload
figure
plotStyle = {'b-','k','r'};
for i = 1:3
mp = Mp(i);
mc = 1.06; mr = 6.4;           % each mass in kg
L = 0.7; J = 0.005;            % m, kg-m^2 respe.
spec = [mp mc mr L J];
% % Call the the function
[t,x] = ode45(@(t,x)AlFagera(t,x,spec),[t0 :0.001: tf],x0);

legendInfo{i} = ['mp=',num2str(Mp(i)),'kg'];

fx = diff(x(:,9))./diff(t);
fy = diff(x(:,10))./diff(t);
tt=0:(t(end)/(length(fx)-1)):t(end); % this time vector

% to plot the cart positions in x and y direcitons
subplot(1,2,1)
plot(t,x(:,1),plotStyle{i})
axis([0 20 0 0.18]);
grid
xlabel('time (s)');
ylabel('cart position in x direction (m)');
hold on
legend(legendInfo,'Location','northeast')

subplot(1,2,2)
plot(t,x(:,2),plotStyle{i})
axis([0 20 0 1.1]);
grid
xlabel('time (s)');
ylabel('cart position in y direction (m)');
hold on
legend(legendInfo,'Location','northeast')

end

% to plot the input torque, (bagn-bang signal), just one sample
figure
plot(tt,fy)
grid
set(gca,'XTick',[0:20])
xlabel('time (s)');
ylabel('input signal, f_y (N)');
</code>```

Furthermore, the results I'm getting and what I supposed to get are shown:

Major difficulties, initial conditions are not clearly stated in the paper, the input force direction, is only in y (which it should be), or it has different direction. I appreciate any help.

the paper I'm trying to recreate is:
  R. M. T. Raja Ismail, M. A. Ahmad, M. S. Ramli, and F. R. M. Rashidi, “Nonlinear Dynamic Modelling and Analysis of a 3-D Overhead Gantry Crane System with System Parameters Variation.,” International Journal of Simulation–Systems, Science & Technology, vol. 11, no. 2, 2010.
  http://ijssst.info/Vol-11/No-2/paper2.pdf

Body:
This is how I would go about simulating a nonlinear ODE in Matlab. As I mentioned in a (now-deleted) comment on your question, I typically work with linear ODE's in my line of work, which means that I usually use the (awesome) functions in the Control System Toolbox.

Now, I'll start by saying that you haven't given any definitions of what the matrices are in your equation, so I can't give you a concrete example of how to solve your specific example. If you update your question to give numbers for everything then I can modify this answer to solve your problem. That said, you give:

$$
M(q)\ddot{q}+C(q,\dot{q})\dot{q}+G(q)=Q
$$

First I would say that this can be re-written as:

$$
\ddot{q} = \frac{1}{M(q)}\left(Q-C(q,\dot{q})\dot{q} -G(q)\right) \\
$$

So, for an example for you, I chose an RLC circuit, which takes the form:

$$
\begin{array}
.\dot{I} = \frac{1}{L}\left(V_{\mbox{in}} - V_C - IR\right) \\
\dot{V} = \frac{1}{C}I
\end{array}
$$

Typically your input signal would be a smooth function of time. Here you're looking for a bang-bang signal, which is akin to a light switch. At some time, the input signal goes from nothing immediately to some value, then later from that value immediately back to nothing.

So, where typically you would use an interpolate command to get values defined sample time increments, here you don't want those commands interpolated. You don't want a ramp, you want the signal to immediately shift.

So this question really is two parts:

How do I pass parameters to an ODE45 (or 23 or whatever else) function in Matlab, and

How do I define a step change in an input signal for an ODE45 function?

The answers are (examples to follow)

Define your ODE function as a function in its own script, such that the first line of the script is something like function [dq] = AlFageraODE(t,x,parameter1,parameter2,...,parameterN). Then, when you want to solve the ODE, call Matlab's built-in ODE solver as follows: [t,y] = ode45(@AlFageraODE,[t0,t1],[y0,y1],[ ],parameter1,parameter2,...,parameterN);. The square brackets in bold there need to be included because that is where you can pass specific options to the ODE solver. If you don't want to pass anything specific and are okay with the default settings, you still need to put something, so put an empty array - this is done with an empty array []. After that you can put in parameters that will be passed to your custom function.

To get a true step function, you need to split the simulation into three distinct sets - before the step, during the step, and after the step. Anything else will result in the need to interpolate the input command. The last entry in the outputs will be the initial conditions for the next segment of the simulation.

Below, I've written the custom ODE function, and then below that is the script used to solve the custom ODE. Note that the R, L, and C values are set in the calling script, not in the custom ODE. This is because those values are passed in to the custom ODE, along with what the applied voltage should be during that particular segment.

The examples:

The custom ODE function (again, this simulates an RLC circuit, but you can modify it for any custom ODE needing parameters passed in.)

.

function dx = RoboticsODE(t,x,Vin,R,L,C)
dx = zeros(2,1);

I = x(1);
V = x(2);

di_dt = (1/L)*(Vin - V - I*R);
dv_dt = (1/C)*I;

dx(1) = di_dt;
dx(2) = dv_dt;

The script that solves that ODE for a bang-bang signal.

.

%% Clear/close everything
clear;
close all;
clc;

%% Simulation Configuration
v0 = 0;             % Initial *output* voltage
i0 = 0;             % Initial circuit current
C = 47*(1/1000);    % Capacitance, F
R = 0.1;            % Resistance, Ohm
L = 22*(1/1000);    % Inductance, H

appliedVoltages = [0,1,0]; % The applied voltages at t0, bangOn, bangOff
tStart = 0;         % t0
bangStart = 1;      % bangOn time
bangWidth = 1;      % bangOff time = bangOn time + bangWindow
endWindow = 5;      % endWindow is how long to "watch" the simulation after
                    %   the bang-bang signal goes "off".

%% Output Initialization
outputTime = zeros(0,1);
outputVoltage = zeros(0,1);
outputCurrent = zeros(0,1);
inputVoltage = zeros(0,1);

%% Dependent Configuration
currentValues = [i0;v0];
samplePoints = cumsum([tStart,bangStart,bangWidth,endWindow]);
% A note on the above - I use the cumulative sum (cumsum) because I defined
% each point as the number of seconds *after* the previous event. If you
% defined absolute time points then you'd just use those time points
% directly with no cumulative sum.
nSegments = numel(samplePoints)-1;

%% Simulation
for currentSegment = 1:nSegments
    % Setup the simulation by getting the current time window and "intial"
    % conditions.
    Vt = appliedVoltages(currentSegment);
    t0 = samplePoints(currentSegment);
    t1 = samplePoints(currentSegment+1);
    sampleTime = [t0;t1];

    % Run the simulation by solving the ODE for this particular segment.
    [intermediateTime,intermediateOutput] = ...
        ode45(@RoboticsODE,sampleTime,currentValues,[],Vt,R,L,C);

    % Assign outputs
    nOutputPoints = numel(intermediateTime);
    outputTime(end+1:end+nOutputPoints) = intermediateTime;
    outputCurrent(end+1:end+nOutputPoints) = intermediateOutput(:,1);
    outputVoltage(end+1:end+nOutputPoints) = intermediateOutput(:,2);
    inputVoltage(end+1:end+nOutputPoints) = Vt*ones(nOutputPoints,1);

    % Setup the next simulation by setting the "initial" conditions for
    % that simulation equal to the ending conditions for the current
    % simulation.
    currentValues(1) = outputCurrent(end);
    currentValues(2) = outputVoltage(end);
end

%% Output Plot
plot(outputTime,inputVoltage);
hold on;
plot(outputTime,outputVoltage);
title('RLC Circuit with Step Input to ODE45');
xlabel('Time (s)');
ylabel('Voltage (V)');
legend('Input Voltage','Output Voltage');

The plot of the output.

Finally, as I mentioned, if you would be willing to give concrete numbers for your equation then I could tailor this to solve your particular problem. As it stands, I can't provide any solution to a symbolic nonlinear ODE so this example is the best I can give you.

:EDIT:

I've got the problem solved for you. The code is attached below. I'll say this, though: It's important, for a step input (bang-bang, etc.) to segment the ODE solver process, as I described above. This is because Matlab tries to optimize solving the ODE and may not take process time in exactly the way you would expect.

The segmenting method is again, as described above, where you split the solving process at every discontinuity. The initial conditions for the following step is equal to the ending conditions of the current step.

The images below are the solutions I got with the segmented method and the "all-in-one" method. The all-in-one is the way you had it setup, where the force function was determined by an if statement in the ODE function. Because Matlab chooses the sample time increments, the positive and negative segments aren't guaranteed to have exactly the same number of samples. I think this is the reason for the drift in the output of the all-in-one solution.

I found several problems with your method. When I corrected them, I got a plot that looked (to me) to exactly duplicate the plots from the paper you linked.

The biggest problem - fx and fy should be the same.

Also a problem, the pulse width should be 1s. You used a square wave of period 1s, meaning that there was a 0.5s "positive" and 0.5s "negative" signal. I halved the frequency and got the proper 1s signal width.

Your initial conditions for x and y were not zero. They are zero in the paper, so I set them to zero in the simulation to replicate the figures in the paper.

Here's the code! First, the ODE script:

.

function varDot = AlFagera(t,var,spec,F)
% In general, I did a lot of cleanup with this function to make things
% easier for me to read.

%% Misc Declarations
% varDot = zeros(8,1);
varDot = zeros(12,1); % to include the input torque
g = 9.80;               % Acceleration of gravity (m/s^2)

%% Define Forces if Undefined
% If the segmentSolution is being used, then the force is supplied to the
% function. If it's not being used (the "all-in-one" solution), then the
% force is determined by the simulation time.
if isempty(F)
    if t >=1 && t<=3
        fy = -1.*sign(sin(t*pi));
    else
        fy = 0;
    end
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % I'll highlight this, because I think this was the key problem     %
    % you were having. The force for fx and fy should be the same. You  %
    % had fx = 0 for all cases.                                         %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %fx = 0;
    fx = fy;
    F = [fx;fy;0;0];
end
%% Crane Specifications
mp = spec(1);
mc = spec(2);
mr = spec(3);
L = spec(4);
J = spec(5);

%% Breakout the Input Variable
x        = var(1);
y        = var(2);
theta    = var(3);
phi      = var(4);

xDot     = var(5);
yDot     = var(6);
thetaDot = var(7);
phiDot   = var(8);

%% Repackage the Inputs into Useful Form
q = [...
    x; ...
    y; ...
    theta; ...
    phi];

qDot = [...
    xDot; ...
    yDot; ...
    thetaDot; ...
    phiDot];

%% Simplified expressions for (extensive) use later
mpL  = mp*L;
cosT = cos(theta);
sinT = sin(theta);
cosP = cos(phi);
sinP = sin(phi);

%% Matrix Expressions
M = [...
    mr+mc+mp      , 0              , mpL*cosT*sinP , mpL*sinT*cosP; ...
    0             , mp+mc          , mpL*cosT*cosP , -mpL*sinT*sinP; ...
    mpL*cosT*sinP , mpL*cosT*cosP  , mpL*L+J       , 0; ...
    mpL*sinT*cosP , -mpL*sinT*sinP , 0             , mp*(L*sinT)^2+J];
C = [...
    0 , 0 , -mpL*sinT*sinP*thetaDot+mpL*cosT*cosP*phiDot , mpL*cosT*cosP*thetaDot-mpL*sinT*sinP*phiDot; ...
    0 , 0 , -mpL*sinT*cosP*thetaDot-mpL*cosT*sinP*phiDot , -mpL*cosT*sinP*thetaDot-mpL*sinT*cosP*phiDot; ...
    0 , 0 , 0                                            , -mpL*L*sinT*cosT*phiDot; ...
    0 , 0 , mpL*L*sinT*cosT*phiDot                       , mpL*L*sinT*cosT*thetaDot];
G = [...
    0; ...
    0; ...
    mpL*g*sinT; ....
    0];

%% Assign Outputs
qDdot = M\(-C*qDot-G+F);
varDot = [...
    qDot; ...
    qDdot; ...
    F];

Then, the script that solves the ODE:

.

clear all;
close all;
clc;

% Compare the all-in-one method of solving the problem with the segmented
% method of solving the problem by setting the variable below equal to
% "true" or "false".
segmentSolution = true;

t0 = 0;tf = 20;

% Your initial conditions here for x- and y-positions were not zero, so I
% set them to zero to reproduce Figure 2 and Figure 3 in the paper you
% linked.
% Also - you don't ever use the last 4 values of this except as a way to
% output the force. This isn't used in the segmentSolution because there
% the input force is supplied to the function.

x0 = [0 0 0 0, 0 0 0 0,0 0 0 0];  % Initial Conditions

%% Specifications
Mp = [0.1 0.5 1];      % Variable mass for the payload
figure
plotStyle = {'b-','k','r'};

%% SegmentSolution Settings
fx = [0,1,-1,0];
fy = [0,1,-1,0];
tStart = 0;
tOn = 1;
bangWidth = 1;
tEndWindow = 17;
sampleTime = cumsum([tStart,tOn,bangWidth,bangWidth,tEndWindow]);
nSegments = numel(sampleTime)-1;
%% Simulation
for i = 1:3
    mp = Mp(i);
    mc = 1.06; mr = 6.4;           % each mass in kg
    L = 0.7; J = 0.005;            % m, kg-m^2 respe.
    spec = [mp mc mr L J];
    %% Call the the function
    initialConditions = x0;

    if segmentSolution
        t = zeros(0,1);
        x = zeros(0,numel(x0));
        outputFx = zeros(0,1);
        outputFy = zeros(0,1);
        for currentSegment = 1:nSegments
            inputForce = [fx(currentSegment),fy(currentSegment),0,0].';
            t0 = sampleTime(currentSegment);
            t1 = sampleTime(currentSegment+1);
            [intermediateT,intermediateX] = ode45(@AlFagera,[t0 :0.001: t1],initialConditions,[],spec,inputForce);
            nOutputSamples = numel(intermediateT);
            index1 = size(t,1)+1;
            index2 = size(t,1)+nOutputSamples;
            t(index1:index2) = intermediateT;
            x(index1:index2,:) = intermediateX;
            initialConditions = x(end,:).';
            outputFx(index1:index2) = inputForce(1)*ones(nOutputSamples,1);
            outputFy(index1:index2) = inputForce(2)*ones(nOutputSamples,1);
        end
        tt = t;
    else
        inputForce = []; % Leave this empty for the all-in-one solver.
                         % There's a check in the code to setup the force
                         % when it's not defined.
        [t,x] = ode45(@AlFagera,[t0:0.001:tf],initialConditions,[],spec,inputForce);
        outputFx = diff(x(:,9))./diff(t);
        outputFy = diff(x(:,10))./diff(t);
        tt=0:(t(end)/(length(outputFx)-1)):t(end);
    end
    legendInfo{i} = ['mp=',num2str(Mp(i)),'kg'];

    %fx = diff(x(:,9))./diff(t);
    %fy = diff(x(:,10))./diff(t);
    %tt=0:(t(end)/(length(fx)-1)):t(end); % this time vector

    % to plot the cart positions in x and y direcitons
    subplot(1,2,1)
    plot(t,x(:,1),plotStyle{i})
    axis([0 20 0 0.18]);
    grid
    xlabel('time (s)');
    ylabel('cart position in x direction (m)');
    hold on
    legend(legendInfo,'Location','northeast')

    subplot(1,2,2)
    plot(t,x(:,2),plotStyle{i})
    axis([0 20 0 1.1]);
    grid
    xlabel('time (s)');
    ylabel('cart position in y direction (m)');
    hold on
    legend(legendInfo,'Location','northeast')
end

% to plot the input torque, (bang-bang signal), just one sample
figure
plot(tt,outputFy);
grid
set(gca,'XTick',[0:20])
xlabel('time (s)');
ylabel('input signal, f_y (N)');

I took the liberty of cleaning up the code in the ODE function, I hope you don't mind.

So, to summarize, the solution to your problem is:

Pass inputs to the ODE function (such as parameters and applied forces), and

Segment the ODE solution at each discontinuity.


问:
TCP Communication with PCDuino
I'm working on a robot that is controlled by an xbox controller connected to a windows computer and commands are sent to a pcduino through a tcp connection. I have it working by sending a string of 1's and 0's to tell the pcduino which motors to turn on. I'm trying to optimize it by just sending an int and using bit masks to make the decisions on the pcduino but I can't get the pcduino to receive the int correctly. I tested the windows function sending the command with sokit and its sending the correct values but the pcduino is receiving the same number even when the commands are changing.

This is what its doing:

Windows          -> PCDuino

command = 1      -> sendBuff = 73932

cmdstring = 1    -> n = 1

command = 1025   -> sendBuff = 73932

cmdstring = 1025 -> n = 4

My windows functions are:

```<code>bool Client::Send(char * smsg)
{
    int iResult = send(ConnectSocket, smsg, strlen(smsg), 0);

    if (iResult == SOCKET_ERROR)
    {
        std::cout << "Sending Message has failed: " << WSAGetLastError() << "\n";
        Stop();
        return false;
    }
    return true;
}
</code>```

```<code>    bool sendCommand()
{
    cmdbuffer << command;
    cmdstring = cmdbuffer.str();

    if (!client->Send((char *)cmdstring.c_str()))
    {
        std::cout << "Disconnected from Server. Press Enter to Exit";
        std::cin.ignore();
        std::cin.get();
        return false;
    }
    return true;
}
</code>```

PCDuino Loop Function

```<code>void loop()
{
    recBuff = 0;
    deviceFlag = 0;

    //Read Socket

/******************************************************************************/

    read(connfd, sendBuff, strlen(sendBuff));
    recBuff = atoi(sendBuff);

/******************************************************************************/

    //Set Current Device to Receive Instructions From
    checkAuto(recBuff, currDevice);

    //Find Current Device of Command
    deviceFlag = checkDevice(recBuff);

    //If Current Device and Set Device are the Same Parse Command
    if (deviceFlag == currDevice)
    {
        parseHex(recBuff);
    }
    usleep(50000);
}
</code>```

I have a printf after the read call and that's where I am getting the 73932 number. I think I have everything you guys need but if there's anything else I need to add let me know. I'm stumped...I don't know if its just a casting problem or what.

Update 1

What I have before everything the setup and loop functions on the PCduino run is:

```<code>int listenfd = 0, connfd = 0;
int n;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
</code>```

答:
Sorry but its not really clear from your code whats going on, but the area drawing my attention is:

```<code>   read(connfd, sendBuff, strlen(sendBuff));
   recBuff = atoi(sendBuff);
</code>```

I'm assuming sendBuff is a char* or char[] of a certain size.  You are reading into that buffer up to strlen(sendBuff) characters.  So lets hope this is running in DEBUG mode you are reading characters into the buffer up to the length of the string that is currently held in the buffer.  Unless you have set it elsewhere then the string currently in the buffer in Debug configuration should be zero characters long, meaning you are asking to read zero characters.

IF I have understood what you posted then I think you want something more like this.

```<code>    const size_t MaxSize = 16;
    char sendBuffer[MaxSize];
    const size_t readRv = read(connfd, sendBuff, MaxSize);
    if (readRv > 0)
    {
        recBuff = atoi(sendBuff);
    }
</code>```

Title: TCP Communication with PCDuino

Body:
Sorry but its not really clear from your code whats going on, but the area drawing my attention is:

   read(connfd, sendBuff, strlen(sendBuff));
   recBuff = atoi(sendBuff);

I'm assuming sendBuff is a char* or char[] of a certain size.  You are reading into that buffer up to strlen(sendBuff) characters.  So lets hope this is running in DEBUG mode you are reading characters into the buffer up to the length of the string that is currently held in the buffer.  Unless you have set it elsewhere then the string currently in the buffer in Debug configuration should be zero characters long, meaning you are asking to read zero characters.

IF I have understood what you posted then I think you want something more like this.

    const size_t MaxSize = 16;
    char sendBuffer[MaxSize];
    const size_t readRv = read(connfd, sendBuff, MaxSize);
    if (readRv > 0)
    {
        recBuff = atoi(sendBuff);
    }


问:
One BEC for multiple ESC (Quadcopter)
I'm building a quadcopter and have discovered that most ESC have a built-in BEC, but I was wondering if it wouldn't be better to use only one.

What if I delivered power to my four ESC with a unique BEC ? Would that work ?
I think this would be easier to configure (you have to set it up only once for the four ESC) and it would prevent each ESC from having it's own behavior.

Am I doing it wrong ?

Here is an image of what I'm talking about :

Edit : trying to find the original image and upload it.

Given the answer by Ian McMahon it appears that this schema is not the right thing to do, since I had misunderstood the role of BECs.

So would the right schema would look like this ?
Edit : trying to find the original image and upload it.
I'm still not sure if I'm getting it.

Do I need 4 ESCs with integrated BECs and connect all three cables to flight controller ?

答:
Typically you want to power the ESCs directly from the battery, and use a BEC to power 5v electronics such as your controller.  However, a lot of ESCs have the ability to provide 5v power back to the controller over the 5v line on their control cable (servo-style 3 pin cable).  In that case, you wouldn't need to use a BEC at all, but it's possible you might have issues with more than one ESC all trying to supply power on the 5v line with them all hooked together.  For maximum flexibility, it might make sense to select an ESC which has switchable BEC capability.

My project experience (since removed) can be found in an earlier revision of this answer.

Title: One BEC for multiple ESC (Quadcopter)


答:
Convert the int to a byte buffer

Send the byte buffer out via whatever medium (wireless/wired)

On recvive at the microcontroller end, convert the byte to int.

Eg.

```<code>int a = 2 bytes.
int b = 2 bytes.
</code>```

char array[4] = to hold both the ints in byte array for wireless sending.

So your output array will have

```<code>array[0] = int a_1st_part
array[1] = int a_2nd_part
array[2] = int b_1st_part
array[3] = int b_2nd_part
</code>```

Now send the output array out (via socket/wireless/uart).

When you receive do the opposite.

```<code>array[0] + array[1] //make up for int a.
array[2] + array[3] //make up for int b.
</code>```

Title: TCP Communication with PCDuino

Body:
I'm working on a robot that is controlled by an xbox controller connected to a windows computer and commands are sent to a pcduino through a tcp connection. I have it working by sending a string of 1's and 0's to tell the pcduino which motors to turn on. I'm trying to optimize it by just sending an int and using bit masks to make the decisions on the pcduino but I can't get the pcduino to receive the int correctly. I tested the windows function sending the command with sokit and its sending the correct values but the pcduino is receiving the same number even when the commands are changing.

This is what its doing:

Windows          -> PCDuino

command = 1      -> sendBuff = 73932

cmdstring = 1    -> n = 1

command = 1025   -> sendBuff = 73932

cmdstring = 1025 -> n = 4

My windows functions are:

```<code>bool Client::Send(char * smsg)
{
    int iResult = send(ConnectSocket, smsg, strlen(smsg), 0);

    if (iResult == SOCKET_ERROR)
    {
        std::cout << "Sending Message has failed: " << WSAGetLastError() << "\n";
        Stop();
        return false;
    }
    return true;
}
</code>```

```<code>    bool sendCommand()
{
    cmdbuffer << command;
    cmdstring = cmdbuffer.str();

    if (!client->Send((char *)cmdstring.c_str()))
    {
        std::cout << "Disconnected from Server. Press Enter to Exit";
        std::cin.ignore();
        std::cin.get();
        return false;
    }
    return true;
}
</code>```

PCDuino Loop Function

```<code>void loop()
{
    recBuff = 0;
    deviceFlag = 0;

    //Read Socket

/******************************************************************************/

    read(connfd, sendBuff, strlen(sendBuff));
    recBuff = atoi(sendBuff);

/******************************************************************************/

    //Set Current Device to Receive Instructions From
    checkAuto(recBuff, currDevice);

    //Find Current Device of Command
    deviceFlag = checkDevice(recBuff);

    //If Current Device and Set Device are the Same Parse Command
    if (deviceFlag == currDevice)
    {
        parseHex(recBuff);
    }
    usleep(50000);
}
</code>```

I have a printf after the read call and that's where I am getting the 73932 number. I think I have everything you guys need but if there's anything else I need to add let me know. I'm stumped...I don't know if its just a casting problem or what.

Update 1

What I have before everything the setup and loop functions on the PCduino run is:

```<code>int listenfd = 0, connfd = 0;
int n;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
</code>```

Body:
Convert the int to a byte buffer

Send the byte buffer out via whatever medium (wireless/wired)

On recvive at the microcontroller end, convert the byte to int.

Eg.

int a = 2 bytes.
int b = 2 bytes.

char array[4] = to hold both the ints in byte array for wireless sending.

So your output array will have

array[0] = int a_1st_part
array[1] = int a_2nd_part
array[2] = int b_1st_part
array[3] = int b_2nd_part

Now send the output array out (via socket/wireless/uart).

When you receive do the opposite.

array[0] + array[1] //make up for int a.
array[2] + array[3] //make up for int b.


问:
How to make a stepper motor rotate and come to a position of certain degrees (say for 90 degrees) from any initial position?
I tried this code and it worked:

```<code>void loop()
{
    int y = 104;
    int x2 = vertical2.currentPosition();
    int z2 = y-x2;
    int x1 = horizontal2.currentPosition();
    int z1 = y-x1;

    horizontal2.moveTo(z1);
    horizontal2.run();

    vertical2.moveTo(z2);
    vertical2.run();
}
</code>```

However, the problem is that when the above code was placed inside a loop such as if loop, it was not working. Can anyone help me solve this problem? I am using accelStepper library for the code above.

```<code>void loop()
{
    int dummy=1;
    if(dummy==1)
    {
        int y = 104;
        int x2 = vertical2.currentPosition();
        int z2 = y-x2;
        int x1 = horizontal2.currentPosition();
        int z1 = y-x1;

        horizontal2.moveTo(z1);
        horizontal2.run();

        vertical2.moveTo(z2);
        vertical2.run();
    }
}
</code>```

答:
As an alternative you could use a light interruption sensor and disk as is typically found inside any old household printer.  Modules can cost \$20 online, but my local thrift shop sells whole printers for \$10 all the time.

Add the ring to your shaft and add the sensor's four wires, then by counting the number of lines for a full rotation you can divide this number for precise positioning.


问:
Choosing a battery: is a harbor freight solar battery OK for a R/C Lawnmower?
I have built an R/C Lawnmower.  I call it the Honey Badger, because it tears stuff up (that's a good thing).  Well, I used used batteries to get the project going and now it's long past time to get the Honey Badger going again.

The Honey Badger is built on an electric wheelchair frame, and originally used wheelchair deepcycle batteries.  U1 if I recall.  There are 4 of them wired in 2 banks in series and parallel to give 24V for the 24V motors.

Going down to the used wheelchair parts place is about an hour drive and requires a weekend visit and will get me used batteries of unknown condition.

Contrast that with Harbor Freight, which is 20 minutes away and has solar batteries the same physical dimensions and comparable (?) electrical characteristics.  I think with coupons, tax, and after playing the game, I can get a battery for ~$50, about the same price as a used U1.

I found that Amazon also has U1 batteries, and they can be had for ~\$120 for 2 with shipping.

Batteries plus will sell me some deepcycle auto batteries of greater Ah capacity for ~$100 each.

Gross for each solution winds up being around the same: ~\$240 - ~\$300.

Is there a difference in technology between a "solar battery" and a "wheelchair battery"?  Is that difference substantial?  Given that I'm pretty rough with this thing, is any particular technology any better suited to these tasks?  Is there a benefit or drawback to using an automotive battery?

I have the charger from the original wheelchair and if I recall, it's good for the capacity and has room to spare.  I think it can put out 5 amps.

答:
Personally, I'd suggest a different approach as I have done. Look into using 18650 cells instead. You can easily score 6-12 of these cells in old laptop batteries, they are lighter and more energy dense than the lead acid batteries you are using and hold up better.

You can buy them for approximately \$2 each on eBay with a 5000 mAh rating as well but I find that in old laptop batteries, the charge controller board goes bad before the cells do, most of the time. These cells are lithium ion and you should invest the extra buck or two for low voltage cut off protection, as dipping below the 3.6 volts per cell can cause damage (i.e. the exploding hoverboard incidents).

At full charge they run at 4.2 V and you can easily get clips to hold them and cheap circuitry which will allow you to charge them via standard USB micro cords you no doubt have for your cellphone. Just multiply your volts per cell to equal the volts you need for your series then stack in parallel for more amps. I have replaced powerwheel batteries with a 3S3P pack quite nicely. Personally I use a smart universal charger but there are several ways to go here.


问:
What are the biggest challenges to build an highly performant robotic hand?
When looking at the robotic hands made by researchers that are said to be rather close to a real human hand, they can easily cost tens of thousands of dollars.

What makes them so much expensive? Sure there are lots of joints where parts must move, but it's still hard to figure out how it can cost so much even with highly precise servomotors.

What is so much expensive when trying to build a humanoid hand? How can we make it less expensive? What do these expensive hands can do, that a diy cheap hand project can't?

Thank you.

答:
Replying to your comment and the robotic hand mentioned in Gizmag, I think I can answer some of your questions, but before I begin, there are some important references that you should consult to really understand the questions that you have asked.

The robotic hand in question operates on the "twisted string" principle, which act as tendons in the hand. The idea is that when you twist a string, it gets shorter--small DC motors are used to accomplish this. See this presentation for a brief introduction to twisted string actuation, and this presentation for a description of how twisted string actuation is used in practice on the robotic hand.

What makes them so much expensive? Sure there are lots of joints where
  parts must move, but it's still hard to figure out how it can cost so
  much even with highly precise servomotors. What is so much expensive
  when trying to build a humanoid hand?

After reading the reference material, I am sure that the answer to this question is obvious. The robotic hand is not as simple as using hobby servos for each of the joints. Small precision DC motors are used to enable the twisted string actuation. Furthermore, a significant number of motors is required because of the number of degrees of freedom (DOF) of the human hand. On top of the actuators themselves, there is the control of the motors, which is certainly non-trivial. If feedback is implemented, then tactile sensors of some sort will be needed, and if you want to mount this on a mobile robot, then you have to worry about weight and power supply.

The short answer is that proper parts are really expensive, and hobby parts won't get the job done.

How can we make it less expensive?

Once the research is done, decreasing cost is done by manufacturing large quantities, which brings the cost of each unit down; however, there must be a reason to make so many robotic hands, so don't count on this happening in the near future.

What do these expensive hands can do, that a diy cheap hand project can't?

Precision comes to mind, but the purpose of the twisted string robotic hand is as much to demonstrate that robotic hands are feasible as to explore and conduct research on twisted string actuation itself.

As an aside to the questions you have asked an the robotic hand we are discussing, I have two important things to mention.

First, I have to say that if you really want to learn about robotics or technology in general, the first thing you should do is understand the differences between secondary and primary sources. Gizmag/Gizmodo/etc generate income by selling ads, so the emphasis is not on proper reporting and even less on the material they purportedly cover--the people writing the articles likely have less knowledge about the subject than you do. You shouldn't count on the veracity of these sources and should fact-check as a matter of course. To do this look for author names and articles that should be referenced, then use Google Scholar to find primary literature on the subject--reading through this material is key.

Second, there are distinct differences in approach to robotics between hobbyists and researchers. Hobby robotics focus on the robot itself as a product that can be seen, touched, and possibly used. In research, the focus is often on underlying theories, and the robot is merely a platform used to demonstrate and apply theory. There are merits to both, and each approach can benefit from the perspectives of the other, but when you try to compare robots used for one approach from the other, you must understand that the objectives are fundamentally different.


问:
Brushless motor from RC car won't spin with even small resistance
I recently bought a RC car kit and after 10 minutes it stopped going.

When I throttle, I can see the motor trying to spin but it will just grind and get hot quite fast.

The motor does move if I disconnect it from the big gear, but not as fast as it did when new and it will still get very hot. Also, I can stop it with my fingers with a very slight touch.

I don't know anything about motors or ESCs, so I'm not sure if my problem is the motor or the ESC.  Did I burn it out?

答:
A couple of things to check:

First, does the gear assembly work smoothly? If it doesn't, then the motor might have broken when attempting to work against too much resistance.

Second, if you apply a reasonable voltage directly to the positive and negative leads of the DC motor, does it still get hot and not work? If so then the motor is toast.

I cannot imagine that the mechanical issue is caused by the ESC.


答:
Sounds like a burnt (shorted) motor.

If you are not able to inspect the ESC with an oscilloscope, try connecting every combination of the motor leades to each other and spin the motor by hand. If only one phase is damaged, then one combination of phase wires connected to each other will provide more resistance than the other two.

Title: Brushless motor from RC car won't spin with even small resistance

Body:
I recently bought a RC car kit and after 10 minutes it stopped going.

When I throttle, I can see the motor trying to spin but it will just grind and get hot quite fast.

The motor does move if I disconnect it from the big gear, but not as fast as it did when new and it will still get very hot. Also, I can stop it with my fingers with a very slight touch.

I don't know anything about motors or ESCs, so I'm not sure if my problem is the motor or the ESC.  Did I burn it out?


问:
Angular momentum of rimless wheel in Passive Dynamic Walking
In Tad McGeer's work, Passive Dynamic Walking, in 1990, he mentions the rimless wheel model, which is used to approximate the bipedal locomotion. I can't understand why the angular momentum is written as follows.

$H^-=(\cos 2\alpha_0+r^2_{gyr})ml^2\Omega^-$

I have the following questions:

Isn't the angular momentum be $I*\omega$, $m^2l\Omega$ as the paper's notation?

If $\alpha_0$ is $\frac{\pi}{2}$ and $r_{gyr}$ approaches to 0, shouldn't the angular momentum before impact, $H^-$, be negative? Then how the conservation goes?

答:
There are some fundamental problems with your questions.

First, $\alpha_0$ and $r_{gyr}$ are fixed parameters that depend on the passive walker.

Second, the equation $$H^-=I*\omega=(cos(2 \alpha_0)+r_{gyr}^2)m l^2 \Omega$$ implies that $$I=(cos(2 \alpha_0)+r_{gyr}^2)m l^2 \neq m l^2.$$

Lastly, I'm not sure that $\alpha_0=\pi/2$ makes sense physically because it is the angle of the leg at support transfer. See Figure 5 in the paper. The gait of each leg is out of phase as expected. $\alpha_0=\pi/2$ would mean that the weight transfers when the leg is perpendicular with the ground, which, I am confident, would not be a smooth walking gait.


问:
How do the PID parameters (Kp, Ki, and Kd) affect the heading of a differential driving robot when they are increased individually?

Question: A PID controller has three parameters Kp, Ki and Kd which could affect the output performance. A differential driving robot is controlled by a PID controller. The heading information is sensed by a compass sensor. The moving forward speed is kept constant. The PID controller is able to control the heading information to follow a given direction. Explain the outcome on the differential driving robot performance when the three parameters are increased individually.

This is a question that has come up in a past paper but most likely won't show up this year but it still worries me. It's the only question that has me thinking for quite some time.
I'd love an answer in simple terms. Most stuff i've read on the internet don't make much sense to me as it goes heavy into the detail and off topic for my case.

My take on this:

I know that the proportional term, Kp, is entirely based on the error and that, let's say, double the error would mean doubling Kp (applying proportional force). This therefore implies that increasing Kp is a result of the robot heading in the wrong direction so Kp is increased to ensure the robot goes on the right direction or at least tries to reduce the error as time passes so an increase in Kp would affect the robot in such a way to adjust the heading of the robot so it stays on the right path.

The derivative term, Kd, is based on the rate of change of the error so an increase in Kd implies that the rate of change of error has increased over time so double the error would result in double the force. An increase by double the change in the robot's heading would take place if the robot's heading is doubled in error from the previous feedback result. Kd causes the robot to react faster as the error increases.

An increase in the integral term, Ki, means that the error is increased over time. The integral accounts for the sum of error over time. Even a small increase in the error would increase the integral so the robot would have to head in the right direction for an equal amount of time for the integral to balance to zero.

I would appreciate a much better answer and it would be great to be confident for a similar upcoming question in the finals.

答:
Andy's response is good, and he hits all of the important points but to fully understand PID control in the context of a differential drive robot, it might be useful to take a step back and consider the dynamics of the system. This may seem like a digression from your specific question, but if you take the time to read through, I am confident that this will lend context to PID control and improve your understanding.

Differential drive robots can be modeled with unicycle dynamics of the form: $$\left[\begin{matrix}\dot{x}\\ \dot{y} \\ \dot{\theta} \end{matrix}\right] = \left[\begin{matrix}cos(\theta)&0\\sin(\theta)&0\\0&1\end{matrix}\right] \left[\begin{matrix}v\\\omega\end{matrix}\right],$$ where $x$ and $y$ are Cartesian coordinates of the robot, and $\theta \in (-\pi,\pi]$ is the angle between the heading and the $x$-axis. The input vector $\left[v, \omega \right]^T$ consists of linear and angular velocity inputs.

Because the objective is to head in a desired direction, so the error can be written as $$e=\theta-\theta_d,$$ and the error dynamics are given by $$\dot{e}=\dot{\theta}=\omega.$$ The relative degree of the system is $\gamma=1$, so by driving the error to 0, the $x$ and $y$ position will not be controlled, which makes sense.

The question is, what angular velocity should be applied to drive the error to zero? Because the error dynamics are a single integrator, linear system, they can be exponentially stabilized by correctly choosing $\omega$; this is where PID control comes in. Recall the definition of PID control and putting it in the context of the system: $$\omega=K_p e+K_i \int_0^t{e dt} + K_d \frac{de}{dt}.$$ As it turns out, because there is no drift term (e.g. the system is given by $x=f(x)+g(x)u=g(x)u \implies f(x)=0$), you can set $K_d=K_i=0$ and simply choose $K_p<0$ to accomplish the objective. On a real system, where the unicycle model is not accurate, there may be cause to include the integral and derivative terms. Knowing the process to get to this point, in addition to your existing intuition about what PID does, will definitely help on your test.


问:
Generalized Voronoi Diagram
I need to compute the Voronoi diagram for a map with some obstacles but I can't find any pseudo-code or example in MATLAB.

The "voronoi" function in MATLAB works with points, but in this case the obstacles are polygons (convex and non-convex). You can see the map in the attached image.

Because the obstacles are polygons I found that the Voronoi algorithm needed is the GVD (Generalized Voronoi Diagram).

Can anyone help with code or examples on internet explaining how to compute this GVD?

答:
The project repositories at Florida State should get you what you are looking for:  https://people.sc.fsu.edu/~jburkardt/m_src/m_src.html

Look at not only the projects which start with "voronoi_," but also "sphere_voronoi."

Title: Generalized Voronoi Diagram


问:
Path planning vs. linear interpolation?
I at moment trying to convince myself that what I need is a simple path planning algorithm, instead of linearly interpolating between a current and a desired state.

I am at moment working with an robot arm (UR) with an camera mounted on to its TCP.  The application i am trying to create is a simple ball tracking application which tracks the movement of the ball, while always keeping the object within sight.

which meant that I needed some form of path planning algorithm which plans the path between my current state and the desired state. The path should should be such that the ball is always kept in focus while the arm moves to the desired state.

But then I began question myself whether it was a bit overkill, and whether a simple straight line interpolation wouldn't suffice?.. I am actual not sure what form of benefit i would have by choosing a pathplanner, than a simple interpolation..

Interpolation would also generate the path I desire, so why choose a pathPlanner at all?

would someone elaborate?
It should be noted that obstacle avoidance is also a part of the task, which could cause trouble for a straight line interpolating.

答:
Path planning is essentially obstacle avoidance.

If there are no obstacles, chances are path planning is Overkill. However, one obstacle that you always have and that is a constraint for the configuration space is the robot itself.

Now if you have no obstacles and start and end configurations can be connected by a straight line in configuration space, the task of path planning indeed simplifies to knowing the line that connect them.

Especially if the camera captures images frequently, movement will be small.

a simple path planning algorithm

There's no such thing. You need to define configuration space which gets very complicated with higher dimensions, perform all kinds of geometric operations on it and finally have some algorithm navigate through it.

I'd say it's not just over-kill, it's over-annihilation.

Title: Path planning vs. linear interpolation?


问:
Which mechanical device could repeatedly present an ID tag to a card-reader
I'm trying to build a test-automation robotic arm which can repeatedly present an ID-tag (such as RFID or NFC card or fob) to a card reader.

I suspect our reader fails either (a) after hundreds of presentations or due to fast presentations or (b) at a specific moment in the reader duty cycle.

The tag needs to move in a well-controlled manner:

Quickly present the card,

Pause (mark)

Quickly remove the card,

Pause (space)

Repeat at 1.

I'm calling the present/remove sequence the mark-space ratio for simplicity.

The tests I want to perform involve varying (a) the frequency and (b) the mark-space ratio, to (a) stress-test and  (b) boundary-test the re-presentation guard times built into the reader to debounce presentations.

The guard times are around 400ms, response around 100ms, so I need something that can move in and out of a 5-10cm range quickly and repeat within those sorts of timescales.

The distance the card needs to move depends on the reader model, as they have different field ranges. I want to get through the edge of the field quickly to avoid any inconsistencies in testing.

I'm able to do any programming (professional) and simple electromechanical design and build (ex-professional, now hobbyist). I only need to build one, it doesn't have to be particularly robust, but it does need to be fairly accurate with regard to the timings to do the second test.

What I've done so far:

I've built one version already using a Raspberry Pi, GPIO, a stepper motor with an aluminium arm screwed to a wheel.  It works, but it's a bit jerky and too slow, even with a 30cm arm to amplify the motion. It will probably do for the repeat test, but it's not time-accurate enough to do the timing tests.

My other design ideas were:

Servo (are these also slow?)

Solenoid (fast, but too limited range? and might cause EM?)

Motor (too uncontrollable, and will require too much mechanical work for me)

Rotating drum (fast, stable, but cannot control mark-space ratio)

I'm not a electro-mechanical design expert, so I'm wondering if I'm missing an electrical device or mechanical design which can do this more easily.

答: I'd go for a linear axis. The cheapest version could be from a printer or you buy a small belt and two gears. A brushless DC would however fit better in this scenario. Such systems are easily faster than a normal user and easy to control. </p>


问:
Maximum distance for robotic arm throwing
I have a 6DOF robotic arm which I am using to throw a ball. Each joint can achieve a maximum velocity of 30 RPM (180 deg/s). I have been trying to generate joint angles manually and feeding them to see how far I can throw the ball until now. This has shown me that it's like less than 2 meters. </p>

<p>But I feel that I may not be combining the motions of the various motors in order get better throwing distance. I wanted to know if there is a simple way of theoretically determining the maximum distance I can throw. I read a few papers that appear very complicated, I do not need a very accurate value, just an estimate so that I decide whether I should move to a different arm. </p>

答:
Throwing distance is dependent on the initial velocity of the ball thrown and the heading angle. Both of these is given by the robot arm.
The velocity is simple, as large as possible. However the angle is not that simple.

You can find the optimal throwing angle calculations here:

What angle should you throw a football for maximum range?

This defines the orientation of the robot. I would recommend:

representing every position of the end-effector that can reach this orientation in joint space.

Then select the point in joint space which is on the obtained surface (might be a volume or hypervolume based on the number of degrees of freedom of the robot) which has enough distance from the joint limits to reach maximum velocity.

You can see how much "overhead" space do you need by knowing the maximum acceleration of the robot and checking how much angular distance do you need to reach maximum joint velocity if you accelerate from 0 speed to maximum speed with maximum acceleration.
-OR-
Just pick the point that is on the orientation surface and is the furthest away from joint limits.

--- EDIT: ---

As @Bending Unit 22 pointed out in the comments, you should select the highest possible position form the ones that satisfy the constrains in point 2.


问:
Holonomic and Non-holonomic UAV's: Gliders vs Quadcopters
Good day I would just like to ask if a fixed wing aircraft such as a glider(without thrust capability therefore needs external forces such as air flow to move constraining its movement) can be considered a non-holonomic system considering the fact that it cannot move freely compared to a quadcopter that is holonomic.

I found this information from: What's the difference between a holonomic and a nonholonomic system?

Mathematically:

Holonomic system are systems for which all constraints are integrable into positional constraints.

Nonholonomic systems are systems which have constraints that are nonintegrable into positional constraints.

Intuitively:

Holonomic system where a robot can move in any direction in the configuration space.

Nonholonomic systems are systems where the velocities (magnitude and or direction) and other derivatives of the position are constraint.

答:
The glider definitely is a nonholomonic system, but not (only) because it has no propulsion.

As Wikipedia defines it:

A nonholonomic system in physics and mathematics is a system whose state depends on the path taken in order to achieve it.

So, if an aircraft can reach a pose (position and orientation) in space regardless of its prior states (path taken) than it is holomonic. To simplify it even more:

A car is a nonholomonic system. It can occupy any position (in 2D, X and Y translations) and orientation (1 orientation around the Z axiz, perpendicular to the road) but what makes it nonholominic is its steering system which does not allow it to move sideways. It can occupy the position just 1 mm (or $\delta y$ distance) to the right of its current position, but ONLY if an adecvate path leads the car to that position.

An omnidirectional robot (e.g. with mecanum wheels, Google search it) is holomonic because it can occupy any pose (2 translations 1 orientation) regardless of its previous states (path taken). It can move to the immediate right, unlike the car, with $\delta y$ distance.

You might want to take a look at underactuated systems. Those are the ones that require external forces.


问:
Cosine interpolation between two transformation matrices?
Is it possible to perform cosine interpolation between two transformation matrices?

It make sense for the translation part, but how about the rotational part?

答:
Yes, you can.

same as for the translations, you extract the 3 angles form the matrix, you have the starting angles and the target angles. Interpolate as you wish (sync-async, cos-spline-linear) and for each timestamp you can re-create the matrix (knowing the 3 angels and the 3 translations).

Advantage for cos-interpolation would be the continuity of higher order derivates (same as in the case of the interpolation for the linear axes)


问:
The velocity profile of my robot is fluctuating
I am presently doing a robotics project. I am using USARSIM (Urban Search and Rescue Simulation) to spawn a robot. I am trying to create different behaviors, like:

goal following behavior;

obstacle avoidance behavior, and;

wall following behavior for my robot.

I first generate the robots in USARSIM. Then I specify a goal location to the robot and provide it with a speed. The robot then moves to the goal location at the specified speed. USARSIM provides me the (x, y, z) coordinates of the vehicle at every time stamp. Based on the the coordinates received, I am trying to calculate the instantaneous speed of the robot at every time stamp. The instantaneous speed graph is fluctuating a lot.

In a specific case, I am providing the robot with 0.2 m/s. The velocity profile is shown below. I am unable to understand the reason behind it.

Here are some observations that I have made.

As I increase the speed of the robot, the variations are decreasing.

Suppose, I provide a straight trajectory to the robot, it doesn't follow the straight trajectory. Does it explain why my velocity profile is fluctuating a lot ?

Please let me know if any one can provide me a possible explanation for the variance in my velocity profile.

答:
There can be many reasons for the fluctuating velocity.

The most commons is errors due to the finite differences method that I assume you are using.

If the system is not real time, the interrupt when you measure the distance might be sometimes later sometimes earlier then expected. Since the velocity you ploted is always below the target velocity and never above...there might be a nother problem in your case.

I do not know the simulation system you mentioned, but if it is not a real-time simulation system there is a possiblity that the simulation is tardy. Events in simulation happen later then in your computer clock. 1 second of simulation takes 1.2 seconds to calculate for example. If you use a real-time clock to get the interrupts and use that time to calculate the velocity, you think you are at simulation time 1 second but you are actually at simulation time 0.85 seconds, so the distance that should be covered in this time was not yet covered hence you get a lower velocity. This would also mean that your velocity should slowly drift downwards, which is not happening.

If you do not use a fixed time solver for the simulation, it might be that sometimes you are blow the simulation time sometimes you are "catching up".

It might very well be a combination of the above.

These are just guesses.

Are you using the time as a fixed interrupt or do you interrogate the simulation environment for the simulation time?


问:
Which is easier/cheaper: Hbridge vs ESC for controlling a motor?
I was able to find a small ESC for about $12 off of ebay.  If you were designing a robot, would you see that and think?

\$12 bucks for an ESC that connects to simple pulse-wave interface -
  sign me up!

Or would you think:

\$12 just to control a motor? I could throw together an H-bridge for
  $0.50 and be done with it.

My robot in particular actually has two motors and therefor $24 to control the two of them.  But the interface is really easy (plus has the added advantage of being R/C vs computer controlled with a simple change of connectors.

Which way would you go?

答:
What kind of motors?  ESCs typically are for brushless DC motors, which are electronically commutated DC three phase motors, and you can't run them with an H-bridge.

That said, ESCs give you a lot of bang for the buck, and they're certainly worth $12 :)


问:
Configuration space obstacle - calculating collision
I need to calculate the configuration space obstacle to planning a path with a mobile robot. The idea is to divide the obstacles and the robot in triangles and test whether is there any triangle from the robot colliding with any triangle from the obstacles.

The approach to solve this is to test this between two triangles each time so I need to look if any of the 6 edges (3 for each triangle) divide the triangles so 3 vertex from one of them lie in one side and the other 3 vertex lie on the other side of the line.

I wrote some code to calculate the line equation (y = m*x + b) and I think it is correct, but I am having problems when the line is vertical (this means that m = -Inf) because MATLAB gives me a NaN when I calculate the equation for it. I am not sure how to handle this.

Here you can see a snippet from the code where I test the 3 edges from the
robot triangle:

```<code>for i = 1:1:3

    vertex_x = P1(edge(i,:),1);
    vertex_y = P1(edge(i,:),2);
    m = (vertex_y(2) - vertex_y(1))/(vertex_x(2) - vertex_x(1));
    b = -m*vertex_x(1) + vertex_y(1);

    for j = 1:1:6   % For each vertex...
        pto = listaVertices(j,:);
        if (m*pto(1) + b > pto(2))
            % Vertex lies below the edge...
            cont1 = cont1 + 1;
        elseif (m*pto(1) + b < pto(2))
            % Vertex lies above the edge...
            cont2 = cont2 + 1;
        else
            % Vertex lie inside the edge...
            % Do nothing
        end
    end

    % 3 vertex on one side and 1 on the others side means they do not
    % collide. Two of the vertex always lie inside the line (the two vertex
    % of each edge).

    if (cont1 == 1 && cont2 == 3) || (cont1 == 3 && cont2 == 1)
        flag_aux = false;   % Do not collide...
    end
    % Reset the counters for the 3 next edges...
    cont1 = 0;
    cont2 = 0;

end
</code>```

Anyone could help with this issue?

答:
For your particular question about m = Inf, you should first check if
vertex_x(2) = vertex_x(1).  Actually, I would implement the check to see if the absolute value of vertex_x(2) - vertex_x(1) < some_very_small_number.  If that condition is true, then the equation for that line segment is y = vertex_x(1) and you just need to see if the other line segment contains that value for x.  If the condition is false then use the check you already have.


问:
Stability of PID values update function for quadrotor
A reviewer of the last paper I sent replied me that the it is very dangerous to update a PID with next kind of formula (paper is about quadrotor control):

$$
K_p (t + 1) = K_p (t)+e(t) (μ_1 (Pe(t)) + μ_4 (Pe(t)))
$$

$Pe(t)$ is the % relationship between the desired angles and the real angles, and $e(t)$ is the difference between those angles. $μ_1$ and $μ_4$ are the membership functions of a fuzzy function. I think that the reviewer is talking about the time increment update rather than the fuzzy usage and specific formula.

How can stability of this formula be tested, please?

EDIT:

membership functions are represented in following graph:

$e(t)$ is not the absolute difference between angles, just the difference. It can be negative

答:
I think I may have reason for your reviewer's caution. You are updating the proportional gain of a PID controller, and you are concerned with the stability of your update law. Restating your update: $$K_p(t+1)=K_p+e(t)(\mu_1(Pe(t))+\mu_4(Pe(t))).$$ You have re-stated that $e(t)$ is the difference, which means that the error is not positive semi-definite ($e(t)\geq 0$). However, the membership functions $\mu_1$ and $\mu_4$ are positive semi-definite; this implies that $E(t)=e(t)(\mu_1(Pe(t))+\mu_4(Pe(t)))$ is either positive or negative semi-definite, which means that $K_p$ grows unbounded in some region $D$.

At this point, it is clear that the update law is not stable in some region (in the sense of Lyapunov) for $e(t)\neq 0$. We can substantiate this with discrete-time Lyapunov analysis.

$Proof:$ Dropping the time dependence for clarity, let $$V(K_p)=\frac{1}{2}K_p^2$$ be a candidate Lyapunov function. The rate of change along solutions is given by $$\begin{align}\nabla V(K_p)&=V(K_p+E)-V(K_p)\\&=\frac{1}{2}(K_p+E)^2-\frac{1}{2}K_p^2\\&=K_pE+\frac{1}{2}E^2\end{align}.$$
For stability of the system, we must have $\nabla V(K_p)<0$. This implies $$K_pE+\frac{1}{2}E^2<0$$$$\to K_p<-\frac{1}{2}E.$$ We can conclude from converse Lyapunov results that the system is unstable for at least $K_p>-\frac{1}{2}E$, which is an obvious reason for concern. There may be a better Lyapunov candidate function to demonstrate this result, but we can be sure that the system is locally unstable.


问:
convert toolframe coordinate to world frame coordinates?
I am not sure how i should explain this, I am looking for a way to plot the trajectory an robot arm.  An object is seen from the toolFrame frame, but how do I plot the position of each joint, such that the frame they uses are the same.

One way would be to use the world frame as reference, but how would i plot the position of the object related to the world frame?

答:
Assuming you have solved the inverse kinematics (IK) problem already...

I suppose you have a transformation matrix for each joint, build up from one line in the DH table (if you used DH to describe the robot).
Form the IK you have obtained

$Q = [q_1, q_2, q_3, q_4, q_5, q_6]$

Having all Q values you can now write:

$H_{0,1} = A_1(q_1)$

$\Rightarrow$ $H_{0,1}(1:3, 4)$ will give you the $x$, $y$ and $z$ Coordinates of joint 1

$H_{0,2} = H_{0,1}*A_2(q_2)$

$\Rightarrow$ $H_{0,2}(1:3, 4)$ will give you the $x$, $y$ and $z$ Coordinates of joint 2

$H_{0,3} = H_{0,2}*A_3(q_3)$

$\Rightarrow$ $H_{0,3}(1:3, 4)$ will give you the $x$, $y$ and $z$ Coordinates of joint 3

$H_{0,4} = H_{0,3}*A_4(q_4)$

$\Rightarrow$ $H_{0,4}(1:3, 4)$ will give you the $x$, $y$ and $z$ Coordinates of joint 4

$H_{0,5} = H_{0,4}*A_5(q_5)$

$\Rightarrow$ $H_{0,5}(1:3, 4)$ will give you the $x$, $y$ and $z$ Coordinates of joint 5

$H_{0,6} = H_{0,5}*A_6(q_6)$

$\Rightarrow$ $H_{0,6}(1:3, 4)$ will give you the $x$, $y$ and $z$ Coordinates of joint 6

$H_{0,tool} = H_{0,6}*A_{tool}$

where

$A_i$ is the DH-transformation matrix associated with joint $i$.

the index $_0$ represents the world frame

the intex $_{tool}$ represents the tool frame

$H_{i,j}$ represent the transformation matrix from frame $i$ to frame $j$


问:
How to make an "invisible line following robot"?
I would like to build a robot which follows a virtual path (Not a visible path like a 'black line on a white surface', etc).

I'm just enthusiastic by seeing some sci-fi videos which show robots carry goods and materials in a crowded place. And they really don't follow a physical line. They sense obstacles, depth, etc.

I would like to build one such robot which follows a specific (virtual)  path from point A to B.

I have tried a couple of things:

Using a magnetic "Hall effect" sensor on the robot and wire carrying current (beneath the table). The problem here was that the vicinity of the hall effect sensor is so small (< 2cms) that it is very difficult to judge whether robot is on the line or off the line. Even using series of magnets couldn't solve this issue, as my table is 1 inch thick. So this idea flopped :P

Using an ultraviolet paint (on a line) and using UV leds on the robot as sensors. This will give more Zig-Zag motion for the robot. And due to potential threats of using UV light source, even this idea flopped :P

I finally thought of having a camera on top and using image processing algorithms to see whether robot is on the line or diverging.

Is there any better solution than this? Really looking for some creative and simple solutions. :)

答: Well you don't need any line for that matter. The one thing you would probably need are global coordinates. if you can place your robot in a field defined by global coordinates and apply simple rules of Newtonian physics, the robot can go from one point to the other. Based on it's present location, it will find out the present steering angle, desired steering angle and the goal coordinates (also known as "pose"). Once you provide the robot with a speed, it will start moving towards the goal coordinates. In every iteration, it will recalculate its pose and make adjustments when necessary.</p>


问:
Computing the Jacobian Matrix -- chain rule?
I am learning about robot kinematics and the Jacobian matrix, and I'm trying to understand how to compute the Jacobian matrix given a kinematic chain, such as a robot arm. I understand the theory behind the Jacobian matrix, but I'm not sure actually how it would be calculated in practice.

So, let's say that I have a 7 DoF robot arm, with 7 joints and 6 links between the joints. I know how to compute the transformation matrix between each joint, and by applying forward kinematics, I know the pose of the end effector for any configuration of joint angles. To calculate this, I have written some code which stores each transformation matrix, and then multiplies them in series to create the transformation matrix between the first joint and the end effector.

However, how do I now go about computing the Jacobian matrix? My solution so far, is to write down each transformation matrix by hand, then multiply them all by hand, to yield the overall transformation matrix, with respect to the joint angles. I could then differentiate this to create the Jacobian matrix. The problem with this though, is that the maths becomes very, very complicated as I move along the kinematic chain. By the end, there are so many terms as a result of the multiple matrix multiplications, that it just becomes so tedious doing this by hand.

Is there a better way to do this? In the case of calculating the forward kinematics, I didn't have to do it by hand, I just wrote some code to multiply the individual matrices. But when I want the Jacobian matrix, it seems like I need to compute the derivative of the overall transformation matrix after it has been computed, and so I need to do this by hand. What's the standard solution to this? Is it something to do with the chain rule for differentiation...? I'm not sure exactly how this applies here though...

Thank you!

答:
You are right about the tedious nature of multiplying all those individual matrices by hand!  You could search online for robot kinematics software and find some nice tools to help with this, but you learn it so much better when you actually work out the equations.  Since you've already written the forward kinematics code, it's clear you understand that process.  I recommend you use a symbolic algebra package (I used to use Maple IV, and that functionality is now within MatLab).  Re-write the forward kinematics program, but do not plug in values for each joint angle.  You'll end up with very long expressions for each term of $\vec x$, which can be reduced significantly by applying trigonometric identities.  The identities for $\sin (\theta_2 + \theta_3)$ and $\cos (\theta_2 + \theta_3)$ are particularly helpful for articulated arm geometries.

Regarding the Jacobian, I have always found differentiating the forward kinematics to be rather straightforward.  The chain rule isn't a major complicating factor, since each term is based on partial, not full, derivatives.  A symbolic algebraic tool can be helpful here, too.

I think the key for your situation is to first determine the kinematics in closed-form (keeping the $\theta_i$ terms in the equations).  Also compute the Jacobian in closed-form.  Then you have the equations ready for plugging in joint values regardless of the robot's pose.