问:
Poor accuracy of hand eye calibration when using vanilla Tsai's method
I’m working on the hand eye calibration for the robotic arm. I attached the camera near the tip of the robot (or end effector) and took around 40 pictures of an asymmetric circles pattern. I implemented the basic hand-eye calibration code (at the bottom) based on the papers such as this (http://people.csail.mit.edu/tieu/stuff/Tsai.pdf). I referred the similar questions such as Hand Eye Calibration or Hand Eye Calibration Solver. The implementation is almost same as this (http://lazax.com/www.cs.columbia.edu/~laza/html/Stewart/matlab/handEye.m).

When I ran my code, I noticed that the quality of the result was very bad, especially in the rotation matrix. I calculated the quality based on R squared or the coefficient of determination. R2 for the rotation matrix after the least square regression was always around 0.2~0.3 (regarding the translation vector, R2 was around 0.6).

When I compared the returned homogeneous matrix from the ground truth (which I measured and calculated carefully by hand), they are very different as shown below. The rotation around z axis should be around -90 degrees, but the output was around a half.:

The output from the code

Homogeneous matrix:

[[  0.6628663   0.74871869  0.02212943   44.34775423]
[  -0.74841069   0.66234872  0.02672996  -21.83390692]
[  0.00534759   -0.0342871   0.99939772  39.74953567]
[  0.           0.           0.           1.        ]]

Rotation radian (rz, ry, rx):

(-0.8461431892931816, -0.005347615473812833, -0.03429431203996466)

Ground truth

Homogeneous matrix:

[[ -0.01881762   0.9997821   -0.00903642 -70.90496041]
[ -0.99782701  -0.01820849   0.06332229 -19.55120885]
[  0.06314395   0.01020836   0.99795222  60.04617152]
[  0.           0.           0.           1.        ]]

Rotation radian (rz, ry, rx):

(-1.5896526911533568, -0.06318598618916291, 0.01022895059953901)

My questions are

Is it common to get the poor result from the vanilla Tsai’s method?

If yes, how can I improve the result?

If no, where did I make a mistake?

Here is the code I used:

```<code>import numpy as np
from transforms3d.axangles import mat2axangle, axangle2mat
def find_hand_to_camera_transform(list_of_cHo, list_of_bHe):
"""
:param list_of_cHo: List of homogeneous matrices from Camera frame to Object frame(calibration pattern such as chessboard or asymmetric circles)
:param list_of_bHe: List of homogeneous matrices from robot's Base frame to End effector (hand) frame
:return: eHc: Homogeneous matrix from End effector frame to Camera frame
Notation:
- H: 4x4 homogeneous matrix
- R: 3x3 rotation matrix
- T: 3x1 translation matrix (vector)
- P: Axis vector for Axis-Angle representation
- TH: Angle (theta) for Axis-Angle representation
"""

# Calculate rotational component
lhs = []
rhs = []
for i in range(num_of_poses):
    bRei = extract_rotation(list_of_bHe[i])
    ciRo = extract_rotation(list_of_cHo[i])
    for j in range(i + 1, num_of_poses):  # We don't to use two times same couples
        bRej = extract_rotation(list_of_bHe[j])
        cjRo = extract_rotation(list_of_cHo[j])
        eiRej = np.dot(bRei.T, bRej)  # Rotation from i to j
        ciRcj = np.dot(ciRo, cjRo.T)  # Rotation from i to j
        eiPej, eiTHej = mat2axangle(eiRej)  # Note: mat2axangle returns with normalization (norm = 1.0)
        ciPcj, ciTHcj = mat2axangle(ciRcj)
        lhs.append(find_skew_matrix(eiPej + ciPcj))
        rhs.append(ciPcj - eiPej)

lhs = np.array(lhs)
lhs = lhs.reshape(lhs.shape[0] * 3, 3)
rhs = np.array(rhs)
rhs = rhs.reshape(rhs.shape[0] * 3)
cPe_, res, _, _ = np.linalg.lstsq(lhs, rhs)
r2_rot = 1 - res / (rhs.size * rhs.var())

cTHe = 2 * np.arctan(np.linalg.norm(cPe_))
cPe = 2 * cPe_ / np.sqrt(1 + np.dot(cPe_.reshape(3), cPe_.reshape(3)))
cPe = cPe / np.linalg.norm(cPe)
cRe = axangle2mat(cPe, cTHe, is_normalized=True)
eRc = cRe.T

# Calculate translational component
lhs = []
rhs = []
for i in range(num_of_poses):
    bRei = extract_rotation(list_of_bHe[i])
    bTei = extract_translation(list_of_bHe[i])
    ciTo = extract_translation(list_of_cHo[i])
    for j in range(i + 1, num_of_poses):  # We don't to use two times same couples
        bRej = extract_rotation(list_of_bHe[j])
        bTej = extract_translation(list_of_bHe[j])
        cjTo = extract_translation(list_of_cHo[j])
        eiRej = np.dot(bRei.T, bRej)
        eiTej = np.dot(bRei.T, bTei - bTej)
        lhs.append(eiRej - np.eye(3))
        rhs.append(np.dot(eRc, ciTo) - np.dot(np.dot(eiRej, eRc), cjTo) + eiTej)

lhs = np.array(lhs)
lhs = lhs.reshape(lhs.shape[0] * 3, 3)
rhs = np.array(rhs)
rhs = rhs.reshape(rhs.shape[0] * 3)
eTc, res, _, _ = np.linalg.lstsq(lhs, rhs)
r2_trans = 1 - res / (rhs.size * rhs.var())

eHc = np.eye(4)
eHc[:3, :3] = eRc
eHc[0:3, 3] = eTc
return eHc
</code>```

答:
The most likely issues are too much noise, inaccurate camera calibration, not ensuring everything has settled when you take each data point, your camera and robot not being fixed rigidly enough, or your transforms being transposed or otherwise inconsistent.

A detailed overview of pitfalls and how to improve your results can be found at https://github.com/jhu-lcsr/handeye_calib_camodocal. Many of the instructions there apply to any method of solving for hand eye calibration and I've been updating the document and code every time someone encounters a new problem over the last two years, so at this point it should be pretty good.


问:
Calculating J3 rotation relative to J2?
From any robot spec sheet:

I am assuming that the range of motion given for the J3 or 'U' axis is specified as a function of the position of the lower or J2 axis. Correct?

How do I find the absolute range of motion of J2 from the spec sheet? That is, what is the maximum positive and negative value that J3 can rotate? Because if I were to rotate using the range given for J2 then the arm would collide with the base.

答:
I think from the spec sheet, it means that at some configurations, J3 could actually reach +255$^\circ$. For example, when J2 = -100$^\circ$, J3 may be able to reach that maximum of 255$^\circ$.

In other words, the range of J3, for example, depends on a specific value of J2. To find out the exact range of J3 given a specific value of J2, you may need a 3D model of the robot.

ContentLicense: CC BY-SA 3.0

Title: Calculating J3 rotation relative to J2?


问:
How to setup CLion for ROS?
How can I setup the C++ IDE CLion to display documentation and auto completion correctly when working with ROS?</p>

答:
Start CLion from a commandline with your sourced ROS workspace (i.e. after calling source devel/setup.bash)

Open a project's CMakeLists.txt, and tell it to open it as a project rather than as a file.

That's it, you've got your workspace integrated :)

Debugging:

Debugging built files (nodes which you run through rosrun) is easy, you just normally run them in the IDE

Debugging launch files is more complicated, as they cannot be launched by the IDE. You can launch the launch file from command-line, then find the PID of the node you want to debug, and connect the IDE debugger to it ("Run -> Attach to local process"). Of course this is difficult to use for capturing initialization bugs.

Debugging nodes that are shell scripts or scripts in unsupported languages is impossible.

There are several more steps you could do to deepen the integration:

Set the CMake Generation path in "Build, ... -> CMake -> Generation Path" to your workspace's build directory, so that you can compile only once in the IDE and have the results available in console (otherwise, you'll have two different builds, one in IDE, and one in console). Unfortunately, until https://youtrack.jetbrains.com/issue/CPP-1887 is fixed, you cannot use any variables in the default generation path, so setting up the catkin layout requires some manual work.

To automatically source ROS when launching CLion, you can add the sourcing to ~/.xsessionrc. This might, however, have unexpected consequences. If you don't want to do that, use the following approach.

Create a desktop launcher that launches CLion from the system menu (Dash, launcher panel etc.) with correct environment (if you source ROS in your .bashrc): I edited the desktop file ~/.local/share/applications/jetbrains-clion.desktop to look like the following. You also have to make sure the file is not writable for your updater scripts/Jetbrains toolbox, otherwise they'll overwrite it with each update.

.

```<code>[Desktop Entry]
Version=1.0
Type=Application
Name=CLion
Icon=/home/peci1/bin/jetbrains/apps/CLion/.icon.svg
Exec=bash -i -c "/path/to/clion/bin/clion.sh" %f
Comment=A smart cross-platform IDE for C and C++
Categories=Development;IDE;
Terminal=false
StartupWMClass=jetbrains-clion
</code>```

If you're using Jetbrains toolbox to install CLion (which you should IMO), the path to the binary changes with every update (until https://youtrack.jetbrains.com/issue/ALL-653 is resolved), but you can use this trick to always launch the latest installed version:

Exec=bash -i -c "$(ls -td /path/to/jetbrains/apps/CLion/ch-0/*/ | head -n1)/bin/clion.sh" %f

Install the Python support plugin to be able to code in both C++ and Python from the single IDE.

Title: How to setup CLion for ROS?

Body:
Start CLion from a commandline with your sourced ROS workspace (i.e. after calling source devel/setup.bash)

Open a project's CMakeLists.txt, and tell it to open it as a project rather than as a file.

That's it, you've got your workspace integrated :)

Debugging:

Debugging built files (nodes which you run through rosrun) is easy, you just normally run them in the IDE

Debugging launch files is more complicated, as they cannot be launched by the IDE. You can launch the launch file from command-line, then find the PID of the node you want to debug, and connect the IDE debugger to it ("Run -> Attach to local process"). Of course this is difficult to use for capturing initialization bugs.

Debugging nodes that are shell scripts or scripts in unsupported languages is impossible.

There are several more steps you could do to deepen the integration:

Set the CMake Generation path in "Build, ... -> CMake -> Generation Path" to your workspace's build directory, so that you can compile only once in the IDE and have the results available in console (otherwise, you'll have two different builds, one in IDE, and one in console). Unfortunately, until https://youtrack.jetbrains.com/issue/CPP-1887 is fixed, you cannot use any variables in the default generation path, so setting up the catkin layout requires some manual work.

To automatically source ROS when launching CLion, you can add the sourcing to ~/.xsessionrc. This might, however, have unexpected consequences. If you don't want to do that, use the following approach.

