答:
The information matrix is the inverse of the covariance matrix.  In this case, the covariance is over the variables (x,y,z,qx,qy,qz).  It is assumed that your quaternion is normalized to be unit magnitude.

You should be able to get an estimate of the information matrix from the ICP.

Edit:

In general the covariance estimate can be found by the following procedure.

Set I = 0 (I will be the information matrix for the system)

For each input.

Get the covariance (must be estimated somehow empirically).

Invert the covariance to get the information W

Calculate the Jacobian J of your error in the output space with respect to the input (see http://en.wikipedia.org/wiki/Jacobian_matrix_and_determinant)

Transform the information into the error space via X = J^T * W * J

Set I = I + X

Invert I to get the covariance S of the output

Edit 2:

The covariance formula that you linked to is the covariance of the points in the point cloud.  For the mapping, you want the covariance estimate for the estimated transform which is not at all the same thing.  It is a little difficult to explain.  Try looking at http://en.wikipedia.org/wiki/Non-linear_least_squares .  In your case the x_i would be points in P_A, y_i would be points in P_B, f would be the function that transforms points from P_A to P_B (i.e. f(x_i, T) = T(x_i) where T(x) is applying T to x), and beta would be the transform parameters.  In the last equation in the theory section, the J^TWJ term is the estimated information for the parameters.  Inverting this provides a covariance estimate (this is based on the Cramer-Rao lower bound, see http://en.wikipedia.org/wiki/Cram%C3%A9r%E2%80%93Rao_bound).  For the typical case of independent measurements, the J^T * W * J term ends up just being a sum of J_i^T * W_i * J_i for each measurement i.

Title: RGB-D SLAM - Compute Information Matrix

Body:
currently im working on a RGB-D SLAM with a Kinect v1 Camera. In the front-end the SLAM estimates the pose with Ransac as an initial guess for the ICP. With the pose estimation i transform the pointcloud to a pointcloud-scene which represents my map.

To smooth the map im trying to implement a graph optimizing algorithm (g2o).
Until now, there is no graph representation in my frontend, so i started to integrate that.

Im trying to build a .g2o file with the following fromat:

VERTEX_SE3 i x y z qx qy qz qw

where x, y, z is the translation and qx, qy, qz, qw ist the Rotation in respect to the initial coordinate system. And,

EDGE_SE3 observed_vertex_id observing_vertex_id x y z qx, qy, qz, qw inf_11 inf_12 .. inf_16 inf_22 .. inf_66

Translation and rotation for the edge is the pose estimate that i compute with Ransac and ICP (visual odometry).

Now im getting stuck with the information matrix.
I read the chapter 3.4 THE INFORMATION FILTER in Thrun's Probabolistic Robotics and several threads in this forum, such as:

The relationship between point cloud maps and graph maps

and

information filter instead of kalman filter approach

From the second link, i got this here.

The covariance update
  $$P_{+} = (I-KH)P$$
  can be expanded by the definition of K to be

$$ P_{+} = P - KHP$$
  $$ P_{+} = P - PH^T (HPH^T+R)^{-1} HP$$

Now apply the matrix inversion lemma, and we have:

$$P_{+} = P - PH^T (HPH^T+R)^{-1} HP$$
  $$ P_{+} = (P^{-1} + H^TR^{-1}H)^{-1}$$

Which implies:
  $$ P_{+}^{-1} = P^{-1} + H^TR^{-1}H$$

The term $P^{-1}$ is called the prior information,$$H^TR^{-1}H$$
  is the sensor information (inverse of sensor variance), and this gives us  $P^{-1}_+$, which is the posterior information.

Could you please point this out for me.
What data do i need to compute the information matrix?


问:
Verifying motor selection calculations
I'm trying to select a brushed DC motor for a project. I tried following the advice on sizing electric motors, mentioned in this question, but a few details were missing, and I'm unsure if I properly followed the procedure.

For my application, I need:

Nm = number of motors = 2

Wd = wheel diameter = 12 cm

Wp = estimated weight of platform = 5 kg

Minc = maximum incline under load = 5 degrees

Vmax = maximum velocity under load = 5 km/hr

Fpush = maximum pushing force = 1.25 kg

Ur = coefficient of rolling friction = 0.015

These are my calculations:

Step 1: Determine total applied force at worst case.

```<code>Ftotal = Wp * (Ur*cos(Minc) + sin(Minc)) + Fpush = 1.7604933161 kilogram
</code>```

Step 2: Calculate power requirement.

```<code>Vradps = maximum velocity under load in radians/second = 23.1481481481 radian / second

Pmotor = required power per motor = (Ftotal * Vradps * Wd/2)/Nm = 1.22256480284 kilogram * meter * radian / second
</code>```

Step 3: Calculate torque and speed requirement.

```<code>Tmotor = required torque per motor = Pmotor/Vradps = 5281.47994829 centimeter * gram = 73.345953832 inch * ounce
RPMmin = required revolutions per minute per motor = Vradps / 0.104719755 = 221.048532325 rev / minute
</code>```

Are my calculations correct? Intuitively, the final Tmotor and RPMmin values seem right, but my calculation for Pmotor doesn't exactly match the one used in the link, which doesn't explicitly do the conversion to radians / second and therefore doesn't result in the proper units.

Here's my Python script for reproducing the above calculations:

```<code>from math import *
#http://pint.readthedocs.org/en/0.6/tutorial.html
from pint import UnitRegistry

ureg = UnitRegistry()

def velocity_to_rpm(v, r):
    kph = v.to(kilometer/hour)
    r = r.to(kilometer)
    d = r*2
    rpm = (kph / (2*pi*r)) * ((1*hour)/(60.*minute)) * rev
    return rpm

def velocity_to_radps(v, r):
    return velocity_to_rpm(v, r).to(radian/second)

# Units
km = kilometer = ureg.kilometer
meter = ureg.meter
newton = ureg.newton
cm = centimeter = ureg.centimeter
hr = hour = ureg.hour
mm = millimeter = ureg.millimeter
rev = revolution = ureg.revolution
minute = ureg.minute
sec = second = ureg.second
kg = kilogram = ureg.kilogram
gm = gram = ureg.gram
deg = degree = ureg.degree
rad = radian = ureg.radian
oz = ureg.oz
inch = ureg.inch

# Conversions.
km_per_mm = (1*km)/(1000000.*mm)
hour_per_minute = (1*hour)/(60.*minute)
minute_per_second = (1*minute)/(60*sec)
minute_per_hour = 1/hour_per_minute
gm_per_kg = (1000*gm)/(1*kg)
cm_per_km = (100000*cm)/(1*km)

# Constraints
target_km_per_hour = (5*km)/(1*hour) # average walking speed
estimated_platform_weight = 5*kg
maximum_incline_degrees = 5*deg
maximum_incline_radians = maximum_incline_degrees * ((pi*rad)/(180*deg))
maximum_pushing_force = estimated_platform_weight/4.
maximum_velocity_at_worst_case = (5*km)/(1*hour)
rolling_friction = 0.015 # rubber on pavement
velocity_under_max_load = target_km_per_hour
number_of_powered_motors = 2

# Variables
wheel_diameter_mm = 120*mm
wheel_radius_mm = wheel_diameter_mm/2
wheel_radius_km = wheel_radius_mm * km_per_mm
rev_per_minute_at_6v_unloaded = 33*rev/(1*minute)
rev_per_minute_at_6v_loaded = rev_per_minute_at_6v_unloaded/2.
mm_per_rev = (wheel_diameter_mm * pi)/(1*rev)
target_rpm = velocity_to_rpm(target_km_per_hour, wheel_radius_mm)
target_radps = velocity_to_radps(target_km_per_hour, wheel_radius_mm)

# Calculate total applied force at worst case.
total_applied_force_worst_case = estimated_platform_weight * (rolling_friction*cos(maximum_incline_radians) + sin(maximum_incline_radians)) + maximum_pushing_force
print 'Ftotal:',total_applied_force_worst_case

# Calculate power requirement.
vel_in_radps = velocity_to_radps(velocity_under_max_load, wheel_radius_mm)
print 'Vradps:',vel_in_radps
required_power = total_applied_force_worst_case * velocity_to_radps(velocity_under_max_load, wheel_radius_mm) * wheel_radius_mm.to(meter)
required_power_per_motor = required_power/number_of_powered_motors
print 'Pmotor:',required_power_per_motor

# Calculate torque and speed requirement.
required_angular_velocity = velocity_under_max_load/wheel_radius_km * hour_per_minute * minute_per_second * rad #rad/sec
required_rpm = required_angular_velocity / 0.104719755 * (rev/rad) * (sec/minute)
required_torque_per_motor = (required_power_per_motor/required_angular_velocity).to(gm*cm)
print 'Tmotor: %s, %s' % (required_torque_per_motor, required_torque_per_motor.to(oz*inch))
print 'PRMmin:',required_rpm
</code>```

答:
I think your Pmotor calculation is correct.  The reason for the difference with the CIRC link is in the P=F*v equation they are referring to the linear velocity.  Your conversion is converting the rotational velocity back into linear velocity.

I don't think the Ftotal calculation is correct because your estimated weight isn't correct.  Kg is a unit of mass, not weight.  To convert to weight, you need to multiply by the gravitational pull of the earth (9.8 m/s^2).  This is also why the units on your power estimate isn't in Watts.  Your torque units should then be N*m or equivalently oz(force)*in.  Note that this is ounce force not the sometimes used ounce mass.  It is important to distinguish between mass and force even though the ounce unit is sometimes abused to ambiguously mean either in one Earth gravity environments.

ContentLicense: CC BY-SA 3.0

Title: Verifying motor selection calculations


问:
Drive motor voltage / other specifications of Roomba 650
I salvaged some parts off my dead Roomba 650, and I'm trying to use the drive motor assembly . I got the pinout of the connector but I don't know what voltage / PWM / other specifications are there for this motor.

I've attached the picture of the drive motor assembly.

Any help would be appreciated!

Thank you,
Pratik

Edit: The Image is here: Drive Motor Module

答:
FYI, iRobot has released the spec for the motor interface here:

http://www.irobot.com/~/media/MainSite/PDFs/About/STEM/Create/Create_2_Wheel_Hack.pdf


问:
Determine current roomba state / operating mode
Using the SCI messages, I would like to determine the current operating mode or state of a iRobot Roomba 780. Finally, I would like to detect and separate four states:

Cleaning

In docking station

Returning to docking station

Error (e.g. trapped on obstacle)

What is a fast and reliable way to detect those states using SCI data?

The Roomba SCI Sensor packets "Remote Control Command" and "Buttons" seem to return the currently called commands and not the currently executed ones.

答:
The manual you linked to is not for the Roomba 780. You'll want to reference the one on this page: http://www.irobot.com/create

You can tell if the robot is on the dock by checking the "Home Base" bit in the charging sources available packet (#34).

There is currently no way to know via the OI if Roomba is trying to find the dock.


问:
SLAM noob here, a few questions regarding EKF-SLAM
I've recently been learning about SLAM and have been attempting to implement EKF-SLAM in python. I've been using this great article as a guide. Some progress has been made, but I'm still confused by certain stages.

Firstly, does the inverse sensor model have to compute range and bearing, as opposed to cartesian coordinates? Why is this approach used?

Secondly, what format should my robot provide its heading in? Currently I just use a running offset from the origin angle (0), without wrapping it between 0 and 360. Turning right yields positive degrees, and left negative. I ask this as I assume the sensor model expects a certain format.

Thirdly, when computing the jacobians for adding new landmarks, (page 35) is Jz simply the absolute rotation of the robot (-540 degrees for example) plus the bearing the landmark was detected at?

And finally, what's the best approach for managing the huge covariance matrix? I'm currently thinking of a good way to 'expand' P when adding new landmarks.

Here's my current implementation: http://pastebin.com/r7wUMgY7

Any help would be much appreciated! Thanks.

答:
I've addressed your first two questions below.

Firstly, does the inverse sensor model have to compute range and bearing, as opposed to cartesian coordinates? Why is this approach used?

Given your current state (which includes the pose of the robot and the position of the landmarks), the inverse sensor model predicts what the observation should be. In other words, if you have a laser scanner that reports the range and bearing of the landmark from your current pose, you want to compare that observation with what the inverse sensor model predicts. The reason why it is not converted to Cartesian coordinates is because the noise of the laser scanner observation is in range and bearing. Usually you want your observation model to generate a prediction whose form is as close to what your physical sensor provides as possible.

Secondly, what format should my robot provide its heading in? Currently I just use a running offset from the origin angle (0), without wrapping it between 0 and 360. Turning right yields positive degrees, and left negative. I ask this as I assume the sensor model expects a certain format.

If the only place the heading is used is in cosines and sines, then it shouldn't matter. However, you need to be careful whenever you take the difference between two angles. For example 179 degrees minus -179 degrees gives 358 degrees. In reality, the difference is -2 degrees, (which is equivalent to 358 degrees if you know it must be wrapped), but an algorithm minimizing the error might think 358 degrees is a large error.

Also, the traditional 2D coordinate system has the angle being report with respect to the x-axis, with x forward, y left and z up. As a result, turning right should decrease the heading angle.


问:
Noise in motion and measurement models
When using an EKF for SLAM, I often see the motion and measurement models being described as having some noise term.

This makes sense to me if you're doing a simulation, where you need to add noise to a simulated measurement to make it stochastic.  But what about when using real robot data?  Is the noise already in the measurement and thus does not need to be added, or does the noise matrix mean something else?

For example, in Probabilistic Robotics (on page 319), there is a measurement model: $z_t^i = h(y,j) + Q_t$, where $Q_t$ is a noise covariance.  Does $Q_t$ need to be calculated when working with real data?

答:
When using the EKF (or standard KF) on a real robot, you will want to tell the filter how much noise there is in each measurement, and in the process.

The purpose of this is so that the Kalman filter can decide how much it "trusts" each source of data, and therefore, the weighting to give each measurement in its final estimation.

For real robot data, the noise is already in the measurement. I think when you say "noise matrix", you are referring to the covariance matrix. This is not the actual noise per se, but rather, the noise covariance matrix describes the magnitude of the noise (that can be expected by the Kalman Filter), and the correlation between different noise terms, for a normal distribution of noise. You will generally want as accurate a noise covariance as possible, however, it can simply be estimated. When working with real data, you can perform a quick experiment to estimate the noise covariance, or you can also estimate it by consulting datasheets, or select a somewhat sensible value. Where there is not much data available, the covariance will normally be a diagonal matrix (ie. no correlation). The diagonal elements of the covariance matrix is also referred to as the variance. That means that you are telling the Kalman filter what the variance of the different noise sources are (square of standard deviation of the noise).

If on the other hand, you are wondering why the models related to the Kalman Filter may have a noise term (as opposed to a noise covariance), they are only models, and those equations are not actually used in the algorithm. The equations used by the algorithm will have terms representing the noise covariance (not the actual noise - which is unknown), which it normally keeps an online estimate of.

Title: Noise in motion and measurement models


问:
EKF-SLAM, how best to manage the 'P' covariance matrix, programatically
I've recently been learning about SLAM and EKF-SLAM.

I've began my implementation in python, but have had trouble managing the updating of P, especially when it comes to adding new landmarks. Currently there is no 'P' but just a few separate matrices that I have to stitch together when needed.

My implementation can be seen here: http://pastebin.com/r7wUMgY7

How best should I manage the large covariance matrix, should I be using one matrix, like the algorithm suggests? Thanks in advance.

答:
You must use one matrix, because you must manage the cross covariances. The best way to add a landmark is to expand the matrix, by copying it into a larger one (with two extra rows for x,y and two extra columns for the same). Then, you have to initialize all the off-diagonal terms using the jacobian matrix.  Similarly, the state vector must be expanded to include the new landmark as well.

This answer shows how to initialize a new landmark in this way.  Note the matrix shown there is block represented. It could in fact be very large.

Now how you represent that matrix is up to you. However, keeping many small matrices that you stitch together is no more efficient (cpu or memory) than keeping one large one.


问:
EKF-SLAM Computing the jacobians for landmark updates
I've been working through this informative guide on EKF-SLAM but I'm having difficulty understanding the jacobians required for the 'landmark update', on page 35.

What exactly is Jxr and Jz taking as input? Is it taking the the current rotation of the robot, plus the addition of the odometry update? IE, the rotation that is now stored in the 'X' state vector. Or are they taking the angle from the Inverse Sensor Model, and if so, what's the 'delta' angle from?

Thanks.

答:
The answer

Specifically, the arguments to this jacobian are the state of the robot.

The reason

It is the jacobian of the measurement function with respect to the landmark state.

If you knew the state of the robot and landmark, what function would you use to predict what the measurement would be? If you have a range sensor, it would be the distance between the landmark and robot positions. Take the jacobian of this function, with respect to each of the state variables (robot x, robot y, robot theta, landmark x, landmark y)

In their first example, we're measuring the difference in x and y.

So the predicted position of the landmark equals the position of the robot plus the $x$ and $y$ difference (rotated a little by the robot rotations).

So the jacobian is $$\begin{bmatrix}
\frac{d h_1}{dx_r}, \frac{d h1}{dy_r}, \frac{d h1}{d\theta_r}\\
\frac{d h_2}{dx_r}, \frac{d h2}{dy_r}, \frac{d h2}{d\theta_r}\\
\end{bmatrix}$$

Here, $h1$ is the function which gives the $x$ coordinate of the landmark, and $h2$ is the function which gives the $y$ coordinate of the landmark.


问:
How to estimate yaw angle from tri-axis accelerometer and gyroscope
I would like to estimate the yaw angle from accelerometer and gyroscope data. For roll and pitch estimate I've used the following trigonometric equations:

```<code>roll  = atan2(Ax,Az)  * RAD_TO_DEG
pitch = atan2(Ay,Az)  * RAD_TO_DEG
</code>```

and a simpified version of the Kalman Filter to consider also angular rates. The roll and pitch estimates are accurate (accelerometer values need to be filtered in presence of chassis vibrations).

In order to get the Yaw angle I'm using the following equation:

```<code>yaw = atan2(Ax,Ay)  * RAD_TO_DEG;
</code>```

but the it doesn't work. Do you have any advice?

答: yaw can be measured by rate gyro and magnetometer not with accelerometer because accelerometer values depends on gravity component but on rotation in z axis only there is no change in gravity componets</p>


问:
How to find theta1 to theta5 after D-H parameter
```<code>Joint   θi    di    ai-1    αi-1
1     θ1-90  -d1     0      180
2      θ2     0      0      -90
3      θ3     0     a2       0
4     θ4-90   0     a3       0
5      θ5     0     0        90
</code>```

I am confused about the right way to look for my theta1-theta5.
Probably from the offset limit of the angles or calculation from x0 to x5 angle rotation or from atan2(x,y).

答: I am not sure if this answers properly your question, but in this case theta1-theta5 are supposedly your joint variables, i.e. they are the value read from the encoders of your robotic arm. The -90 placed on joint 1 and joint 4 are instead the offset between the encoder readout and the actual joint configuration.</p>


问:
Quadcopter Propeller size + Motor
i would like to build quad that uses bigger propellers like 15" . My question is what kind of motor shall i use ? Low or high KV? Do all motors support this kind of propellers ? Will they burn because of it ?I found they say CW and CCW motors does that mean you can't set way they spin ? I'm totally new in this so thank you for answer .

okey so given this one it should be able to hold 15" prob since it's in description
shall i get 12A ESC since on 15 size prob they used max 8.8 or shall i get 25A ESC cause max continous is 20 ?

答:
The Information you provide are a bit short.
This depends a lot on the power of the motors. See my answer on this question: Choosing motor for a tricopter

If you choose some a motor big enought for your application then it won't burn regardless of the prop size. If it is too small, it will burn regardless of the prop size ;)

Usually the motor manufactures provide you with a test sheet, something like this: http://www.funtobuyonline.com/media/wysiwyg/920_datas.jpg

Which is one for your motor. This might be japanese (not sure) but the columns are in this case from left to right:

Voltage,Prop Size, Power, Current, Power, Thrust, RPM, Efficency

If the Power at 100% exceed the motor specification then the motor will burn... pretty simple

Title: Quadcopter Propeller size + Motor


问:
Robotics with Kinect
I want to learn robotics and really interested in making a robot based on Kinect sensor.

I see so many projects like this one, and just wondering how it works on top level. I downloaded Kinect SDK and did some basic tutorials, but I just don't think that Microsoft SDK is the library to use for real robotics projects. Any suggestions where to start and what library to use? Any good books in particular or online resources?

答:
Evil Closet Monkey nicely itemized the possible Kinect libraries in his answer to another Kinect related question mentioning OpenKinect SDK and OpenNI SDK besides Windows SDK.

A good book on Kinect is Making Things See by Greg Borenstein from O'Reilly.

Title: Robotics with Kinect


问:
looking for a circular track and bearing with a spindle
I've really tried to find something online that's suitable but what I'm after is

I've two concentric circular rings, one of which has a diameter about 10mm smaller than the larger .

The rings themselves are in the region of 300mm diameter.

I'm trying to find a way to connect the two together and allow the smaller to 'slide' in a circular rotational way within the larger one.

I'm also trying to let the 2 rings pivot vertically in relation to each other - the intention being of producing a gyroscopic-esque motion.

What type of bearings/tracks/spindles would suffice?

答:
Been searching for the nearly exact same thing, probably have to build it myself...bearing-in-track was the only way to allow 3 concentric rings to rotate, spin, and tumble independently of each other.  My design had a "track" for the bearing to travel in also but an additional track on the outside of the inner ring, with a bearing on either side of the spindle. Got me?

Have found nothing of the sort in 12 years of looking.  Any help in this direction will get me exited all over.

bonkus


问:
How is it possible to maintain the total thrust when controlling yaw of a quadcopter?
I'm working on the control of a quadcopter and I'd like to understand how come controlling the yaw does not increase the overall thrust. My understanding is that the control is carried out through 2 PIDs per axis (roll, pitch and yaw). The output of the last PID is sent as a PWM signal to correct the rotor speeds of the propellers. The mixing looks something like that:

$T_{FrontLeft} = thrust + roll_{pid} + pitch_{pid} + yaw_{pid}$
$T_{FrontRight} = thrust - roll_{pid} + pitch_{pid} - yaw_{pid}$
$T_{RearLeft} = thrust + roll_{pid} - pitch_{pid} - yaw_{pid}$
$T_{RearRight} = thrust - roll_{pid} - pitch_{pid} + yaw_{pid}$

All the quadcopter controls seem to work that way from what I could gather. So the basic idea to control yaw is to add $yaw_{pid}$ to the clockwise motors and substract the same amount $yaw_{pid}$ to the counterclockwise motors to make the quadcopter turns clockwise. Which translates into a increase of speed of clockwise motors and a decrease of speed for counterclockwise motors from the same amount.

But we know that each motor produces thrust and torque according to those equations:

$T = C_T\rho n^2 D^4$

$Q = C_Q\rho n^2 D^5$

where $T$ is thrust, $Q$ is torque, $C_T$ and $C_Q$ are system dependent constants, $ρ$ is the air density, $n$ is rotor speed, and $D$ is rotor diameter. Which means that the thrust produced by each motor is proportional to the propeller speed squared.

So if $n$ is the speed of all propellers before correction, the thrust of the clockwise propellers after correction will be proportional to $(n+\Delta)^2$ and the thrust produced by the counterclockwise propellers to $(n-\Delta)^2$. The total thrust for these 2 propellers will be proportional to:

$(n+\Delta)^2 + (n-\Delta)^2 = 2n^2 + 2\Delta^2$

As you can see, there is an increase of $2\Delta^2$ in the overall thrust produced by those 2 propellers (and $4\Delta^2$ when we take the 4 propellers into account). Of course, in real life, when we control the yaw the quadcopter does not go up.

So what am I missing?

(the same stands for roll and pitch control but since the quadcopter turns around the roll or pitch axis, the total thrust is no longer entirely on the vertical axis and I could imagine that the projection on the vertical axis is not increasing, but that does not work with yaw)

答:
You are correct that theoretically total thrust can not be maintained. However, about hover, it can be assumed that the torque is small and that total thrust can be maintained.

In control, we are usually interested in linear systems. We have more tools and knowledge for dealing with linear systems. In most cases when we are dealing with a nonlinear system we linearize the system around some operating point with the assumption that it will adequately describe the system around that operating point.

In this case, people have linearized the nonlinear equations that describe the quadrotor dynamics. These equations drop the $2\Delta^2n$ term.


问:
How do I work out the kinematic solution of a robot arm?
I draw a robotic arm in Solidworks, but I'm not so sure about how to find out the DOF, forward and backward kinematic.

Could anyone help me understand how to work out the kinematic solution of this robot arm?

答:
This is a huge field you are asking for. I don't know what exactly you are looking for and what is your background. But, initially, I would suggest you first to go through basics. Read some stuff related to Robotics kinematics and representations from DH Parameters, Forward Kinematics and Inverse Kinematics. You define your problem based on that reading and decide what you need to use.
And by the way, your drawing and labeling does not suffice the proper representation. Please check it first.! </p>


答: I don't know about the Robot which you have. But for your α1, try using 0 instead of 180. I think, two parallel Z axis confuses us, but taking 0 for parallel  rotation axes will make difference in values (in case of COS θ).</p>

Title: How to find theta1 to theta5 after D-H parameter

Body:
```<code>Joint   θi    di    ai-1    αi-1
1     θ1-90  -d1     0      180
2      θ2     0      0      -90
3      θ3     0     a2       0
4     θ4-90   0     a3       0
5      θ5     0     0        90
</code>```

I am confused about the right way to look for my theta1-theta5.
Probably from the offset limit of the angles or calculation from x0 to x5 angle rotation or from atan2(x,y).


问:
How important are events like "Robocup" to the advancement of Robotics in general?
Are events like Robocup advantageous to the development of robotic  advancement?

Or is it merely entertainment which advances robotics by allowing entry level participation which helps maintain interest?

Do the DARPA Grand's provide a better vehicle for advancement? (pun intended)

答:
Robotics is a relatively new field of study. Besides technological problems, there are psychological and even moral issues that need to be resolved.

Some examples of these non-technological issues include familiarity with and fear of robots, trusting robots and robot rights.  Other issues have to do with popularity. You may be interested in reading this similar question asking whether toy robots move technology forwards. Many of the arguments there hold for any kind of activity including robots. With that in mind, let's focus on the technological aspects only.

With contests for simpler robots, such as Robocup, generally the effect is that the popularity of robotics increases. With more people getting drawn to robotics, the technology is sure to move forwards. In other words, popularity brings advancements, which is true for most if not all scientific fields.

The more complex challenges, like the DARPA challenge surely help advance the technology. However, they are more of a short-term solution than a long-term one. With the DARPA challenge, you attract expert roboticists to create a solution for a complex problem. That's good, but that's just it. With Robocup, you create interest in robotics among many young students. You don't really get anything out of it immediately, but you get a new generation of roboticists that each would go on the rest of their lives inventing new things.

While both kinds of challenges are definitely beneficial, I would say the ones like Robocup have a better shot at advancing robotics towards its goals (pun responded). Imagine if only one type of challenge existed. If there were DARPA challenges only, robotics would advance greatly, but eventually roboticists would die out and there would be no one to pick up where they left. If there were Robocup challenges only, you don't make an instant improvement, but you will have a continuous supply of fresh minds entering the field.

In conclusion, DARPA challenges provide instant solutions, while Robocup contests provide a sustainable source of inventors.


问:
Simulate IMU (2D gyro and accelerometer) data
If I have a robot path in 2D space,

i.e. a vector of (x,y) locations, and I need to generate artificial IMU data (simulate them), how would I go about it?

How do I model equations to generate the values given a time frame and positions?

I've come across imusim I'd like to know how to model them and generate using Matlab or something similar.

答:
This is really simple. First of all, you need to understand how the sensor works. In other words, you need understand whether the measurements is coming from linear or nonlinear model. Second, what is the type of the sensor's noise?

CASE STUDY:
Let's say you want to simulate DC Voltemeter to measure a battery's voltage of 5 Volt. In an ideal case, the model of the system is

$$
V_{b}(k+1) = V_{b}(k)
$$
It is just a constant value whether you measure it now or in the future, the value is 5 Volt. In the reality, this is not the case. If you measure it now, you might get 4.9 Volt, later on 5.1 Volt. The measurements vary which means the sensor is noisy. In many cases, the noise is Gaussian with zero mean and some variance (i.e. $\mathcal{N}(0, \sigma^{2}))$. Therefore, the measurement model is

$$
Z(k+1) =  V_{b}(k+1) + \delta
$$

where $\delta$ is the measurement noise (i.e. $\mathcal{N}(0, \sigma^{2})$).

To simulate this scenario in Matlab,

```<code>clear all; clc;
ideal_value = 5;
sigma = 0.01;
real_value = ideal_value + sigma*randn(5,1)
</code>```

The output is then

```<code>real_value =
    5.0009
    5.0173
    4.9939
    4.9926
    4.9825
</code>```

In reality, there is no way to know the ideal value. If you want to decrease the accuracy of your sensor, you need to increase the value of the $\sigma$. In 2D laser scenario, the input of the sensor is the Cartesian location ($x, y$) and the output is the polar coordinates ($r, \phi$) with some Gaussian noise. Let's say we have a 2D laser sensor that is located in the origin and we have a tree in planar environment. The sensor with update rate 10 Hz provides the range $r$ and the bearing $\phi$ to the tree with some noise in both the range and the bearing.  Therefore the following code simulates the scenario

```<code>clear all
clc

tree_x = 4;
tree_y = 4;

sigma_r = 0.1; % m
sigma_p = deg2rad(1); % rad

dt = 1/10;

t = 0:dt:0.5;
for i = 1:numel(t)
    r(i) = sqrt( tree_x^2 + tree_y^2 ) + sigma_r*randn();
    p(i) = atan2( tree_y, tree_x ) + sigma_p*randn();
end
r
rad2deg(p)
</code>```

The results are

```<code>r =
    5.7598    5.7581    5.6356    5.5525    5.6130    5.7552
p =
   44.6549   45.6293   44.1343   44.7299   44.5913   44.7023
</code>```

Body:
This is really simple. First of all, you need to understand how the sensor works. In other words, you need understand whether the measurements is coming from linear or nonlinear model. Second, what is the type of the sensor's noise?

CASE STUDY:
Let's say you want to simulate DC Voltemeter to measure a battery's voltage of 5 Volt. In an ideal case, the model of the system is

$$
V_{b}(k+1) = V_{b}(k)
$$
It is just a constant value whether you measure it now or in the future, the value is 5 Volt. In the reality, this is not the case. If you measure it now, you might get 4.9 Volt, later on 5.1 Volt. The measurements vary which means the sensor is noisy. In many cases, the noise is Gaussian with zero mean and some variance (i.e. $\mathcal{N}(0, \sigma^{2}))$. Therefore, the measurement model is

$$
Z(k+1) =  V_{b}(k+1) + \delta
$$

where $\delta$ is the measurement noise (i.e. $\mathcal{N}(0, \sigma^{2})$).

To simulate this scenario in Matlab,

clear all; clc;
ideal_value = 5;
sigma = 0.01;
real_value = ideal_value + sigma*randn(5,1)

The output is then

real_value =
    5.0009
    5.0173
    4.9939
    4.9926
    4.9825

In reality, there is no way to know the ideal value. If you want to decrease the accuracy of your sensor, you need to increase the value of the $\sigma$. In 2D laser scenario, the input of the sensor is the Cartesian location ($x, y$) and the output is the polar coordinates ($r, \phi$) with some Gaussian noise. Let's say we have a 2D laser sensor that is located in the origin and we have a tree in planar environment. The sensor with update rate 10 Hz provides the range $r$ and the bearing $\phi$ to the tree with some noise in both the range and the bearing.  Therefore the following code simulates the scenario

clear all
clc

tree_x = 4;
tree_y = 4;

sigma_r = 0.1; % m
sigma_p = deg2rad(1); % rad

dt = 1/10;

t = 0:dt:0.5;
for i = 1:numel(t)
    r(i) = sqrt( tree_x^2 + tree_y^2 ) + sigma_r*randn();
    p(i) = atan2( tree_y, tree_x ) + sigma_p*randn();
end
r
rad2deg(p)

The results are

r =
    5.7598    5.7581    5.6356    5.5525    5.6130    5.7552
p =
   44.6549   45.6293   44.1343   44.7299   44.5913   44.7023

ContentLicense: CC BY-SA 4.0


问:
Power issues involving Raspberry Pi
I have a Raspberry Pi (Model B) attached to a Roomba. I'm using this part to bring the unregulated 17V+ power of the Roomba down the 5V/1A of the Pi. The problem is that the Pi will randomly reboot and cause peripherals (such as the bluetooth adapter) to freak out and not work. We can sometimes drive it around for a little while before it reboots, other times it happens almost immediately.</p>

答:
The Raspberry Pi B, and in particular the Raspberry Pi B2 are fairly sensitive to having enough current to meet their peek power needs. For most of my apps, I have been using a 1.5A supply, and that has been more than sufficient for the Raspberry Pi B+, however when I started trying to use the Raspberry Pi B2 I needed a peak of 3A to be able to not have it "brown out" and reboot.

I would recommend upping your available power, and see if it makes a difference.

Title: Power issues involving Raspberry Pi


问:
joint positions of a robot
I would likte to find the joints positions using joint angles, link lengths etc.

How can I define the position of the each joint using DH parameters?

答:
Please see some of the many other similar questions on this site.  For example:

jacobian of Abb irb140 robot

Finding inverse kinematics algorithm for a specific manipulator

Forward Kinematics/D-H parameters for perpendicular joint axes

Title: joint positions of a robot


问:
How to send commands to create 2 over Bluetooth
I'm very new to create 2. I want to send commands using Bluetooth. I have already bought the bluetooth USB radio. What other devices do I need to get or how can I set up sending commands over bluetooth. Any help is appreciated.
Thanks.</p>

答: Once you pair your computer's Bluetooth with the dongle on the robot, it should create a virtual serial port.  Then you can talk to the Roomba over this port.  Try out the tethered driving tutorial, except your tether is wireless.</p>


问:
Can I use ROS with a Roomba?
Is there anything different between a iRobot Roomba and the Create?  I want go start building my own turtlebot and playing with ROS but with the cost of all the parts I'm going to have to do it piece by piece.  It's pretty easy to find cheap used Roombas.  </p>

答:
Can you use a Roomba with ROS? Absolutely.

Can you use a Roomba with the existing turtlebot code? Most likely but it may depend on model of the Roomba since older models have a slightly different API. Of course even if there are API differences that haven't been accounted for it should not be too difficult to adjust the code to handle them.

Title: Can I use ROS with a Roomba?


问:
how to implement tracking problem with PID controller
I'm trying to implement the tracking problem for this example using PID controller. The dynamic equation is

$$
I  \ddot{\theta} + d \dot{\theta} + mgL \sin(\theta) = u
$$

where

$\theta$ : joint variable.

$u$ : joint torque

$m$ : mass.

$L$ : distance between centre mass and joint.

$d$ : viscous friction coefficient

$I$ : inertia seen at the rotation axis.

$\textbf{Regulation Problem:}$

In this problem, the desired angle $\theta_{d}$ is constant and $\theta(t)$ $\rightarrow \theta_{d}$ and $\dot{\theta}(t)$ $\rightarrow 0$ as $t$ $\rightarrow \infty$. For PID controller, the input $u$ is determined as follows

$$
u = K_{p} (\theta_{d} - \theta(t)) + K_{d}( \underbrace{0}_{\dot{\theta}_{d}} -  \dot{\theta}(t) ) + \int^{t}_{0} (\theta_{d} - \theta(\tau)) d\tau
$$

The result is

and this is my code  main.m

```<code>clear all
clc

global error;
error = 0;

t = 0:0.1:5;

x0 = [0; 0];

[t, x] = ode45('ODESolver', t, x0);

e = x(:,1) - (pi/2); % Error theta

plot(t, e, 'r', 'LineWidth', 2);
title('Regulation Problem','Interpreter','LaTex');
xlabel('time (sec)');
ylabel('$\theta_{d} - \theta(t)$', 'Interpreter','LaTex');
grid on
</code>```

and ODESolver.m is

```<code>function dx = ODESolver(t, x)

global error; % for PID controller

dx = zeros(2,1);

%Parameters:
m = 0.5;       % mass (Kg)
d = 0.0023e-6; % viscous friction coefficient
L = 1;         % arm length (m)
I = 1/3*m*L^2; % inertia seen at the rotation axis. (Kg.m^2)
g = 9.81;      % acceleration due to gravity m/s^2

% PID tuning
Kp = 5;
Kd = 1.9;
Ki = 0.02;

% u: joint torque
u = Kp*(pi/2 - x(1)) + Kd*(-x(2)) + Ki*error;
error = error + (pi/2 - x(1));

dx(1) = x(2);
dx(2) = 1/I*(u - d*x(2) - m*g*L*sin(x(1)));

end
</code>```

$\textbf{Tracking Problem:}$

Now I would like to implement the tracking problem in which the desired angle $\theta_{d}$ is not constant (i.e. $\theta_{d}(t)$); therefore, $\theta(t)$ $\rightarrow \theta_{d}(t)$ and $\dot{\theta}(t)$ $\rightarrow \dot{\theta}_{d}(t)$ as $t$ $\rightarrow \infty$. The input is

$$
u = K_{p} (\theta_{d} - \theta(t)) + K_{d}( \dot{\theta}_{d}(t) -  \dot{\theta}(t) ) + \int^{t}_{0} (\theta_{d}(t) - \theta(\tau)) d\tau
$$

Now I have two problems namely to compute $\dot{\theta}_{d}(t)$ sufficiently and how to read from txt file since the step size of ode45 is not fixed. For the first problem, if I use the naive approach which is

$$
\dot{f}(x) = \frac{f(x+h)-f(x)}{h}
$$

the error is getting bigger if the step size is not small enough. The second problem is that the desired trajectory is stored in txt file which means I have to read the data with fixed step size but I'v read about ode45 which its step size is not fixed. Any suggestions!

Edit:

For tracking problem, this is my code

main.m

```<code>clear all
clc

global error theta_d dt;
error = 0;

theta_d = load('trajectory.txt');

i    = 1;
t(i) = 0;
dt   = 0.1;
numel(theta_d)
while ( i < numel(theta_d) )
   i = i + 1;
   t(i) = t(i-1) + dt;
end

x0 = [0; 0];
options= odeset('Reltol',dt,'Stats','on');
[t, x] = ode45(@ODESolver, t, x0, options);

 e = x(:,1) - theta_d; % Error theta

plot(t, x(:,2), 'r', 'LineWidth', 2);
title('Tracking Problem','Interpreter','LaTex');
xlabel('time (sec)');
ylabel('$\dot{\theta}(t)$', 'Interpreter','LaTex');
grid on
</code>```

ODESolver.m

```<code>function dx = ODESolver(t, x)

persistent i theta_dPrev

if isempty(i)
    i = 1;
    theta_dPrev = 0;
end

global error theta_d dt ;

dx = zeros(2,1);

%Parameters:
m = 0.5;       % mass (Kg)
d = 0.0023e-6; % viscous friction coefficient
L = 1;         % arm length (m)
I = 1/3*m*L^2; % inertia seen at the rotation axis. (Kg.m^2)
g = 9.81;      % acceleration due to gravity m/s^2

% PID tuning
Kp = 35.5;
Kd = 12.9;
Ki = 1.5;

if ( i == 49 )
    i = 48;
end
% theta_d first derivative
theta_dDot  = ( theta_d(i) - theta_dPrev ) / dt;
theta_dPrev = theta_d(i);

% u: joint torque
u = Kp*(theta_d(i) - x(1)) + Kd*( theta_dDot - x(2)) + Ki*error;
error = error + (theta_dDot - x(1));

dx(1) = x(2);
dx(2) = 1/I*(u - d*x(2) - m*g*L*sin(x(1)));

i = i + 1;
end
</code>```

trajectory's code is

```<code>clear all
clc

a = 0:0.1:(3*pi)/2;

file = fopen('trajectory.txt','w');

for i = 1:length(a)
    fprintf(file,'%4f \n',a(i));
end

fclose(file);
</code>```

The result of the velocity is

Is this correct approach to solve the tracking problem?

答:
I think that just PID is not a good approach to solve a tracking problem. </p>

<p>It is better to use nonlinear control method that are suitable for that task like "Exact feedforward linearization based on differential flatness". You can get an overview in the open access paper: https://hal.archives-ouvertes.fr/hal-00431712 and references therein. </p>

Body:
I think that just PID is not a good approach to solve a tracking problem.

It is better to use nonlinear control method that are suitable for that task like "Exact feedforward linearization based on differential flatness". You can get an overview in the open access paper: https://hal.archives-ouvertes.fr/hal-00431712 and references therein.


问:
where can I get openinterface.py?
I am trying to program the create2 irobot using python. there is a script called openinterface.py. where can I download this script?</p>

答:
It looks like openinterface.py itself is not easily found anymore, but you can probably use instead pyrobot, which is based on openinterface.py. Pyrobot is an interface for Roomba and Create 1, not Create 2, but it should be easy to adapt it to work with the Create 2. The default baud rate needs to be changed from 57600 to 115200, and there are a few functions/sensors that are different between Create 1 and Create 2. The differences are listed on the last page of the Create 2 Open Interface Specification.

Apart from pyrobot, there are several Python wrappers for the Create 1 that you could look into, namely Brian Bingham's Pici, Rose-Hulman Institute of Technology's pyCreate, and Brown's pyCreate (in brown-ros-pkg).

Update: I have since modified the PyRobot code to work with the Create 2, and made it available for download under the name PyRobot 2. This is part of a project called MICbots using mobile robots for audio data collection.

Title: where can I get openinterface.py?


问:
Glasses with eye sensors
Someone could tell me if there are wearable devices such as glasses, with sensors that can detect eye movement?

In particular, I would need a device like google glass, having a sensor or a camera that is facing the eye, and it can capture the movement, possibly interfaced with a mobile device.

Alternatively, are there micro-cameras on the market, which can be connected via Bluetooth or USB to a mobile device?

答: These devices are called gaze trackers. There are open source libraries for using webcams and out of the box solutions available. Google has many more options. Cheers!</p>

Title: Glasses with eye sensors


答:
The robot you have modeled is a RR:R robot (3 rotational joints) with a sliding base from what I can understand. It is not clear if it has a spherical wrist.

The kinematic solution to such a robot can be given by first splitting the problem in to two parts. One to solve the kinematics for the 3 rotational joints and then computing the axial shift of the end effector axis in accordance with the shift of the base reference coordinates.

You can solve the forward kinematics using the Denavit Hartenberg parameter calculation and subsequently calculate the inverse kinematics for your RRR robot.

The forward kinematic transformation matrix for your RRR robot will only contain the three joint theta angles and the three link lengths. Apply this to calculate joint positions w.r.t the base frame using the transformation matrix for each of the joints to achieve the total transformation matrix for the robot.

I will try post the solution to this soon, but you can look it up in the Robot Modeling and Control by Spong and VIdyasagar (page 68) : http://www.fit.hcmup.edu.vn/~hungnv/teaching/Robotics/0471649902_-_Robot_Modeling_and_Control.pdf

I find its the best place to learn to apply forward and inverse kinematic solutions for an anthropomorphic robot arm.

Title: How do I work out the kinematic solution of a robot arm?

Body:
I draw a robotic arm in Solidworks, but I'm not so sure about how to find out the DOF, forward and backward kinematic.

Could anyone help me understand how to work out the kinematic solution of this robot arm?


答:
Essentially when applying the DH parameter method to compute Forward Kinematics for a robot arm(assuming that it is anthropomorphic robot arm kinematics you are interested in), you are to set reference frames at each joint such that the z axis coincides with the axis of rotation of the joint.

The next step is to find the DH values for the joints w.r.t the base reference frame, i.e the link lengths(L1,L2 etc, also represented frequently as 'a'), the theta angles (of rotation at the joints),d (joint offset distances), and "alpha" angles (joint offset angles).

You can find those values by inspecting the frames of the robot once you assign them.

Then input those DH parameter values in a transformation matrix that relates the frame of reference to the previous frame of reference, i.e. for Joint 1, it will be T(1 to 0), for Joint 2 T(2 to 1) etc.

The then final step is to premultiply the transformation matrices
T(n to 0) = T(1 to 0)* T(2 to 1) * T(3 to 2)...* T(n to n-1) to compute the Total Transformation matrix(T (n to 0) that relates the end effector(nth frame of reference) to the base reference frame. That is your Forward Kinematic solution for the robot arm.

A good reference textbook would be Robot Modeling and Control by Spong, Vidyasagar. Look for chapter on Forward Kinematics. See link for the book chapter : http://www.fit.hcmup.edu.vn/~hungnv/teaching/Robotics/0471649902_-_Robot_Modeling_and_Control.pdf

If you can be more specific about the type of robot you are trying to compute kinematics for, I can be more specific with my answer. Hope this helps.

Title: joint positions of a robot

Body:
I would likte to find the joints positions using joint angles, link lengths etc.

How can I define the position of the each joint using DH parameters?


答:
I think you might need two "lazy susans" in the channel.  Shown in green in this image.  And then the rider in the channel does not have to be round.  In fact it is probably best to rigidly attach to one side of the lazy susan.  Now you can put a simple shaft and bearing in the inside ring.

One more note, if the load is not great, and you don't care about cantilevering the lazy susan, you can get away with only one lazy susan on one side.

Title: looking for a circular track and bearing with a spindle

Body:
I've really tried to find something online that's suitable but what I'm after is

I've two concentric circular rings, one of which has a diameter about 10mm smaller than the larger .

The rings themselves are in the region of 300mm diameter.

I'm trying to find a way to connect the two together and allow the smaller to 'slide' in a circular rotational way within the larger one.

I'm also trying to let the 2 rings pivot vertically in relation to each other - the intention being of producing a gyroscopic-esque motion.

What type of bearings/tracks/spindles would suffice?


答:
If you want to solve it mathematically (not within the SolidWorks), the DOF is the number of independent variables needed to define the configuration of the mechanism. Since you've planar motion in three joints (rotations about one axis) in addition to the slide this will make the DOF is 4 in this case.
Because your problem is in one plan (Planar robot), you can solve the forward kinematics, by direct projection of the components in the two directions, horizontal and vertical, using the trigonometric functions sin and cosine as we do in the basic physics, and adding the parameter d (for example) for the horizontal component with proper sign to act for the slider movement. As for the backward (inverse) kinematics which will need more investigation, you can also try to solve it algebraically, based on some geometric basics taking the advantage of the simplicity ; in that case you'll take the pose (position and orientation) of the end effector (the tip point), and solve for the three angles, and the slide (d), with some math manipulation you can figure out this. This I'm describing the shortcut to workout your problem. However, if you've more time, and will do more work on kinematics, you can follow one the two approaches:

The product of exponential method ( which I prefer) you can refer to it in the: A Mathematical Introduction to Robotic Manipulation, by Murray

Or you can use the DH convention, the widely used method. The inverse kinematics is a large topic in the robotic literature, you can find a lot about around. However, if you looking to that in the SolidWrok, this is another issue.


问:
Help to dimension the right controller for the following Tranfer Function
I have a generic problem to create a controller for the following system:
$$\ddot{x}(t) = a y(t)$$
where $a$ is a constant real value.
The system could be seen as an equivalent of a mass-spring-damper system, where damper and spring are removed. Also $x(t)$ is the $x$ dimension and $y$ is simply the force moving the mass. BUT in this case I need to drive the force using $x(t)$ and not the contrary.

Transforming according Laplace I get:
$$ y(t) = \frac{1}{a}\ddot{x}(t)$$
$$ Y(s) = \frac{1}{a}s^{2}X(s)$$
$$ G(s) = \frac{Y(s)}{X(s)} = \frac{s^{2}}{a}$$

Considering that $a = 1$ I implemented a possible example in Simulink.

Please not that I put the output given by the scope for showing up the resulting answer of the system.

So I have 2 questions:

Is it possible to develop such a system? As far as I know the degree of the numerator should be $=<$ the degree of the denominator. So is the above system possible?

Is it possible to create a PID or PD controller to stabilize the output of the system?

Regards

答:
Nope, the system is not feasible since the causality principle states that the degree of the denominator of the transfer function must be greater or equal to the degree of the numerator, as you have correctly pointed out. The system analysis, indeed, does always proceed in terms of integral blocks (i.e. $1/s$) and not derivatives. In this respect, what is the system you have in mind? Are you 100% sure that you caught all its implications?

Even assuming the double derivatives as a purely ideal system to stabilize - only in simulation -, a PID is unable to cope with the task. Imagine we are at equilibrium, then the system output $y$ is equal to the input $r \neq 0$ and the error $e=r-y$ before the PID is thus zero. However, a constant output means that upstream to the double derivatives we must have a signal $u$ varying as $t^2$. The signal $u$ is also the PID output, while the PID input is $e=0$, as said. You must have then a double integrator in the PID. But this is only a theoretical speculation.


问:
How to make a robot move using Arduino other than timing to predefined locations?
How to make a robot move using Arduino other than timing to predefined locations? and without the use of sensors?? I want to make my car move to different locations on a board..want to know the possible options without using sensors and encoders??
And how does cartesian robot work for predefined locations..does it require sensor too?</p>

答:
Cartesians Robot use sensors. All robot need sensors. Sometime they are external (camera looking at the robot), sometime they are on the robot (IMU).

Basically what you're asking is :

How can an animal without any way to sense the world move from an exact point to another ?

Well, it can't.

Why do you wish not to use sensors ? There are very cheap ones out there that could help you with your project. You just need to define this project a little better so you can find the sensor that works for you.

Btw, going to predefined location without sensor like encoders, is not really feasible either. Or a pain. You'll need to calculate an approximate speed from the voltage (and, as someone pointed out, knowing the voltage would need a sensor) you input in the motor and, trust me, it's not going to be very accurate. The drift is going to kill you.


答:
As far as I can see, what you have there is just a system where you're inputting a scaled acceleration.

$$
\begin{bmatrix}
\dot{x}(t)\\
\ddot{x}(t)
\end{bmatrix} = \begin{bmatrix}0 & 1\\ 0 & 0\end{bmatrix}\begin{bmatrix}x(t)\\\dot{x}(t)\end{bmatrix} + \begin{bmatrix}0\\a\end{bmatrix}y(t)
$$
$$
\dot{x} = Ax + By
$$
In classical state space representation. The controllability matrix has full rank, so the system is controllable. That is we need to design some matrix K such that:

$$
\dot{x} = (A-BK)x
$$

is stable. For a continuous time system, this means that $(A-BK)$ must have negative real parts on its eigenvalues. Now if:

$$
K = \begin{bmatrix}k_1 & k_2 \end{bmatrix}
$$

then

$$
(A-BK) = \begin{bmatrix}0 & 1\\ -ak_1 & -ak_2\end{bmatrix}
$$

with eigenvalues

$$
\lambda_1 = \frac{-ak_2 - \sqrt{a^2k_2^2 - 4ak_1}}{2}
$$
$$
\lambda_2 = \frac{-ak_2 + \sqrt{a^2k_2^2 - 4ak_1}}{2}
$$

Here $k_1$ is the P value and $k_2$ is the D value in a PD controller that uses $x(t)$ as the "driving force". For any given nonzero $a$, they can be be chosen to stabilize the system w.r.t $x$. Note also that: 1) if $k_2=0$ we can't stabilize the system and 2) at any point in time $y(t) = -ak_1x(t) -ak_2\dot{x}(t)$. As $y(t)$ depends on $x(t)$ and $\dot{x}(t)$, both of which go to zero, $y(t)$ goes to zero. Did I understand your question correctly?

Title: Help to dimension the right controller for the following Tranfer Function

Body:
I have a generic problem to create a controller for the following system:
$$\ddot{x}(t) = a y(t)$$
where $a$ is a constant real value.
The system could be seen as an equivalent of a mass-spring-damper system, where damper and spring are removed. Also $x(t)$ is the $x$ dimension and $y$ is simply the force moving the mass. BUT in this case I need to drive the force using $x(t)$ and not the contrary.

Transforming according Laplace I get:
$$ y(t) = \frac{1}{a}\ddot{x}(t)$$
$$ Y(s) = \frac{1}{a}s^{2}X(s)$$
$$ G(s) = \frac{Y(s)}{X(s)} = \frac{s^{2}}{a}$$

Considering that $a = 1$ I implemented a possible example in Simulink.

Please not that I put the output given by the scope for showing up the resulting answer of the system.

So I have 2 questions:

Is it possible to develop such a system? As far as I know the degree of the numerator should be $=<$ the degree of the denominator. So is the above system possible?

Is it possible to create a PID or PD controller to stabilize the output of the system?

Regards


问:
Low power to motors -- motor power jumper issue
I'm currently working on my first robotics project using the Initio kit from 4tronix powered by Raspberry Pi. The setup was fairly simple, and I've been testing it out over the last couple of days. All of the sensors work as expected; however, my motor tests are failing. When I input commands to actually move the robot, I can hear the DC motors running but they're not getting enough power to do anything. In the instructions, it says if this issue is encountered, that the power selection jumper might not be set correctly and provides this diagram:

For comparison, here's how I have the wiring for the motors setup:

I'm not entirely sure what it means to have the power selection jumper being set incorrectly and would greatly appreciate it if someone could explain this to me or point out if they see anything wrong with my setup.

答: I had exactly the same problem ; I contacted 4tronix and they said "Use Energiser or Eneloop recharcheable batteries" (I was using Duracells) I did as they said and it worked fine. Mind you I am still not sure what initio.py actually does ....</p>


问:
How to calculate Euler Angles from gyroscope output?
I am using a tri-axis accelerometer and tri-axis gyroscope to measure the linear acceleration of a body. I need to get the orientation of the body in euler form in order to rotate the accelerometer readings from the body frame into the earth frame. Please help I'm so stuck</p>

答:
Look into a complementary filter. It isn't the correct way to go out this but it will give you usable data for attitudes around level. It's also worth mentioning that you will not be able to track yaw. There is no way to account for bias/noise with the two sensors you've listed.

complementary filter:
http://www.pieter-jan.com/node/11


问:
Using a Bitmap maze image to navigate the maze
I'm working on an robot that would be able to navigate through a maze, avoid obstacles and  identify some of the objects in it. I have a monochromatic bitmap of the maze, that is supposed to be used in the robot navigation.

I am just a first year electrical engineering student, and so need help on how I can use the bmp image. I will be making my robot using the Arduino mega microcontroller.

So how should I get started on it.

If you need me to elaborate on anything kindly say so.

Link: http://ceme.nust.edu.pk/nerc/files/theme_ind_2015.pdf

答:
It sounds like what you have is an occupancy grid, which you could simply convert to a 2D array of booleans in memory. Your challenge will be to figure out what grid square you are in at any given time, and (when you are very confident about your location) mark down additional map obstacles as "occupied" on your map.

One way to figure out where you are over time is to use a particle filter, and one way to find a path across an occupancy grid is to use the A* search.


问:
Any image transfer protocol for wireless serial transfer?
I want to send image over wireless serial communication. I am planning to capture images using either raspberry pi or stm32 mcu using DCMI and then transfer image using wireless serial communication module such as Xbee or 3DR radio which can provide air data rate upto 250Kbps at baud rate of 115200

I would like to know if there is any protocol which can send a jpeg compressed image as a wireless serial data.

答:
If you need realtime imagery, you should look at the many analog cameras and transmitters on the market.  The FPV folks use them all the time and have really worked them out.

Obviously you'll have to deal with analog noise and conversion to digital on the other end, but it is the only thing that will give you any real range (0.5km at least) and realtime performance.

Here's one I use: http://www.readymaderc.com/store/index.php?main_page=product_info&products_id=266


问:
using range-only sensors for mapping in SLAM
SLAM noob here but trying to implement an algorithm that fuses odometry data and mapping based on wifi signal strengths for a 2D robot.

1)
After various readings of different resources,
I came across this - http://www.qucosa.de/fileadmin/data/qucosa/documents/8644/Dissertation_Niko_Suenderhauf.pdf
that explained what sensors are used in mapping and how they are categorized.

There are range-bearing sensors (stereo cameras,RGB-d cameras) that provide both distance and angle (range and bearing), from which is easy to locate (x,y) coordinates of landmarks ---> I can develop a map.

But in case I'm using wifi signal strengths (Received signal strengths) etc, in which case it is range-only (meaning, I can only establish from a robot pose(x,y,theta) as to how far this signal is coming from), how am I developing a map at all?

My question is similar to this - What algorithm can I use for constructing a map of an explored area using a number of ultrasound sensors? but not quite same.

Even if I were using IMU/GPS, how am I using GPS to develop a map? What is my state space there? If I am getting GPS signals / wifi signals/ radio signals, am I estimating the transmitter/AP's location as the map? or the walls of a room I'm navigating in, as a map?

A lot of SLAM literature talks about motion model and measurement model, the former gives me the pose of the robot quite easily because of the odometry and imu.

The latter though is more for development of a map. Am I right in understanding this? If yes, say
a] I have walls in a room and I'm using Lidar scanner -
this still gives me the location of the wall using the number of beams that give me bearing, and the average distance from all the beams.

