答:
Writing the equations by hand and deriving them is certainly the best way to understand what is happening "in the background". Generating the equations and deriving them using a syombolics engine, like @SteveO suggested is essentially the same process but someone else, in this case a symbolic engine, is doing the work for you.

There are however different approaches to obtain the jacobi matrix, geometrically.

You can consider that the Jacobi matrix is built up from submatrices.

$$ J = \left[
     \begin{matrix}
       J_T \\ \hdashline
       J_\omega
       \end{matrix} \right] =
       \left[
      \begin{matrix}
       J_{T_{1}}\quad J_{T_{2}}  \quad \dots \quad J_{T_{n}}\\ \hdashline\hdashline
       J_{\omega_{1}}  \quad J_{\omega_{2}} \quad \dots \quad J_{\omega_{n}}\\
       \end{matrix} \right] =
\left[
   \begin{matrix}
    \frac{\delta x}{\delta q_1} \;     \frac{\delta x}{\delta q_2} \; \dots \;     \frac{\delta x}{\delta q_n} \\
   \frac{\delta y}{\delta q_1} \;     \frac{\delta y}{\delta q_2} \; \dots \;     \frac{\delta y}{\delta q_n} \\
\frac{\delta z}{\delta q_1} \;     \frac{\delta z}{\delta q_2} \; \dots \;     \frac{\delta z}{\delta q_n} \\
\hdashline
\frac{\delta \alpha}{\delta q_1} \;     \frac{\delta \alpha}{\delta q_2} \; \dots \;     \frac{\delta \alpha}{\delta q_n} \\
\frac{\delta \beta}{\delta q_1} \;     \frac{\delta \beta}{\delta q_2} \; \dots \;     \frac{\delta \beta}{\delta q_n} \\
\frac{\delta \gamma}{\delta q_1} \;     \frac{\delta \gamma}{\delta q_2} \; \dots \;     \frac{\delta \gamma}{\delta q_n} \\
    \end{matrix} \right]
$$

If your joint is a rotational joint than the its corresponding part in the Jacobi matrix is

$$ \left[
   \begin{matrix}
    J_{T_{i}} \\ \hdashline
    J_{\omega_{i}}
    \end{matrix} \right] =
    \left[
   \begin{matrix}
    \overrightarrow b_{i-1} \times \overrightarrow r_{i-1,ee}   \\ \hdashline
    \overrightarrow b_{i-1}
    \end{matrix} \right]
$$

If your joint is a translational joint than the its corresponding part in the Jacobi matrix is
$$ \left[
   \begin{matrix}
    J_{T_{i}} \\ \hdashline
    J_{\omega_{i}}
    \end{matrix} \right] =
    \left[
   \begin{matrix}
    \overrightarrow b_{i-1}  \\ \hdashline
    0_{_{1 \times 3}}
    \end{matrix} \right]
$$

where

$\overrightarrow b_{i-1}$  is the vector of the joint axis

$\overrightarrow r_{i-1,ee}$ is the vector pointing from the origin of the joint coordinate system to origin of the end-effector coordinate system

$i$ refers to the Denavti Hartenber coordinate system numerotiation

Title: Computing the Jacobian Matrix -- chain rule?

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

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

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

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

Thank you!


问:
how to find maximum force of a robot joint
I want to know if there is any equation that calculates the maximum force of a robot joint. The force that we should not exceed.

For example in human leg, if we apply a big external force to the knee, it will break. now how can i find the necessary force that will just make the leg move without breaking the knee.

I have a programme that generates robot morphologies randomly with different sizes, so I have to know the force to not exceed for each joint. I think this depend on weight, mass, inertia of each robot part.

I can not do this by trial and error because I have hundreds different morphologies.

This video shows the behaviour of robot if I apply a big force. It is in Gazebo robotic simulator.

Thanks in advance!

答:
As I understand, you do not actually need the force, you just want that your simulation to behave somewhat realistically.

Instead of complicating everything with dynamics, I suggest you remain at kinematic models (will be much much faster, considering you will evaluate your models probably millions of times, if I undertand you goals corretly, in the fitness function).

Instead of maximum force, determine a realistic maximum velocity, acceleration and joint limit. In this case you could still assure a realistic behavior, bounded change in position and velocity, and have fast running models.

To continue your analogy, if the knee is moved with limited acceleration and velocity and the joint motion limits (motion range of the joint) is also defined correctly, the knee will not break.

ContentLicense: CC BY-SA 3.0


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

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

I have the following questions:

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

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

答:
In McGeer's 1990 work on Passive Dynamic Walking, the angular momentum equation that you have posted is the angular momentum of the system just before the impact of the swing foot, about the impending impact point. It consists of two parts:

the angular momentum due to the velocity of the center of mass about the impact point, given by $\cos(2\alpha_0) ml^2 \Omega_-$; and

the angular momentum due to the velocity of the rotational inertia about the center of mass, given by $r^2_{gyr} ml^2 \Omega_-$.

To answer question 1, the equation is already in the form $H = I*\omega + ml^2\Omega$, as you would expect. The challenge comes in because of two factors.

First, the overall rotational inertia $I$ about the impact point is defined using a radius of gyration, since the system is rotationally symmetric about the center of mass: $I = r^2_{gyr} ml^2$.

Second, the angular velocity $\Omega_-$ is about the foot of the supporting leg, some of which is lost due to the impact of the swinging foot with the ground. This means the required $\Omega$ to find the angular momentum about the impact point is actually equal to $cos(2\alpha_0) \Omega_-$, leading to the equation as written in McGeer's work.

To answer question 2, both $\alpha_0$ and $r_{gyr}$ are constants for a rimless wheel (as @NBCKLY said in his answer):

$\alpha_0$ is the angle between legs, given by $\alpha_0 = 2\pi/n$ (where $n$ is the number of legs). This means that in order to have $\alpha_0 = \pi/2$, there would need to be 4 legs on the wheel and the majority of the energy will be lost at every step (not a likely scenario).

$r_{gyr}$ is the radius of gyration, a proxy for the constant rotational inertia of the model about the center of mass. Since the distribution of mass of the model does not change, this value also will not change.

There has been lots of work done more recently on the concepts that you are exploring in passive dynamic walking and underactuated robotics which I would invite you to investigate using your preferred research platform.


问:
Estimating the displacement of a drone in three dimensions
Assuming a drone is in two dimension, it has to predict its future position by calculating its future displacement:

For a real quad-rotor, why should we not only estimate the displacement of a robot in three dimensions but also the change of orientation of the robot, its linear velocity and its angular velocity?

答: By assuming that the drone is 2D as you have done, you are fixing the vertical axis (e.g. height from the ground). For a real drone operating in 3D, there are six degrees of freedom corresponding to the x,y, and z position of the robot in space as well as the roll,pitch, and yaw of the drone.</p>


问:
Solving Inverse Kinematics with Gradient Descent
I am trying to implement my own inverse kinematics solver for a robot arm. My solution is a standard iterative one, where at each step, I compute the Jacobian and the pseudo-inverse Jacobian, then compute the Euclidean distance between the end effector and the target, and from these I then compute the next joint angles by following the gradient with respect to the end effector distance.

This achieves a reasonable, smooth path towards the solution. However, during my reading, I have learned that typically, there are in fact multiple solutions, particularly when there are many degrees of freedom. But the gradient descent solution I have implemented only reaches one solution.

So my questions are as follows:

How can I compute all the solutions? Can I write down the full forward kinematics equation, set it equal to the desired end effector position, and then solve the linear equations? Or is there a better way?

Is there anything of interest about the particular solution that is achieved by using my gradient descent method? For example, is it guaranteed to be the solution that can be reached the fastest by the robot?

Are there cases when the gradient descent method will fail? For example, is it possible that it could fall into a local minimum? Or is the function convex, and hence has a single global minimum?

答:
There are more approaches to solve the inverse kinematics equations.

If you want to continue to use the pseudo-inverse based approach and still obtain more then 1 solution you can flip the sign of joint angle 1 for example (if it is a puma type robot arm) in the initial guess and run the iterative solver again. Same for joint angle 3. You can have situations where it will not converge (e.g. out of reach, singular, etc.)

There are however method which analytically calculate all angles. These should also be faster then the iterative method. These are based on geometrically obtaining a formula for your joint angles and applying that formula once, without any iterations.

You can find more infomration about these here and here and here


问:
problem in serial communication between PC and ATMEGA 8535(AVR)
I have written code to send data from controller to pc through serialport using interrupt
but it echos garbage value exactly 3 times back.

```<code>    ISR(USART_RX_vect)
{
    unsigned char index = UDR;

    UDR = index;
}

void uartInit()
{
    UCSRA=0x00;
    UCSRB=0x18;
    UCSRC=0x86;
    UBRRH=0x00;
    UBRRL=0x67;
    UCSRB |= (1 << RXCIE); // Enable the USART Receive Complete interrupt (USART_RXC)
    _delay_ms(10);
}

int main(void)
{
    uartInit();
    lcd_init();
    sei();

   while(1)
    {
     }
}
</code>```

EDIT:
Function used to set baud rate..

```<code>#define FOSC 16000000// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

void USART_Init( unsigned int baud )
{
/* Set baud rate */
UBRRH = (unsigned char)(baud>>8);
UBRRL = (unsigned char)baud;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 1stop bit */
UCSRC = (0<<USBS)|(3<<UCSZ0);
}
</code>```

答:
You are setting the UBRR register incorrectly: it should not directly hold the desired baudrate, but a value that depends on your CPU speed (which you defined as the macro FOSC, but never used) and the baudrate. The exact calculation is described in the ATMega8535 datasheet (p.147).

See the AVR UBRR Calculator for easy calculation of the proper UBRR register values (note that the calculator assumes U2X = 0, as seen in Table 72, p.173).

EDIT: I just noticed your macro MY_UBRR, sorry about that. Are you calling USART_Init with baud = MY_UBRR? If so, I'll delete this answer.


问:
Using Accelerometer, Gyroscope and any sensor to track speed, position,

Problem

Currently working on reverse engineering this application zepp.com/baseball. This is a wearable device that can track a users

speed

positional tracking

when the object makes contact with another one

3-D Rendering

Currently using an accelerometer and gyroscope to get the yaw, pitch, and roll(orientation) of the device, but do not know how to use that information to calculate speed, or if the device has collided with another object?

答:
You are essentially making your own IMU.  The way this works is essentially:

the accelerometer gives you linear acceleration