Create a desktop launcher that launches CLion from the system menu (Dash, launcher panel etc.) with correct environment (if you source ROS in your .bashrc): I edited the desktop file ~/.local/share/applications/jetbrains-clion.desktop to look like the following. You also have to make sure the file is not writable for your updater scripts/Jetbrains toolbox, otherwise they'll overwrite it with each update.

.

[Desktop Entry]
Version=1.0
Type=Application
Name=CLion
Icon=/home/peci1/bin/jetbrains/apps/CLion/.icon.svg
Exec=bash -i -c "/path/to/clion/bin/clion.sh" %f
Comment=A smart cross-platform IDE for C and C++
Categories=Development;IDE;
Terminal=false
StartupWMClass=jetbrains-clion

If you're using Jetbrains toolbox to install CLion (which you should IMO), the path to the binary changes with every update (until https://youtrack.jetbrains.com/issue/ALL-653 is resolved), but you can use this trick to always launch the latest installed version:

Exec=bash -i -c "$(ls -td /path/to/jetbrains/apps/CLion/ch-0/*/ | head -n1)/bin/clion.sh" %f

Install the Python support plugin to be able to code in both C++ and Python from the single IDE.


问:
Extended Kalman Filter in robotics - Worth it?
I wonder if Extended Kalman Filter(EKF) is used in robotics, or is only Kalman Filter(KF) used in robotics.

Kalman Filter is included in Linear Quadratic Gaussian(LQG) controllers. But how would EKF work i practice?

I know how to build a Extended Kalman Filter just by linearizing the mathematical model in the estimated state vector.

What is your experience in EKF?

答:
The Kalman filter is an optimal linear filter in the presence of Gaussian noise. It is optimal in the sense that it minimizes the mean-squared error. This means that the covariance of the estimated states will be minimized:

$$
P = E\{(x_k - \hat{x}_{k|k})(x_k - \hat{x}_{k|k})^T\}.
$$

As this covariance is minimized, the goal of any kind of estimation filtering is accomplished -- the error between the true state $x_k$ and the estimated state $\hat{x}_{k|k}$ is driven to zero [1] [2].

The Extended Kalman filter is more or less a mathematical "hack" that allows you to apply these techniques to mildly nonlinear systems. I say "hack" because it is sub-optimal, i.e., it does not have any mathematical guarantees like the KF does. If you initialize the filter with poor conditions (i.e., the initial state), it will quickly diverge. If propagation and/or measurement updates happen at too great a timestep, it will quickly diverge. As you state in your question, you build an EKF by linearizing your system -- which implies that you loose information about your system and if you operate too far from your linearization point, the solution will be incorrect (like trying to fit a line to a quadratic).

There is another standard implementation of Kalman filters called the Unscented Kalman Filter (UKF). The UKF is ideal for grossly nonlinear systems because: (1) you don't have to do the math / computation to linearize, and (2) it intelligently chooses sigma points to propagate (instead of an entire model) that best represent the statistics of the system. The UKF kind of bridges "the best of both worlds" from Kalman filtering (which assumes a Gaussian noise and belief propagation) and nonlinear Particle filtering (which makes no assumption of the form of the belief propagation), another type of Bayes filter.

In my experience (3-wheeled ground robots, aerial robots), and EKF is a nice and computationally efficient way to estimate state and fuse information from multiple sensors (accel, gyro, airspeed, camera). Tuning can often be a pain, but the more intuition about your system and the noise of your sensors, the easier it becomes. Because of the EKF's efficiency, relative ease-of-implementation, and demonstrated effectiveness it is used widely in robotics.

For more information on applying an EKF to wheeled robots (or aircraft) I would direct you Dr. Randy Beard's notes on Robot Soccer and Rober Labbe's iPython Notebooks on Bayesian filters.

[1] R. W. Beard and T. W. McLain, Small Unmanned Aircraft. Princeton, New Jersey: Princeton University Press, 2012.

[2] R. Faragher, “Understanding the basis of the kalman filter via a simple and intuitive derivation [lecture notes],” IEEE Signal Process. Mag., vol. 29, no. 5, pp. 128–132, 2012.


问:
What is the best way to go about building a robot hand that can type on keyboard, move &click mouse, swipe touchscreens?
How would you go about building a robot that can use a computer? Type on the keyboard, move & click mouse? I am talking about physically manipulating the hardware inputs, and the robot would be able to see the screen. Not connected to anything. It's purely autonomous. My hope is that this will replace human QA testers.</p>

答:
Your question contains a bunch of questions which i would try to reveal in the first place:

Q: What kind of drive would i need to solve the task of typing keyboards, clicking a mouse etc.?

A: Basically this is answered by your requirements of motion which are force, velocity, range to name the most important. Every type of drive has its own privileges according these requirements, but you totally have an eye on costs and your control as well. For these kind of tasks i would suggest a pneumatic drive for example. But it could be a combination of different types as well, e.g. wrist - electrical drive, finger - pneumatics and so on.

Q: What kind of control would i need to control these motions?

A: For this you have to consider several aspects such as complexity, your chosen drive, energy consumption (mobile systems!!) and costs as well. Hardware would not be a problem since embedded systems nowadays are quite powerful and performant. But in your case your control would contain closed loops since you need a feedback on force to not destroy your touchpad and keyboard. Which is in general quite complex and difficult to solve in realtime. If we are speaking of recognition by images etc., then hallelujah..

Q: Which tools do i need?

A: First of all a your well trained brain :) But in general you would start to desing a simulation for your drives and control to be sure everything COULD work out fine. Then you would need tools for design and layout. These tools are quite expensive as you may have guessed already..

Q: Where to start?

A: Think in modules. Start with the very basic part and easily spoken integrate all parts to subsystems, all subsystems to a whole system. But don't forget to run tests /  simulations on every level! Every change afterwards will exploder your time (and cost) consumption exponential!


问:
PID Controller Output Mapping for Motor Speed Control
Hi, I want to control the speed of a conveyor belt. I can measure the linear velocity of the belt using a encoder mounted at the roller of the belt. My confusion is not with the PID but only the mapping of PID output to PWM for the motor.

The PID error is in terms of meter/seconds(m/s) of the conveyor belt. The P, I and, D parts are summed to give a control signal. The motor interprets 0 as 0 PWM and 16393 as 100% PWM. The range from 0 to 16393 is serially communicated to the motor. I want this to be from the PID.

My question is: How do I map the PID output based on error(m/s) to PWM for the motor.

Example: I am using just PI and ignoring D for now to avoid noise amplification issues.

The maximum speed of the belt is when 16393 is sent to it and the speed is 0.5 m/s. I set desired speed as 0.2 m/s,

At the start, error = 0.2 m/s
Lets say Kp = 4, Ki = 2.

output = Kp * error + Ki * sum_of_errors * sampling_time

I would get a PID output but it would be very small compared to 16393 needed for the 100 % PWM for the motor. I need 100 % PWM to power motor in the start and gradually decrease the PWM as the belts speed goes from 0 m/s to 0.2 m/s. How can I map this small PID output to 16393 need for the Motors 100 % PWM?

答:
Convert your PWM units to belt velocity units, or vice-versa.  The quick and dirty way of doing this is to multiply your P, I, and D terms by $16,393 \over 0.5$.  The PWM-to-belt velocity mapping won't be exactly linear, like this method assumes, but it will be close enough that your controller can squash any residual errors.

Caution:  since you are controlling the velocity of the belt, in which the speed of the conveyor is sure to lag behind the speed of your control input, you should consider setting your I gain to 0 until you are "close" to the desired speed.  Otherwise that windup will induce overshoot in your conveyor speed.


问:
Holonomics Movement vs Holonomics Constraint
I'm reading Mechanics of Robotic Manipulation by Matthew T Mason and I stumbled upon the concept of kinematic constraints. The book mentioned about two types of constraints: holonomic and nonholonomic constraints

Following is one example of a holonomic constraint mentioned in the book:

A rectangular block sliding in a channel with free variations in the coordinates x,y,and theta. The channel imposes a constraint so that the rectangle's y value is fixed. The holonomic constraint is described below:

While the following is an example of a nonholonomic constraint mentioned:

Suppose that we add a wheel to the block, so it behaves like a unicycle or an ice skate. At any given point in time, the block can move forward and backward, it can rotate about the wheel center, but it cannot move sideways. The nonholonomic constraint equation is described below as:

The author also wrote that:

".. it is evident that each independent holonomic constraint reduces
  the degrees of freedom of the system by one, but a nonholonomic
  constraint does not."

All of the explanations so far seem to contradict my understanding of the physical meaning of robotic holonomic movement:

I've always thought that a holonomic robot means that it can move in all directions and hence the total number of controllable degrees of freedom is equal to the total degrees of freedom. But how is that possible when every holonomic constraint reduces the degree of freedom of the system?

And how come doesn't a nonholonomic constraint reduce the degree of freedom of the system? Isn't the unicycle constraining the block from moving sideways? Why is the degree of freedom of the system not considered as reduced then?

I hope someone can help to clarify my understanding.

答:
You can look at degrees of freedom as if they were the number of variables that you need to use to describe your system. So, for a robot moving in a 2D plane, its state would be represented by:
$$
s=\begin{bmatrix}
   x  \\
   y \\
   \theta \\
\end{bmatrix}
$$

For a robot moving in a 2D plane to be holonomic, it must have the ability to change any state variable at any given time, no matter the value that the other variables have at the moment.

So, for instance, this means that in order to be holonomic, the robot must be able to change its $Y$ variable to any value it wants without altering $X$ and $\theta$. In the example you give for a non-holonomic constraint, while it is possible for the robot to reach any $X$, $Y$ and $\theta$ values, it has a limit on the number of paths that it must take (one such impossible path would be to move sideways!).

Generally speaking, in order to be holonomic, the number of degrees of fredoom must be the same as the number of differentiable degrees of freedom:
$$DOF=DDOF$$

DOFs define the possibility of reaching various configurations, e.g. position ($X$ and $Y$) and orientation ($\theta$)

DDOFs define the number of independently admissible velocities, e.g. linear velocity ($\dot{X}$ and $\dot{Y}$) and angular velocity ($\dot{\theta}$).

Holonomic restrictions limit the number of DOFs. For instance, your wheeled robot cannot fly, hence $Z$ (height) does not belong in the state.

Non-holonomic restrictions limit the ability to change the derivative of the state at will, hence they reduce the number of DDOFs. For instance, you cannot have your unicycle rotating (constant $\dot{\theta}$) while only moving in the $X$ direction.

Interestingly enough, a lighthouse is holonomic!

Everything that is stationary is holonomic because it has 0 DOFs and 0 DDOFs!

So, in a nutshell:

1) DOFs = number of variables in the state

2) DDOFs = velocities that can be changed independently

3) Holonomic restrictions reduce DOFs

4) Non-holonomic restrictions reduce DDOFs

5) A robot is holonomic if, and only if, DOFs=DDOFs

ContentLicense: CC BY-SA 4.0


问:
How can we estimate the likelihood field for a particular scan in probabilistic terms?