b] Or if I have just a single laser scanner, I can still use a camera (distance) and the heading of the robot to calculate the location of wall (the map). https://shaneormonde.wordpress.com/2014/01/25/webcam-laser-rangefinder/#more-403

But If I have wireless signal strengths, I have a distance (distance of the transmitter from which I'm getting the RSS, not the distance of the wall) as to where they are coming from. But how am I estimating the location of walls here?

2) What does the term "correspondences" mean in SLAM literature?

答:
SLAM is so huge topic with a lot of challenging problems. For beginners, I don't really recommend you to read papers. The authors of academic papers assume you know not only the  basics in the field but they assume you know the problem that they handle. What you really need is a book that covers the problem in a complete manner, therefore this book is the way to go with. Read the book and do some simulation in Matlab. It answers your questions. The book is really big however you need only to focus on the basics (i.e. focus on EKF-SLAM for the time being).

Chapter 1, 2, 3 ( math prerequisites )

Chapter 5,6 ( motion and measurement models  )

Chapter 7 ( Localization problem )

Chapter 10 ( SLAM problem )

Once you are done with these chapters, you should do some simulations and read some academic papers regarding EKF-SLAM. Once you reach this level, you are able to know your path.


答:
The system could be seen as an equivalent of a mass-spring-damper
  system, where damper and spring are removed