the rotational gyro gives you angular velocity

integrate the rotational gyro over time to give you angular position

integrate the accelerometer over time to give you linear velocity

double integrate the accelerometer over time to give you linear position

Of course, integrations like this introduce errors, so that is why people typically combine estimates from many different sensors (and sensing modalities) with something like a Kalman Filter.

Also note that these integrations don't work anymore if you max out the sensing range of your sensors.  For example, some cheap accelerometers won't measure over 3gs.  And I imagine that swinging a bat and hitting a ball will produce some pretty high gs.  And a low resolution (bit count) will also severely affect the accuracy.


问:
What's the difference between the term "pose estimation" and "visual odometry"?
I'm reading a paper:

Choi C, Trevor A J B, Christensen H I. RGB-D edge detection and
  edge-based registration[C]//Intelligent Robots and Systems (IROS),
  2013 IEEE/RSJ International Conference on. IEEE, 2013: 1568-1575.

which refers:

Visual features such as corners, keypoints, edges, and color are
  widely used in computer vision and robotic perception for applications
  such as object recognition and pose estimation, visual odometry, and SLAM

I previously assume pose estimation to be roughly equal to visual odometry, yet the text above seems to deny.

So what's their difference? I didn't find much info from google. IMHO, it seems pose estimation is estimating the pose of moving object with the camera static, while visual odometry is estimating the pose of camera in a static(mostly) scene, is that precise enough?

答: Visual odometry is the task to estimate the motion of the camera relative to the last frame(s). You don't care about loop closures or mapping. If you sum up the relative transformations between frames, you get a guess on the transformation relative to the first frame (your current camera pose). Visual odometry is in this case a way to initialize your pose estimation. This however is a noisy process so you can add more advances techniques (e.g. loop closures) to improve this estimation. </p>


问:
Does anyone know what might be giving me this error coming from an i2c device
Here is the background. I am trying to write a service for the HiTechnic prototype board.

Using the Appendix 2 from the blue tooth developers kit from Lego's site I am able to understand what is going on with this service I am trying to build however the response I get is always 221 = 0xDD = "Communication Bus Error" or 32 = 0x20 = "Pending communication transaction in progress".

I figured out that the HiTechnic prototype board is using i2c address 0x08 so I modified the brick code to use that address instead of the standard 0x02. It goes out and configures the device, I get a response and then it does an LSWrite which seems OK then I get a get an error when it does the LSGetStatus.

I know this thing works - I can bit bang it all day long with an Arduino but I only did that to test it out - see this link

I am not sure what else to try. Here is how I am setting it up in the connect to brick handler.

```<code> pxbrick.Registration registration = new pxbrick.Registration(
                new LegoNxtConnection(LegoNxtPort.Sensor1),
                LegoDeviceType.DigitalSensor,
                Contract.DeviceModel,
                Contract.Identifier,
                ServiceInfo.Service,
                _state.Name);
        Debugger.Break();
        // Reserve the port
        LogInfo("ConnectToBrickHandler");
        yield return Arbiter.Choice(_legoBrickPort.ReserveDevicePort(registration),
            delegate(pxbrick.AttachResponse reserveResponse)
            {
                Debugger.Break();
                if (reserveResponse.DeviceModel == registration.DeviceModel)
                {
                    registration.Connection = reserveResponse.Connection;
                }
            },
            delegate(Fault f)
            {
                Debugger.Break();
                fault = f;
                LogError("#### Failed to reserve port");
                LogError(fault);
                registration.Connection.Port = LegoNxtPort.NotConnected;
            });
</code>```

I have also tried setting AnyPort as well so that it will hit the TestPortForI2CSensorHandler that just does what I explained before - it seems to set the mode fine and then gets an error when it tries to read the device information.

Here is the data. - this first part is the set input more - both the message and response - You can see it is totally fine.

Send command data.

```<code>0
5
0
11
0
receive command data. (_commState.SerialPort.Read(receiveData, 0, packetSize);)
2
5
0
</code>```

Then it does an LSWrite - everything still seems fine... You can see I have modified the NxtComm code to use 0x08 instead of 0x02 which it would normally use, then the last byte is also 0x08 which is the starting address of the manufacturer. It's asking for 16 bytes which would be the manufacturer and sensor type. like I said - I know that works I can print that info out using the Arduino.

```<code>128
15
0
2
16
8 // i2c address
8 //I assume this is what address I want to read from?
Got response: True Error code Success [02/25/2013 02:20:31]
-- SendCommandHandler (NxtComm) [02/25/2013 02:20:31]
--- RequestResponseHandler (NxtComm) [02/25/2013 02:20:31]
--- CommSendImmediateHandler (NxtComm) [02/25/2013 02:20:31]
Send command data.
</code>```

Then it tries to get the status

```<code>0
14
0
</code>```

Here is the response...

```<code> 2
14
32
 0
</code>```

It's either 32 or 221. It's making me nuts...

If anyone has anything that might help me out I would so much appreciate it. At this point I am running out of ideas. I can see what is going on, I can understand the entire transaction but can't seem to figure out why it just errors out like that.

Also - just for grins I tried 0x10 which is what they tell you on the HiTechnic website. That gets a response of 2,14,0,0 from the NXT brick - that would indicate there is no data but as I pointed out I can get data using the Arduino. How could I have two different I2C device addresses?

答:
Triumphant

Check this out. Under normal circumstances you would configure your sensor by giving it a port. It would look like the following.

```<code>pxbrick.Registration registration = new pxbrick.Registration(new LegoNxtConnection((LegoNxtPort)_state.SensorPort),
</code>```

Well, inside of the NxtBrick code there is a method called TestPortForI2CSensorHandler and reading the code you can see that if you pass in “AnySensorPort” it will try all four ports. Genuis that I am thought! Oh great. I will just let the already created code do the work for me, after all, at that point all I wanted to do was see of the thing worked. Well here is the problem. When you do that it creates a type of I2CReadSensorType inside of the ctor it executes this line of code.

```<code>ExpectedI2CResponseSize = 16;
</code>```

That doesn’t seem to work. OK - not seems, it doesn’t work. It won’t work for the sonsor sensor or any other digital sensor. I assume
 because it’s 0 based, so 16 is actually 17 bytes? I am guessing. At anyrate, I changed it to 15 and low and behold it works. I even went back and tried it with the LEGO sonar sensor. It works to a point - that is to say it actually gets data back but it seems
 like the sensor type data (which is “SuperPr” on the prototype board) is 0xFF for all the bytes. The name manufacturer is indeed set to LEGO though so I know it read data.
 if you change the ExpectedI2CResponseSize  back to 16 it fails.

The other issue I had is that the NxtCommType contains the following.

```<code>[DataMember, Description("The default I2C Bus Address of the Ultrasonic or other I2C Sensor.")]
public const byte DefaultI2CBusAddress = 0x02;
</code>```

For my purposes at the moment I am just flipping it to 0x10 for the prototype board (which oddly enough when connected to my Arduino

shows up as 0x08 but that is another story). I need to modify things so I can use sensors that have differing i2c addresses but for now I am thrilled!

I would love to see someone like Trevor Taylor comment on this as to how it ever worked with 16 as the ExpectedI2CResponseSize.

Awesome!

Body:
Triumphant

Check this out. Under normal circumstances you would configure your sensor by giving it a port. It would look like the following.