I am trying to implement a scan matcher using Scan based sensor model but I cant figure out how to estimate likelihood for a particular scan. Is there any implementation available ? Would be thankful for help

答:
It looks like ROS has a few packages (in rough order of apparent usefulness):

Scan matcher

laser scan matcher

Local map

crsm-slam

mrpt-localization

amcl


问:
How would i implement position and heading readings into my SLAM system?
I am trying to build a low-cost SLAM system with an MPU-6050 and GY-271 (magnetometer). Currently, i have a robot with an Arduino that collects the sensor data and a Raspberry Pi that (hopefully) will do the SLAM calculations.

I want my robot to be able to use all three sensor readings in SLAM to create a 2D map of the environment. However, considering that i want a 2D map, i will not need all the axis readings correct?

I read another post on here where one of the answers said that only the yaw from the gyroscope, and the x and y from the accelerometer would be needed.

My question is, how would i implement this into my SLAM robot? I was thinking of passing the accelerometer and odometry readings through a kalman filter on the Arduino and then the same for the gyro and magnetometer readings. Would that be correct?

Would i also need to use all the axis (x, y, and z) readings from the magnetometer? Or just one or two axis?

Thanks.

答:
Based on your comments thread, I think what you want is a Kalman filter. I think this ahrs implementation will be helpful for you. If you search "mpu6050 ahrs" you'll also find a dozen or so other implementations to look through. If you want you can modify it so that it explicitly sets the Z coordinate to zero, but it should actually figure that out automatically.

To map the room (and do SLAM), you will need a sensor which can tell you how far away the walls are. Sonor tends to be a good low-cost entry point, though it has plenty of implementation difficulties.


问:
Reducing noise between 3 ultrasonic sensors and make Autonomous Robot more precise
I made an autonomous robot with 3 ultrasonic sensors. I want to reduce the noise between the 3 sensors and make it gradually slow when it approaches an obstacle. My code is mentioned below. Please help me in this.

Distance 1 is front sensor

Distance 2 is left sensor

Distance 3 is right sensor.

If you can suggest any  improvements to this code, I would be grateful.

```<code>//CODE FOR AUTONOMOUS WITH 3 ULTRASONIC SENSORS
/*code written By
Faraz Hassan
For Autonomous Rover Obstacle Avoidance */
//include newping and adafruit libraries to the code
#include <NewPing.h>
#include <AFMotor.h>

AF_DCMotor motor1(1);
AF_DCMotor motor2(2);
AF_DCMotor motor3(3);
AF_DCMotor motor4(4);

int trigger_c = A0;          // Controls the pulse sent from the right sensor
int echo_c    = A1;          // Controls the pulse received from the right sensor
int trigger_a = A2;          // Controls the pulse sent from the left sensor
int echo_a    = A3;          // Controls the pulse received from the left sensor
int trigger_b = A4;          // Controls the pulse sent from the front sensor
int echo_b    = A5;          // Controls the pulse received from the front sensor

int tp = 250;//delay

long  duration_b,duration_a, duration_c, distance1, distance2, distance3;

void setup()
{
// set all the motor control pins to outputs

 Serial.begin(9600);
        pinMode(trigger_b, OUTPUT);    // Arduino signal output from trigger_front
        pinMode(echo_b, INPUT);        // Arduino signal input from echo_front
        pinMode(trigger_a, OUTPUT);    //Arduino signal output from trigger_left
        pinMode(echo_a, INPUT);        // Arduino signal input from echo_left
        pinMode(trigger_c, OUTPUT);    // Arduino signal output from trigger_right
        pinMode(echo_c, INPUT);        //Arduino signal input from echo_right

}

void loop()
{
// Find distance Sonar….
// Clears the trigPin
digitalWrite(trigger_b, LOW);       //Sends a 2 µs LOW signal to the trigPin to make sure it’s turned off at the beginning of the program loop.
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigger_b, HIGH);     // Sends a 10 µs HIGH signal to the trigPin to initiate the sequence of eight 40 KHz ultrasonic pulses sent from the transmitting transducer.
delayMicroseconds(10);
digitalWrite(trigger_b, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration_b= pulseIn(echo_b, HIGH);  //Defines the duration variable as the length (in µs) of any HIGH input
                                    //signal detected at the echoPin.
                                    //The Echo pin output = time it takes the trigger pin emitted ultrasonic pulse to travel to the object and back to the sensor.
// Calculating the distance
distance1= duration_b*0.034/2;       // Defines the distance variable as the duration (time in d = s x t) multiplied by the speed of sound converted from meters per second to centimeters per µs (0.0344 cm/µs).
        //(d=s*t) * speed of sound converted from meters per second to centimeters per µs (0.0344 cm/µs).
// Prints the distance on the Serial Monitor

Serial.print("front:   ");
Serial.print(distance1);
Serial.print("  ");
Serial.print("left:  ");
Serial.print(distance2);
Serial.print("  ");

Serial.print("right:  ");
Serial.print(distance3);
Serial.println("  ");

// Find distance Sonar2….
// Clears the trigPin
digitalWrite(trigger_a, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigger_a, HIGH);
delayMicroseconds(10);
digitalWrite(trigger_a, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration_a = pulseIn(echo_a, HIGH);
// Calculating the distance
distance2= duration_a*0.034/2;
// Prints the distance on the Serial Monitor
digitalWrite(trigger_c, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigger_c, HIGH);
delayMicroseconds(10);
digitalWrite(trigger_c, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration_c = pulseIn(echo_c, HIGH);
// Calculating the distance
distance3= duration_c*0.034/2;

motor1.setSpeed(255);
motor2.setSpeed(255);
motor3.setSpeed(255);
motor4.setSpeed(255);
motor1.run(FORWARD);
motor2.run(FORWARD);
motor3.run(FORWARD);
motor4.run(FORWARD);
 if(Serial.available()>0)//Checking is Serial data available
  {
    int input = Serial.read(); //Storing value of read data into variable assigned
//    switch(input)
//    {
//     case 'o' : forward(); //Calling respective functions if mathced with case label
//     break;
//
//     case 'x' : stopMotors();
//     break;
//     default : break;
//    }
  }
if (distance1 < 28|| distance2 < 28|| distance3 < 28)       //DISTANCE1 FRONT SENSOR  DISTANCE2 LEFT SENSOR  DISTANCE 3 RIGHT SENSOR
{ stopMotors();
delay (1000);
if (distance2 < distance3)   //  LEFT SENSOR DISTANCE < RIGHT SENSOR DISTANCE
{ stopMotors();
   delay (1000);
  turnRight();
delay (700);
revers();
delay(700);
}
if (distance2 > distance3)  //  LEFT SENSOR DISTANCE >  RIGHT SENSOR DISTANCE
{ stopMotors();
delay (1000);
  turnLeft();
delay (700);
revers();
delay(700);
}
if (distance2 == distance3)  //  LEFT SENSOR DISTANCE ==  RIGHT SENSOR DISTANCE
{ revers();
delay (1000);

}
}

if (distance1 > 28)
forward();   // FRONT SENSOR  DISTANCE > 25

}

void revers()
{
// turn on motor A
   Serial.println("<Mars Rover> Backward");
motor1.run(BACKWARD);
motor2.run(BACKWARD);
motor3.run(BACKWARD);
motor4.run(BACKWARD);

 motor1.setSpeed(190);
 motor2.setSpeed(190);
 motor3.setSpeed(190);
  motor4.setSpeed(190);
  delay(tp);
}
void forward()
{
       Serial.println("<Mars Rover> Forward");
       motor1.setSpeed(255);
       motor2.setSpeed(255);
       motor3.setSpeed(255);
       motor4.setSpeed(255);
       motor1.run(FORWARD);
       motor2.run(FORWARD);
       motor3.run(FORWARD);
       motor4.run(FORWARD);
        delay(tp);

}
void turnRight()
{
  Serial.println("<Mars Rover> Right");
       motor1.setSpeed(255);
       motor2.setSpeed(255);
       motor3.setSpeed(255);
       motor4.setSpeed(255);
       motor1.run(FORWARD);
       motor2.run(FORWARD);
       motor3.run(BACKWARD);
       motor4.run(BACKWARD);

// Turn period
delay(tp);

}
void turnLeft()
{  Serial.println("<Mars Rover> Left");
       motor1.setSpeed(255);
       motor2.setSpeed(255);
       motor3.setSpeed(255);
       motor4.setSpeed(255);
       motor1.run(BACKWARD);
       motor2.run(BACKWARD);
       motor3.run(FORWARD);
       motor4.run(FORWARD);

//Turn period
delay(tp);

}
void stopMotors()
{
// Stop motors
  Serial.println("<Mars Rover> Stop");
      motor1.setSpeed(0);
       motor2.setSpeed(0);
       motor3.setSpeed(0);
       motor4.setSpeed(0);
       delay(tp);
}
</code>```

答:
There are two issues in the question:

noise (interference) among the three sensors

how to handle the motion with relation to the sensor readings

The noise between sensors is most probably a hardware issue (cabling or EMI) or it might be related to the sensors being close to each other. Without more info about the current implementation, this is all I can say at first thought.

Coming to the motion algorithms:

The current distance to action decisions are based on distinct cases (for example the distances being smaller than a treshold) however gradual motion requires a proportional control mechanism.

Proportional control can be applied to any sensed variable that you want to keep in control. Applying it to the distance variable, you could set up a speed - distance relationship, as follows:

```<code>d_min_allowed = 10 //the distance that you want the robot to completely stop
d_slowdown_start = 28 //the distance that you want the robot to start slowing down)
distance = (distance1+distance2+distance3)/3   // updated sensor readings

if (distance < d_slowdown_start) {
// start slowdown
error = (distance - d_min_allowed);
motorspeed = Kp*(error);
(Kp=255/ (d_slowdown_start-d_min_allowed) = 255 / 18)
}
</code>```

Once you get this one running, setting up similar proportional control mechanisms for steering will be a joyful challenge.

For more information and background, you can check the following topics online: system control, proportional control, PID control.

Body:
There are two issues in the question:

noise (interference) among the three sensors

how to handle the motion with relation to the sensor readings

The noise between sensors is most probably a hardware issue (cabling or EMI) or it might be related to the sensors being close to each other. Without more info about the current implementation, this is all I can say at first thought.

Coming to the motion algorithms:

The current distance to action decisions are based on distinct cases (for example the distances being smaller than a treshold) however gradual motion requires a proportional control mechanism.

Proportional control can be applied to any sensed variable that you want to keep in control. Applying it to the distance variable, you could set up a speed - distance relationship, as follows:

d_min_allowed = 10 //the distance that you want the robot to completely stop
d_slowdown_start = 28 //the distance that you want the robot to start slowing down)
distance = (distance1+distance2+distance3)/3   // updated sensor readings

if (distance < d_slowdown_start) {
// start slowdown
error = (distance - d_min_allowed);
motorspeed = Kp*(error);
(Kp=255/ (d_slowdown_start-d_min_allowed) = 255 / 18)
}