This is correct if you assume $x(t)$ to be the output but you are not.

y is simply the force moving the mass.

If $y$ is the force, this means it is the input of the system?!

BUT in this case I need to
  drive the force using x(t) and not the contrary

This is impossible. What  you are saying makes no sense.

This is not a dynamic system and your simulink diagram is not correct. Your actual system is an amplifier of the second derivative of a given signal. You have the output as a function of time (i.e. $y(t)$), therefore there is no point of applying transfer function tool. The input of this system is the second derivative of a given signal, thus if the input is the step function which means $x(t) = 1, t \geq 0 $, its second derivative is zero. If you set the input as $x(t) = sin(t)$ and $a=0.5$, the output is

and this is the matlab script for the above picture.

```<code>clear all; clc;

dt = 0.0001;
t = -pi:0.01:2*pi;

x = sin(t); % the input
% plot(t, x, 'b')

dx = diff(x)./diff(t); % the first derivative of the input
% hold on
% plot(t(2:end), dx, 'r')

ddx = diff(dx)./diff(t(2:end)); % the second derivative of the input
% hold on
plot(t(3:end), ddx, 'b')

a = 0.5;

% output
y = 1/a * ddx;
hold on
plot(t(3:end), y, 'r')

l= legend(['$\ddot{x}(t)$'], 'y(t)');
set(l,'Interpreter','Latex');
</code>```