pxbrick.Registration registration = new pxbrick.Registration(new LegoNxtConnection((LegoNxtPort)_state.SensorPort),

Well, inside of the NxtBrick code there is a method called TestPortForI2CSensorHandler and reading the code you can see that if you pass in “AnySensorPort” it will try all four ports. Genuis that I am thought! Oh great. I will just let the already created code do the work for me, after all, at that point all I wanted to do was see of the thing worked. Well here is the problem. When you do that it creates a type of I2CReadSensorType inside of the ctor it executes this line of code.

ExpectedI2CResponseSize = 16;

That doesn’t seem to work. OK - not seems, it doesn’t work. It won’t work for the sonsor sensor or any other digital sensor. I assume
 because it’s 0 based, so 16 is actually 17 bytes? I am guessing. At anyrate, I changed it to 15 and low and behold it works. I even went back and tried it with the LEGO sonar sensor. It works to a point - that is to say it actually gets data back but it seems
 like the sensor type data (which is “SuperPr” on the prototype board) is 0xFF for all the bytes. The name manufacturer is indeed set to LEGO though so I know it read data.
 if you change the ExpectedI2CResponseSize  back to 16 it fails.

The other issue I had is that the NxtCommType contains the following.

[DataMember, Description("The default I2C Bus Address of the Ultrasonic or other I2C Sensor.")]
public const byte DefaultI2CBusAddress = 0x02;

For my purposes at the moment I am just flipping it to 0x10 for the prototype board (which oddly enough when connected to my Arduino

shows up as 0x08 but that is another story). I need to modify things so I can use sensors that have differing i2c addresses but for now I am thrilled!

I would love to see someone like Trevor Taylor comment on this as to how it ever worked with 16 as the ExpectedI2CResponseSize.

Awesome!


问:
Tring to run 12 V DC geared motor using Samsung Li Ion ICR16850 batteries
I am trying to run this motor.

Using the batteries stated in the title. The motor requires 12 V and I am supplying 11.98V to the motor, through a motor driver. After a while, the motor keeps slowing down and the battery voltage drops down to 5-6 V, but after I remove the battery from the motor driver it again shows 11.9V.

Is this battery capable enough to run my motors, or do I need a new one?

答:
Assuming that the motor is in a healthy condition...

Voltage is only one aspect, you have to be sure that you battery can supply the current drawn by your motor.
The maximum current, according to the link you have specified is approx 10 Ampers.

I am not sure how many batteries and in which config you are using, the description I have found is this one. It states that the maximum current that the batteries can supply is 5.2 ampers. So if you do not have any parallel connections in the battery configuration (I assume you have serial ones because of the higher voltage you have specified) you cannot supply the 10 amps required by the motor for maximum torque. Try to measure also the current, not just the voltage and see if this is the problem. You can use more then one batteries (probably 2, maybe 3) connected in parallel to each other to solve this problem.

Another source of the problem could be a short circuit with a very short duration in the driver when switching the transistors. Try to measure the current also before and after the driver stage to identify if this is the problem.


答:
A fully charged LiPo battery cell should has a voltage of 4.2 V. Assuming that you have three cells in series, that would give 12.6 V. When you apply a big load, this voltage of course, will decrease instantly but if you measured 11.98 V in open-circuit that means the batteries were not fully charged. I guess your batteries were not charged at all.

Here is the discharge characteristic of the Samsung IRC16850, taken from this site.

A discharge current of 7 A will drain your battery flat in 20 minutes.

Furthermore a discharged battery's voltage is not the same when the load is still connected and when it is in open circuit. After disconnecting the load the battery voltage will rise, this will be the OCV (open circuit voltage).

This is a figure of a LiPo battery pack, 12 cells in series. When the load is disconnected the voltage has risen from 2.7 V to ~3.2 V in a short period of time (PB 6 voltage). This happens with your batteries too but if you reconnect the motor the voltage will drop back.

And finally, if you measure 5-6 V on your battery pack that means one cell's voltage is around 2 V and the cells are probably damaged now. The Samsung ICR18650's discharge cut-off voltage 2.75V, which means that you should not use it when the voltage is lower. Actually you should not use the cells but recharge when the voltage drops to 3 V.

If a cell is heating up it means that its internal resistance has risen. The dissipated heat will be:

$$ P = R_{internal} \times I_{discharge}^2 $$

this means that a part of the stored energy is wasted on heating the cell itself (which is very DANGEROUS as LiPo cells can easily catch fire). The effective battery capacity is lower in this case.

Without load your motor should drain 800 mA and the batteries should last 2.5 hours with that. I suggest to make some tests without any load attached to you motor, or just some light load. These batteries would be capable of supporting that, just make sure that they are fully charged. But probably you will need new cells too.

Title: Tring to run 12 V DC geared motor using Samsung Li Ion ICR16850 batteries

Body:
I am trying to run this motor.

Using the batteries stated in the title. The motor requires 12 V and I am supplying 11.98V to the motor, through a motor driver. After a while, the motor keeps slowing down and the battery voltage drops down to 5-6 V, but after I remove the battery from the motor driver it again shows 11.9V.

Is this battery capable enough to run my motors, or do I need a new one?


答:
If the robot's orientation is fixed, then determining its linear displacement is sufficient to determine its location in the world. This is because one unit of "forward" on the robot is equivalent to one unit of "forward" in the world.

However, when the robot is allowed to rotate, one unit of "forward" for the robot now corresponds to a partial unit "forward" and a partial unit "sideways".

The clearest way to imagine this is to imagine that the robot has rotated 180 degrees, such that it is looking in the direction opposite to that which it had when it started. Now one unit of "forward" for the robot actually translate to one unit of "backward" in the world. Similarly, one unit of "left" now corresponds to one unit of "right" and vice-versa.

In this manner, local coordinates, as established relative to the robot, are only useful when the orientation of the robot is known relative to the world. If you don't know which way you're pointed, you can't know which way you're moving.

Title: Estimating the displacement of a drone in three dimensions

Body:
Assuming a drone is in two dimension, it has to predict its future position by calculating its future displacement:

For a real quad-rotor, why should we not only estimate the displacement of a robot in three dimensions but also the change of orientation of the robot, its linear velocity and its angular velocity?


答:
Pose estimation means determining position and orientation.

Odometry is using a (any) sensor to determine how much distance has been traversed, so visual odometry is just clarification that the particular sensor to be used for odometry is visual (a camera, typically). Traversed distance, though, means that odometry is relative - your car odometer may indicate that you traveled 10 miles, but that doesn't really mean anything unless you know your starting position.

Similarly, a wheel encoder on the left and right wheels could give you distance and rotation as the vehicle moves, but again that doesn't mean anything unless you know the starting position and orientation.

As given above, a pose is a position and orientation. It is an absolute value between one frame and another. An accelerometer and a magnetometer can give you an absolute orientation (relative to Earth's gravity and magnetic North), but they can't give you an absolute position. You would need to add a GPS for that.

You can integrate the accelerometer to estimate the elapsed position, but that is meaningless without a starting position and is also prone to accumulating errors. Similarly, visual odometry doesn't mean anything without a known starting position and is also prone to accumulating errors.

So, in conclusion, a pose is an absolute measurement between one frame and another, of position and orientation.

Odometry is generally used to refer to an elapsed or relative position and orientation and, because it is not absolute, is prone to drift over time.

Title: What's the difference between the term "pose estimation" and "visual odometry"?

Body:
I'm reading a paper:

Choi C, Trevor A J B, Christensen H I. RGB-D edge detection and
  edge-based registration[C]//Intelligent Robots and Systems (IROS),
  2013 IEEE/RSJ International Conference on. IEEE, 2013: 1568-1575.

which refers:

Visual features such as corners, keypoints, edges, and color are
  widely used in computer vision and robotic perception for applications
  such as object recognition and pose estimation, visual odometry, and SLAM

I previously assume pose estimation to be roughly equal to visual odometry, yet the text above seems to deny.

So what's their difference? I didn't find much info from google. IMHO, it seems pose estimation is estimating the pose of moving object with the camera static, while visual odometry is estimating the pose of camera in a static(mostly) scene, is that precise enough?


问:
How to split tasks between interrupts and the main loop on a bare metal controller?
I'm working on a robotics project where I have 3 services running. I have my sensor DAQ, my logic ISR (motor controller at 20kHz) and my EtherCAT slave controller.

DAQ and EtherCAT run in the idle and the logic runs during an interrupt. The logic does some calculations and controls the motor. The EtherCAT service (kinda like CANbus) runs together with my DAQ in the idle loop. I can not run the DAQ in the interrupt because that leaves me with less than 100ns for the EtherCAT service to run.

I'm not sure whether this is the right way to do this especially considering all the scary things i've read regarding data corruption when using interrupts.

Does anyone have some nice ideas on how to handle these services?

I'm running all my code on a Zynq 7020 (on the ARM Cortex) and it's written in C++.

Here is an example of my code:

```<code>/**
 * Get all sensor data
 */
void Supervisor::communication(void) {
    // Get all the sensors data
    dispatchComm.getData(&motorAngle, &motorVelocity, &jointAngle, &springAngle, &tuningParameter);

}

/**
 * Run all the logic
 */
void Supervisor::logic(void) {

    dispatchLogic.calculate(tuningParameter, motorAngle, motorVelocity, jointAngle, springAngle);

    dispatchLogic.getData(&angle, &magnitude);

    // Dispatch values to the motor drive
    dispatchComm.setMotorDriveSetpoint(angle, magnitude);
    dispatchComm.writeToPiggyback((uint32_t) (tuningParameter), motorAngle, motorVelocity);
}
</code>```

答:
Some very general advice.

My first impression from your question is that you are struggling with the fact that no hardware provides infinite resources. You can either slow down your control loops or look for better hardware (which may not exist).

If your control has nested loops, then run each one a slow as possible. Are you controlling position at 20kHz? Pull that out and run that at 500Hz (A little faster if your mechanical mechanism is designed for high performance). Is you DAQ measuring current for the controller? Try running your current control at 5kHz but commutating at 20kHz.

All those numbers are assuming a meso scale device using electro-magnetic actuators.

Regarding interrupts, the rule of thumb is to do as little as possible, as quickly as possible, inside the interrupt and everything else outside it. However it feels like you might be using a timer interrupt to substitute for a real-time task scheduler (nothing wrong with that), in which case, you will want to do everything needed for that cycle in the interrupt. Add a time-overrun check at the end so that if your interrupt is taking longer than 50us you know about it and can adjust your strategy or optimize code.

If you are writing interrupts then you need to go learn the details about data corruption issues. They are not scary and they are straightforward to manage on all modern processors. You can protect data in your idle loop by disabling interrupts in critical sections or using higher level synchronization constructs if you really need to.

A final thought; even though you are coding in C++, you should read the processor datasheet and instruction set so that you have an idea of the capabilities and limitations of the hardware if you have not already.

EDIT:

From the limited code you added it looks like high level control for a series elastic actuator. The spring will dominate the mechanical time constant of the actuator system and you probably do not need that loop to run at 20kHz in lockstep with your motor commutation.


问:
Calculate the uncertainty of a 6-dof pose for graph-based SLAM
This question is strongly related to my other question over here.

I am estimating 6-DOF poses $x_{i}$ of a trajectory using a graph-based SLAM approach. The estimation is based on 6-DOF transformation measurements $z_{ij}$ with uncertainty $\Sigma_{ij}$ which connect the poses.

To avoid singularities I represent both poses and transforms with a 7x1 vector consisting of a 3D-vector and a unit-quaternion:

$$x_{i} = \left( \begin{matrix} t \\ q \end{matrix} \right)$$

The optimization yields 6x1 manifold increment vectors

$$ \Delta \tilde{x}_i = \left( \begin{matrix} t \\ log(q) \end{matrix} \right)$$

which are applied to the pose estimates after each optimization iteration:

$$ x_i \leftarrow x_i \boxplus \Delta \tilde{x}_i$$

The uncertainty gets involved during the hessian update in the optimization step:

$$ \tilde{H}_{[ii]} += \tilde{A}_{ij}^T \Sigma_{ij}^{-1} \tilde{A}_{ij} $$

where

$$ \tilde{A}_{ij} \leftarrow A_{ij} M_{i} = \frac{\partial e_{ij}(x)}{\partial x_i} \frac{\partial x_i \boxplus \Delta \tilde{x}_i}{\partial \Delta x_i} |_{\Delta \tilde{x}_i = 0}$$

and

$$ e_{ij} = log \left( (x_{j} \ominus x_{i}) \ominus z_{ij} \right) $$

is the error function between a measurement $z_{ij}$ and its estimate $\hat{z}_{ij} = x_j \ominus x_i$. Since $\tilde{A}_{ij}$ is a 6x6 matrix and we're optimizing for 6-DOF $\Sigma_{ij}$ is also a 6x6 matrix.

Based on IMU measurements of acceleration $a$ and rotational velocity $\omega$ one can build up a 6x6 sensor noise matrix

$$ \Sigma_{sensor} = \left( \begin{matrix} \sigma_{a}^2 & 0 \\ 0 & \sigma_{\omega}^2 \end{matrix} \right) $$

Further we have a process model which integrates acceleration twice and rotational velocity once to obtain a pose measurement.

To properly model the uncertainty both sensor noise and integration noise have to be considered (anything else?). Thus, I want to calculate the uncertainty as

$$ \Sigma_{ij}^{t} = J_{iterate} \Sigma_{ij}^{t-1} J_{iterate}^T + J_{process} \Sigma_{sensor} J_{process}^T$$

where $J_{iterate} = \frac{\partial x_{i}^{t}}{\partial x_{i}^{t-1}}$ and $J_{process} = \frac{\partial x_{i}^{t}}{\partial \xi_{i}^{t}}$ and current measurement $\xi{i}^{t} = [a,\omega]$.

According to this formula $\Sigma_{ij}$ is a 7x7 matrix, but I need a 6x6 matrix instead. I think I have to include a manifold projection somewhere, but how?

For further details take a look at the following publication, especially at their algorithm 2:

G. Grisetti, R. Kümmerle, C. Stachniss, and W. Burgard, “A tutorial on graph-based SLAM,” IEEE Intelligent Transportation Systems Maga- zine, vol. 2, no. 4, pp. 31–43, 2010.

For a similar calculation of the uncertainty take a look at the end of section III A. in:

Corominas Murtra, Andreu, and Josep M. Mirats Tur. "IMU and cable encoder data fusion for in-pipe mobile robot localization." Technologies for Practical Robot Applications (TePRA), 2013 IEEE International Conference on. IEEE, 2013.

.. or section III A. and IV A. in:

Ila, Viorela, Josep M. Porta, and Juan Andrade-Cetto. "Information-based compact Pose SLAM." Robotics, IEEE Transactions on 26.1 (2010): 78-93.

答: Because a the pose has six degrees-of-freedom, the covariance matrix representing its uncertainty should be $6 \times 6$. To determine how the covariance matrix propagates after each new IMU measurement, you must determine the error state propagation equation, where the error is a minimal parameterization of the error in your state. How to do this for a rotation parameterized as a unit quaternion is explained in detail in Section 2 of Indirect Kalman Filter for 3D Attitude Estimation by Trawny. Note that this implementation explicitly estimates the gyroscope bias as part of the state vector. You would need to replace that with the position and add your accelerometer measurements. In fact, I recommend reading that document (or at least the first two sections) very carefully, I learned a lot the first time I read it.


问:
Change Message Interval ArduPilot
I am using Mavlink protocol (in c++) to communicate with the ArduPilotMega, I am able to read messages such as ATTITUDE for example.

I am currently getting only 2Hz (message rate) and I would like to increase it. I found out that I should use MESSAGE_INTERVAL in order to change it, and that I probably need to use the command MAV_CMD_SET_MESSAGE_INTERVAL to set it.

So my question is, how do I send that command using mavlink in c++?

I tried doing this with the code below but it did not work, I guess that I should use the command that I mentioned above but I don't know how.

```<code>mavlink_message_t command;
mavlink_message_interval_t interval;

interval.interval_us = 100000;
interval.message_id = 30;

mavlink_msg_message_interval_encode(255, 200, &command, &interval);
p_sensorsPort->write_message(command);
</code>```

Update: I also tried this code below, maybe I am not giving it the right system id or component id.

```<code>mavlink_message_t command;
mavlink_command_long_t interval;

interval.param1 = MAVLINK_MSG_ID_ATTITUDE;
interval.param2 = 100000;
interval.command = MAV_CMD_SET_MESSAGE_INTERVAL;
interval.target_system = 0;
interval.target_component = 0;

mavlink_msg_command_long_encode(255, 0, &command, &interval);
p_sensorsPort->write_message(command);
</code>```

Maybe I am missing something about the difference between target_system, target_component and sysid, compid. I tried few values for each but nothing worked. Is there any ack that will be able to tell me if it even got the command?

答:
You don't need to send any mavlink message. You can simply change the parameter SR1_EXTRA_1 to desired Attitude data rate and your data rate will be changed. Similarly you can change other parameter to change data rate of other messages.
More information of messages can be found at https://github.com/ArduPilot/ardupilot/blob/master/ArduCopter/GCS_Mavlink.cpp#L821

Title: Change Message Interval ArduPilot


问:
Particle filters: How to do resampling?
I understand the basic principle of a particle filter and tried to implement one. However, I got hung up on the resampling part.

Theoretically speaking, it is quite simple: From the old (and weighted) set of particles, draw a new set of particles with replacement. While doing so, favor those particles that have high weights. Particles with high weights get drawn more often and particles with low weights less often. Perhaps only once or not at all. After resampling, all weights get assigned the same weight.

My first idea on how to implement this was essentially this:

Normalize the weights

Multiply each weight by the total number of particles

Round those scaled weights to the nearest integer (e.g. with int() in Python)

Now I should know how often to draw each particle, but due to the roundoff errors, I end up having less particles than before the resampling step.

The Question: How do I "fill up" the missing particles in order to get to the same number of particles as before the resampling step? Or, in case I am completely off track here, how do I resample correctly?

答:
one simple way to do this is
numpy.random.choice(N, N, p=w, replace=True)  where N is the no. of particles and w = normalized weights.</p>

Title: Particle filters: How to do resampling?


问:
Do you have to stop first when switching direction for proper encoding readings?
Since the encoder is square wave not quadrature, do you have to stop first before changing directions for proper measurements?

In other words, if you are commanding along in one direction at some low speed like 50mm/s or less and want to change direction to -50mm/s, would you first need command it to zero and wait for the encoder to read 0 speed, and then command the reverse direction, in order to get as accurate as possible encoder readings?

答:
From the OI Spec (encoder count sensors):

NOTE: These encoders are square wave, not quadrature, so they rely on
  the robot’s commanded velocity direction to know when to count
  up/down. So if the robot is trying to drive forward, and you force the
  wheels to spin in reverse, the encoders will count up, (and
  vice-versa). Additionally, the encoders will count up when the
  commanded velocity is zero and the wheels spin.

If you manually move the wheel while it is at rest, it will always assume it was moved forward.

So when driving forward, you may get slightly more accuracy if you stop briefly and let the robot settle, If you are moving backwards, it may be best to set it to, say -1 mm/s, for a brief time then 0.


答:
You have to analytically compute all IK solutions.  This is basically done with straightforward geometry.  Most robotics textbooks with a section on manipulation will have a detailed explanation of this.  But you might also want to check out the ikfast library.

I am not sure if your gradient decent solution is guaranteed to have any special properties.  But I think it will probably be the closest solution in joint space except for in some special cases.  Note that there may be reasons to choose a different IK solution.  My answer to this post has a list of some metrics that you may be interested in: Evaluating the similarity of two 7 Degree of Freedom Arms.

Yes, I believe that there are circumstances that can cause gradient decent to fail.  (But this probably depends on the degrees of freedom and workspace of your arm).  See this thread for more info: Is the geometric inverse problem's solution "continuous" for a redundant robot?.

Title: Solving Inverse Kinematics with Gradient Descent

Body:
I am trying to implement my own inverse kinematics solver for a robot arm. My solution is a standard iterative one, where at each step, I compute the Jacobian and the pseudo-inverse Jacobian, then compute the Euclidean distance between the end effector and the target, and from these I then compute the next joint angles by following the gradient with respect to the end effector distance.

This achieves a reasonable, smooth path towards the solution. However, during my reading, I have learned that typically, there are in fact multiple solutions, particularly when there are many degrees of freedom. But the gradient descent solution I have implemented only reaches one solution.

So my questions are as follows:

How can I compute all the solutions? Can I write down the full forward kinematics equation, set it equal to the desired end effector position, and then solve the linear equations? Or is there a better way?

Is there anything of interest about the particular solution that is achieved by using my gradient descent method? For example, is it guaranteed to be the solution that can be reached the fastest by the robot?

Are there cases when the gradient descent method will fail? For example, is it possible that it could fall into a local minimum? Or is the function convex, and hence has a single global minimum?


答:
It is also often the case that the author lacks knowledge, makes mistakes, or is adding unnecessary statements to their work. Just because it is published does not make it true.

In this case though, it might be that the conjuction "and" and commas are confusing you.

such as object recognition and pose estimation, visual odometry, and SLAM

could probably be written more clearly as

such as object recognition, object pose estimation, visual odometry, and SLAM.

so I would interpret them as different.


问:
How to find Friction or Viscous force b (nmsec) in DC motor
PLease guide me
How to find Friction or Viscous force b (nmsec) in DC motor for a particlar speed.
The motor is connected with a gear and the ration is 26:1
I want to find for 200 rpm and the motor no load speed is 4900rpm
please guide me</p>

答:
When no other load is on the motor, any torque that the motor is producing is to overcome the friction. If you know how to calculate your friction from the torque needed to overcome it (I don't), then the rest is easy.

You need a way to control the speed, a way to measure the speed, and a way to measure the current. You also need the motor specs, specifically the torque constant, Kt. A variable power supply should allow you to dial in 200 rpm. When you're at the correct speed, measure the current. Then multiply your measured current by Kt, and you now know the torque. Then simply convert the torque to friction using the equation $T = b\omega$ (rearrange for the friction coefficient to get $b = \frac{T}{\omega}$) where $T$ is the torque in N m and $\omega$ is the angular velocity in rad/s to get $b$ in N m s.


问:
Adhesion for a heavy wall-climbing robot
I have come across a number of methods for developing wall-climbing robots.

Suction

Chemical Adhesion

Gecko like hair adhesion

Electroadhesion

Which method would be the best for heavy robots (5kg+)? Are there any other methods that I have missed?

答: Depends on what you want to climb on, if it is glass, probably your best bet will be suction, but I have no idea what you will need for normal house walls. Don't forget that many walls will not be able to survive 5kgs of weight that tears down the paint. Also if you want to climb on normal walls, you probably shouldn't use chemical adhesives, as they will leave some form of residue.</p>


问:
Suggestion for correct battery pack
I am trying to run 2 12V Geared DC motors which has No-load current = 800 mA(Max), Load current = upto 9.5 A(Max). Runtime to be atleast 3-4 hours.

The motor takes about 10-12 V for operation.

I need a proper battery pack for these, but how can I determine the specs I should go for?

答:
You haven't given a nominal (average or anticipated "normal") current draw for what you expect during the routine operation, so what I'm going to do will probably give you an over-specified battery pack for what you need.

Typically you would have some "worst case" load (all your sensors powered on, microcontroller powered on, all motors at full load, etc.) - this will provide the worst-case current draw and will establish what kind of a "C" rating the battery pack needs to have (more on this later).

Also, you typically aren't going to be operating at worst-case all the time, so you assume maybe your average duty cycle has all your electronics on and maybe your motors at 60% - again, this would be the average motor power during the entire time your device is powered on. This would establish what total capacity was required to provide the desired run time.

A "C" rate is the current that would drain (or charge) 100% of battery capacity in 1 hour. So, for a 1000mAh battery, 1C is (1000mAh/1h) = 1000mA, or 1A. Different battery styles and chemistries have different charging and discharging C rates, or maximum allowable current limits. The nice thing about using a C rate instead of an actual current limit is that it scales correctly for all batteries of a particular style and chemistry, regardless of capacity.

So, the easiest way to determine capacity is to figure your nominal total load and multiply that by your run time requirement. The best way to work with load is to multiply the current for each component by its operating voltage and get an operating power. Sum all of your component power requirements, then divide that by the battery pack's nominal voltage. Once you get a total current requirement in terms of your battery voltage, then multiply that by your desired run time to get required battery capacity.

In your case, you don't give an average load current, just a maximum current. So, based on that, you need a $(12\mbox{V})*(9.5\mbox{A})*(4\mbox{h}) = 456\mbox{Wh}$ battery. This is a significant amount of capacity.

If you are using a lead-acid battery, with a nominal voltage of 12V, then you need a capacity of 38Ah. If you are using a LiPO battery, with a nominal cell voltage of 3.6V, then you would need 3 (10.8V) or 4 (14.4V) in series (3S or 4S pack), and your required capacity is 42.2Ah or 31.7Ah, respectively.

Depending on how detailed you want to be with your battery pack specifications (or how stringent your requirements are) you may want to dig a little deeper with the pack design.

For instance, quality battery manufacturers should provide a curve that shows battery capacity versus discharge limits. As battery discharge current increases, the pack heats up and the internal resistance of the battery increases. This means that more power is wasted in the battery pack, reducing the effective output capacity of the battery.

More important even than that is checking the battery cycles versus depth of discharge. Some batteries could give you 2000 cycles if you discharge down to 40 percent state of charge but only 500 cycles if you went to 20 percent state of charge. Then it's up to you to determine what the benefit is of driving to a lower state of charge.

For instance, if you need to have 10Ah of capacity, you could either go to a (10/0.6) = 16.6Ah battery to go to a 40% state of charge during one "run" or you could use a (10/0.8) = 12.5Ah battery and push to a 20% state of charge. Both packs get you the capacity you need, but you'll wear out the smaller pack first because you're driving to a deeper depth of discharge. However, the benefits (reduced weight, reduced volume) may outweigh the cost (literally, cost of replacing the packs on a 4:1 basis) of using the larger pack. The smaller pack may also actually be less expensive than the larger pack, which could also help justify that decision.

I'll add too that, while you may commonly "float" a lead-acid battery to near 100% state of charge, it's bad (read:fires happen) when you try to do the same for lithium chemistry batteries. That is, lithium batteries may typically only ever get charged to 90% state of charge.

So, in summary,

Multiply your load current by the load voltage to get load power. Do this for each device you want to run.

Add these load powers together to get the total load power required, then multiply that by the desired run time to get the capacity requirement.

Choose a battery chemistry. This is generally based on energy density (how much the batteries weigh for a given capacity) and specific energy (how much space the batteries take up for a given capacity).

Based on the chemistry selected, add nominal cell voltages together until the desired operating voltage is achieved.

Using the same number of batteries selected above to achieve operating voltage, add the maximum cell voltages together and ensure that no maximum voltage specification is exceeded.

Divide the total capacity requirement in Wh or mWh by the nominal pack voltage calculated in step 4 to get the ideal battery capacity.

Find the allowable charge limits on the battery, based on depth of discharge limits and common charge limits. For instance, if the battery manufacturer suggests limiting discharge to 40% state of charge (a 60% depth of discharge), and suggests not charging above 90% state of charge, then the battery only really has 50% of its rated capacity available as useful output.

Find the actual required battery capacity by (ideal capacity)/(max charge - min charge). So a 10Ah battery that can only run between 40% and 90% would be (10Ah)/(0.9 - 0.4) = 20Ah pack required.

Finally, design the pack. The number of cells in series was calculated in step 4 above. Find a particular cell to use and get that battery's capacity. Divide the actual required capacity found in step 8 above and divide that by the cell capacity to get the number of cells to put in parallel. Take the ceiling of that number, which means if you find you need 2.05 cells in parallel, you need 3 cells in parallel to meet your requirements.

The total number of batteries required is the number in series (from step 4) multiplied by the number in parallel (from step 9).

Title: Suggestion for correct battery pack


问:
Why do series elastic actuators have more accurate and stable force control?
The other day, somebody was telling me about a robot in their lab, and they mentioned that it has "series elastic" actuators. But after doing a bit of Googling, I'm still not sure as to what this means, and have been unable to find a simple explanation. It seems that it is something to do with the link between the actuator and the load having a spring-like quality to it, but this is rather vague...

In any case, the what I am really interested in is the advantages and disadvantages of series elastic actuators. Specifically, I have read that one of the advantages is that it allows for "more accurate and stable force control". However, this appears counter-intuitive to me. I would have thought that if the link between the actuator and the load was more "springy", then this would lower the ability to have accurate control over the force send to the load, because more of this force would be stored and dissipated in the spring, with less directly transferred to the load.

So: Why do series elastic actuators have "more accurate and stable force control"?

答:
Series elastic actuators tend to have more stable force control because the spring filters out the high-frequency motion of the mechanism. A low frequency in the system dynamics means that you can use slower control techniques, which is important when using digital controllers with naive control implementations, and sensors with significant abbe error and latency.

In short, springs make the implementation of the controller easier when the designer does not have the skill or the time to optimize the performance of the actuator.

Your intuition is generally correct, except that SEA designers try to use springs without much dissipation. They are often (usually) measuring the displacement of the spring to estimate force.

Beware of people using SEA as a buzzword they don't really understand. Once upon a time it referred to a specific thesis and patent from MIT. The Series Elastic Actuator as designed at MIT was hyped in typical MIT fasion as innovative and orginal, probably a bit beyond what it actually was. Over time it's come to mean the general approach of intentionally inserting extra compliance into an actuator. Meanwhile, using appropriate compliance has been good mechanism design for hundreds of years.

The original papers are worth reading.

As a final note, the latency in your sensing->actuation response (including the mechanical time constants) is the key issue. If you don't specifically need mechanical filtering (maintaining smooth contact with the environment was one of the original motivations) you can filter electronically.


问:
Pushing Buttons Remotely over Ethernet
So I want to program something that will simply push a button, but controllable over ethernet.  I'm new to robotics so I don't know where to start.  What's the best way to control an actuator over a network connection?</p>

答:
You can use an Ethernet-enabled microcontroller as someone mentioned above. The board can be used as the interface between the network and the mechanism that you will be using to push the button.

For the mechanism you can use a servo motor or a pneumatic that releases with less force(you can control this by adjusting the inputs to the pneumatics manually). Any thing you use will have to have a control or a drive circuitry that triggers the mechanism.

You will have to write a code block for the conversion of the frame received via the Ethernet to a control signal understandable by the control circuitry.

Title: Pushing Buttons Remotely over Ethernet


问:
I'm looking for hands-on experience with different types of leg and hip designs for walking robots
I'm looking to find out, How do human-like legs compare to chicken legs and four-leg systems. In terms of cost, performance, speed, strength and accuracy.

I'm interested in things like speed, agility, turning radius, complexity and cost.

For a design large enough for a person to ride, rider fatigue is also important -- how do they compare in terms of achievable ride smoothness, vibration, and so on?

Are there quantitative benefits of 3 DOF hip joints, compared to 2 DOF?

I realize other factors will come into play as well, such as actuators, joint designs and control systems.
However, my interest at the moment is how basic leg designs compare to one another.

Edit: I'm looking for someone who has used these mechanisms first hand.

答:
Google "strandbeest"

I got the perportions in the photograph from a robotic toy. These legs move very smoothly and would make for a comfortable ride.

The numbers are from counting the holes in the toy's construction beams. The drawing is one half of one side of the toy with another mirror image leg to the  right. The circle the  left is a pivot and the circle on the right is a crank with a radios of three holes.

For a smooth ride you need to have four legs on each side with the same fixed and moving points with 2 pairs of 2 legs on each side driven 180 degrees from each other at the moving point.

Good luck. I could not post the picture so email me for the picture.


问:
Conventional Land Vehicle Dynamic Models for GPS/INS augmentation
I am looking to augment a GPS/INS solution with a conventional land vehicle (car-like) model. That is, front-wheel steered, rear wheels passive on an axle.  I don't have access to odometry or wheel angle sensors.

I am aware of the Bicycle Model (e.g. Chapter 4 of Corke), but I am not sure how to apply the heading/velocity constraint on the filter.

So my questions are:

Are there any other dynamic models that are applicable to the land vehicle situation, especially if they have the potential to provide better accuracy?

Are there any standard techniques to applying such a model/constraint to this type of filter, bearing in mind I don't have access to odometry or wheel angle?

Are there any seminal papers on the topic that I should be reading?

答:
When doing filtering, the Kinematic model comes into play only during the prediction step.  That is, you predict that the next state is one which is reachable given your current kinematic constraints. I'll reiterate: this is not  a hard constraint on the filter output. It simply makes unreachable states unlikely, with only the granularity available to the 2-D Gaussian distribution.

Then, the sensors are used to find which of the predicted states are likely given given the new information (GPS, etc).

If you must apply a kinematic model as a constraint (i.e., we cannot consider any state outputs which violate the kinematic model), then I know of only one option off hand: Use a particle filter to sample all nearby states, then apply a zero weight to all states which are not reachable given your Kinematics. Note, a particle filter is a general term with lots of different meanings.

A particle can represent all positions, $x,y,\theta$, e.g., a grid over the environment.

A particle can represent all nearby positions. In this case you sample the kinematic model many times with some noise, and propagate those forward. This implicitly honors the kinematic constraint.

A particle can represent possible paths (i.e., fastslam).

Then, you can re-weight each particle according to it's probability given the GPS measurements.

However, I recommend that you use the INS in place of the wheel odometry during the prediction step. It will likely be a reasonable proxy, especially over the short term. In fact, this is a very common practice in the literature.

To make this clearer, you predict your next pose $x^+$, based on your current pose $x^-$, and your INS measurement which gives you a $\delta x$ (because you integrate the accellerations). So your EKF_PREDICT function goes from:

$x_{t+1|t} = f_{kinematics}(x_{t}, u_t)$, with odometry $u_t$ instead of the control vector. To something like:

$x_{t+1|t} = x_{t}+\delta x$.

What have we lost? We have lost the ability to condition on the fact that the robot can only take certain types of movements, i.e., is kinematically constrained.  To compensate for this, what I've suggested is you then condition the estimate based on the liklihood given the kinematic model. That means, during the EKF_UPDATE step.

To do this, you need to find the conditional probability:

$P(\delta x | x_{t}, u_t)$


答:
For a design large enough for a person to ride, rider fatigue is also important -- how do they compare in terms of achievable ride smoothness, vibration, and so on?

Current and past designs tend to be pretty slow.

My vote is for chicken legs...

Title: I'm looking for hands-on experience with different types of leg and hip designs for walking robots

Body:
I'm looking to find out, How do human-like legs compare to chicken legs and four-leg systems. In terms of cost, performance, speed, strength and accuracy.

I'm interested in things like speed, agility, turning radius, complexity and cost.

For a design large enough for a person to ride, rider fatigue is also important -- how do they compare in terms of achievable ride smoothness, vibration, and so on?

Are there quantitative benefits of 3 DOF hip joints, compared to 2 DOF?

I realize other factors will come into play as well, such as actuators, joint designs and control systems.
However, my interest at the moment is how basic leg designs compare to one another.

Edit: I'm looking for someone who has used these mechanisms first hand.


问:
VFH (Vector Field Histogram+): Obtaining the Primary Polar Histogram
Good day

Note: I have found out that my code works. I have placed a minor explanation to be further expounded.

I have been having trouble obtaining the right directional output from my implementation. I noticed that every time I put an obstacle at the right, it gives left, it gives the right steering direction, the problem is with the presence of a left obstacle where it still tends to steer itself towards that obstacle. I have checked the occupancy map generated using matlab and was found to be correct. I couldn't pinpoint what is exactly wrong with my code for I have been debugging this for almost a week now and was hoping if someone can see the error I cannot.

Here is my code implementation:

```<code>//1st:: Create Occupancy Grid from Data-------------------------------------------------
// > Cell Size/Grid Resolution  = 5meters/33 cells = 0.15meters each = 15cm each
// > Grid Dimension = 5meters by 5meters / 33x33 cells //Field of view of robot is 54 degrees
//or 31 meters horizontal if subject is 5 meters away
// > Robot Width = 1meter 100cm
// > Because the focal length of the lens is roughly the same as the width of the sensor,
// it is easy to remember the field of view: at x meters away, you can see about x meters horizontally,
// assuming 4x3 stills mode. Horizontal field of view in 1080p video mode is 75%
// of that (75% H x 55% V sensor crop for 1:1 pixels at 1920x1080).

//Converting the Position into an Angle--------------------------------------------
//from:
//  A. https://decibel.ni.com/content/docs/DOC-17771
//  B. "USING THE SENSOR KINECT FOR LANDMARK" by ANDRES FELIPE ECHEVERRI GUEVARA
//1. Get angle
// > Each pixel from the image represents an angle
// > angle = ith pixel in row * (field of view in degrees/number of pixels in row)
// > field of view of Pi camera is 54 degrees horizontal
//2. Convert Polar to Cartesian
// > x = z*cos(angle)
// > y = z*sin(angle)

int arrOccupancyGrid[33][33];
float matDepthZ[33][33];
int robotPosX = 0;
int robotPosY = 0;
int xCoor=0; //Coordinates of Occupancy Map
int yCoor=0;
int xPosRobot=0; //Present cordinates of robot
int yPosRobot=0;
float fov = 54; // 54 degrees field of view in degrees must be converted to radians
float nop = 320; //number of pixels in row
int mapDimension = 33; // 33by33 array or 33*15cm = 5mby5m grid
int mapResolution = 15; //cm

//Limit max distance measured
/*
for(i=0; i< nop ;i++){
    if(arrDepthZ.at(i)>500){
        arrDepthZ.at(i) = 500;
    }
}
*/

for (i=0 ; i < nop; i++){
    //Process data/Get coordinates for mapping
        //Get Angle
        int angle = ((float)(i-160.0f) * ((float)fov/(float)nop)); //if robot is centered at zero add -160 to i
        //cout << "arrDepthZ " << arrDepthZ.at(i) << endl;
            //cout << "i " << i << endl;
            //cout << "fov " << fov << endl;
            //cout << "nop " << nop << endl;
            //cout << "angle " << i * (fov/nop) << endl;
        arrAngle.push_back(angle);
        //Get position X and Y use floor() to output nearest integer
        //Get X --------
        xCoor = (arrDepthZ.at(i) / mapResolution) * cos(angle*PI/180.0f); //angle must be in radians because cpp
        //cout << "xCoor " << xCoor << endl;
        arrCoorX.push_back(xCoor);
        //Get Y --------
        yCoor = (arrDepthZ.at(i) / mapResolution) * sin(angle*PI/180.0f); //angle must be in radians because cpp
                //cout << "yCoor " << yCoor << endl;
        arrCoorY.push_back(yCoor);
    //Populate Occupancy Map / Cartesian Histogram Grid

        if((xCoor <= 33) && (yCoor <= 33)){ //Condition Check if obtained X and Y coordinates are within the dimesion of the grid
            arrOccupancyGrid[xCoor][yCoor] = 1; //[increment] equate obstacle certainty value of cell by 1
            matDepthZ[xCoor][yCoor] = arrDepthZ.at(i);
        }

        //cout << "arrCoorX.size()" << arrCoorX.size() << endl;
        //cout << "arrCoorY.size()" << arrCoorY.size() << endl;

}

for (i=0 ; i < arrCoorX.size(); i++){
  file43 << arrCoorX.at(i) << endl;
}

for (i=0 ; i < arrCoorY.size(); i++){
  file44 << arrCoorY.at(i) << endl;
}

for (i=0 ; i < arrDepthZ.size(); i++){
  file45 << arrDepthZ.at(i) << endl;
}

//------------------------- End Create Occupancy Grid -------------------------

//2nd:: Create 1st/Primary Polar Histogram ------------------------------------------------------
//1. Define angular resolution alpha
// > n = 360degrees/alpha;
// > set alpha to 5 degrees resulting in 72 sectors from 360/5 = 72 ///// change 180/5 = 35
//2. Define number of sectors (k is the sector index for sector array eg kth sector)
// > k=INT(beta/alpha), where beta is the direction from the active cell
//to the Vehicle Center Point (VCP(xPosRobot, yPosRobot)). Note INT asserts k to be an integer

cout << "2nd:: Create 1st/Primary Polar Histogram" << endl;

//Put this at the start of the code away from the while loop ----------------
int j=0;
int sectorResolution = 5; //degrees 72 sectors, alpha
int sectorTotal = 36; // 360/5 = 72 //// change 180/5 = 36
int k=0; //sector index (kth)
int maxDistance = 500; //max distance limit in cm
//vector<int>arrAlpha; //already initiated

float matMagnitude[33][33]; //m(i,j)
float matDirection[33][33]; //beta(i,j)
float matAngleEnlarge[33][33]; //gamma(i,j)
int matHconst[33][33]; //h(i,j) either = 1 or 0

float robotRadius = 100; //cm
float robotSafeDist = 50; //cm
float robotSize4Sector = robotRadius + robotSafeDist;

for (i=0; i<sectorTotal; i++){
    arrAlpha.push_back(i*sectorResolution);
}
//---------end initiating sectors----------

//Determine magnitude (m or matMagnitude) and direction (beta or matDirection) of each obstacle vector
//Modify m(i,j) = c(i,j)*(a-bd(i,j)) to m(i,j) = c(i,j)*(dmax-d(i,j)) from sir Lounell Gueta's work (RAL MS)
//Compute beta as is, beta(i,j) = arctan((yi-yo)/(xi-xo))
//Enlarge robot and compute the enlargment angle (gamma or matAngleEnlarge)
int wew =0;
int firstfillPrimaryH = 0; //flag for arrayPrimaryH storage
for (k=0; k<sectorTotal; k++){
    for (i=0; i<mapDimension; i++){
        for (j=0; j<mapDimension; j++){
            //cout << "i" << i << "j" << j << "k" << k << endl;
            //cout << "mapDimension" << mapDimension << endl;
            //cout << "sectorTotal" << sectorTotal << endl;
            //Compute magnitude m, direction beta, and enlargment angle gamma
            matMagnitude[i][j] = (arrOccupancyGrid[i][j])*( maxDistance-matDepthZ[i][j]); //m(i,j)
            //cout << "matMagnitude[i][j]" <<  (arrOccupancyGrid[i][j])*( maxDistance-matDepthZ[i][j]) << endl;
            matDirection[i][j] = ((float)atan2f( (float)(i-yPosRobot), (float)(j-xPosRobot))*180.0f/PI); //beta(i,j)
            //cout << "matDirection[i][j]" << ((float)atan2f( (float)(i-yPosRobot), (float)(j-xPosRobot))*180.000/PI) << endl;
            //cout << "matDepthZ[i][j]" << matDepthZ[i][j] << endl;
            if(matDepthZ[i][j] == 0){ //if matDepthZ[i][j] == 0; obstable is very far thus path is free, no enlargement angle
                matAngleEnlarge[i][j] = 0; //gamma(i,j)
                //cout << "matAngleEnlarge[i][j]" << 0 << endl;
            }
            else{ //if matDepthZ[i][j] > 0 there is an obstacle so compute enlargement angle
                matAngleEnlarge[i][j] = asin( robotSize4Sector / matDepthZ[i][j])*180/PI; //gamma(i,j)
                //cout << "matAngleEnlarge[i][j]" << asin( robotSize4Sector / matDepthZ[i][j])*180.0f/PI << endl;
            }

            wew = k*sectorResolution; //k*alpha
            //cout << "wew" << k*sectorResolution << endl;
            //Check if magnitude is a part of the sector
            if ( ((matDirection[i][j]-matAngleEnlarge[i][j]) <= wew) && (wew <= (matDirection[i][j]+matAngleEnlarge[i][j])) ){
                matHconst[i][j]=1; //Part of the sector
                //cout << "Part of the sector ---------------------------------------------------------------" << endl;
                //cout << "matHconst[i][j]=1" << matHconst[i][j] << endl;
            }
            else{
                matHconst[i][j]=0; //Not Part of the sector
                //cout << "Not Part of the sector" << endl;
                //cout << "matHconst[i][j]=0" << matHconst[i][j] << endl;
            }
            //Compute primary polar histogram Hp(k)
            //cout << "firstfillPrimaryH" << firstfillPrimaryH << endl;
            if (firstfillPrimaryH==0){ //If first fill at sector
                //cout << "matMagnitude[i][j]" << matMagnitude[i][j] << endl;
                //cout << "matHconst[i][j]" << matHconst[i][j] << endl;
                float temp = matMagnitude[i][j]*matHconst[i][j];
                //cout << "matMagnitude[i][j]*matHconst[i][j]" << temp << endl;
                arrPrimaryH.push_back(temp);
                firstfillPrimaryH=1; //Trigger flag
                //cout << "arrPrimaryH kth" << arrPrimaryH.at(k) << endl;
            }
            else{ //If sector filled previously
                arrPrimaryH.at(k) = arrPrimaryH.at(k)+(matMagnitude[i][j]*matHconst[i][j]);
                //cout << "arrPrimaryH kth" << arrPrimaryH.at(k) << endl;
            }

        }
    }
    firstfillPrimaryH=0; //Reset flag
}
</code>```

答: I have found out that my code works. It is just that most of the literature I have read uses Lidar or Sonar sensors for histogram updates. I had assumed that in the case of a stereo vision set-up, all sectors are updated simultaneously. However only the sectors in the field of view of the camera is update unlike in the lidar implementation that samples a complete 360 degree sweep of its surroundings. Another thing I have found out that when deriving the X and Y coordinates from the depthmap, the resulting map is a mirror image of the actual surrounding thus the sectors must be labeled counter clockwise. I used the formula from NI' s paper linked at the code. The same case is also true when using the camera matrix with open cv to obtain the real world X,Y coordinates from the depth map. I shall edit this question to a clearer one soon :)</p>


问:
Distance calculation with two robots and two obstacles
I have a problem with two robots and two obstacles in a space. Each robot can communicate its measurements to the other and can measure angles and distances.
The two obstacles in the environment are identical to each other.

Each robot can see both obstacles but not each other. Therefore have angle theta 1 and 2 combined with distance 1 and 2. Can the distance between the two robots be calculated?

So far I have placed circles with radius of the measured distance over each landmark (triangles in my workings), this provides 4 possible positions for each robot. Red and black circles correspond to robot 1 and blue and green to robot 2. Using the relative size of the angle measurements I can discount two of these positions per robot.
This still leaves me with two possible positions for each robot shown with the filled or hashed circles.

Is it possible to calculate which side the robot is to the landmarks and the distance between each other?

Robot 1 only has the two measurements of angle and distance and can therefore assign an id to each obstacle, but when information is transmitted to robot 2, robot 2 does not know which obstacle will have been designated an id of 1 or 2.

答:
Is it possible to calculate which side the robot is to the landmarks and the distance between each other?

No, because the whole thing is point symmetric around the point in the middle between both obstacles. Each robot could be on either side, which gives 2 possible values for the distance between them, either for both being on the same side or being on opposite sides.

Some solutions could represent both robots colliding with each other and you could rule those out if they are not colliding, but in general, you don't know which solution is correct.

Each robot can see both obstacles but not each other.

Whatever property of the obstacles is used to identify them could possibly be added to each robot, which could then be detected by the other one.

Each robot can communicate its measurements to the other and can measure angles and distances.

In theory, you could measure the time this communication takes. Either by

having synchronized clocks and sending a time stamp or

having each robot throw the message received back at the other robot immediately to let the signal travel the distance twice.

From that time and the speed you can calculate the distance. In practice, if the signal speed is very high, you need very precise timers to do this properly.


问:
How to get manufactured part from CAD file?
I am working through the book Learning Robotics using Python, which is for Python programmers who want to learn some robotics. Chapter 2 shows you how to use LibreCAD to design the plates and poles that form the chassis of the turtlebot-like robot. For instance, the base plate looks like this:

Then, there is nothing more about it but suddenly in a later chapter there is a picture of the fully manufactured plates assembled into a chassis, and the author acts as if this should just be something we know how to do:

How did he do that? We have these CAD drawings, and suddenly there are these plates that were manufactured via some magical process the book never discusses, he never gives things like tolerances, the material that they are supposed to be made out of, etc., the kinds of things discussed here:

http://www.omwcorp.com/how-to-design-machined-parts.html

I know nothing about this stuff, in terms of how to go from CAD design specs to getting an actual part manufactured. What kinds of companies should I use, what is a reasonable price to expect, what is the process?

In general, how do I go from CAD design to manufactured item? Do I find a local machine shop that specializes in robotics, bring my CAD drawings, and work with them to try to build the parts?

I am totally a noob, I hope this isn't a question like this:

http://blog.stackoverflow.com/2010/11/qa-is-hard-lets-go-shopping/

答:
I think this is a great question.

The two basic options are make it yourself or have someone else make it. EDIT: check the bottom for a third option...

Make it yourself

To make it yourself you need to choose a material and manufacturing process for the part, then acquire the material and skills needed. (Usually people select a process they know how to do already.)

For a hobby robot, often the exact material is not too important. For instance, for the part you show, you could make it from wood, plastic, or metal and it would work ok. Cardboard or corrugated plastic (for making posters) would work too and you could cut it with a hobby/xacto knife.

The way to go is to find a friend that likes to make things and then get their help to learn some making skills. You can also try learning from a website or book. (another website)

Have someone else make it

There are some companies that focus on the hobby market and you may find their services the easiest to use. Pololu and eMachineShop are two of many. I have never used them so you should read reviews online to determine if they will work for you.

There are lots of companies that specialize in fabricating parts using one process or another. You would have to learn a little bit about each process to choose whether it will work for any given part. If you are only making a few parts it is usually too expensive for a hobby project. eMachineShop is an easy way to get a general idea of what the cost of different processes because you can create your shape and then ask for quotes for different processes to make that shape. Laser cutting vs machining for the circular plate for instance.

If you can afford to use eMachineShop, it's definately worth checking out your local shops. The two factors that determine the cost are the quantity of parts and how "hungry" the shop is, meaning, how much business do they have going on right now. It's harder work to contact a lot of local shops, but if you do, you will probably be able to find one that will be cheaper than eMachineShop.

For simple shapes there are companies that have a catalog of basic designs for which you can change some dimensions or details when you order. Misumi is a good example. For basic shapes like shafts, brackets, bearing blocks and spacers, there is a good chance that you can get a semi-custom part cheaper than if you had a shop make it.

Option 3 - Adapt something that is close

There is no rule that you have to start from raw, unprocessed, material when making something. You can use something you find in a junk yard or at a store that is close to what you want and make small changes to it. Also, very few robots are made entirely from scratch. They all use components like bearings, motors, couplings, gears, and other things. There are many sources for these components. In the US, McMaster Carr is a good place to start, RS is an international company worth checking.


问:
How to further understand the computed torque model controller
For the following controller what do $q_{des}$ and $q_{act}$ stand for? Also, what is the general principle of this controller?

Thanks!

答:
Setting desired values for a robot's joints $q$ and measuring the actual values is fundamental to any feedback control scheme.   I suggest you study the basics of feedback control if you are getting stuck on the meaning of those terms.

This controller allows the robot to achieve a desired position in joint space, $q$, with a PD control law that computes joint accelerations necessary to achieve those positions.   It then adds in a desired joint acceleration $\ddot q$ (this may be the novelty of this approach but I need more background information to confirm that) which, when passed through the system dynamics model $D$, determines the torques $\tau$, to apply to each motor.   $h(q, \dot q)$ appears to be a position and velocity observer that ensures $q$ achieves its final state, or it may be the actual plant dynamics.   I can clear up this answer if you also post more details about how the controller is defined from whatever reference you are using.


问:
kalman filter with redundant sensors
Suppose I have one robot with two 3D position sensors based on different physical principles and I want to run them through a Kalman filter. I construct an observation matrix two represent my two sensors by vertically concatenating two identity matrices.

$H = \begin{bmatrix} 1&0&0\\0&1&0\\0&0&1\\1&0&0\\0&1&0\\0&0&1 \end{bmatrix}$ $\hspace{20pt}$
 $\overrightarrow x = \begin{bmatrix} x\\y\\z \end{bmatrix}$

so that

$H \overrightarrow x = \begin{bmatrix} x\\y\\z\\x\\y\\z \end{bmatrix}$

which represents both sensors reading the exact position of the robot. Makes sense so far. The problem comes when I compute the innovation covariance

$S_k = R + HP_{k|k-1}H^T$

Since

$H H^T = \begin{bmatrix}
 1 & 0 & 0 & 0 & 0 & 1 \\
 0 & 1 & 0 & 1 & 0 & 0 \\
 0 & 0 & 1 & 0 & 1 & 0 \\
 0 & 1 & 0 & 1 & 0 & 0 \\
 0 & 0 & 1 & 0 & 1 & 0 \\
 1 & 0 & 0 & 0 & 0 & 1 \\
 \end{bmatrix}$

then, no matter what $P$ is, I'm going to wind up with $x$ innovations from the first sensor being correlated to $z$ innovations from the second, which seems intuitively wrong, if I'm interpreting this right.

Proceeding from here, my gain matrix ($K = P_{k|k-1} H^T S_k^{-1}$) winds up doing some pretty odd stuff (swapping rows and the like) so that, when updating a static system ($A = I_3, B = [0]$) with a constant measurement $\overrightarrow z = [1,0,0]$ I wind up with a predicted state $\hat x = [0,0,1]$.

If I separate the sensors and update the filter with each measurement separately, then $H H^T = I_3$, and I get sensible results.

I think I am confused about some technical points in one or more of these steps. Where am I going wrong? Does it not make sense to vertically concatenate the observation matrices?

I suppose that I could just set the off-diagonal 3x3 blocks of $S_k$ to 0, since I know that the sensors are independent, but is there anything in the theory that suggests or incorporates this step?

Title: kalman filter with redundant sensors

Body:
Are you sure about your expression for $HH^T$?

I get

$$
HH^T = \begin{bmatrix}
1 & 0 & 0 & 1 & 0 & 0 \\
0 & 1 & 0 & 0 & 1 & 0 \\
0 & 0 & 1 & 0 & 0 & 1 \\
1 & 0 & 0 & 1 & 0 & 0 \\
0 & 1 & 0 & 0 & 1 & 0 \\
0 & 0 & 1 & 0 & 0 & 1
\end{bmatrix}
$$
which agrees with your intuition.


问:
Issue using Digit LEDs Raw (op code 163) on Create2
If I understand the manual, each leg in each of the 7 segment displays is labeled with a letter A-G.  These letters then map to specific bits in a byte - 1 byte for each of the 4 displays.  Setting a bit turns on the corresponding leg while not setting it leaves it off.

With this understanding, I tried to turn on all the A segments by sending

```<code>[163][1][1][1][1]
</code>```

Instead of the A segment in each display turning on, the displays all showed a 1. Further testing shows that if I send the numbers 1-9 for any of the displays, they will display the number sent.  Sending the number 10 or greater turns on various combinations of the segments.

I was able to activate individual segments with the following numbers:

```<code>63 G
64 A
65 B
66 C
67 D
68 E
69 F
</code>```

However, I haven't been able to determine how the bytes sent affect the individual segments. Either I don't understand the manual or Digit LEDs Raw does not work as the manual specifies.

UPDATE 03JUNE2016

I have confirmed this behavior exists in the following firmware versions:

r3-robot/tags/release-3.4.1:5858 CLEAN

r3_robot/tags/release-3.2.6:4975 CLEAN

答:
From what I see here, it appears that the manual does not reflect the behavior that you are seeing.  The sequence of ASCII values [163][1][1][1][1] (0xA3 0x01 0x01 0x01 0x01) should produce 4 lit A segments on the display, just like you noted.

The behavior you're seeing doesn't even match what the manual says for code 164 (ASCII input).  For all the displays to show a '1', that command would be 0xA4 0x31 0x31 0x31 0x31.


答:
If you consider the system to be completely static (as you have drawn it), there is no way to know.

However, if the system you are describing is not limited to 2 obstacles and one precise moment in time, then your robots can discover where they are by moving around.  It sounds like the full set of data that your robot has access to -- at every timeslice -- is the following:

Unordered set of (distance, angle) pairs, indicating the obstacles it sees

Unordered set of (distance, angle) pairs, indicating the obstacles the other robot sees

Distances and angles to landmarks are the raw inputs for the SLAM algorithm.  So in the most extreme case, each robot would be able to run SLAM for both itself and the other robot (based on reported positions), merge the two maps, and then calculate the distance between the localized positions of each robot on that map.

There may be a simpler way to do it that I'm completely overlooking.  However, based on the assumption that the obstacle IDs are not shared between robots, I'm not sure how that might work.

Title: Distance calculation with two robots and two obstacles

Body:
I have a problem with two robots and two obstacles in a space. Each robot can communicate its measurements to the other and can measure angles and distances.
The two obstacles in the environment are identical to each other.

Each robot can see both obstacles but not each other. Therefore have angle theta 1 and 2 combined with distance 1 and 2. Can the distance between the two robots be calculated?

So far I have placed circles with radius of the measured distance over each landmark (triangles in my workings), this provides 4 possible positions for each robot. Red and black circles correspond to robot 1 and blue and green to robot 2. Using the relative size of the angle measurements I can discount two of these positions per robot.
This still leaves me with two possible positions for each robot shown with the filled or hashed circles.

Is it possible to calculate which side the robot is to the landmarks and the distance between each other?

Robot 1 only has the two measurements of angle and distance and can therefore assign an id to each obstacle, but when information is transmitted to robot 2, robot 2 does not know which obstacle will have been designated an id of 1 or 2.

ContentLicense: CC BY-SA 4.0


问:
augmenting room magnetic field for smartphone sensors
is it possible to enhance (or redirect) the earth's magnetic field in a room or house so that one can write a small program that makes smartphones with hall-effect sensors detect more reliably in which direction they are pointing?

I presume a fridge magnet won't do the job...

答:
This question might be better suited to the Physics StackExchange, but the back-of-the-envelope calculation goes like this:

The Earth's magnetic field is 31.869 µT, and a refrigerator magnet is 5000µT.  So the refrigerator magnet will very readily affect the magnetometer (not usually called a hall-effect sensor) on a smartphone.

However, you will run into two very serious problems

The strength of a magnet follows the inverse square law -- it drops off rapidly with distance.  You can verify this with a handheld compass: see how close your magnet needs to be in order for it to pull the needle away from magnetic north.

The magnetic field curves around the magnet.  For the earth, this is not a major concern because you are (more or less) standing on the surface where the lines run (more or less) straight from north to south.

For your room-sized magnetic field to work, you would need to establish a magnet far enough away that its field lines would have minimal curvature through the area that you want to measure, and strong enough that those field lines would have enough strength to dominate the 31.869 µT provided by Earth's magnetic field.


答:
One of the most common controllers is a computed-torque controller, also known as the inverse dynamics. The preceding controller is based on the feedback linearization principle which is an approach that maps a nonlinear model into a linear one and treats it as such as we will show momentarily. Consequently, one can utilize linear controllers such as PD and PID controllers to control nonlinear systems. For example, dynamics equation of robot is usually represented as follows,
$$
M(q) \ddot{q} + C(q,\dot{q}) + G(q) = \tau
$$

where $q, M(\cdot), C(\cdot), G(\cdot)$ and $\tau$ are a set of generalized coordinates, the inertia matrix, the Coriolis/Centripetal vector, the gravity vector and the control input, respectively. One of many goals of a control engineer is to choose the control input $\tau$ so that the robot should follow a desired trajectory (i.e. denoted as $q_{des}$ or $q_{d}$ for short). The aforementioned equation can be rewritten as

$$
\ddot{q} = M^{-1}(q)[\tau  - C(q,\dot{q}) - G(q)]
$$

Now if we can cancel the nonlinear terms (i.e. $M(\cdot), C(\cdot)$ and $G(\cdot) $), then we can choose any linear controller. Assume now the matrix $M(\cdot)$ and the vectors $C(\cdot), G(\cdot)$ are given, therefore, one can easily choose the control input $\tau$ as follows

$$
\tau = M(q)[ \Lambda] + C(q,\dot{q}) + G(q)
$$

where $\Lambda$ depends on the chosen controller. In the PD computed-torque, $\Lambda$ is defined as follows
$$
\Lambda = \ddot{q}_{d} + k_{p} \dot{e} + k_{d} e
$$

where $e$ is the tracking error $ e(t) = q_{d}(t) - q(t)$ which is defined as the difference between the desired and actual joint angles (i.e. they  are in your case $q_{des}$ and $q_{act}$ ). The disadvantage of computed-torque control is the fact that the parameters of the model must be provided precisely. If there is uncertainly which is always the case,   the PD computed-torque controller is not applicable. It is solely utilized in a pure simulation. Another disadvantage of the preceding controller is the fact that it requires the measurements of joint angles, hence the feedback name.

Note: I think you can now see how the diagram is generated from the above equations.

Title: How to further understand the computed torque model controller

Body:
For the following controller what do $q_{des}$ and $q_{act}$ stand for? Also, what is the general principle of this controller?

Thanks!


问:
Can too much input current destroy my motor driver?
I have a 18 V rated driver I'm using to drive two 12 V DC gear motors using my Arduino. I bought a new battery pack which is rated 3300 mAh 25C, 11.1V making the total current input 82.5 A. My driver is rated for 7 V min and 18 V max, no current rating is given.

My motors are 12V max current under load is 9.5 A.

So just to be sure, can using this battery destroy my motor driver?

This is the datasheet.

答:
You are approaching the problem from wrong side. Current capability of a battery (25C) has nothing to do with that how much current will it actually source. It is the load (motors in that case) what defines the current, not the battery. You could use 10C, 25C, 50C battery, and the current flowing through the motors would be (approximately) the same, as long as it does not exceed the maximum current allowed for the battery (82 Amps in your case)

As a side note - I find it hard to believe, that there is no maximum current defined in the motor driver datasheet. It is the key information. Please post te link to the datasheet, or just a part number.


问:
Quadcopter: X-Y Velocity PID Controller
Good day,

Introduction

I am currently working on an autonomous quadcopter project. I have currently implemented a cascaded PID controller consisting of two loops. The inner rate loop takes the angular velocity from the gyroscope as measurements. The outer stabilize/angle loop takes in angle measurements from the complementary filter (gyroscope + accelerometer angles).

Question:

I would like to ask if it is effective to cascade a Lateral Velocity (X and Y - axis) PID controller to the the Angle Controller (Roll and Pitch) to control drift along the X-Y plane. For the outermost PID controller, the setpoint is 0 m/s with the measured velocities obtained from integrating linear accelerations from the accelerometer. This then controls the PID controller responsible for the Pitch (if Y velocity PID) and Roll (if X velocity PID).

答:
Your setup as is will certainly not work. Roll and Pitch do not map to X and Y one-to-one. You will need to use linear algebra to convert demanded XY (see this stack overflow question on how) into roll, pitch, and yaw for control.  Moving only one will not move the other.  </p>

<p>For your general question about cascaded PID controllers, that part of your strategy is on the right track. It is possible to cascade PID controllers, and PID controllers are frequently used in cases where an inner loop or plant is unmodelable. </p>

Title: Quadcopter: X-Y Velocity PID Controller

Body:
Your setup as is will certainly not work. Roll and Pitch do not map to X and Y one-to-one. You will need to use linear algebra to convert demanded XY (see this stack overflow question on how) into roll, pitch, and yaw for control.  Moving only one will not move the other.

For your general question about cascaded PID controllers, that part of your strategy is on the right track. It is possible to cascade PID controllers, and PID controllers are frequently used in cases where an inner loop or plant is unmodelable.


问:
What software to use to send (OI) commands to Create 2. Using windows laptop and supplied Create 2 cable?
I read most of the iRobot Create 2 Open Interface (OI). It says send these serial commands to the Create 2 to get it to do the described action, but no suggestion of what software to use to send these serial commands through the USB interface.  I did install the FTDI Drivers to enable the USB to serial connection.  Question: What serial software should I use to communicate with Create 2?  Is there a tool to verify that the supplied usb to serial cable supplied with Create 2 is functioning and if the Create 2 is functioning? (I did a reset on Create 2 using Spot and Dock buttons)</p>

答:
Any serial port terminal emulator program should let you read the spew when the robot is reset.  This will verify the cable (at least the RX path).  Hyperterminal used to be a good one on Windows.  Realterm and Putty are also good.

To verify the TX path of the cable, you can send the BELL character (ASCII code 7) which will reset the robot.  I think most emulators should let you send this with CTRL-G.  Unfortunately, this is the only command you can send to the robot from a terminal emulator.  To send any more commands, you need send commands programmatically.