Once you get this one running, setting up similar proportional control mechanisms for steering will be a joyful challenge.

For more information and background, you can check the following topics online: system control, proportional control, PID control.


问:
How many AR markers should I use to get the object pose?
I'd like to get the object pose based on the attached AR marker to the object. I believe I only need one tag to get the 6D pose. However, I sometimes see more than one AR markers are used in the research papers or the demos by Boston Dynamics (https://boygeniusreport.files.wordpress.com/2016/02/screenshot-76.png) or by the team at Amazon Robotics Challenge.

Do I need to use more than one marker? If so, how can I calculate the 6D pose from more than one marker's information?

答:
Without knowing exactly what type of AR marker you are interested in, I'll talk about two types that I am familiar with: ArUco and April Tags. Both are AR markers that have open source libraries with stripped down (and possibly outdated) versions implemented in OpenCV.

These libraries will give you the full pose of the camera based on the marker in the field-of-view. The library uses the physical marker size and camera calibration parameters to estimate the pose of the camera w.r.t an individual marker or set of markers. You may use multiple markers in the form of a marker map to enhance the estimate of the camera pose. I imagine when people use multiple markers as in the Boston Dynamics example it is to ensure track continuity as markers enter/leave the field-of-view or to mark specific aspects of a scene.

If you are interested in using ROS, perhaps this aruco_localization repo will be of use. It was set up to localize a mini-quadrotor with an upwards facing camera, as seen here.


问:
What parameters can be/should be looked on while deciding to work with a microcontroller in a bot
I understand that choosing a microcontroller is all based on the needs and that there is no perfect Mcu.presently I have to select an MCU for a robot my team is building for the 2018 Abu robotics competition and I want to know how does the specs matter like what clocking speeds are ideal for what applications etc... while selecting one.</p>

答:
Typically a decision like this is made based on a list of design requirements. Have you listed these out? What do you expect the MCU to do? How many peripherals will you have?  Since you have a deadline, I would focus first on getting something to work very quickly using a simple board such as an Arduino or teensy. This buys you two things: (1) You have something working, even if it doesn't have all the bells and whistles you wanted. (2) You learn your design requirements thoroughly enough to pick a good part.

Based on their 2017 rulebook, it looks like they don't say anything about how many processors you can have. In that case, I would recommend using something like an odroid for your higher level computer, which will give you enough power to do some lightweight computer vision and all of the planning/SLAM you could want. It has the added bonus of running linux, which gives you access to ROS rather than reimplementing everything in embedded C on an MCU.


问:
How can I improve the map in my Mobile Autonomous Robot using KINECT

A little background of my aim

I am in the process of building a mobile autonomous robot which must navigate around an unknown area, must avoid obstacles and receive speech input to do various tasks. It also must recognize faces, objects etc. I am using a Kinect Sensor and wheel odometry data as its sensors. I chose C# as my primary language as the official drivers and sdk are readily available. I have completed the Vision and NLP module and am working on the Navigation part.

My robot currently uses the Arduino as a module for communication and a Intel i7 x64 bit processor on a laptop as a CPU.

This is the overview of the robot and its electronics:

The Problem

I implemented a simple SLAM algorithm which gets robot position from the encoders and the adds whatever it sees using the kinect (as a 2D slice of the 3D point cloud) to the map.

This is what the maps of my room currently look like:

This is a rough representation of my actual room:

As you can see, they are very different and so really bad maps.

Is this expected from using just dead reckoning?

I am aware of particle filters that refine it and am ready to implement, but what are the ways in which I can improve this result?

Update

I forgot to mention my current approach (which I earlier had to but forgot). My program roughly does this: (I am using a hashtable to store the dynamic map)

Grab point cloud from Kinect

Wait for incoming serial odometry data

Synchronize using a time-stamp based method

Estimate robot pose (x,y,theta) using equations at Wikipedia and encoder data

Obtain a "slice" of the point cloud

My slice is basically an array of the X and Z parameters

Then plot these points based on the robot pose and the X and Z params

Repeat

答:
Is this what would be expected: in principle yes. Although you may be able to improve your odometry model, in general it is not enough to get a good map. Without a description of your system its difficult to say how to improve it. On most systems translation estimation is better than rotation. You could add a gyro and measure the rotation. This should improve your results significantly.

Instead of implementing a particle filter yourself, you could use a SLAM implementation e.g. from openslam. This should save you a lot of time, and will most likely give better results.


问:
Problem with Coordinate Transformation
So I have a quad with a black-box estimator on it. The black box estimates the pose of the quad. I also have a Vicon system that I'm using to get the ground truth pose of the quad. I'm trying to transform the output from the black-box system into the coordinate frame of the Vicon system so I can compare the two.

I have two series' of points recorded using the whole setup that I am trying to use to compute this transformation (from one world frame to the other world frame).

If you're not familiar, it is possible to compute a transformation between two frames given a set of points in each frame.

I have implemented the method described in the paper Least-Squares Rigid Motion Using SVD

But I'm getting wonky results:

If it's not clear, if the transformation were working correctly, the points labeled 'transformed' displayed on the graph below would roughly overlap with those labeled 'Vicon'. As you can see, they only overlap for less than half a second.

Any suggestions? Ideas about what could be wrong?

答:
Turns out I was transforming before interpolating the data, and my interpolation function assumed that the two streams of data were taken at the same time stamps. A simple mistake. So I was comparing data from different points in time. Consequently, it makes sense that resulting fitted transformation was incorrect. </p>

<p>@Chuck -- The resulting (correct) transform could indeed look like it involves scaling because I am dealing with 3-D data. Above, only a single axis of data is displayed. When rotating a a vector from one frame to another, the magnitude of the x-component may very well change -- what falls along the 'x-axis' depends on the frame definition.  </p>

Title: Problem with Coordinate Transformation

Body:
Turns out I was transforming before interpolating the data, and my interpolation function assumed that the two streams of data were taken at the same time stamps. A simple mistake. So I was comparing data from different points in time. Consequently, it makes sense that resulting fitted transformation was incorrect.

@Chuck -- The resulting (correct) transform could indeed look like it involves scaling because I am dealing with 3-D data. Above, only a single axis of data is displayed. When rotating a a vector from one frame to another, the magnitude of the x-component may very well change -- what falls along the 'x-axis' depends on the frame definition.


问:
ROS Installation Error : ARCH LINUX
So I had this old lappy on which I used to play with ROS a lot then it got broken so I bought a new one and installed the same distro as that of old one i.e. arch linux. Now when I am installing the ROS via AUR I get this build error please help me fix this.

```<code>Scanning dependencies of target libqt_gui_cpp_sip
[ 85%] Running SIP generator for qt_gui_cpp_sip Python bindings...
Traceback (most recent call last):
File "/opt/ros/jade/share/python_qt_binding/cmake/sip_configure.py", line 50, in <module>
    config = Configuration()
 File "/opt/ros/jade/share/python_qt_binding/cmake/sip_configure.py", line 19, in __init__
    ['qmake', '-query'], env=env, universal_newlines=True)
  File "/usr/lib/python2.7/subprocess.py", line 567, in check_output
    process = Popen(stdout=PIPE, *popenargs, **kwargs)
  File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1343, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
make[2]: *** [src/qt_gui_cpp_sip/CMakeFiles/libqt_gui_cpp_sip.dir/build.make:90: sip/qt_gui_cpp_sip/Makefile] Error 1
make[1]: *** [CMakeFiles/Makefile2:375: src/qt_gui_cpp_sip/CMakeFiles/libqt_gui_cpp_sip.dir/all] Error 2
make: *** [Makefile:128: all] Error 2
==> ERROR: A failure occurred in build().
Aborting...
</code>```

答:
This looks similar to this problem, where the user was missing qt5-base. </p>

<p>(added this as an answer to make the community bot happy)</p>

Title: ROS Installation Error : ARCH LINUX

Body:
This looks similar to this problem, where the user was missing qt5-base.

(added this as an answer to make the community bot happy)


问:
Controlling Robots Through Serial
I recently have been working on a little project. Unfortunately, I've ran into a bit of a road block with controlling servos using serial commands. The servos do appear to move when i put in any character into serial, but only a little. When i type in say, 90 characters of random gibberish, both servos connected to my arduino move several degrees. Here's my code:

```<code>#include <Servo.h>
Servo ULF; // Upper left front servo
Servo LLF; // Lower left front servo
byte index = 0;
int commandnum=1;
int steps = 0; // position of LLF servo
int partnum = 0; // unused for now
String command = ""; // the command we're building
void setup()
{
  LLF.attach(0);
  ULF.attach(1);
  Serial.begin(9600);
}

void loop()
{
  while(Serial.available() > 0) { // while there are more than zero bytes to read
      char in = Serial.read();
      if(in=='!') {
             //! is escape character
       commandnum++;
       partnum = 0;
       Serial.println("New Command. Command #: "+commandnum);
        break;
      }
      command+=in;
      if(in == ' ') {
        partnum++;
        //if we have a space, there's a new section to the command
      }
      if(command == "LLF") {
        Serial.read(); //skip a space

        Serial.println("Lower Left Foot Selected.");
        int angle = Serial.parseInt(); // find the angle we want
        Serial.println("ANGLE: "+String(angle));

        for(int pos = 0; pos < angle; pos++) // for loop through positions to reach goal
        {
           LLF.write(pos); // write servo position
           delay(15);
        }
        for(int pos = angle; pos > 0; pos--) // for loop through positions to reach goal
        {
           LLF.write(pos); // write servo position
           delay(15);
        }
      }
   }
}
</code>```

Any help would be much appreciated.

EDIT: Another note, nothing is printed in the serial monitor.

Also, these are micro towerpro rc servos.

答:
Does a simple serial sketch work? If yes, then try using this code:
What this does is it takes two bytes simultaneously, the  first indicating the pin number and the second the analog value, and then sets the pin mode. I am sure you can modify it for your own needs. This is the code I use for my robot. Hope this helps. (sorry, arduino indentation is weird)</p>

```<code>int pin = -999;
int val = -999;
int count = 0;

void setup()
{
    Serial.begin(9600);
}

void loop()
{

}

void serialEvent()
{
    //As soon as a byte arrives
    while(Serial.available())
    {
        //Read it
       int data = Serial.read();
       if (count == 0)
       {
           pin = data;
       }
       else if(count == 1)
       {
           val = data;
       }
       count = count + 1;

       if (count == 2)
       {
          //Time for reset
          count = 0;

          //execute
          analogWrite(pin,val);

       }
    }

}
</code>```

Title: Controlling Robots Through Serial

Body:
Does a simple serial sketch work? If yes, then try using this code:
What this does is it takes two bytes simultaneously, the  first indicating the pin number and the second the analog value, and then sets the pin mode. I am sure you can modify it for your own needs. This is the code I use for my robot. Hope this helps. (sorry, arduino indentation is weird)