Body:
The system could be seen as an equivalent of a mass-spring-damper
  system, where damper and spring are removed

This is correct if you assume $x(t)$ to be the output but you are not.

y is simply the force moving the mass.

If $y$ is the force, this means it is the input of the system?!

BUT in this case I need to
  drive the force using x(t) and not the contrary

This is impossible. What  you are saying makes no sense.

This is not a dynamic system and your simulink diagram is not correct. Your actual system is an amplifier of the second derivative of a given signal. You have the output as a function of time (i.e. $y(t)$), therefore there is no point of applying transfer function tool. The input of this system is the second derivative of a given signal, thus if the input is the step function which means $x(t) = 1, t \geq 0 $, its second derivative is zero. If you set the input as $x(t) = sin(t)$ and $a=0.5$, the output is

and this is the matlab script for the above picture.

clear all; clc;

dt = 0.0001;
t = -pi:0.01:2*pi;

x = sin(t); % the input
% plot(t, x, 'b')

dx = diff(x)./diff(t); % the first derivative of the input
% hold on
% plot(t(2:end), dx, 'r')

ddx = diff(dx)./diff(t(2:end)); % the second derivative of the input
% hold on
plot(t(3:end), ddx, 'b')

a = 0.5;

% output
y = 1/a * ddx;
hold on
plot(t(3:end), y, 'r')