int pin = -999;
int val = -999;
int count = 0;

void setup()
{
    Serial.begin(9600);
}

void loop()
{

}

void serialEvent()
{
    //As soon as a byte arrives
    while(Serial.available())
    {
        //Read it
       int data = Serial.read();
       if (count == 0)
       {
           pin = data;
       }
       else if(count == 1)
       {
           val = data;
       }
       count = count + 1;

       if (count == 2)
       {
          //Time for reset
          count = 0;

          //execute
          analogWrite(pin,val);

       }
    }

}


问:
Using a Sick laser with Matlab in Windows
Is there a Matlab toolbox available to use Sick lasers in Windows?

I found one toolbox for Matlab in GNU/Linux.  Is there another way to use Sick laser via Matlab in Windows?

答: I have worked with the Sick LIDAR Matlab/C++ Toolbox, its pretty easy to use and does the job very well.</p>


问:
How do I evaluate the minimum requirements of the processor and camera for a visual SLAM robot?
I would like to build a visual SLAM robot (just for self-learning purpose) but I get frustrated how I know which processor and camera should be used for visual SLAM.

First, for the processor, I have seen three articles, which shows different systems are used for implementing their SLAM algorithm:

Implementing SLAM algorithm (however it uses ultrasonic sensor rather than visual sensor) in Raspberry Pi (processing power is only 700 MHz) in Implementing Odometry and SLAM Algorithms on a Raspberry Pi to Drive a Rover

I have also seen that Boston Dynamics use Pentium CPU, PC104 stack and QNX OS for their Big Dog project, BigDog Overview
November 22, 2008

Then, I also found a project uses a modern XILINX Zynq-7020 System-on-Chip (a device that combines FPGA resources with a dual ARM Cortex-A9 on
a single chip), for a Synchronized Visual-Inertial Sensor System, in A synchronized visual-inertial sensor system with FPGA pre-processing for accurate real-time SLAM

But after reading those, I have no clue how they end up with those decisions to use those kinds of processors, stacks or even OSes for their project. Is there a mathematical way, or a general practice, to evaluate the minimum requirement of the system (as cheap and as power efficient as possible) for an algorithm to run?

If not, how could I know what processor or system I have to prepare for a visual SLAM robot? If there is no simple answer, it is also cool if you can recommend something I could read to have a good start.

Secondly, I also cannot find clear information which camera I should use for a visual SLAM robot. I also have no idea how they evaluate the minimum requirement of the camera. I found a lot of papers saying they use RGB-D camera but when I Google to find one, there are very few commercially available. The one I found is Xtion Pro Live from ASUS Global (for $170). Are there any practice I can choose a suitable camera system for visual SLAM too?

答:
In college I served as the team leader in development of an autonomous underwater vehicle (AUV).  In the beginning we were confronted with very much the same question you are presenting right now.  Ultimately it came down to, we knew that we didn't know what we didn't know.  Collectively we had all had some amount of embedded systems development experience, but jumping from making a small dual axis gimbal project to making a completely autonomous robot capable of interpreting it's environment was massive, and we had no idea the level of computing we would need.  That being said, we were relying heavily on vision systems which, from doing some small experiments with a Raspberry pi attempting to interpret live video feeds, we knew was going to be processor intensive.  Therefore, our solution was to GO BIG.  As the centeral processor we crammed in a Gigabyte Core i7-6500U.  It more than adequately addressed all our requirements.  With something like this, you can't necessarily know what all you are going to need system wise until you are done.  Then you can look at how much your system requires and scale down to more appropriate hardware afterwards.
I hope this helps.  I know it's a frustrating situation to be in.</p>


问:
Question about terminology of robotic architecture
Most home or entertainment robots I see are either manual human remote control or have the processor on-board and are completely self contained. Contrast to this robots which are neither, but are controlled wirelessly by a cpu elsewhere not in the body. Another cpu in the body is there merely to relay commands and readings back wirelessly to and from the main cpu. A hypothetical example of this are the battle droids from Star Wars, which were controlled by a "droid control ship", without which they were helpless. So this is the type of robotics architecture I am referring to. I have built such a robot already, so this is really a robotics question, not a science fiction question. I just wanted to convey the architecture I am referring to with a well known example.

What is the term for the physical shell?

What is the term for the main external cpu that houses the actual algorithm?

If the term "robot" applies, Which entity is the term "robot" more appropriately applied to? Or are there other actual industry terms which specifically classify the components in this architecture? I'm after the most widely accepted terms that still are precise.

答:
Disclaimer: This is not a perfect answer. I liked the topic so much, I've not held back and I'm giving my thoughts on it. I can improve it or delete it, according to comments.

The dumb bots would be called agents.

The main intelligent brain would be called the central command and control system.

Robot is by definition a mechanism that reacts (manipulates) to its environment through its senses (sensors).

In this topology (hierarchical control), I'd say the whole thing forms the "Robot system". However, the agents would be called "robots" too, because for an outsider they are interacting with the environment themselves.


问:
Looking for cheap Xbox/playstation like remote controller for robots
I saw some radio controllers for kids robots alike xbox/playstion game pads few months ago. But I couldn't find them by searching. I am looking for some cheap radio controllers for RC cars or other kids robots like console game pads.May you help me?</p>

答:
What about using an inexpensive 2.4GHz RC transmitter?

I already had one for a WLToys V222 quadcopter
If you don't already have one, you can pick one up on ebay for \$5 to \$15.

I opened up the quadcopter and Identified the chips it used

Mini54 microcontroller

MPU-6050 Motion Tracking Device

BK2423 2.4 GHz Transceiver

Based on this, I found the NRF24L01 which appeared to be compatible which I purchased on eBay for a whopping \$0.67US.  Add a \$15 Arduino Mega (or a $2 Arduino Nano clone) and you are all set to go.

After a bit of time and part in hand I hooked it up to the Arduino and I was able to control a servo using my inexpensive wireless controller.

SUCCESS!!

My guess is that the protocol varies depending manufacturer; so, a bit of reverse protocol engineering may be required.  If you would like more information on the code and config for the controller I used, Up Vote this and add a comment.

There are also 2.4GHz gamepads available for a similar price.  Their protocol might also be a bit different; so, a bit of reverse protocol engineering may be required in that case as well.


问:
Any open source simulation software which is able to simulate robots and their movements?
I am searching for an open source simulation software which is able to simulate robots and their movements in a factory. I would like to send control signals and receive sensor data back. This software should allow me to communicate with it. I want to use java to send control signals and be able to receive back sensor data.

My goal is it to use the simulation software on a Raspberry Pi.

I would be grateful for any kind of help.

答:
You should check out Robot OS at www.ros.org. ROS is basically an OS (a term I am using loosely in this context) that comes with different libraries that give you the capability to build a robot. There is a a publish/subscribe feature that lets you asynchronously capture data from nodes (sensors) so you can create a robot that can graph nodes that can communicate with one another using what ROS terms as topics. A node can also be a graphical view of the entire system you want to build.

ROS also includes a robot geometry library that keeps track of where different parts of the robot are with respect to each other. Ultimately, the Geometry library gives you the ability to visualize the state of the system being developed.

Unfortunately it is in C++, although I believe you can use Python also, and I do not think it will provide functionality in Java.

What I know is that every serious Robotics project I have seen uses ROS.


答:
I rewrote your program a bit. Not tested since I have no servos.</p>

```<code>#include <Servo.h>
Servo ULF; // Upper left front servo
Servo LLF; // Lower left front servo
byte index = 0;
int commandnum=1;
int steps = 0; // position of LLF servo
int partnum = 0; // unused for now
String command = ""; // the command we're building
char in;                // character to read
int angle;              // desired angle

void setup()
{
  LLF.attach(0);
  ULF.attach(1);
  Serial.begin(9600);
}

void loop()
{
    // define a protocol for commands, maybe like this:
    // [XXX<d>] where XXX is command and <d> is the angle,
    // the brackets [] indicates start and stop of a "packet" ( the command ).
    // Example: [LLF120], [LLF035], [LLF005]. I am here assuming a 3-digit
    // value for angle.

    // You also need to reset the variables that holds the command data
    // when the command has been executed so that they are ready for the next command.
    // and to use parseInt() you must ensure that the serial buffer has all the
    // digits that you sent.

  if(Serial.available() > 0) { // if there are more than zero bytes to read
      in = Serial.read();
      if(in == '[') // start of packet, now read command
      {
        command = "";

        // get command, 3 chars
        while(command.length() < 3)
        {
            if(Serial.available() > 0)
                command += Serial.read();

            delay(10);
        }

        // get angle
        while(Serial.available() < 3)
        {
            delay(10);
        }

        angle = Serial.parseInt(); // find the angle we want

        // flush buffer, all info received
        Serial.flush();
      }

      if(command == "LLF") {

        Serial.println("Lower Left Foot Selected.");

        Serial.println("ANGLE: "+String(angle));

        for(int pos = 0; pos < angle; pos++) // for loop through positions to reach goal
        {
           LLF.write(pos); // write servo position
           delay(15);
        }
        for(int pos = angle; pos > 0; pos--) // for loop through positions to reach goal
        {
           LLF.write(pos); // write servo position
           delay(15);
        }
      }
   }
}
</code>```

Title: Controlling Robots Through Serial

Body:
I recently have been working on a little project. Unfortunately, I've ran into a bit of a road block with controlling servos using serial commands. The servos do appear to move when i put in any character into serial, but only a little. When i type in say, 90 characters of random gibberish, both servos connected to my arduino move several degrees. Here's my code:

```<code>#include <Servo.h>
Servo ULF; // Upper left front servo
Servo LLF; // Lower left front servo
byte index = 0;
int commandnum=1;
int steps = 0; // position of LLF servo
int partnum = 0; // unused for now
String command = ""; // the command we're building
void setup()
{
  LLF.attach(0);
  ULF.attach(1);
  Serial.begin(9600);
}

void loop()
{
  while(Serial.available() > 0) { // while there are more than zero bytes to read
      char in = Serial.read();
      if(in=='!') {
             //! is escape character
       commandnum++;
       partnum = 0;
       Serial.println("New Command. Command #: "+commandnum);
        break;
      }
      command+=in;
      if(in == ' ') {
        partnum++;
        //if we have a space, there's a new section to the command
      }
      if(command == "LLF") {
        Serial.read(); //skip a space

        Serial.println("Lower Left Foot Selected.");
        int angle = Serial.parseInt(); // find the angle we want
        Serial.println("ANGLE: "+String(angle));

        for(int pos = 0; pos < angle; pos++) // for loop through positions to reach goal
        {
           LLF.write(pos); // write servo position
           delay(15);
        }
        for(int pos = angle; pos > 0; pos--) // for loop through positions to reach goal
        {
           LLF.write(pos); // write servo position
           delay(15);
        }
      }
   }
}
</code>```

Any help would be much appreciated.

EDIT: Another note, nothing is printed in the serial monitor.