l= legend(['$\ddot{x}(t)$'], 'y(t)');
set(l,'Interpreter','Latex');


问:
Square with hinge on all four sides
I want to make a component that will be a square plate that will behave like it has a motorized hinge on all four sides. That is, it can "open" by pivoting around any one of its four sides. I want it to pivot by up to 45 degrees. </p>

<p>I thought about designing it so that 3 hinges could be detached while one pivots, but I wonder if there's a simpler way to do this. </p>

答:
You could try having four lids on top of each other.

The top lid solid and hinged to the lid below.

The second lid a hollow frame hinged to the lid below 90$^{\circ}$ offset

The third lid a hollow frame hinged to the lid below 90$^{\circ}$ offset

The fourth lid a hollow frame hinged to the box 90$^{\circ}$ offset

Title: Square with hinge on all four sides


问:
Standalone (or capable of being) Robotics Simulator
I'm a software engineer who volunteers with a non-profit that introduces young girls to technology. We have recently been talking about methods of introducing these children to the world of robotics, and I am curious what types of low-cost options we have.

One very appealing idea would be to have an online simulator, or (more preferable) an off-line standalone-simulator that we can build and program simple robots with. Perhaps nothing more than dragging components together, and then programming the interactions between those components.

What solution(s) exist that I might be able to make use of in our outreach?

答:
Stage and Gazebo are open source 2D and 3D simulators respectively. They are created and maintained by the Player project. They are very easy to use and have a lot of pre-built maps and robots. Depending on the experience of your audience you may need to do a bit of the heavy lifting (i.e. building configuration files and the main classes).

They have a couple of additional benefits as well. First, so long as you create your main control code as player plug-ins then they can be easily adapted to real robots. Second, there are a large number of plug-ins already built to work with real hardware. Third, they work with ROS.


问:
How do I work out the kinematic solution of a robot arm?
I draw a robotic arm in Solidworks, but I'm not so sure about how to find out the DOF, forward and backward kinematic.

Could anyone help me understand how to work out the kinematic solution of this robot arm?

答:
You should first learn about forward and reverse kinematics

There is a really good pdf on this here

https://www.google.co.uk/url?sa=t&source=web&rct=j&ei=Z2EmVe36BZXnapTAgIgD&url=http://www.cs.cmu.edu/~./15464-s13/lectures/lecture6/IK.pdf&ved=0CDwQFjAH&usg=AFQjCNFvIj48gbaCsqiCgD9c9g6uPibNMA

It requires you to know the fundamentals of vectors and matrices.

You should also know how to calculate the jacobian etc

I would start by reading this before you attempt any design/programming