Also, these are micro towerpro rc servos.

Body:
I rewrote your program a bit. Not tested since I have no servos.

#include <Servo.h>
Servo ULF; // Upper left front servo
Servo LLF; // Lower left front servo
byte index = 0;
int commandnum=1;
int steps = 0; // position of LLF servo
int partnum = 0; // unused for now
String command = ""; // the command we're building
char in;                // character to read
int angle;              // desired angle

void setup()
{
  LLF.attach(0);
  ULF.attach(1);
  Serial.begin(9600);
}

void loop()
{
    // define a protocol for commands, maybe like this:
    // [XXX<d>] where XXX is command and <d> is the angle,
    // the brackets [] indicates start and stop of a "packet" ( the command ).
    // Example: [LLF120], [LLF035], [LLF005]. I am here assuming a 3-digit
    // value for angle.

    // You also need to reset the variables that holds the command data
    // when the command has been executed so that they are ready for the next command.
    // and to use parseInt() you must ensure that the serial buffer has all the
    // digits that you sent.

  if(Serial.available() > 0) { // if there are more than zero bytes to read
      in = Serial.read();
      if(in == '[') // start of packet, now read command
      {
        command = "";

        // get command, 3 chars
        while(command.length() < 3)
        {
            if(Serial.available() > 0)
                command += Serial.read();

            delay(10);
        }

        // get angle
        while(Serial.available() < 3)
        {
            delay(10);
        }

        angle = Serial.parseInt(); // find the angle we want

        // flush buffer, all info received
        Serial.flush();
      }

      if(command == "LLF") {

        Serial.println("Lower Left Foot Selected.");

        Serial.println("ANGLE: "+String(angle));

        for(int pos = 0; pos < angle; pos++) // for loop through positions to reach goal
        {
           LLF.write(pos); // write servo position
           delay(15);
        }
        for(int pos = angle; pos > 0; pos--) // for loop through positions to reach goal
        {
           LLF.write(pos); // write servo position
           delay(15);
        }
      }
   }
}


问:
Scan an Auditorium, Count People, and Display Open Seats
I'm looking for any recommended approaches to be able to digitally process a room full people, like an auditorium or a movie theater and output the following information:

How many people are in the room

Locate unoccupied and available seating

Display the available seating to ushers, or people attending late, on an iPad or TV outside the auditorium. Similar to viewing airplane seat occupancy online.

Some sensors I'm considering

LiDar Scanning

Many ceiling (IR) cameras looking straight down (or perpendicular to the seating if the seating is inclined)

Some Challenges: Be able to take accurate enough measurements when:

The lights are on

The lights are off or in low light

People are standing

People are sitting

Seating is a long bench, not a chair

Constraints:

Individual sensors for each seat isn't ideal, as we need to count people when they are standing as well.

Thoughts on LiDar:

I like the thought of scanning the room with LiDar to develop a 3D Map from which I can determine the number of prominent heads to count, and distance/location of each head to identify a seat that is taken or open.

Are there any affordable (under $10,000) LiDar scanners that make this easy?

Thoughts on Top Down Infrared (IR) Cameras :

The auditorium seats 700 people and has a balcony. If the cameras are positioned in a top-down perspective, we would need to install about 22 cameras. It would be nice to have less of an installation overhead. Also, we'd like to respect the audience and not look down shirts.

Thoughts on 1 or 2 Infrared (IR) Cameras Viewing the Crowd from the stage:

This could work for counting faces (using OpenCV or other Computer Vision library) but would make it difficult to tell what seats are open and available, especially when people are standing.

Images of the Auditorium:

答:
Consider normal COTS video feed under good lighting conditions and using OpenCV to count people.  You would have to make general assumptions about what qualities make an image of a person.  Find how well it works.  Then refine your assumptions.  You may want to eventually try training OpenCV.  There exist OpenCV examples files for face recognition, cat recognition, eye recognition, ect.  However, in your case, you need body recognition from above.

Likely, over time, you will develop a complex procedure to identify people, stop counting people in walk ways and tell the difference between a person and a purse.

The initial attempt may be to record an empty room, subtract that image from an image of a full room and detect / count the areas which are different.


问:
Calculating the resistor for a buzzer
Please note: Although this question tangentially involves a Raspberry Pi, this is really more just a pure robotics question at heart.

I'm trying to connect my Raspberry Pi 1 Model A to this buzzer. I've seen wiring diagrams of this in action, and believe I need to put a resistor in between the buzzer and the (3.3V) output GPIO pin. If this is incorrect, please begin by correcting me!

My question is: how do I calculate the required ohms of this resistor? This particular buzzer is rated at 6VDC.

答:
Without a more detailed spec sheet I can't say for sure, but this is my understanding:
The buzzer has a self-drive circuit is rated for input 6V max, at which point it will pull 45mA and oscillate at 300-500Hz.
You don't need to explicitly limit the current into the buzzer, however 3.3V may not be enough to turn on the drive circuit.

I also recommend enabling in software the pull-down resistor of the pin you will be using.

Putting a resistor between the output pin and the buzzer will decrease the voltage across the buzzer and limit the current through it, which will reduce the volume.
It can also cause unwanted ringing without the use of a capacitor in parallel. See page 31 of this document for an example.

Title: Calculating the resistor for a buzzer


答:
A Near-IR or IR camera which can rotate and tilt, that is installed over the stage would probably be an acceptable and fairly well performing solution.

Installation would be simple: screw on, and take the cable down (hidden somehow), to a computer system for processing.

This would take several pictures/or continuous video and an image processing software can determine how many people are seated.

One particular point is that, the seats are in fact long and non-discrete sofas. So, the software should assume a capacity for each of the seats.

If this is a one time installation, you could sort things out on the way. However, if this is for a product to be installed at several stations, more generic systems would be preferred.

Title: Scan an Auditorium, Count People, and Display Open Seats

Body:
I'm looking for any recommended approaches to be able to digitally process a room full people, like an auditorium or a movie theater and output the following information:

How many people are in the room

Locate unoccupied and available seating

Display the available seating to ushers, or people attending late, on an iPad or TV outside the auditorium. Similar to viewing airplane seat occupancy online.

Some sensors I'm considering

LiDar Scanning

Many ceiling (IR) cameras looking straight down (or perpendicular to the seating if the seating is inclined)

Some Challenges: Be able to take accurate enough measurements when:

The lights are on

The lights are off or in low light

People are standing

People are sitting

Seating is a long bench, not a chair

Constraints:

Individual sensors for each seat isn't ideal, as we need to count people when they are standing as well.

Thoughts on LiDar:

I like the thought of scanning the room with LiDar to develop a 3D Map from which I can determine the number of prominent heads to count, and distance/location of each head to identify a seat that is taken or open.

Are there any affordable (under $10,000) LiDar scanners that make this easy?

Thoughts on Top Down Infrared (IR) Cameras :

The auditorium seats 700 people and has a balcony. If the cameras are positioned in a top-down perspective, we would need to install about 22 cameras. It would be nice to have less of an installation overhead. Also, we'd like to respect the audience and not look down shirts.

Thoughts on 1 or 2 Infrared (IR) Cameras Viewing the Crowd from the stage:

This could work for counting faces (using OpenCV or other Computer Vision library) but would make it difficult to tell what seats are open and available, especially when people are standing.

Images of the Auditorium:


问:
IR pattern projector
I am currently working on a robotics project in which I wish to integrated a depth/object scanner. Now my focus is currently on an IR camera in combination with some sort of IR pattern projector.

Now I am having a hard time finding any sort of IR projector which can project a pattern. I have found several topics suggesting that I use an IR-LED and create a pattern in front of it, but that would mean the projector would take up significant space.

Are there any projectors out on the market in a sensible form-factor for consumers? I came across the Structure Core, but that's only available to OEMs.

答:
Consider using coherent light from an infrared laser and an interference pattern.  Examples of this technique include the Kinect box.

A non-repeating totally random pattern across the entire field of view is ideal.  However would likely be difficult to create.  Recall the pattern from such a projector is actually constructed using a hologram. A more regimented pattern which repeats may be easer to create.  However, this limits the depth perception to less then that which creates a reflected pattern 360 degrees out of phase based on the parallax of the projector and camera.

Title: IR pattern projector


答:
According to the Arduino reference for Servo.attach( ), you should be using pins 9 and 10, not 0 and 1.

Note that in Arduino 0016 and earlier, the Servo library supports only servos on only two pins: 9 and 10.

Verify that you are setting the proper pin number in code.  Specifically, look at these lines in your originally-posted code:

```<code>void setup()
{
  LLF.attach(0);
  ULF.attach(1);
</code>```

Title: Controlling Robots Through Serial

Body:
According to the Arduino reference for Servo.attach( ), you should be using pins 9 and 10, not 0 and 1.

Note that in Arduino 0016 and earlier, the Servo library supports only servos on only two pins: 9 and 10.

Verify that you are setting the proper pin number in code.  Specifically, look at these lines in your originally-posted code:

void setup()
{
  LLF.attach(0);
  ULF.attach(1);


问:
First steps in robotics
I am a High School student and a beginner coming to Robotics and I have no idea where to start. I have spent days searching tutorials and books I could read to start building and programming my first robot but most of them just makes me much more confuse, most of them requires me to buy pre-assembled components and just assemble the components I ordered as a puzzle, but I want to learn to build a robot from scratch.

My questions are:
 1. What should I read / learn first?
 2. What programming language should I use? (I know a variety of programming languages. C++ being the one I know the best )
 3. What should I learn from physics? ( Circuits, Electricity, etc )
 4. How do you think I should start from this point where I know absolutely nothing but to program?

答:
I am a graduate student whose research is applied to robotics. I recommend:

Linear algebra and Calculus

Basic programming skills, learn arduino and another language

Electronics courses - basic electric circuits

Mechanics courses - statics and dynamics

Control theory - as much as you can

I would recommend pursuing a degree in either electrical engineering, computer science, or mechanical engineering. Also, I cannot over emphasize how important learning control theory is. It is the basis for getting your robot to perform in an optimal manner. However, you really should learn the above first before moving on to control theory.

Title: First steps in robotics


问:
Driving Rhino DC servo motor using Arduino through commands sending from MATLAB
I have a servo motor (http://robokits.download/documentation/RMCS220x_DCServo_Driver.pdf). I wrote a code in Arduino to rotate it in some defined angles and position. Code is given below:

```<code>#include <SoftwareSerial.h>
// software serial #1: RX = digital pin 10, TX = digital pin 11
// I have Arduino Uno so I created extra RX and TX to send and receive data.
// Becuase using inbuilt RX0 and TX0, I was unable to transfer data to motor
// and get feedack in PC
SoftwareSerial serial1(10, 11);

void setup()
{
  Serial.begin(9600);
  serial1.begin(9600);
}

void loop()
{

  if (Serial.available() > 0)
  {
    delay(5);
    serial1.println(Serial.readString());
  }

  if (serial1.available() > 0)
  {
    delay(5);
    Serial.println(serial1.readString());
    delay(5);
  }
}
</code>```

Using this code what I am able to do is, in terminal I enter some value say "G400" or "R821" etc. and motor rotate accordingly. But, this is not my aim. I don't want to put values manually, instead I used matlab script which give me some angle after calculations. I have to send this value to motor. Say, after calculations, matlab gives 26.4 degree, then I have input value to motor 26.4/0.2 = 132 counts i.e. "G132". Value changes every time for next calculation it may be 40 degree. What should be the  coding for this in Arduino as well as in MATLAB.

Thanks.

答:
After trying so many times, I came out with a solution to operate above-mentioned motor through Matlab. Here, I will rotate single motor only but in actual I have to rotate 4 motors for my robotic arm. So here is my arduino mega code to receive data from Matlab.

```<code>int doi;
char d[5];
int d1;int d2;int d3;int d4;
String stringG1 ; String stringG2 = "G"; String stringG3 = "G"; String stringG4 = "G";
void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);
  }
void loop()
{

  if(Serial.available()>0)
  {
    d1 = Serial.parseFloat();d2 = Serial.parseFloat();d3 = Serial.parseFloat();d4 = Serial.parseFloat();

    stringG1 = "G" + String(d1);
    Serial1.println(stringG1);

    if (Serial1.available()>0)
    {
      Serial.print(Serial1.readString());
    }

  }
}
</code>```

In above code, I used d1,d2,d3, and d4 because I have to send four angle values to four DC motor. But at this moment I have only 1 motor with me so I tested this code for single motor only. In future, I will extend this code to rotate all four motors.

Matlab side code to tansfer angle values to Arduino Mega is:

```<code>portName = 'COM9';
s = serial(portName,'BaudRate',9600,'Terminator','LF');
s.timeout = 1;
try
    try
        fopen(s);
    catch
        delete(s);
        fopen(s);
    end
catch
    disp('Unable to open the port ');
end
%%
angle = [250,200,50,120];
    %dataOut = angle;
    fprintf(s,'%d\n',angle);
   % fread(s)

%%

    try
       fclose(s);
       try
           delete(instrfind('port','COM9'));
       catch
       end
catch
    disp('Unable to close the port ');
    end
</code>```

In above Matlab code one most important thing is be noted is that this piece of code

```<code>portName = 'COM9';
    s = serial(portName,'BaudRate',9600,'Terminator','LF');
    s.timeout = 1;
    try
        try
            fopen(s);
        catch
            delete(s);
            fopen(s);
        end
    catch
        disp('Unable to open the port ');
    end
</code>```

will take some time to established connection between Matlab and Arduino Mega. If you try to run whole code at once it will do nothing. To run above code first we have to establish connection between Matlab and Arduino. For that first run only above piece of code. Then run

```<code>angle = [250,200,50,120];
        %dataOut = angle;
        fprintf(s,'%d\n',angle);
       % fread(s)
</code>```

as many times as you want to change the values in angle array.

To close the connection between Matlab and Arduino run the last remaining piece of code. Look carefully, I have inserted %% in Matlab code to break down code in sections which eases me to run code section wise using run section command in Matlab.

Any suggestions to improve code will be most welcomed.

Thanks.

Body:
After trying so many times, I came out with a solution to operate above-mentioned motor through Matlab. Here, I will rotate single motor only but in actual I have to rotate 4 motors for my robotic arm. So here is my arduino mega code to receive data from Matlab.

int doi;
char d[5];
int d1;int d2;int d3;int d4;
String stringG1 ; String stringG2 = "G"; String stringG3 = "G"; String stringG4 = "G";
void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);
  }
void loop()
{

  if(Serial.available()>0)
  {
    d1 = Serial.parseFloat();d2 = Serial.parseFloat();d3 = Serial.parseFloat();d4 = Serial.parseFloat();

    stringG1 = "G" + String(d1);
    Serial1.println(stringG1);

    if (Serial1.available()>0)
    {
      Serial.print(Serial1.readString());
    }

  }
}

In above code, I used d1,d2,d3, and d4 because I have to send four angle values to four DC motor. But at this moment I have only 1 motor with me so I tested this code for single motor only. In future, I will extend this code to rotate all four motors.

Matlab side code to tansfer angle values to Arduino Mega is:

portName = 'COM9';
s = serial(portName,'BaudRate',9600,'Terminator','LF');
s.timeout = 1;
try
    try
        fopen(s);
    catch
        delete(s);
        fopen(s);
    end
catch
    disp('Unable to open the port ');
end
%%
angle = [250,200,50,120];
    %dataOut = angle;
    fprintf(s,'%d\n',angle);
   % fread(s)

%%

    try
       fclose(s);
       try
           delete(instrfind('port','COM9'));
       catch
       end
catch
    disp('Unable to close the port ');
    end

In above Matlab code one most important thing is be noted is that this piece of code

portName = 'COM9';
    s = serial(portName,'BaudRate',9600,'Terminator','LF');
    s.timeout = 1;
    try
        try
            fopen(s);
        catch
            delete(s);
            fopen(s);
        end
    catch
        disp('Unable to open the port ');
    end

will take some time to established connection between Matlab and Arduino Mega. If you try to run whole code at once it will do nothing. To run above code first we have to establish connection between Matlab and Arduino. For that first run only above piece of code. Then run

angle = [250,200,50,120];
        %dataOut = angle;
        fprintf(s,'%d\n',angle);
       % fread(s)

as many times as you want to change the values in angle array.

To close the connection between Matlab and Arduino run the last remaining piece of code. Look carefully, I have inserted %% in Matlab code to break down code in sections which eases me to run code section wise using run section command in Matlab.

Any suggestions to improve code will be most welcomed.

Thanks.


问:
How to receive messages from a UR10 URScript?
I've been looking at existing this UR TCP/IP communication protocol answer, the data linked but I'm still a little confused to how I could retrieve values from calculations, for example get_inverse_kin()

I've tried to figure it out based on the available articles on the Universal Robots support site, but even that has a usage guide: "How to use this Support site" :)

I can receive the Realtime data and parse it based on the Client_Interface.xlsx specifications, but that does not include calculations done via the motion module.

The other thing I have in mind is writing a URScript along these lines:

store the result of the get_inverse_kin() in a float[] (e.g. angles = get_inverse_kin(pose_here)

make a string representation of the data (e.g. str = "{\"angles:\":[0,1,2,3,4,5]}")

open a socket to the computer to send the data (e.g. socket_open("COMPUTER_IP_HERE", 50000, "motion_results")

Send the angles string (e.g. socket_send_line(str, "motion_results"))

This feels a bit long-winded though. Is how values should be sent ?

What is the most efficient way of receiving URScript motion module results on a computer connected to the Control Box ?

答: did you take a took at this? Reading data from the URRobot is not possible via the commands but the robot sends its state messages as Matlab data which can be shown in the linked forum of how to get the TCP Position for example. He uses Python as the interfacing software.</p>


问:
State vector for a Quad-copter?
Whatever literature I've read on quad-copter dynamics, the state of a quad copter is define as a 12x1 vector, containing the coordinate positions (x,y,z) and velocity (xdot, ydot, zdot) in Earth frame, euler angles (theta, phi, psi) and euler angle derivatives (thetadot, phidot, psidot). However, this code that I am reading seems to have modeled the state vector as a 13x1 vector. It's modeled as : [x,y,z,xdot,ydot,zdot,qw,qx,qy,qz,p,q,r]. I am lost at these last 7 variables. In the initialization module, (qw,qx,qy,qz) are initialized as Quat(1),Quat(2),Quat(3),Quat(4) respectively, and (p,q,r) are all zero. I'm guessing the (p,q,r) are derivatives hence are set to zero during initialization. The Quat() is supposed to be the vector of quaternions, which is again something I haven't found in most literature on modeling of quad-copter dynamics. What is this and why is it needed?
I have no prior background in robotics or control systems! </p>

答:
Quaternions are just another way of modelling space orientation of a body. They are used in the same way you would use Euler angles. You can find algorithms (check Wikipedia, I found some there written in several programming languages) to go from quaternions to Euler and reverse.
There is no real reason to use them instead of Euler angles, I prefer using the latter, but in some projects I encountered quaternions and simply made the conversion. </p>

Title: State vector for a Quad-copter?


答:
Just an additional point:

Representing the orientation through Euler angles limits the maneuvers (essentially angle of rotation). For example: won't be able to execute a 360-degree flip. Using quaternions to represent the dynamics avoids that. A better alternative is to use rotational matrices (known also as direction cosine matrices). Rotational matrices are 3x3 matrices that uniquely represent the orientation.

Also, note that the relation between quaternion $ Q =[q_v, q_0] $ and the "angular velocity" is given by

$$ \frac{d}{dt}[q_v,q_0] = \frac{1}{2}[q_0 \omega + q_v\times\omega, - q_v\cdot \omega] $$

Here $ q_v, \omega $ are three-dimensional vectors and $ q_0 $ is a scalar.

Title: State vector for a Quad-copter?

Body:
Whatever literature I've read on quad-copter dynamics, the state of a quad copter is define as a 12x1 vector, containing the coordinate positions (x,y,z) and velocity (xdot, ydot, zdot) in Earth frame, euler angles (theta, phi, psi) and euler angle derivatives (thetadot, phidot, psidot). However, this code that I am reading seems to have modeled the state vector as a 13x1 vector. It's modeled as : [x,y,z,xdot,ydot,zdot,qw,qx,qy,qz,p,q,r]. I am lost at these last 7 variables. In the initialization module, (qw,qx,qy,qz) are initialized as Quat(1),Quat(2),Quat(3),Quat(4) respectively, and (p,q,r) are all zero. I'm guessing the (p,q,r) are derivatives hence are set to zero during initialization. The Quat() is supposed to be the vector of quaternions, which is again something I haven't found in most literature on modeling of quad-copter dynamics. What is this and why is it needed?
I have no prior background in robotics or control systems! </p>


答:
I agree with what @PrestonRoy regarding the academic aspects.

But, there is a big learning by doing component too.  The earlier you start the better.  Don't wait until you "know everything you need to".

JOIN A ROBOTICS TEAM AND DIVE IN!

In the process of doing, you will learn a lot about what robotics is what your need to learn.

Last year my Freshman son told me he was joining our Robotics Team.  When I asked him what her wa going to do, he said "they need a CAD guy".  My response: "Jeremy, you don't know anything about CAD."  His response: "Dad, have you ever heard of YouTube?"  LOL.  Last year our team won our first award for Robotics Design, thanks A LOT to his CAD work.

There are LOTS of opportunities at the High School Level

Here are the programs our High School participates in:

First Robotics FRC (the photo above is from FRC)

First Robotics FTC

VEX Robotics Competition

MATE (underwater)

For more options, here is another Long list from NASA

FINALLY

If your High School has a team, join it.

If not, find another one locally.

If not, start a team.

If you need help, I can help - I would just need a bit more regarding where you are located.

Title: First steps in robotics

Body:
I am a High School student and a beginner coming to Robotics and I have no idea where to start. I have spent days searching tutorials and books I could read to start building and programming my first robot but most of them just makes me much more confuse, most of them requires me to buy pre-assembled components and just assemble the components I ordered as a puzzle, but I want to learn to build a robot from scratch.

My questions are:
 1. What should I read / learn first?
 2. What programming language should I use? (I know a variety of programming languages. C++ being the one I know the best )
 3. What should I learn from physics? ( Circuits, Electricity, etc )
 4. How do you think I should start from this point where I know absolutely nothing but to program?


答:
Because you are using dead reckoning the errors in estimating the pose of the robot accumulate in time. From my experience, after a while, dead reckoning pose estimation becomes useless. If you use extra sensors,like Gyroscope or Accelerometer the pose estimation will improve but since you have no feedback at some point it will diverge as before. As a result, even if you have good data from the Kinect, building an accurate map is difficult since your pose estimation is not valid.

You need to localize your robot at the same time as your try to build your map (SLAM!). So as the map is being created, the same map is also used to localize the robot. This ensures that your pose estimation will not diverge and your map quality should be better. Therefore I would suggest to study some SLAM algorithms (i.e. FastSLAM) and try to implement your own version.

Title: How can I improve the map in my Mobile Autonomous Robot using KINECT

Body:
A little background of my aim

I am in the process of building a mobile autonomous robot which must navigate around an unknown area, must avoid obstacles and receive speech input to do various tasks. It also must recognize faces, objects etc. I am using a Kinect Sensor and wheel odometry data as its sensors. I chose C# as my primary language as the official drivers and sdk are readily available. I have completed the Vision and NLP module and am working on the Navigation part.

My robot currently uses the Arduino as a module for communication and a Intel i7 x64 bit processor on a laptop as a CPU.

This is the overview of the robot and its electronics:

The Problem

I implemented a simple SLAM algorithm which gets robot position from the encoders and the adds whatever it sees using the kinect (as a 2D slice of the 3D point cloud) to the map.

This is what the maps of my room currently look like:

This is a rough representation of my actual room:

As you can see, they are very different and so really bad maps.

Is this expected from using just dead reckoning?

I am aware of particle filters that refine it and am ready to implement, but what are the ways in which I can improve this result?

Update

I forgot to mention my current approach (which I earlier had to but forgot). My program roughly does this: (I am using a hashtable to store the dynamic map)

Grab point cloud from Kinect

Wait for incoming serial odometry data

Synchronize using a time-stamp based method

Estimate robot pose (x,y,theta) using equations at Wikipedia and encoder data

Obtain a "slice" of the point cloud

My slice is basically an array of the X and Z parameters

Then plot these points based on the robot pose and the X and Z params

Repeat


问:
Correct Quadcopter Yaw control implementation
I have built a quadcopter from scratch, including my own flight controller.

I have implemented a sensor fusion algorithm (Madgwick algorithm), which returns me current Yaw, Pitch and Roll angles. Then, a PID control algorithm based on these measured angles and desired angles (which are set by the control sticks on a transmitter) adjusts the speed of the motors.

For pitch and roll controls the algorithm is obvious and works just fine (i.e, pitch stick is 100% forward - desired pitch is "30 degrees", and current measured pitch is trying to catch up with that value using PID control). However for Yaw I would like the yaw stick to rotate the quad in the corresponding direction as long as I am holding the "yaw stick" in a non-zero position, with a rotating speed, proportional to the yaw stick angle. Since I have current measured Yaw angle (relative to a "reference yaw" which is the yaw that the quad had when the throttle was zero, not relative to the "absolute magnetic North-origined yaw"), I am basically just adding a "quadRotationSpeed = yawStickValue*delta_t" to the "desired yaw angle" in each iteration of the control loop, and then do the rest as a regular PID control: based on desiredYaw and measuredYaw I am calculating the motor torques.

Now the questions:

1) Is this approach wrong?

2) When I turn the yaw stick, the quad seems to be rotating with the speed, proportional to the stick angle, but when I let go off the stick, it rapidly turns back half way and then keeps turning slowly back to the "desired angle" I set with the yaw stick.