答:
For people just starting out with robot kinematics, I highly suggest using one of these powerful libraries and not doing the math yourself.

OpenRave

ROS MoveIt!

Matlab Robotics Toolkit

Orocos

These libraries typically let you specify the dimensions and joint configuration of your robot in something more intuitive than DH parameters.  (Translations and rotations in XML for example).  They can quickly and easily give you forward and inverse kinematics solutions.

But once you get something up and running.  I then recommend doing some reading on the theory behind all this.  (Other answers listed some good books).  Things will make more sense, and you will be able to do more advanced things.


问:
What middle-ware do you recommend for a swarm of AUVs?
Working with a swarm of robots, collaboration between the nodes is really important(either for the goal of simulation or real-word operation). Middle-wares are the frameworks for this special purpose. I know some of the relevant middle-wares like ROS(general-purpose but popular) or uMVS(that is basically design for AUVs). Now, I have two questions:

Do you know any other choice for the above mentioned purpose?

What criteria should I consider for choosing a middle-ware suitable for my purpose?

Thank you.

答: I don't know if their software can extend to AUVs, but the Rice University Multi-Robot Systems Lab has done very advanced things with robot swarms.</p>


答:
Microsoft robotics is FREE and includes a simulator. It is not exactly the easiest environment in the world, however it IS robust and appropriate to real robotics.  I think with some teacher involvement to set things up beforehand, it could be usable. There is a simulator 'package' for LEGO, Neato and some other robots, and they can be programmed in C# or a visual drag and drop language.

Again, I think it would need some work up front to make it easy for youngsters to use, but it wouldn't be that hard, and would be my approach given your requirements. I would say as far as complexity goes, this (windows) vs. a Linux environment with Gazebo/ROS, the windows environment would be slightly less complicated, although most of that would hopefully be hidden with preparation work.

Title: Standalone (or capable of being) Robotics Simulator

Body:
I'm a software engineer who volunteers with a non-profit that introduces young girls to technology. We have recently been talking about methods of introducing these children to the world of robotics, and I am curious what types of low-cost options we have.

One very appealing idea would be to have an online simulator, or (more preferable) an off-line standalone-simulator that we can build and program simple robots with. Perhaps nothing more than dragging components together, and then programming the interactions between those components.

What solution(s) exist that I might be able to make use of in our outreach?


问:
Enable Bluetooth Adapter for BeagleBone Black
I recently bought a USB 2.0 Bluetooth Adapter. It claims to have support from Linux kernels of versions 3.4 and higher. I have a BeagleBone Black with Debian GNU/Linux 7 image and kernel 3.8. I am developing on BeagleBone Black by hosting it through USB with ssh.

I have tried both hot plugging and  plugging in before boot and failed.

Then, I tried this tutorial. However, I cannot find the connman directory on my BeagleBone Black device. I looked up and assumed I needed to install the connman package, but my BeagleBone Black has no internet access.

I have also tried lsusb -v, as suggested by an answer of a similar question to this, with no luck. The weird thing is, while lsusb itself prints

Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

  Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

lsusb -v only prints

Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

then hangs. Information regarding bus 002, which I believe the device is connected to, is not printed. I have to restart the ssh connection to get back to work.

How should I approach to get the dongle to work on my BeagleBone Black? If the connman package is sufficient, how do I install it on my BeagleBone Black without internet access. Why does lsusb -v hang?

Any help is appreciated!

答: You could try this tutorial, you will need internet to download some packages. http://www.instructables.com/id/Wireless-Arduino-Control-Using-the-BeagleBone-Blac/step2/Configuring-the-BBB-or-RPi-for-Bluetooth-Operation/</p>


答:
The actual problem turned out to be that my BeagleBone Black is flawed/damaged. I plugged the Bluetooth Adapter into a plain new BeagleBone Black before powering it, and the Bluetooth Adapter is recognized! Not only does lsusb prints out the adapter info, but also lsusb -v does not hang at all. The overall performance of the new board (boot time, compilation time, execution time) is also several times better. I suspect that it was due to the various improper power-off.

In case anyone is just as careless, the BeagleBone Black SHALL be powered off by:

Holding down the power button for about 8 seconds then releasing it.

Using halt or shutdown -h now command in the Userspace.

Title: Enable Bluetooth Adapter for BeagleBone Black

Body:
I recently bought a USB 2.0 Bluetooth Adapter. It claims to have support from Linux kernels of versions 3.4 and higher. I have a BeagleBone Black with Debian GNU/Linux 7 image and kernel 3.8. I am developing on BeagleBone Black by hosting it through USB with ssh.

I have tried both hot plugging and  plugging in before boot and failed.

Then, I tried this tutorial. However, I cannot find the connman directory on my BeagleBone Black device. I looked up and assumed I needed to install the connman package, but my BeagleBone Black has no internet access.

I have also tried lsusb -v, as suggested by an answer of a similar question to this, with no luck. The weird thing is, while lsusb itself prints

Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

  Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

lsusb -v only prints

Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

then hangs. Information regarding bus 002, which I believe the device is connected to, is not printed. I have to restart the ssh connection to get back to work.

How should I approach to get the dongle to work on my BeagleBone Black? If the connman package is sufficient, how do I install it on my BeagleBone Black without internet access. Why does lsusb -v hang?

Any help is appreciated!


答:
I basically did an application using a very similar, if not identical, robot of this type for my Masters Thesis.   I don't know if it will be of any assistance however here is the link.

http://repository.lib.ncsu.edu/ir/bitstream/1840.16/1331/2/etd.pdf


问:
My PID Controller in Java is not operating correctly
I was looking for an implementation of a PID controller in Java and I found this one:

https://code.google.com/p/frcteam443/source/browse/trunk/2010_Post_Season/Geisebot/src/freelancelibj/PIDController.java?r=17

So, for what I could understand about it I am using it this way:

```<code>package lol.feedback;

public class dsfdsf {

    public static void main(String[] args) throws InterruptedException {
        final PIDController pidController = new PIDController(1, 1, 1);
        pidController.setInputRange(0, 200); // The input limits
        pidController.setOutputRange(50, 100); // The output limits
        pidController.setSetpoint(120); // My target value (PID should minimize the error between the input and this value)
        pidController.enable();
        double input = 0;
        double output = 0;
        while (true) {
            input = output + 30;
            pidController.getInput(input);
            output = pidController.performPID();
            System.out.println("Input: " + input + " | Output: " + output + " | Error: " + pidController.getError());

            Thread.sleep(1000);
        }
    }

}
</code>```

But he never stabilizes. He doesn't behave like a PID at all... This is the output I get:

```<code>Input: 30.0 | Output: 100.0 | Error: 90.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
</code>```

Can someone help me tell me what I am missing?

Thank you!

答: If a PID loop isn't properly "tuned" then it can result in oscillatory behavior similar to what you are seeing after the first few initial iterations. What I would try first is to change the input value only once (ie pull it out of the while loop) and then see what you get. Doing this would basically be applying what is called a Step input to your system to see how it responds. Since the input does not change after the initial "step", the resulting output over time allows you to easily determine if your tuning is damped, critically damped, or overdamped. </p>


答:
You have a few problems that I see.  The biggest problem is that your values for P, I, and D and too aggressive.  This is making the PID loop oscillate from hard stop to hard stop.

You generally want to take a cautious approach to tuning a PID loop.  Since PID control is feedback based, it is pretty easy to get a positive feedback loop which makes the system diverge.  My preferred approach to tuning is to start with tuning P leaving I and D at 0.0.  With the way your system is defined, a P value of 1.0 will try to remove all the error in a single time step.  I would start with a lower P value and increase it until the system responds quickly without much overshoot.  You might start with 0.1 and increase in small steps until you find something reasonable.  Note, that using the P value alone, you will always have some residual error.

After tuning the P value, I would move onto the I value.  The purpose of the I value is to reduce steady state error.  It does this by responding to the accumulation of error over time.  If the steady state error is acceptable, it is possible to not use the I term at all.  Because it is integrating the error over time, it is more powerful than the P value and you will need a smaller constant.  You might start with a value of 0.01 and try increasing it from there.  You should be able to remove the steady state error with just P and I.  Increasing the value of I will add momentum to your system and will tend to increase overshoot.  The implementation you are using calculates the integral error with a simple integration, so the value of I you need will depend on your update rate for an actual physical system.

After tuning P and I, then I would move onto D.  The purpose of the D term is to reduce overshoot.  It does this by predicting future reduction in error based on estimating the derivative of the error.  The derivative of the error can be a noisy estimate on some systems, so keep that in mind if you use D.  The value you need for D will depend on the values you are using for P and I.  The implementation you are using calculates the D term based on a simple difference, so the constant you need will also depend on your integration rate for an actual physical system.  Using some D might allow you to be more aggressive with your usage of P and I.

You have some other problems as well.  Your output range is pretty tight around the desired output.  Ideally your input would be 120 which implies your ideal output would be 90.  The value 90 is near the edge of your allowed output range of [50,100].  This is going to make it a bit more difficult on the PID controller.

The implementation you are using has a bug in the integral error integration.  Integral error has a problem that it can accumulate without bound over time in some situations.  This integral windup can cause very unintuitive outputs from PID systems.  For this reason, all practical PID systems limit the magnitude of the integral error.  The calculation used in the implementation only really works for outputs near 0 I think.

The implementation has:

```<code>/* Integrate the errors as long as the upcoming integrator does
   not exceed the minimum and maximum output thresholds */
if (((m_totalError + m_error) * m_I < m_maximumOutput) &&
    ((m_totalError + m_error) * m_I > m_minimumOutput)) {
    m_totalError += m_error;
}
</code>```

but I think this should be:

```<code>/* Integrate the errors as long as the upcoming integrator does
   not exceed the minimum and maximum output thresholds */
/* What the output would be if integral error is updated */
double outputWithI = (m_P * m_error + m_I * (m_totalError + m_error) + m_D * (m_error - m_prevError));
if ((outputWithI < m_maximumOutput) &&
    (outputWithI > m_minimumOutput)) {
    m_totalError += m_error;
}
</code>```

The problem with the original implementation is that if the integral term alone doesn't get the output into the correct range then the error isn't integrated.

A common alternative approach is to directly limit the magnitude of m_totalError and therefore the total contribution of the I term.  An implementation along these lines might look something like:

```<code>m_totalError += m_error;
if (m_totalError < -m_maxTotalErrorMagnitude) {
    m_totalError = -m_maxTotalErrorMagnitude;
} else if (m_totalError > m_maxTotalErrorMagnitude) {
    m_totalError = m_maxTotalErrorMagnitude;
}
</code>```

I'm more used to seeing this solution used, although I think either should work.

Title: My PID Controller in Java is not operating correctly

Body:
I was looking for an implementation of a PID controller in Java and I found this one:

https://code.google.com/p/frcteam443/source/browse/trunk/2010_Post_Season/Geisebot/src/freelancelibj/PIDController.java?r=17

So, for what I could understand about it I am using it this way:

```<code>package lol.feedback;

public class dsfdsf {

    public static void main(String[] args) throws InterruptedException {
        final PIDController pidController = new PIDController(1, 1, 1);
        pidController.setInputRange(0, 200); // The input limits
        pidController.setOutputRange(50, 100); // The output limits
        pidController.setSetpoint(120); // My target value (PID should minimize the error between the input and this value)
        pidController.enable();
        double input = 0;
        double output = 0;
        while (true) {
            input = output + 30;
            pidController.getInput(input);
            output = pidController.performPID();
            System.out.println("Input: " + input + " | Output: " + output + " | Error: " + pidController.getError());

            Thread.sleep(1000);
        }
    }

}
</code>```

But he never stabilizes. He doesn't behave like a PID at all... This is the output I get:

```<code>Input: 30.0 | Output: 100.0 | Error: 90.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
Input: 80.0 | Output: 100.0 | Error: 40.0
Input: 130.0 | Output: 50.0 | Error: -10.0
</code>```

Can someone help me tell me what I am missing?

Thank you!

Body:
You have a few problems that I see.  The biggest problem is that your values for P, I, and D and too aggressive.  This is making the PID loop oscillate from hard stop to hard stop.

You generally want to take a cautious approach to tuning a PID loop.  Since PID control is feedback based, it is pretty easy to get a positive feedback loop which makes the system diverge.  My preferred approach to tuning is to start with tuning P leaving I and D at 0.0.  With the way your system is defined, a P value of 1.0 will try to remove all the error in a single time step.  I would start with a lower P value and increase it until the system responds quickly without much overshoot.  You might start with 0.1 and increase in small steps until you find something reasonable.  Note, that using the P value alone, you will always have some residual error.

After tuning the P value, I would move onto the I value.  The purpose of the I value is to reduce steady state error.  It does this by responding to the accumulation of error over time.  If the steady state error is acceptable, it is possible to not use the I term at all.  Because it is integrating the error over time, it is more powerful than the P value and you will need a smaller constant.  You might start with a value of 0.01 and try increasing it from there.  You should be able to remove the steady state error with just P and I.  Increasing the value of I will add momentum to your system and will tend to increase overshoot.  The implementation you are using calculates the integral error with a simple integration, so the value of I you need will depend on your update rate for an actual physical system.

After tuning P and I, then I would move onto D.  The purpose of the D term is to reduce overshoot.  It does this by predicting future reduction in error based on estimating the derivative of the error.  The derivative of the error can be a noisy estimate on some systems, so keep that in mind if you use D.  The value you need for D will depend on the values you are using for P and I.  The implementation you are using calculates the D term based on a simple difference, so the constant you need will also depend on your integration rate for an actual physical system.  Using some D might allow you to be more aggressive with your usage of P and I.

You have some other problems as well.  Your output range is pretty tight around the desired output.  Ideally your input would be 120 which implies your ideal output would be 90.  The value 90 is near the edge of your allowed output range of [50,100].  This is going to make it a bit more difficult on the PID controller.

The implementation you are using has a bug in the integral error integration.  Integral error has a problem that it can accumulate without bound over time in some situations.  This integral windup can cause very unintuitive outputs from PID systems.  For this reason, all practical PID systems limit the magnitude of the integral error.  The calculation used in the implementation only really works for outputs near 0 I think.

The implementation has:

/* Integrate the errors as long as the upcoming integrator does
   not exceed the minimum and maximum output thresholds */
if (((m_totalError + m_error) * m_I < m_maximumOutput) &&
    ((m_totalError + m_error) * m_I > m_minimumOutput)) {
    m_totalError += m_error;
}

but I think this should be:

/* Integrate the errors as long as the upcoming integrator does
   not exceed the minimum and maximum output thresholds */
/* What the output would be if integral error is updated */
double outputWithI = (m_P * m_error + m_I * (m_totalError + m_error) + m_D * (m_error - m_prevError));
if ((outputWithI < m_maximumOutput) &&
    (outputWithI > m_minimumOutput)) {
    m_totalError += m_error;
}

The problem with the original implementation is that if the integral term alone doesn't get the output into the correct range then the error isn't integrated.

A common alternative approach is to directly limit the magnitude of m_totalError and therefore the total contribution of the I term.  An implementation along these lines might look something like:

m_totalError += m_error;
if (m_totalError < -m_maxTotalErrorMagnitude) {
    m_totalError = -m_maxTotalErrorMagnitude;
} else if (m_totalError > m_maxTotalErrorMagnitude) {
    m_totalError = m_maxTotalErrorMagnitude;
}

I'm more used to seeing this solution used, although I think either should work.