3) After this yaw maneuver the quad seems to be much less stable during the flight, but gradually it stabilizes.

My quad is about 800 grams and is quite large, about 60 cm in diagonal.

答: So I reimplemented the whole Yaw control thing using PID on raw gyro data, ignoring the sensor fusion current Yaw angle, which turned out to work perfectly. Since gyro returns the speed of change of the yaw angle, and I wanted to control the speed of change of the angle using control sticks, doing so directly is the most natural approach.</p>


问:
What happens when I connected my unpowered servo connector power wire to the powered arduino 5V pin?
I was playing at connecting wires to 'get the feel of it' when I accidentally connected the servo connector red wire to the arduino 5V pin while the arduino is connected to my comp, (and hence powered). I did not connect a battery to the ESC though.
Did I just effectively ran 5 V through my BEC and risk damaging it?
What I only managed to find online is I shouldn't have done that when the battery is connected because I will burn out my Arduino. But since I didnt have my battery connected to the ESC, will my BEC get damaged instead?
I couldn't check my ESC now because I don't have any suitable batteries with me right now and I have to wait till Monday to get my batteries. Just thought I can find a quicker answer here.

答: Should be fine. If I remember correctly, the inputs to the ESC (more or less) control power mosfets. Putting input to a mosfet without power does not hurt it.</p>


问:
In the SLAM for dummies what is z-h in updating X?
In SLAM for Dummies there is on page 40 this formula:

$X = X+K(z-h)$

What is $z-h$ in updating $X$?

答: This is a good question, as the document is not clear. It appears that $z$ is the range/bearing measurement to the landmark (see discussion about $J_z$ on page 35), and $h$ is the estimate for range/bearing that the EKF gives (see page 38). This means that $z-h$ is the error (also called the innovation, for historic reasons). In the update we increment $X$ by the Kalman gain $K$ times the error $z-h$. </p>


问:
Processor and command interface preference for a robot arm
I want to build a robot arm that'll be approximately 1.25 meter long and will be able to lift up to 2 kilograms. It'll have 6 dof and it is an expensive project. And most importantly, i am the only programmer in this brand new robotics facility of ours. :)

The robot that i want to build will be led by Inverse Kinematics, so with all these parameters and matrices, i think that i'll need a tough processor (Not so sure).

Assuming that my robots control interface will be on an Android tablet, i thought that i also could develop my program for Android, and send necessary commands to the control chip via RS-232 interface.

So, my question is, are standart 1 GHz Android tablets suitable for these tasks? If not, has anybody got an advice for me?

答:
This is a much bigger project than you think, and processing power is the least of your concerns. You may want to skip straight to step #9. Otherwise, here are some questions you need to ask yourself, based on my experience of building something very similar as a hobby project (I used a desktop PC for processing):

1: Exactly how far should the robot reach? You say 1.25 meters - but at what height, and in what direction? If it absolutely must reach anything within a 1.25 meter dome around its base, then either it's maximum reach must be longer, or you have a very big engineering challenge. Look at some of the robots from Fanuc or Kuka; their online catalogs have cutout views that show how far the arm will reach in each direction, and those areas are never perfect domes. Also, how close to the base must the robot reach? If the first arm (from the base) is significantly longer than the 2nd arm, then it won't be able to reach anything close to the base. Also, 6 DOF DOESN'T MEAN IT CAN HAVE ANY POSITION WITH ANY MOVEMENT! The shoulder and elbow joints of robot arms are almost always in the same DOF (and sometimes the wrist too). You can move the arm in any direction or hold the grasper in any orientation, but you can't do both at the same time. If you look at the human arm, the shoulder has 3 DOF, the elbow has one, the forearm has one, and the wrist has two. That's 7 in total, and that's what you need for total flexibility. If you search for 7 DOF, you'll see examples showing how they can move in ways that 6 DOF arms can't. This may not be important for your project, but it's important to know because otherwise you may do a lot of needless debugging.

2: Start with the grasper first. There are companies that make these specially, and it's best to look at their work to see what you might need. These can be very expensive parts if they need motors or sensors. This is the most important part of the arm, and fortunately it's the first part you can prototype and test. Figure out what you want, cheaply and quickly fabricate a version yourself, and move it around by hand to ensure it actually does what you want it to do. You may find that it needs to do more or less than you expected. I've seen people learn a lot simply by using a pair of popsickle sticks.

3: Exactly how much force should the arm lift? Start with the outermost part, the end effector (aka grasper/gripper/whatever). That needs to have a grip capable of holding 2kg, or roughly 20 newton-meters (you'll be doing all forces in newton-meters now; it's a lot easier than foot-pounds because 1kg is 9.8NM, and it's best to round up). How does it hold it? Does it pinch sideways? If so, it needs to have some amount of grip. If it lifts from the bottom like a fork, it needs to have a certain amount of torque in the last up/down DOF. We'll come back to this.

4: (AKA #3 part 2) Now that you know what the end effector needs to do, you can get a better idea of how it should be shaped and how much it will weigh. And after going through step 1 and lots of graph paper, you may know how long each segment of the arm needs to be. With this knowledge, you can start calculating how much each segment will weigh and therefore how much force each DOF needs to support. It's safest to calculate this with each segment fully outstretched, but for the lowest 2 joints you may be able to estimate that they will always be at an angle and therefore don't need quite as much force.

5: Time to look at motors, the beautiful yet evil Medusa of robotics. Again, what does the robot need to do? Does it need to be fast, or powerful, or precise? If it needs precision but can be slow, you may need geared stepper motors. If it needs to be fast or powerful, you may need geared DC or AC motors. Speaking of which, DC motors will probably be easier to control. But each of these options have problems; stepper motors are quite weak and they don't know their position, while DC and AC motors simply don't know their positions. You'll need rotary encoders for DC/AC motors (incremental encoders at minimum), and may need absolute encoders no matter which motor type you choose. Absolute encoders tell you the exact angle of the arm, incremental ones will only tell you the change in angle. So, absolute encoders are better, but they are also much more expensive. You can avoid this problem by purchasing industrial servo motors (which look a lot like the stepper motors), but those are much more expensive because they have rotary encoders already built in. But those servos may be worth it just for the easier integration, if the maker has a nice software package that you can use.

6: You'll need to power all these motors (probably through drivers, which are another piece of hardware), and also power all the sensors and controllers, and they probably won't require the same voltage. Hopefully your motors can at least share a single voltage. You can buy velcro loops and labels in bulk.

7: Don't forget the weight of the motors in the arm; you'll need to include that when calculating the torque required for the next motor.

8: Make sure you have some arrangement for fast and cheap shipping of new components, and whatever discounts possible.

9: Realize this is way too complicated, and look up a robot refurbisher/supplier in your area. Retired industrial robots are much cheaper than new ones, and they can help you get set up and figure out what adjustments you need.