问:
How to interrupt on a data ready trigger when communications to the sensor are interrupt driven?
Background: I'm using the L3GD20H MEMS gyroscope with an Arduino through a library (Pololu L3G) that in turn relies on interrupt-driven I2C (Wire.h); I'd like to be able to handle each new reading from the sensor to update the calculated angle in the background using the data ready line (DRDY). Currently, I poll the STATUS register's ZYXDA bit (which is what the DRDY line outputs) as needed.

General question: With some digital output sensors (I2C, SPI, etc.), their datasheets and application notes describe using a separate (out-of-band) hardware line to interrupt the microcontroller and have it handle new sets of data. But on many microcontrollers, retrieving data (let alone clearing the flag raising the interrupt line) requires using the normally interrupt-driven I2C subsystem of a microcontroller. How can new sensor data be retrieved from the ISR for the interrupt line when also using the I2C subsystem in an interrupt-driven manner?

Possible workarounds:

Use nested interrupts (as @hauptmech mentioned): re-enable I2C interrupt inside of ISR. Isn't this approach discouraged?

Use non-interrupt-driven I2C (polling)--supposedly a dangerous approach inside of ISRs. The sensor library used depends on the interrupt-driven Wire library.

[Edit: professors' suggestion] Use a timer to interrupt set to the sample rate of the sensor (which is settable and constant, although we measure it to be e.g. 183.3Hz rather than 189.4Hz per the datasheet). Handling the I2C transaction still requires re-enabling interrupts, i.e. nested interrupts or performing I2C reads from the main program.

[Edit:] Here's a comment I found elsewhere on a similar issue that led me to believe that the hang encountered was from I2C reads failing inside an interrupt handler: https://www.sparkfun.com/tutorials/326#comment-4f4430c9ce395fc40d000000

…during the ISR (Interrupt Service Routine) I was trying to read the
  device to determine which bit changed. Bad idea, this chip uses the
  I2C communications which require interrupts, but interrupts are turned
  off during an ISR and everything goes kinda south.

答:
I'm using the L3GD20H MEMS gyroscope with an Arduino ...
  How is the sensor's interrupt line intended to be used if the
  microcontroller can't handle the interrupt from an ISR using an
  interrupt-driven I2C subsystem?

I'm assuming you've already looked at the L3GD20H datasheet and the L3GD20H errata sheet,
and you understand that the data-ready pin (DRDY) is sometimes called an interupt pin (INT2), not to be confused with "the" programmable interrupt pin (INT1).
In particular,
p. 45 of the datasheet says that reading the IG_SRC register clears the interrupt signal on INT1.

If I were you, my next step would be to look at Arduino software for the L3GD20H and see how they handled it.
(If someone has already done it, it must be possible, right?)

The Adafruit L3GD20 Library for the Arduino

The NorDevX L3GD20H Gyro Arduino Code Using I2C

The Pololu L3GD20 Arduino library

easy method

Perhaps the easiest method is polling: connect the interrupt pin of the L3GD20H up to some general-purpose digital input pin of the Arduino.
Then write a function to check that pin and do the appropriate things.
Then call that function every time through the main loop().

Just because a pin is labeled "interrupt" doesn't mean it has to be handled by an interrupt routine.

currently more difficult method

Several people have requested that someone improve the Wire library to make it non-blocking
(
"Wire library and blocking";
"Make Wire library non-blocking";
"I2C Wiring Library - Lockup";
etc.
).

With such a theoretical future Wire library,
you could write one interrupt handler that handles a pin-change interrupt of some Arduino pin connected to the interrupt pin of the L3GD20H.
On a low-to-high change, that interrupt handler would do nothing and immediately return.
On a high-to-low change, that interrupt handler would call the (non-blocking)
functions of the Wire library that
appends the appropriate message to the end of a queue in a RAM buffer.
If the I2C hardware was idle at that instant (i.e., it wasn't already in the middle of sending out a byte, possibly in the middle of a message to some other device on the I2C bus),
that (non-blocking) function would pull the first byte of the next message in the queue and start sending it out the I2C hardware.

Much later, after that interrupt handler returned to the main loop(),
the I2C hardware would finish transmitting a byte (the first byte of this message, or some byte in some previous message),
and that I2C hardware would trigger a different interrupt handler (internal to the improved Wire library) that would pull the next byte from the queue in RAM and start sending that byte out the I2C hardware, check for and buffer up any incoming byte in the I2C hardware, etc.


问:
Blade 180QX :What does this red wire do?
I have a Blade 180QX quadrotor / quadcopter and I had to move a red wire shoved under the circuit board when I fixed a broken power wire. Now the red wire shown out straight from the circuit board is not in the right configuration - or at least as it was. If I understood what it was for I might know how to place it. Is this a horizon sensor (temperature)?
Ever since I had to move this wire, the quadrotor goes unstable when flying. The only appreciable change is the wire POSITION.
The red wire was not attached anywhere else on the board. It was shoved under the circuit board inside the battery holder.

答:
The red wire is the antenna. It can be seen sticking out of the board if you google for other images of "Blade 180QX board". It should only be connected at one end.

This thread recommends that you stick it out the side rather than putting it under the board, which is what would generally be the advice for antenna.

It might be that by repositioning it you have introduced some interference, but the new position should introduce less interference, so it's possible that something else is causing your unstability.

ContentLicense: CC BY-SA 3.0


答:
Whilst not wishing to detract from Rob's answer, and following on from Pete's suggestion of googling for other images, if you go to the manufacturer's website, Bladehelis, for that particular product, and look at the replacement parts link, you will see the controller board listed, the 5-in-1 Ctrl Unit, RX/ESC/Mix/Gyros/Ch6: 180 QX HD. On that page there is an image, albeit not a particularly good one, that clearly shows the red wire/antenna:

Without wishing to go into the mechanics of antennas (for this, take a look at How antenna radiates(how currents flows through wire)), it is sufficient to say that antennas only require to be connected to the PCB at one end, and so, you have not damaged your device, nor have you accidently disconnected the other end of the red wire, as it is meant to be "loose" anyway.

The manual, unfortunately, is of no help at all, with regards to this matter.

As an aside, if you want to have a look at a good blog about this copter, then take a look at Blade 180 QX HD Quadcopter Breakdown, on diysoup. There are plenty of photos of the PCB there, as well as a wealth of other information.

Title: Blade 180QX :What does this red wire do?

Body:
I have a Blade 180QX quadrotor / quadcopter and I had to move a red wire shoved under the circuit board when I fixed a broken power wire. Now the red wire shown out straight from the circuit board is not in the right configuration - or at least as it was. If I understood what it was for I might know how to place it. Is this a horizon sensor (temperature)?
Ever since I had to move this wire, the quadrotor goes unstable when flying. The only appreciable change is the wire POSITION.
The red wire was not attached anywhere else on the board. It was shoved under the circuit board inside the battery holder.


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

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

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

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

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

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

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

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

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

答:
First let me state that how long it takes you to drive to a particular location or whether the batteries are used, etc. is all too specific to your scenario to matter with regards to what appears to be your root question, which is,

"Is there a difference in technology between a "solar battery" and a "wheelchair battery"?

In short, for what you have provided, the answer is no, there is no difference. The wheelchair batteries are lead-acid, as are the "solar batteries" and the batteries at your local battery shop.

Lead-acid batteries all charge at about the same voltage (14.7V), are all "dead" at about the same voltage (10.8V), etc. The specifics of each battery, such as the number of charge cycles you could expect, depth of discharge before you damage the battery, etc., would probably vary by manufacturer, but that data isn't typically published and you would have to contact the manufacturer to get it.

If I were you, I would use past experience with operational life (in minutes) that you got from your current battery and use that as a guide to spec the battery capacity for your next battery. Ignore driving times, because if you're purchasing the correct battery you should only have to get one. Also, I wouldn't buy a used lead-acid battery. They're easily abused and, just because it can be charged to full capacity doesn't mean that it will hold that capacity. Damaged lead-acid batteries form internal bridges that short out the battery internally; this is what happens with a battery that won't "hold" a charge.

Generally, try to prevent ever discharging past 20% of capacity. So, for the sake of an example, if your old battery was 20Ah, and you would run it until it was completely dead (open circuit voltage of 10.8V) to get your lawn dead, then:

It took 20Ah to mow your lawn.

You were damaging the battery discharging 100% of the capacity.

So, you should look at a battery where 20Ah is at least 80% of the capacity, meaning you need a battery of at least (20/0.8) = 25Ah capacity. Anything larger than this may be a waste of money, but anything under this capacity will very likely suffer a significantly shorter life expectancy due to over-discharging the battery.


问:
Accurate 3D Printing W/Sketchup
I have 3D printers at my school, but unfortunately they are not super high quality. I want to try 3D printing a model I made on google sketchup, but I would like for it to be fairly accurate.

What measures can I take to prevent error in the model? I understand that I need to export the file as an STL; is there anything I can do to the model before hand to ensure accuracy?

What can I do to calibrate a 3D printer for best results?

答:
What I've found 3d printing with SketchUp:

Use good geometry. Free Drawing should pretty much never be used. Make sure all of your arcs & angles are clean.

You can not have unclosed areas. Some programs are very good about this. Sketchup is not. Lines that go no where should be removed, and all lines should be connected to the model.

Pick a good ruby script for exporting as an STL. There are many free scripts available, and any of them should work if you do what is mentioned above.

Good Luck!

Title: Accurate 3D Printing W/Sketchup


问:
Finding high torque servo for robotic arm
I am new working with robotic arms but I am having trouble finding the correct servo for the base of the arm.

It is a 2 link robot - each link weighs 1.2 kg and is 40 cm long. I have a gripper of 10 centimeters. The servo in the gripper can hold a max of 4kg. The whole robotic arm, including the maximum load it will carry and the servos and other accessories, is 8.3 kg. The maximum load it needs to carry is 4 kg at the end of the arm at 90 cm.

What servo could I use to move the rotary base and what servo could I use to lift the arm in the base? The last one is to move the link so it would be preferable to have a 2 axis servo.

The only specification I need right now is what servo to use my energy supply are two 12 volts DC batteries connected in series with 18Ah. I need the servo to be DC. The other things can be worked around the servo that can best do the work.

答:
The only servo I can think about, for your case, is the HS-7950TH. It can operate between 4 and 7 volts and 300 mAh at max.

With its titanium gears, it has maximum stall torque of 35 kg when used with 7 volts and 300 mAh, that should be enough for your requirements.


问:
Understanding Drift in Simultaneous Localization and Mapping (SLAM)
I am trying to understand the effect of drift in Simultaneous Localization and Mapping (SLAM). My understanding is that drift occurs because the robot tracks its position relative to a set of landmarks it is storing, but each landmark has a small error in its location. Therefore, an accumulation of these small errors over a long trajectory causes a large error by the end of the trajectory.

However, what I am confused about is what would happen when the robot tracks its way back to its starting positions. Suppose the robot starts in position A, and then starts to move along a path, mapping the environment as it does so, until it reaches position B. Now, the robot will have some error in its stored position of B, due to the drift during tracking. But then suppose the robot makes its way back to A, by tracking relative to all the landmarks it created during the first path. When it reaches A, will it be back at the true position of A, i.e. where it started the first path? Or will it have drifted away from A?

My intuition is that it will end up at the true position of A, because even though the landmarks have errors in them, as long as the error is not too large then the robot will eventually get back to the position where it stored the landmarks for A. And once it is there, those landmarks are definitely correct, without error, because they were initialized before any drift errors had started to accumulate.

Any help? Thanks!

答:
Your intuition is mostly correct. Returning to where you started and re-observing landmarks you mapped earlier is called closing the loop in the SLAM literature. As you mentioned, your uncertainty will grow as the errors accumulate before you return to the start, if you don't have an absolute sensor. An absolute sensor is one that directly measures your state in the inertial coordinate frame (e.g., GPS). If you are relying on relative sensors (e.g., wheel encoders, an IMU, laser scanner), your uncertainty will grow. This is called dead reckoning in the literature.

Closing the loop can be difficult because how do you know you've returned to the start? How do you know the landmarks you're observing now are the same ones you observed when you started? This depends on a number things. For example, if the landmarks have some sort of unique signature about them (e.g., this is possible with some computer vision algorithms), you can look up each landmark you come across in your "dictionary" of landmarks you've seen so far. But let's say the landmarks are trees that all kind of look the same and you have a laser scanner. Well if you have been keeping track of your uncertainty properly, and you know the uncertainty of your measurements, you can determine the likelihood any new landmark is one you've seen before by calculating the Mahalanobis distance (i.e., distance that takes uncertainty into account) between new observations and landmarks in your current map. If the Mahalanobis distance is below some threshold, then you say you've found a match.

Once you've successfully closed the loop, depending on your SLAM algorithm, the uncertainty in your pose and the landmarks in your map becomes greatly reduced. This intuitively makes sense when you think about it. Let's say right before you close the loop, the uncertainty in your position was $\pm 3$ metres. Then your laser scanner (which has noise of $\pm 0.02$ metres) measures a landmark that you saw earlier, whose position you know pretty well (e.g., $\pm 0.05$ metres). It then makes sense that you know your position way better now! But wait, what about the other landmarks in your map? Their uncertainties are correlated with the uncertainty of your position because they were measured from the robot (these correlations manifest themselves in the off-diagonal terms of your covariance matrix). Then it only makes sense that drastically improving knowledge of your pose also improves your map!

So you're definitely on the right track. If you want to learn more, there is a good chapter on this topic in Probabilistic Robotics by Thrun et al. that has some pretty pictures showing the effects of loop closures. Here is a video that shows a loop closure (watch what happens to the uncertainty ellipses around both the robot and the landmarks when the robot returns to the start).


问:
Having a hard time understanding this equation in monocular EKF SLAM
Reading this paper on visual odometry, where they have used a bearing vector to parameterize the features. I am having a hard time understanding what the state propagation equation for the bearing vector term means :

The vector N is not mentioned in the equations, so its not very clear what it does. Would really appreciate if someone would help me understand it :)

答:
The text says:

[...] where $N^T (\mu)$ linearly projects a 3D vector onto the 2D
  tangent space around the bearing vector $\mu$ [...]


问:
KUKA delimiter .NET
I have a chance to develop a user interface program that lets the user control a KUKA robot from a computer. I know how to program stuff with the KUKA utilities, like OrangeEdit, but I don't know how to do what I want to do. I don't even know what's the "best" language to talk to the robot.

My idea is to control the robot with the arrow buttons, like up/down controls the Z axis and left/right controls the X/Y axes.

Can someone help me here? I know there's a lot of libraries to control the robot even with an Xbox controller, but if I limit the robot to 3 axes I might be able to control with simple buttons.

Edit: Now imagine that i have a routine that consists on going from P1 to P2 then to P3. I know i can "touch up" the points to refresh its coordinates using the console, but can i do it in a .net application? like modifying the src/srcdat files?

答:
I assume you are working with a KRC4 or KRC2 controller since you have mentioned OrangeEdit.

In order give your robot motion reference values you will need a technology packet called RSI Interface. This allows you to transmit ethernet packets to the controller and give new motion references with a 12 ms cylcetime. All you have to do is generate the required message (XML format) from a PC application based on the values of coming from your joystick. I think this approach is the best, preimplemented libraries you can find here: https://sourceforge.net/projects/kct/ or https://github.com/erensezener/kuka-rsi3-communicator

There are also other approches, exploiting some workarounds.
https://www.mb.hs-wismar.de/cea/Kuka_KRL_Tbx/Kuka_KRL_Tbx.html
 or
http://home.mis.u-picardie.fr/~fabio/Eng/documenti/articoli/ChScMoPr_RAM11.pdf

EDIT:
Once the src and dat files are loaded in memory they cannot be changed. You can still give new reference waypoints to the robot  with the above mentioned tools/interfaces.

If the said program is not loaded in memory, you can do a .net ftp server, ftp in the Kuka controller, do the file operations for changing the coordinates. However, I do not think that a Kuka program can be loaded into memory and executed without any manual intervention (e.g switch mode selector to AUT or EXT).

EDIT2: you mentiond KRC4. KRC4 supports customized HMI so instead of a PC connection you might get the same functionality by making an HMI screen with buttons and use the 6D mouse on the console (KCP), instead of a joystick.

Title: KUKA delimiter .NET


答: Also you might want to take a look at Dynamixel servos. They are the mot powerful I have found with a suprisingly open control system.</p>

Title: Finding high torque servo for robotic arm

Body:
I am new working with robotic arms but I am having trouble finding the correct servo for the base of the arm.

It is a 2 link robot - each link weighs 1.2 kg and is 40 cm long. I have a gripper of 10 centimeters. The servo in the gripper can hold a max of 4kg. The whole robotic arm, including the maximum load it will carry and the servos and other accessories, is 8.3 kg. The maximum load it needs to carry is 4 kg at the end of the arm at 90 cm.

What servo could I use to move the rotary base and what servo could I use to lift the arm in the base? The last one is to move the link so it would be preferable to have a 2 axis servo.

The only specification I need right now is what servo to use my energy supply are two 12 volts DC batteries connected in series with 18Ah. I need the servo to be DC. The other things can be worked around the servo that can best do the work.


问:
Does anyone have any walking patterns for a Biped Scout? (LYNXmotion)
I recently got a LYNX Biped Scout and found that it is really hard to actually come up with a working "Gait" or walking pattern.

Making a servo move is easy, that's not the problem, I previously built a robotic arm from scratch (I have pictures if anyone is interested) and that one can be controlled via Arduino and a few potentiometers as it only has 4 degrees of freedom so it's not too hard to keep track of the different limbs.

However the Scout is a different beast entirely. It's a purpose built kit with 12 servos and to control them I'm using the LYNX SSC-32 Sequencer which is distributed freely on their website. The only problem is that making them all move in sequence to produce a convincing walking motion is actually really hard.

Has anyone got any patterns for this robot they would be happy to share?

答:
I recently acquired a scout like you and am facing a similar problem.
I don't know of any areas with gaits predefined, so you'll have to experiment.
For short term you could hard-code a walking gait into a micro-controller.
For long term you will need to program a micro-controller with inverse kinematics
and possibly Zero Moment Point (or you could hard-code balance) and then feed that data for foot positions.

Hope this helps :)


问:
Vision-based Position Estimation for a quadrotor
As a subtask inside a main project I need to compute the position (x,y,z) of a quadrotor using an homography.

To do this I will use a camera (attached to the quadrotor) pointing down to an artificial landmark on the floor. Basically I need to compute the extrinsic parameters of the camera to know the pose with respect to the landmark. I know the projective points of the landmark in the camera, and the intrinsic matrix of the camera but I also need the real landmark position [X, Y, Z].

I suppose that Z coordinate is equal to 0 because the landmark is plane, but I am not sure how to compute the real [X,Y] coordinates.

Any idea how to do that?

I am also interested in put the (x,y,z) position of the quadrotor into a control path, anybody knows where I can find info about the most common controllers for do this kind of task?

答:
It's odd that you're suggesting computing the position of a landmark.  Literally, a mark on the land -- a position that you should already know and will use to localize your vehicle.  You can give it whatever arbitrary location you want.

If you have only one landmark, the most logical choice for it is [0, 0, 0].  Or, you could determine the X,Y coordinates that match the landmark's location within the room.  As long as all the fixed-position objects are assigned coordinates from the same grid, it doesn't matter what they are.


问:
Lateral load on a servo motor
Looking at pictures of existing designs for quadropod robots, the servos in the legs seem to usually be mounted inside the chassis, with a second attachment at back of the servo as well, such as this:

rather than putting what looks like an asymmetrical load, like the knees here:

Is this for aesthetics or are there real structural reasons to minimize the lateral load on the axle on a robot of this size?

答:
The second design will put more stress on the servos over time, so there are indeed real structural reasons for the design.

However, it also looks like the second design is more of a prototype compared to the first.  And it's possible that the second design is trying to save weight, sacrificing some servo life in the interest of that goal.

Reducing total weight and increasing the speed at which you can iterate on your design are just 2 possible factors for why you might use a component in a suboptimal way.  Those tradeoffs really come down to individual preference.

Title: Lateral load on a servo motor


答:
Because a camera is a range-only sensor, you cannot directly estimate the relative position of the object.
Additionally, because you have only one object, there are infinite solutions that are equally possible, given only the angular camera measurements.

Possible solutions:

If you have two images with a known relative position between the two, then you can use single-camera stereo vision to estimate the relative position between the quadrotor and the object.

Another solution is to use range-bearing SLAM and set very high initial range uncertainty, and range observation noise[1][2]. You can estimate the observed range using trigonometry with a level-body assumption and altimeter readings, this will be really inaccurate but SLAM should significantly improve the estimate.

Finally, if you can simply add more objects that you can uniquely identify and know the relative positions of them, then you can use OpenCV solvePnP (see similar question [3]).

[1] http://www.iri.upc.edu/people/jsola/JoanSola/eng/toolbox.html

[2] http://www.mrpt.org/List_of_SLAM_algorithms

[3] Tracking objects from camera; PID controlling; Parrot AR Drone 2

Title: Vision-based Position Estimation for a quadrotor

Body:
As a subtask inside a main project I need to compute the position (x,y,z) of a quadrotor using an homography.

To do this I will use a camera (attached to the quadrotor) pointing down to an artificial landmark on the floor. Basically I need to compute the extrinsic parameters of the camera to know the pose with respect to the landmark. I know the projective points of the landmark in the camera, and the intrinsic matrix of the camera but I also need the real landmark position [X, Y, Z].

I suppose that Z coordinate is equal to 0 because the landmark is plane, but I am not sure how to compute the real [X,Y] coordinates.

Any idea how to do that?

I am also interested in put the (x,y,z) position of the quadrotor into a control path, anybody knows where I can find info about the most common controllers for do this kind of task?


答: If you are able to design the artificial landmark yourself, you can use what some past colleagues of mine used in the context of camera space manipulation.   They designed their targets, like your landmark, as concentric high-contrast circles or ellipses.  With those targets they could extract distance information (measured versus expected diameters), as well as relative position between the camera and the center of the target.</p>


问:
Why does my RoboClaw seem to be ignoring the PID gain settings?
I'm seeing a behavior in my RoboClaw 2x7 that I can't explain.  I've been trying to manually tune the velocity PID settings (I don't have a windows box so I can't use Ionmc's tuning tool) by using command 28 to set the velocity PID gains, then command 55 to verify that they're set correctly, then 35 to spin the wheel at half of its maximum speed.  The problem is that no combination of PID gains seems to make any difference at all.  I've set it to 0,0,0 and the motor still spins at roughly the set point.

I must be doing something wrong, but I'm pouring over the datasheet and I just don't see what it is.  By all rights the motor shouldn't spin when I use 0,0,0!  Any ideas?

答:
Got it!  The problem was that there's a feedforward term in the control loop that the datasheet doesn't talk about.  The wheel and motor and I'm calibrating for are pretty light so the feedforward was enough to get pretty good tracking on its own (ie little error so little reliance on PID).

To solve it I sent in known-to-be-wrong QPPS settings to induce a small error, tuned velocity PID per the directions in the datasheet, and then reset QPPS to where it should be.


问:
Ultrasonic Sensor's Lag (20Hz) effect on PID contol loop rate (150Hz)
Good day, I would like to ask how is it possible to use an ultrasonic sensor for altitude hold in a quadcopter if the sampling rate of the Ultrasonic sensor (HC-SR04) is only 20Hz before incurring any errors through polling when I had tested it. I have seen this sensor being implemented on other projects however I could not find any papers that explain the use of this sensor in better detail. I have seen possible solutions on the raspberry pi one using interrupts and the other using Linux's multithreading.

If my understanding is right, to use interrupts, I need a some sort of data ready signal from the ultrasonic sensor. However this is not available in this particular sensor. Is it possible to use the echo pin as the positive edge trigger for the interrupt service routine (read sonar/calculate distance function). But would this not introduce inconsistent loop execution times which is bad for a consistent PID loop.

Another approach is to use multithreading using the wiring-pi library which enables me to run a function, let's say a function that triggers the sonar and calculates the distance along side the pid control loop. How would this affect the PID control loop rate?

Which is the best way to implement sonar sensor based altitude hold?

答: The best solution is to use interrupts triggered by echo pins change of state. joan's pigpio example worked beautifully. Using multithreading did not give satisfactory results as there is still problem with the timing since multithreading on the raspberry pi operates via pipelining.</p>


问:
Suitable D star variant is for non-holonomic motion planning of mobile robots
I am working on a non-holonomic motion planning problem of a mobile robot in a completely unknown environment. After going through some research papers, I found that D-star algorithm is widely used in such conditions. But there are many D-star variants like Focused D*, D*-Lite, Field D* etc... So which of these variants is suitable in this case? Also please suggest any other better approach for this problem?</p>

答:
A brief overview of some of these variants:

A* A variant Dijkstra's algorithm that maintains a heuristic distance to the goal to first explore parts of the graph that are more likely closer to the goal (same result as Dijkstra's algorithm, but faster).

Theta* An "any-angle" variant of A*. In other words, movements between nodes are not restricted to the immediate neighbourhood. So you get paths that appear more natural and are often the shortest possible distance between two points (e.g., in a grid environment, A* might plan a non-straight line between two points because of the constraint requiring the path to "stay in the grid", Theta* relaxes this).

D* A variant of A* that is fast to update changing edge costs in the graph. For example, let's say the robots path is suddenly blocked by a new obstacle. D* doesn't need to replay the whole path from scratch; rather, it amends the previous path.

Focused D* A variant of D* that uses heuristics to more efficiently choose which parts of the graph are updated when a change in the graph (e.g., an obstacle) is detected.

D* Lite Essentially the same as Focused D* but is more intuitive and easier to program. Is pretty much used in place of Focused D* in virtually all applications.

Field D* An "any-angle" version of D* Lite. You get natural paths that update rather quickly to changing obstacles. This algorithm has been used on Mars rovers. Downside is it is much trickier to implement and understand then Theta*, for example.


问:
Computer stereo vision simulator
In my research project I deal with a mobile robot that perceives through stereo vision. As the stereo input data I currently use several datasets taken from a passenger vehicle that contain real world photos. The datasets are good to get started but have a limited content so I would need to model my own traffic situations to further work on the stereo vision system.

I am thinking about using some kind of synthetic graphics simulation as the input for the stereo system. What are my options? I can imagine a 3D graphics rendering engine whose output would be fed as the input for the stereo vision could probably be used.

I found there are general robotic simulators available like Gazebo but since I am all new to robotic simulation I do not really know where to begin.

EDIT:

I forgot to write that all my code is a pure C++. I use OpenCV and LIBELAS for stereo vision and Point Cloud Library (PCL) for visualization. All glued together into a single C++ project and compiles into single binary.

答:
I did similar project with v-rep, python and opencv.

1- Set up an enviorement with visible objects

2- Set up your vision sensors with parameters

3- Write a python script that connects you to v-rep and do stereo vision application

Example code:

```<code>import vrep
import time
import cv2
import numpy as np

vrep.simxFinish(-1)

clientID = vrep.simxStart('127.0.0.1', 19999, True, True, 5000, 5)

if clientID!=-1:
    print 'Connected to remote API server'
    print 'Vision Sensor object handling'
    res, v1 = vrep.simxGetObjectHandle(clientID, 'Vision_sensor#0', vrep.simx_opmode_oneshot_wait)
    print 'Getting first image'
    err, resolution, image = vrep.simxGetVisionSensorImage(clientID, v1, 0, vrep.simx_opmode_streaming_split)
    if err==0:
        print "Image ok"
    time.sleep(2)
    while (vrep.simxGetConnectionId(clientID) != -1):
        err, resolution, image = vrep.simxGetVisionSensorImage(clientID, v1, 0, vrep.simx_opmode_buffer)
        if err == vrep.simx_return_ok:
            img = np.array(image,dtype=np.uint8)
            img.resize([resolution[0],resolution[1],3])
            cv2.imshow('image',img)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
        elif err == vrep.simx_return_novalue_flag:
            print "no image yet"
            pass
        else:
          print err
else:
  print "Failed to connect to remote API Server"
  vrep.simxFinish(clientID)

cv2.destroyAllWindows()
</code>```

Configuration

OS: Windows 7 x64

IDE: PythonXY(Python version: 2.7, OpenCV version: 2.4)

Simulator: V-REP PRO EDU V3.3.0

Title: Computer stereo vision simulator

Body:
I did similar project with v-rep, python and opencv.

1- Set up an enviorement with visible objects

2- Set up your vision sensors with parameters

3- Write a python script that connects you to v-rep and do stereo vision application

Example code:

import vrep
import time
import cv2
import numpy as np

vrep.simxFinish(-1)

clientID = vrep.simxStart('127.0.0.1', 19999, True, True, 5000, 5)

if clientID!=-1:
    print 'Connected to remote API server'
    print 'Vision Sensor object handling'
    res, v1 = vrep.simxGetObjectHandle(clientID, 'Vision_sensor#0', vrep.simx_opmode_oneshot_wait)
    print 'Getting first image'
    err, resolution, image = vrep.simxGetVisionSensorImage(clientID, v1, 0, vrep.simx_opmode_streaming_split)
    if err==0:
        print "Image ok"
    time.sleep(2)
    while (vrep.simxGetConnectionId(clientID) != -1):
        err, resolution, image = vrep.simxGetVisionSensorImage(clientID, v1, 0, vrep.simx_opmode_buffer)
        if err == vrep.simx_return_ok:
            img = np.array(image,dtype=np.uint8)
            img.resize([resolution[0],resolution[1],3])
            cv2.imshow('image',img)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
        elif err == vrep.simx_return_novalue_flag:
            print "no image yet"
            pass
        else:
          print err
else:
  print "Failed to connect to remote API Server"
  vrep.simxFinish(clientID)

cv2.destroyAllWindows()

Configuration

OS: Windows 7 x64

IDE: PythonXY(Python version: 2.7, OpenCV version: 2.4)

Simulator: V-REP PRO EDU V3.3.0


问:
Which geo-projection to use for odometry
I would like to make a little survey regarding the (geo)spatial projection that you use when elaborating your GPS and movement data for the spatial awareness of your robots.

Moving all GPS coordinates to a planar projection seems to be the more reasonable choice since not only distances (for which several formulas and approximations exist), but bearings must be computed.

Generally, although scales are pretty small here, avoiding equirectangular approximation seems a good idea in order to keep a more consistent system.

Avoiding working in the 3D world (Haversine and other great-circle stuff) is probably a good idea too to keep computations low-cost.

Moving the world to a 2D projection is hence what seems to be the best solution, despite reprojection of all input GPS coordinates is needed.

I would like to get opinions and ideas on the subject
(...if ever anyone is interested in doing it U_U).

答:
It probably depends on the size of the area where you want to operate your robot.

For me it was always good enough to use equirectangular projection, because for my assumptions "at most 1km large area at most 1000km from where I live" the error always comes up as negligible (I don't remember the value now and I don't have time to calculate it, but my guess would be under 1mm). You should calculate it and decide for yourself.

If your robot will operate on a significantly larger part of the Earth and would have problems with this kind of distortion, I guess that it would be worth to invest into a proper 3D world model instead of fighting with projection deformations.


问:
Pick and place robot
I have to simulate a pick and place robot (3 DOF). I tried with MATLAB. It should pick and place different objects according to their geometry.

Where can I find similar m-codes and algorithms?

答:
I assume from your question that you are only simulating the robot's kinematics, and not dynamics or controls.   However, this recommendation would be the same even if you had to complete a full-up controls simulation, also.

Why don't you work out the mathematical equations of the robot (forward kinematics) then invert them manually?  Then write m-code to simulate the robot?

This will teach you so much more about locating objects geometrically into the workspace and having the robot grasp them, than you would learn by copying others' m-codes.   When you get stuck, we will be happy to answer specific questions you encounter.

Title: Pick and place robot


答:
I highly advise against using synthetic image data for testing your stereo vision algorithms. What will happen is that you end up with a system that works excellent on your synthetic data, but poorly in the real-world. Synthetic images are much easier to process than real-world images, as they lack all the shortcomings of real cameras that will make stereo matching hard.

You can try it out yourself. There are some synthetic image sequences out there. Have a look at this one:

https://cerv.aut.ac.nz/set-2/

Title: Computer stereo vision simulator

Body:
In my research project I deal with a mobile robot that perceives through stereo vision. As the stereo input data I currently use several datasets taken from a passenger vehicle that contain real world photos. The datasets are good to get started but have a limited content so I would need to model my own traffic situations to further work on the stereo vision system.

I am thinking about using some kind of synthetic graphics simulation as the input for the stereo system. What are my options? I can imagine a 3D graphics rendering engine whose output would be fed as the input for the stereo vision could probably be used.

I found there are general robotic simulators available like Gazebo but since I am all new to robotic simulation I do not really know where to begin.

EDIT:

I forgot to write that all my code is a pure C++. I use OpenCV and LIBELAS for stereo vision and Point Cloud Library (PCL) for visualization. All glued together into a single C++ project and compiles into single binary.


问:
Why does the ESC stop?
I've built a quadcopter with four brushless motors and ESCs (30A). I'm using an Arduino to control them. I haven't written any complex code; just enough to get them running. Everything is fine until I send a number over 920 to the serial. Then, for some reason, all the motors stop spinning. I'm using three freshly bought and charged LiPo cells (V = 11.1V). Here is the link for the site that I bought them from (I cannot seem to find any other resource about them) : 4x A2212 1000KV Outrunner Motor + 4x HP 30A ESC + 4x 1045 prop (B) Quad-Rotor.

When I tried turning on only one motor, I could write up to about 1800 microseconds, while both with 4 and with 1 motor, the minimum that it works is 800.

Can somebody explain why this happens and I how I can fix it?

Here is my code:

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

int value = 0;

Servo first,second,third,fourth;

void setup() {

  Serial.begin(9600);    // start serial at 9600 baud
  first.attach(6);
  second.attach(9);
  third.attach(10);
  fourth.attach(11);

}

void loop() {

    first.writeMicroseconds(value);
    second.writeMicroseconds(value);
    third.writeMicroseconds(value);
    fourth.writeMicroseconds(value);

    if(Serial.available() > 0){
      value = Serial.parseInt();
    }

}
</code>```

答:
Looking at the documentation for the Arduino servo library it looks like you are reusing the servo library to produce a PWM speed control for your ESC.

Although the writeMicroseconds() function page doesn't mention continuous rotation servos, the write() function page does:

Writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous rotation servo, this will set the speed of the servo (with 0 being full-speed in one direction, 180 being full speed in the other, and a value near 90 being no movement).

What the writeMicroseconds() function page does say is:

On standard servos a parameter value of 1000 is fully counter-clockwise, 2000 is fully clockwise, and 1500 is in the middle.

Which would suggest that 1500 would be static, 1000 would be full speed in one direction, and 2000 would be full speed in the other direction.

For motors which only go in one direction though, an ESC might change those ranges to maximise the controllability of the motor by accepting a larger range of PWM values, and mapping them to unidirectional speed only.

Depending on your ESC, it may be that as you approach 1000, you are reaching the maximum speed, and as you exceed the maximum speed it is capable of the motor shuts off as a protection mechanism.

Ultimately, only the data sheet for your ESC can tell you why your system is behaving the way it is.

Title: Why does the ESC stop?


答:
First of all I would suggest calibrating them.

From the eBay page you linked to, It would seem that the ESCs are probably HobbyWing (or HobbyWing clones). I would suggest finding some spec sheets for HobbyWing ESCs and using that information to calibrate them as well as understand them better.

Since they seem to respond to values in the range 800-1800 they probably need to be calibrated. The usual range is 1000-2000. I've had HobbyWing ESCs and there is a way to send the proper min and max values to the ESC. Besides that you could adjust your code to accept values in the range 800-1800 and assume 900 is the centerpoint. In a sense, you'd be calibrating them yourself via your code.

As far as them not operating over 920, it almost sounds like a power issue. You say you are using "3 freshly bought and charged LiPo cells (V = 11.1V)". Are you in fact using all three at once? I'm not sure how you've wired them up, but here is an example of proper wiring:

Title: Why does the ESC stop?

Body:
I've built a quadcopter with four brushless motors and ESCs (30A). I'm using an Arduino to control them. I haven't written any complex code; just enough to get them running. Everything is fine until I send a number over 920 to the serial. Then, for some reason, all the motors stop spinning. I'm using three freshly bought and charged LiPo cells (V = 11.1V). Here is the link for the site that I bought them from (I cannot seem to find any other resource about them) : 4x A2212 1000KV Outrunner Motor + 4x HP 30A ESC + 4x 1045 prop (B) Quad-Rotor.

When I tried turning on only one motor, I could write up to about 1800 microseconds, while both with 4 and with 1 motor, the minimum that it works is 800.

Can somebody explain why this happens and I how I can fix it?

Here is my code:

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

int value = 0;

Servo first,second,third,fourth;

void setup() {

  Serial.begin(9600);    // start serial at 9600 baud
  first.attach(6);
  second.attach(9);
  third.attach(10);
  fourth.attach(11);

}

void loop() {

    first.writeMicroseconds(value);
    second.writeMicroseconds(value);
    third.writeMicroseconds(value);
    fourth.writeMicroseconds(value);

    if(Serial.available() > 0){
      value = Serial.parseInt();
    }

}
</code>```


问:
Which kind of valve is used for dispensing food grains?
I am doing a project on an automated grain dispenser system using a PLC control. I need a valve for dispensing grain from hopper to packet. I should be able to control the flow of the grain.

So what kind of valve should I use for flow control of the grain? There are different types of grains like rice, wheat, etc., and the valve should be controlled by the PLC (opening and closing of valve).

答:
What scale is this on? I am assuming you are doing this for household purposes and not industrial.

Maybe something like this:

The dry goods are sent into a drum. The drum has a cupola in one side. The goods fill the cupola and when the drum is rotated one cupola full of goods are deposited. Repeat as many times as necessary to deliver N cupolas full.

The image is actually from a fish feeder. Maybe you could even use a modified fish feeder.


问:
Dynamic model of a robot lifted by a balloon (Multibody system)
I'm having a hard time trying to understand how to obtain the dynamic model for a system similar to the image.

The balloon is a simple helium balloon, however the box is actually an aerial differential drive platform (using rotors). Now there's basically a model for the balloon and another for the actuated box. However I'm lost to how to combine both.

The connection between both is not rigid since it is a string.
How should I do it? Is there any documentation you could point me to, in order to help me develop the dynamics model for this system?

Since I'm so lost, any help will be useful. Thanks in advance!

答:
It's just another force, so you would treat it pretty much the same as you would treat gravity, a propeller, or any other force. There are a few points I'll make to help clarify for you:

The string binds the two systems together, meaning that each is now an input to the other (hopefully I'll clarify this with points below).

A string in tension is effectively rigid. A string in compression doesn't transmit force. So you'll need case statements such that the force is only applied across the systems when the string is in tension and that there is no effect when the string is in compression.

The location of the force is wherever the string is tied to the box (call that position_box or p_box for short). Similarly, for the balloon, the location of the force is wherever the string is tied to the balloon (p_bln).

The force is a vector that acts along [p_bln-p_box].

Relating to point (2) above, the force is only transmitted when norm([p_bln-p_box]) >= L_string. Technically the norm shouldn't ever exceed the length of the string, but resolving that length back to L_string could be the force that is applied to each body.

So, this would differ a little from gravity where gravity is always a vector pointing down and always acts on the center of mass, the string is a vector force of variable direction, that always acts at the point of attachment, that may not exist (if the box is closer to the balloon than the length of the string).

Gravity acts through the center of mass, so, provided there are no other reaction forces (not hinged/pivoting, negligible air resistance), there's no torque applied to the body. What you'll find is that, by acting on a point not the center of mass, the string will apply a torque to both bodies, in addition to pulling them.

As I mentioned, the actual distance between the two points may exceed the length of the string; this has to deal with joint stability and how you choose to solve and resolve forces across joints.

FYI, I'm not sure what your background is, but you're entering a pretty complex field by allowing force transmission across a flexible joint. I'm a fan of Rigid Body Dynamics Algorithms by Roy Featherstone, but there are certainly a number of other algorithms that you can use to solve this dynamic system. It looks to me like Featherstone's algorithm is at the heart of Matlab's SimMechanics toolbox, but that's just an educated guess; it could of course be something else.

If you were going to model this in SimMechanics, you would look for two spherical joints, one on each body, with a telescoping joint that allows for motion from 0 to L_string. At lengths < 0, the objects collide, at lengths > L_string the string is taut. Please comment if you would like more guidance, but I think this is about what you were looking for.

:EDIT:

I found this group of examples on the Matlab FileExchange to be very useful when developing models in SimMechanics. The most useful thing I found there was a model (screenshots below) that shows how to interface a SimMechanics block to a SimScape block. This allows a SimMechanics "Prismatic Joint" to be used with a SimScape "Translational Hard Stop" block. Using this setup, you can set the limits on the prismatic joint to start at L_String, the limits on the translational hard stop to be 0 to L_String, and then you can adjust the end stop spring constants and damping until you get a reasonable reaction.

The spring/damping constants will adjust the "snap" applied to each body when the string pulls taut (or when the two collide). You can adjust the upper/lower end stop constants such that a collision (L = 0) is different than the string pulling tight (L = L_String). Again, this should be a prismatic joint inserted between your two spherical joints.

Here's the screenshots! First, create a translational interface between SimScape and SimMechanics: (Provided in the FileExchange package I linked above).

Then, add that interface to a prismatic joint:

Configure the prismatic joint to start at L=L_String. Ensure that there's no internal mechanics set and that motion is automatically computed with force provided by input (this is required to work with the translational interface).

Then, configure the translational hard stop such that the limits are from 0 to L_String. At this point I would accept the default stiffness and damping and run the simulation to see how you think it works. My defaults are because I work with some colossal industrial equipment that uses tensioners bigger than I am. I think the stock defaults are somewhere ~100.

Finally, I would suggest you save that configuration as a custom library block so you can have it in the future. You can do more complex things, like mask the L_String parameters such that you can customize the default lengths, etc. from the custom library block, but a how-to for that is beyond the scope of what I'm covering here. Anyways, once you've set everything up, I would suggest you just link a block to your string and run a quick simulation. Edit the parameters as you see fit until you get the desired response or it matches your experimental data.


答:
You can use a sampling valve. You can have a look here to how it works.

https://www.youtube.com/watch?v=KSQPSDmD-i4

Title: Which kind of valve is used for dispensing food grains?

Body:
I am doing a project on an automated grain dispenser system using a PLC control. I need a valve for dispensing grain from hopper to packet. I should be able to control the flow of the grain.

So what kind of valve should I use for flow control of the grain? There are different types of grains like rice, wheat, etc., and the valve should be controlled by the PLC (opening and closing of valve).


答:
Following on from Octopus's answer, this comes from the thread, Hobbypower ESC-30A on rcgroups.com, where a user was having the same trouble calibrating them.

I bought exactly the same ESCs from eBay and asked the seller for a datasheet. It appears that WaspNest was right, they match Hobywing product.

  Here is a link to the datasheet he sent me:
  https://dl.dropboxusercontent.com/u/...030A%20ESC.jpg

Here is the datasheet, referred to above:

.

There is also the following:

A programming card is available: Hobbywing Pentium Series Brushless Speed Controller ESC Program Card. It should work with these ESC's with no problem.

  Manual?

  See http://www.hobbywing.com/uploadfiles...l/HW-01-V4.pdf and http://www.hobbyking.com/hobbyking/s...88X7478X20.pdf

Unfortunately the first link has expired, and the second link is to the HobbyKing 20A and 30A UBEC, but it could be of some use.

Title: Why does the ESC stop?


答:
Have you calibrated your ESC? If you have not yet done so, you can calibrate it using PWM.

First you send max PWM to the ESC, then you send min PWM to the ESC, then send PWM 20 milliseconds (assuming a 50Hz PWM signal). When you give PWM above 20ms your motor will rotate forwards, and if you give PWM below 20ms your motor will rotate backwards.

Title: Why does the ESC stop?


问:
Applying MoCap data to real life robot
I have a Kinect Sensor, and iPi software I use to create motion capture data to use in film editing. I am looking at creating a small, Raspberry Pi driven bipedal robot just for fun, and I was wondering if it was possible to use the MoCap to control the robot? It will only be 20-30 cm tall, with six servos (hips, knees, ankles). Is it possible to apply the movement from these six joints on the human body to my robot, like having a string directly from my left knee joint to its left knee servo? It could either be in real-time, like following my actions, or using pre-recorded data.

(NOTE: If needed, I can plug it directly to my Apple/Windows computer, if the Pi could not support this. Also, it will have no upper torso at the moment.)

答:
Yes, you could control the legs, but no, you're probably not going to get the effect I think you're after. The legs will probably not walk on their own just because they're miming what your motion capture system recorded.

First, a human leg has more than six degrees of freedom. The hip can flex and extend, abduct and adduct, and rotate laterally and medially. That's three axes of motion for the first joint. The knee and flex and extend (fourth axis of motion), and the ankle also has three axes, like the hip - flex/extend, abduct/adduct, and rotation. That's seven axes of motion.

Second, toes do a great deal to help balance. If you don't have any way to control toe motion (or capture it - they're like force actuators instead of position actuators), then you won't be able to achieve the same control as someone with toes.

Third, you are unlikely to get the same dynamic response as human muscle with (what sounds like) hobby servos. If the servo can't move with the same speed and force as human muscle, then the servo's mechanical response is prone to act as a low-pass filter, which means it could be unable to replicate faster balance/control actions.

Fourth, and biggest - the human, who is being captured, has a different set of dynamic parameters that they are trying to regulate for their motion. Their height, weight, center of gravity, moment of inertia, will all be different than the robot's, especially if the robot is missing a torso.

None of this means specifically that it won't work at all - you have the freedom to design shorter limbs, larger feet, etc., that can attempt to make up for the lack of fidelity in recreating the person. You'll just have to take care to understand that, with fewer degrees of freedom than a person, you may not be able to replicate all motion, and you may have some (severe) trouble getting the robot to balance correctly.

Title: Applying MoCap data to real life robot


答:
Chuck's answer is correct; applying motion capture to a robot will make its legs move in a walking motion, but won't guarantee that the entire setup will remain upright.

One simple fix for that would be to just use the legs for propulsion only, and use a set of wheels for balance.

Title: Applying MoCap data to real life robot

Body:
I have a Kinect Sensor, and iPi software I use to create motion capture data to use in film editing. I am looking at creating a small, Raspberry Pi driven bipedal robot just for fun, and I was wondering if it was possible to use the MoCap to control the robot? It will only be 20-30 cm tall, with six servos (hips, knees, ankles). Is it possible to apply the movement from these six joints on the human body to my robot, like having a string directly from my left knee joint to its left knee servo? It could either be in real-time, like following my actions, or using pre-recorded data.

(NOTE: If needed, I can plug it directly to my Apple/Windows computer, if the Pi could not support this. Also, it will have no upper torso at the moment.)


问:
Difference between an underactuated system, and a nonholonomic system
What's the difference between an underactuated system, and a nonholonomic system? I have read that "the car is a good example of a nonholonomic vehicle: it has only two controls, but its configuration space has dimension 3.". But I thought that an underactuated system was one where the number of actuators is less than the number of degrees of freedom. So are they the same?</p>

答:
They are different things.  An underactuated system does mean that the number of independent control inputs is fewer than the number of degrees of freedom you are trying to command.  This can happen for holonomic systems when they encounter a singularity, or for nonholonomic systems when they are commanded to move in a direction they cannot achieve.  The state space method of looking at this is the controllability matrix, and in kinematics it is the rank of the Jacobian matrix, but you probably don't need to go into that level of detail to understand an underactuated system.

Nonholonomic means quite a different thing.  A holonomic system can have its control kinematics expressed as geometric (including trigonometric) equations.  A nonholonomic system, on the other hand, cannot be expressed as closed-form geometric equations.  Instead, the best you can do is to write differential equations to express the kinematics.

Here's an example:  think of a mobile robot with wheels.  If you ask it to ascend to 10 meters in the air, it is underactuated.  If you ask it to go to position (100 meters, 20 meters) from its current location, then the robot needs to turn its two drive wheels to get to the new position.  Since it is a nonholonomic system, you cannot just count the number of rotations of each wheel to determine where it ended up, because the sequence of rotations matters, not just the total number of rotations (for example, it would end up in a different place if it actuated only the left wheel for so many rotations, then the right. as compared to if it actuated both wheels together for that many rotations).  For a robot manipulator that is holonomic, you can locate it's end effector position by knowing the total number of degrees of rotation of each motor, and you don't need to care in what order the robot moved its axes.


问:
Quadcopter PID Tuning for Altitude Hold/Position Hold along Z axis
Good day, I have just finished tuning the Pitch and Roll PID's. I did this by setting the throttle such that the quad is weightless. I did the tuning of each axes separately.

I would just like to ask what is the best way to tune the PID for maintaining an altitude setpoint.

Is it best to turn off the Pitch and Roll PID controllers while tuning the altitude PID or is it best to have them already active while tuning the latter controller?

I am going to use a cascaded PID controller using the Velocity along the z-axis calculated from the accelerometer output for the inner PID loop (150Hz) and the altitude measurement of the HC-SRO4 ultrasonic sensor (20Hz) for the outer PID loop.

答:
Currently I am performing my research on that, and in my case I decided to tune all the PIDs. Angles of the quadrotor tend to zero, while altitude controller tend to the objective height. That's habitual in bibliography.

In my particular simulations on the computer, PD parameters were enough and all the controllers adapted the same Proportional and Derivative parameters.


问:
Relationship between motor torque and acceleration
I am working on designing and building a small (1 1/2 lbs), 2-wheeled, differential drive Arduino-controlled autonomous robot. I have most of the electronics figured out, but I am having trouble understanding how much torque the motors will actually need to move the robot. I am trying to use the calculations shown here and the related calculator tool to determine what speed and torque I will need. I will be using wheels 32mm in diameter and one of Pololu's High-Power Micro Metal Gearmotors. I performed the calculations for a robot weight of 2 lbs to be safe and found that the 50:1 HP Micro Metal Gearmotors (625 RPM, 15 oz-in) should theoretically work fine, moving the robot at 3.43 ft/s with an acceleration of around 29 ft/s^2 up a 5-degree incline.

However, I have not found an explanation for several things that I think would be very important to know when choosing drive motors. When the robot is not moving and the motors are turned on at full power, they should need to deliver their full stall torque. Based on the calculations, it seems that any amount of torque can get the robot moving, but the more torque, the faster the robot's acceleration. Is this true? Also, if the power source cannot supply the full stall current of the motors, will the robot not be able to start moving? In my case, I am powering the robot through a 7.2V (6S) 2200mAh NiMH battery pack that can provide around 2.6A continuously, and when it does that the voltage drops to less than 1V. Will this be able to power my motors? Once the robot reaches full speed and is no longer accelerating, theoretically the motors will not be providing any torque, but I do not think this is the case. Is it, and if so, how will I know how much torque they will be providing? Will the motors I chose have enough torque to move my robot?

答:
1) but the more torque, the faster the robot's acceleration: YES
$$
F=\frac{Torque}{wheelradius}
$$
and robot's acceleration is
$$
a=\frac{F}{m}
$$
so, from that equation you can see that linear acceleration of the robot increases with the torque

2)Once the robot reaches full speed and is no longer accelerating, theoretically the motors will not be providing any torque:NO

According to the equation:
$$
T=\frac{P}{w}
$$
that appears in one of the tutorials that you sent us, it is not possible to have 0 torque except that when the power=0. When you are at top speed, angular speed is high and torque is just enough to overcome the different resistances to the motion (friction, air resistance, whatever). It represents a very small value, which makes that the acceleration is close to 0, according to my first and second formula.


问:
How to Identify Objects in Space
Using a depth sensing camera like Kinect, I would like to retrieve the position of an predetermined object (e.g. a cup, fork etc so that I would ultimately be able to grab the object). What would be a way to achieve this?</p>

答: You probably want to do this, check it out. They also have code http://personalrobotics.ri.cmu.edu/projects/moped.php</p>

Title: How to Identify Objects in Space


问:
Measure weight of an object using a servo
Assuming a quality industrial servo, would it possible to calculate the weight/resistance of a load? Maybe by comparing current draw in a holding position, or by the time it takes to lift/lower an object. Could it accurately measure grams, kilograms? What kind of tolerance could be achieved?

I'm trying to eliminate the need for a dedicated weight measurement sensor.

答:
This is going to depend on the style of motor in the servo and the style of gearbox. If the servo can't be back-driven when unpowered, then it's likely some form of a worm gear assembly that will prevent static force transmission back to the motor. This means that you won't be able to tell weight by current draw for holding position because the holding current draw will (probably) be zero.

You won't be able to tell anything about holding current draw if the motor is a stepper motor, either, because the stepper motor simply energizes a particular set of poles to full strength; any applied load under that holding torque is held, any applied load over causes the motor to slip.

In both of those cases, you may still be able to glean some information about the load based on the torque required to accelerate the load, by $\tau = I\alpha$, but then this gives you the moment of inertia of the load, and not its weight. This is an important distinction because the moment of inertia depends on the shape of the load as well as its mass.

If you know the shape of the load before hand, or if the load is something like a mass attached to a pulley (winch), then you can use the moment of inertia to calculate mass. If you don't know the shape, though, the moment of inertia alone doesn't get you enough information to find the mass.

Finally, even if you have a back-drivable servo that is actuated by a continuous rotation motor (not stepper), the holding current is going to be based on the torque applied to the servo, where $\tau = mgL\sin{\theta}$. If you get into a situation where $\sin{\theta} = 0$, then you'll wind up with a zero applied torque to hold the load, and you won't be able to get a load mass estimation.

In order to do what you want, you have to have a pretty specific situation setup where you have a lot of information in advance. That said, even if you do have all of that information, there are still other aspects that need to be taken into account: friction/damping losses in the gear box, gear box inertia, motor efficiency (input power (current@voltage) versus mechanical output power (torque@speed)), motor inertia, motor frictional and damping losses, etc.

None of this means it can't be done, but it means that you have to have the system modeled well enough that you can take a "snapshot" of motor inputs and speed and be able to turn that into a useful output torque. The accuracy you can achieve is entirely dependent on your ability to model everything pertinent to the system and the system's ability to stay as-modeled (oil/grease doesn't age/cake, bearings don't wear, motor feedback stays true, etc.).

You will probably find that the effort required to adequately model the servo system is more expensive (time and labor) than purchasing a weight sensor.


问:
Send Arduino sensor data to server with GPRS shield
I'm trying to send Arduino sensor data to a server using a GPRS shield (SIM900 shield from Geeetech). I have this particular set up because the data will be updated to a website and the device will be roaming. I can't use http://www.cosm.org because to the best of my knowledge that only updates every 15 minutes, I need to update about every 5-10 seconds.

In order to connect I tried the code below to form UDP connection but it does not get sent through to the receiving IP and port. I don't know why. No errors occur on the Arduino side, and the server side has been shown to work with an iPhone app that sends a UDP message.

```<code>///connect
void connectUDP()
{
 mySerial.println("AT+CSTT=\"APN\"");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIICR");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIFSR");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIPSTART=\"UDP\",\"SERVER IP\",\"SERVER PORT\"");
 delay(3000);
 ShowSerialData();
 mySerial.println();

}

///send udp packet to server
void sendUDP()
{
 for(int x = 0; x < 30; x++){
   mySerial.println("AT+CIPSEND");
   delay(100);
   ShowSerialData();
   mySerial.println("\"hello world\"");
   delay(100);
   ShowSerialData();
   mySerial.println((char)26);
   delay(1000);
   ShowSerialData();
 }
 mySerial.println();
 //ShowSerialData();
}
</code>```

The server side is as follows (written in python):

```<code>import SocketServer

PORTNO = 14

class handler(SocketServer.DatagramRequestHandler):
    def handle(self):
        newmsg = self.rfile.readline().rstrip()
    print (newmsg)
        self.wfile.write(self.server.oldmsg)
        self.server.oldmsg = newmsg

s = SocketServer.UDPServer(('',PORTNO), handler)
print "Awaiting UDP messages on port %d" % PORTNO
s.oldmsg = "This is the starting message."
s.serve_forever()
</code>```

I can see a possible solution might be to change it to a TCP connection, but I don't know how to do that...

答:
Your code appears a little incomplete - I am assuming that this is because you wished to include only the salient functions.

Once the required missing lines from the GeeTech Wiki - Arduino GPRS Shield - A Simple Source Code Examples (their typo, not mine) are added, the complete (minimal) code would seem to be:

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

SoftwareSerial mySerial(7, 8);

///connect
void connectUDP()
{
 mySerial.println("AT+CSTT=\"APN\"");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIICR");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIFSR");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIPSTART=\"UDP\",\"SERVER IP\",\"SERVER PORT\"");
 delay(3000);
 ShowSerialData();
 mySerial.println();
}

///send udp packet to server
void sendUDP()
{
 for(int x = 0; x < 30; x++){
   mySerial.println("AT+CIPSEND");
   delay(100);
   ShowSerialData();
   mySerial.println("\"hello world\"");
   delay(100);
   ShowSerialData();
   mySerial.println((char)26);
   delay(1000);
   ShowSerialData();
 }
 mySerial.println();
 //ShowSerialData();
}

void ShowSerialData()
{
 while(mySerial.available()!=0)
   Serial.write(mySerial.read());
}

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  connectUDP();
  sendUDP();
}
</code>```

As to why this isn't working, I am not sure, and I am still working on it.

As a sanity check, I presume that, in your actual Arduino sketch, you have substituted SERVER IP and SERVER PORT with actual values (i.e., a real IP address and port number)?  SERVER IP and SERVER PORT are not variables (global or otherwise) nor #defines. As you have not included the entire sketch, it is difficult to tell otherwise.

In addition, make sure that the server address that you specify in the Arduino sketch matches the IP address of the server running the Python script, and that the port that you specify in the Arduino sketch matches PORTNO in the Python script. Sorry if I am stating the obvious, but, like I said, this is a sanity check.

Regarding your second point:

I can see a possible solution might be to change it to a TCP connection, but I don't know how to do that...

You simply need to change UDP to TCP in the following line1:

```<code> mySerial.println("AT+CIPSTART=\"UDP\",\"SERVER IP\",\"SERVER PORT\"");
</code>```

so that it becomes

```<code> mySerial.println("AT+CIPSTART=\"TCP\",\"SERVER IP\",\"SERVER PORT\"");
</code>```

Obviously, as I have pointed out above, you need to provide actual values for <SERVER IP> and <SERVER PORT>, for example:

```<code> mySerial.println("AT+CIPSTART=\"TCP\",\"116.228.221.51\",\"8500\"");
</code>```

On the server side, the following lines in the Python script:

```<code>s = SocketServer.UDPServer(('',PORTNO), handler)
print "Awaiting UDP messages on port %d" % PORTNO
</code>```

need to be changed to:

```<code>s = SocketServer.TCPServer(('',PORTNO), handler)
print "Awaiting TCP messages on port %d" % PORTNO
</code>```

Again, ensure that the PORTNO, in your server side Python script, matches the port specified in the AT command.

1 See m2msupport.net - AT+CIPSTART. The relevant notes being

```<code>AT+CIPSTART=?

+CIPSTART: ("TCP","UDP"),("(0,255).(0,255).(0,255).(0,255)"),(1,65535)
+CIPSTART: ("TCP","UDP"),("DOMAIN NAME"),(1,65535)

OK

Start a TCP connection
AT+CIPSTART="TCP","116.228.221.51","8500"

OK

Start a UDP connection
AT+CIPSTART="UDP","116.228.221.51","9600"

CONNECT OK
</code>```

Note that the web page has a typo, and a period is shown where a comma should be, in the Start a UDP connection example. I have corrected this typo in the example above.

Body:
Your code appears a little incomplete - I am assuming that this is because you wished to include only the salient functions.

Once the required missing lines from the GeeTech Wiki - Arduino GPRS Shield - A Simple Source Code Examples (their typo, not mine) are added, the complete (minimal) code would seem to be:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(7, 8);

///connect
void connectUDP()
{
 mySerial.println("AT+CSTT=\"APN\"");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIICR");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIFSR");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIPSTART=\"UDP\",\"SERVER IP\",\"SERVER PORT\"");
 delay(3000);
 ShowSerialData();
 mySerial.println();
}

///send udp packet to server
void sendUDP()
{
 for(int x = 0; x < 30; x++){
   mySerial.println("AT+CIPSEND");
   delay(100);
   ShowSerialData();
   mySerial.println("\"hello world\"");
   delay(100);
   ShowSerialData();
   mySerial.println((char)26);
   delay(1000);
   ShowSerialData();
 }
 mySerial.println();
 //ShowSerialData();
}

void ShowSerialData()
{
 while(mySerial.available()!=0)
   Serial.write(mySerial.read());
}

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  connectUDP();
  sendUDP();
}

As to why this isn't working, I am not sure, and I am still working on it.

As a sanity check, I presume that, in your actual Arduino sketch, you have substituted SERVER IP and SERVER PORT with actual values (i.e., a real IP address and port number)?  SERVER IP and SERVER PORT are not variables (global or otherwise) nor #defines. As you have not included the entire sketch, it is difficult to tell otherwise.

In addition, make sure that the server address that you specify in the Arduino sketch matches the IP address of the server running the Python script, and that the port that you specify in the Arduino sketch matches PORTNO in the Python script. Sorry if I am stating the obvious, but, like I said, this is a sanity check.

Regarding your second point:

I can see a possible solution might be to change it to a TCP connection, but I don't know how to do that...

You simply need to change UDP to TCP in the following line1:

 mySerial.println("AT+CIPSTART=\"UDP\",\"SERVER IP\",\"SERVER PORT\"");

so that it becomes

 mySerial.println("AT+CIPSTART=\"TCP\",\"SERVER IP\",\"SERVER PORT\"");

Obviously, as I have pointed out above, you need to provide actual values for <SERVER IP> and <SERVER PORT>, for example:

 mySerial.println("AT+CIPSTART=\"TCP\",\"116.228.221.51\",\"8500\"");

On the server side, the following lines in the Python script:

s = SocketServer.UDPServer(('',PORTNO), handler)
print "Awaiting UDP messages on port %d" % PORTNO

need to be changed to:

s = SocketServer.TCPServer(('',PORTNO), handler)
print "Awaiting TCP messages on port %d" % PORTNO

Again, ensure that the PORTNO, in your server side Python script, matches the port specified in the AT command.

1 See m2msupport.net - AT+CIPSTART. The relevant notes being

AT+CIPSTART=?

+CIPSTART: ("TCP","UDP"),("(0,255).(0,255).(0,255).(0,255)"),(1,65535)
+CIPSTART: ("TCP","UDP"),("DOMAIN NAME"),(1,65535)

OK

Start a TCP connection
AT+CIPSTART="TCP","116.228.221.51","8500"

OK

Start a UDP connection
AT+CIPSTART="UDP","116.228.221.51","9600"

CONNECT OK

Note that the web page has a typo, and a period is shown where a comma should be, in the Start a UDP connection example. I have corrected this typo in the example above.


问:
Why can two Series 1 XBees only talk in X-CTU?
I have two Series 1 XBees that won't be in transparent mode because they are in AT command mode when I'm not in X-CTU.  I had asked for help elsewhere and no one had the answer except telling me about flow control.

The XBees had been configured properly with the MY and DL settings.  I'm thinking maybe I should shorten the timeout so they supposedly get out of AT command mode but they both stay in AT command mode.  The only time I can get the two Series 1 XBees to talk is under X-CTU.  I need the two Series 1 XBees to automatically be in transparent mode when powered on.

答:
I meant to answer this question months ago, apologies...

AT mode is the same as Transparent mode. The different modes (AT or API) is determined by the type of firmware that your XBees have on them. By default1, they should have the AT firmware.

From XBee and ZigBee basic concepts - Radio module operating modes (you can ignore the API modes):

Radio module operating modes

The operating mode of an XBee radio module establishes the way a user or any microcontroller attached to the XBee communicates with the module through the Universal Asynchronous Receiver/Transmitter (UART) or serial interface.

Depending on the firmware and its configuration, the radio modules can work in three different operating modes:

AT (transparent) operating mode

API operating mode

API escaped operating mode

In some cases, the operating mode of a radio module is established by the firmware version, which determines whether the operating mode is AT or API, and the AP setting of the firmware, which determines if the API mode is escaped (AP=2) or not (AP=1).

In other cases, the operating mode is only determined by the AP setting, which allows you for configure the mode to be AT (AP=0), API (AP=1) or API escaped (AP=2).

Now, where you are getting confused is that within Transparent mode, there is the AT command mode, which can be accessed by typing +++. This is where you say that you are when the XBees are connected to X-CTU. From XBee and ZigBee basic concepts - Application Transparent (AT) operating mode:

Application Transparent (AT) operating mode

In Application Transparent (AT) or transparent operating mode, all serial data received by the radio module is queued up for RF transmission. When RF data is received by the module, the data is sent out though the serial interface.

To configure an XBee module operating in AT, put it in AT Command mode to send the configuration commands.

AT Command mode

When the radio module is working in AT operating mode, settings are configured using the AT Command mode interface.

To enter AT command mode, you must send the 3-character command sequence through the serial interface of the radio module , usually +++, within one second. Once the AT command mode has been established, the module sends the reply OK\r, the command mode timer is started, and the radio module can receive AT commands.

So, in short, your XBees are in Transparent mode. Unless you have uploaded the API firmware on to them, in which case use X-CTU to upload them with the AT version of the firmware.

You may also find this useful, although, the author himself is confused by thinking that there are three modes:

Transparent;

AT, and;

API.

While there are indeed three modes, as I have already clarified, Transparent and AT are one and the same, and the other two modes are:

API and;

API escaped (also known as API mode 2 (or atap2)).

Nevertheless, the points he makes may still help. From XBEE Series 1

An Xbee module has three communication modes: Transparent mode, Command mode & API mode.

By default, all XBee modules start up in transparent mode.  All data received from the DIN pin is transmitted, and when RF data is being received, it is sent out on the DOUT pin. A pair of XBee modules can act Wireless in this mode.

Command mode is where you can configure XBee using AT commands through any Terminal software like TeraTerm or CoolTerm. Built in terminal of XCTU can also be used. To enter Command mode type in 3 consecutive characters +++ and wait a second. Once the XBee enters command mode, it will answer with OK. While in command mode you can change baud rate, PANID, Destination address, etc. If you are not typing anything for 10 seconds the module will return to Transparent mode, or you can issue the ATCN command to exit.

API (Application Programming Interface) mode is a frame-based method for sending and receiving data to and from an XBee. API MODE is powerful & complicated to setup.It is used to send messages to constantly changing targets (other XBee modules).

API mode has some special abilities to change parameters without entering command mode & Receive packet delivery confirmation on every transmitted packet.

You may also find the answer to the question How does coordinator XBee receive data from router? useful (although that answer refers to Series 2 not Series 1 XBee).

1 The XBees from Digi are shipped with AT mode. However, the XBees from Libelium are shipped in API mode. From the section API mode vs AT command mode on Getting started with the XBee 802.15.4 (serie 1) communication module [C. Pham, LIUPPA laboratory, University of Pau, France.  http://web.univ-pau.fr/~cpham]

By default, the Digi XBee is in AT command mode (also called transparent mode) while the one shipped by Libelium is in API mode 2 (atap2) where some characters are escaped using the escape character 0x7D. The Libelium API assumes that the XBee module is in API mode 2 anyway.


问:
How to select cameras for a stereo vision system?
I am in the process of building a stereo vision system to be used on a UGV. The system is for a robot that will be used in a competition wherein the robot is teleoperated to find relatively small colored rocks in a large outdoor field. I understand how to calibrate such a system and process the data for a stereo vision system. I do not however know how to select cameras for such a system. What are the best practices for picking cameras for a stereo vision system?</p>

答:
That is an interesting topic, and not very easy to get right on the first try. From experience with this, here are the most important things.

Synchronization. The camera must be 100% synced. For example, say the UGV is driving at a modest 36Km/hr (10m/s)  and recording frames at 30 frames per second. That is, at every frame the UGV would cover 3m. Now, say your sync is off by 1ms, one of the cameras will be off by ~0.3m, which is bad [just off the top of my head]. Sync problems are very hard to detect.

Resolution. In the context of stereo, we refer to depth resolution, or how much depth can we resolve given a change in disparity. An excellent explanation can be found here http://pub1.willowgarage.com/~konolige/svs/disparity.htm The equation you want to look at is a function of the focal length of the image and the stereo baseline. $\delta Z = \frac{Z^2}{Bf}\delta d$. This says that depth resolving power $\delta Z$ is inversely proportional to the baseline $B$ times the focal length $f$. That is the longer the baseline, the smaller $\delta Z$, the better. Meaning, you can resolve more depth. The minimum change in disparity $\delta d$ is controlled partially by the image resolution and the algorithm used. For your calculations, you can safely assume that $\delta d$ is at least $1/2$. It is better to be conservative with the choice of $\delta d$.

Overlap. You want to have overlap between the cameras to get stereo. Hence, you need to choose a combination of lens focal length (field of view) and baseline so that you have enough overlap for the application. Basically, trigonometry work on the board, or a quick matlab/python script.

For UGV's, there are two uses for stereo.

Navigation and Pose Estimation In this case you most probably need a large baseline + long focal length. This allows the stereo to see and resolve depth better and longer range.

Obstacle detection and avoidance You will probably need a shorter baseline and wider lens (smaller focal length) so that  you can focus on things very close to you.

Some UGV's might have both stereo setups, the large baseline narrow field of view for navigation and another one or two for obstacle avoidance.

Be very careful what you buy. Some companies offer already built stereo setups. Those are great on the robustness side of things, they don't loose calibration easily and are always in sync. The problem is that the commercially available ones have a small baseline. If you want to build your own. I'm guessing you will end up doing so, make sure the camera are syncable. Firewire is great for this, two camera on the same bus will sync with 125microsecond accuracy out of the box! USB and Gige cams are painful to sync.  When you put everything together, you want to make sure that the lenses are not going to move at all, and the baseline is rigid, very rigid for the application.

Also be careful in lens selection. Not all lenses work with all cameras. Lenses have a resolution too. This is a another topic, here is a short article on this http://www.qualitymag.com/articles/90642-q-a--selecting-lenses-for-machine-vision-systems


问:
How to make a robot arm follow a shape/path
I have constructed a 3 DOF robot arm. I want it to follow a trajectory on a 2D plane (XY). Tha shapes I want to follow are lines, cycles and splines. I now the math behind these 3 shaped (how they are defined). I have the kinematics, the inverse kinematics the jacobian and the whole control system (with the PID controller). The system receives as inputs, Xd(position), Xd'(velocity) and Xd''(acceleration) over time.

I found the following image that shows (more or less) my system.

So here is were I am stuck. How do I translate the shape to the position, velocity and acceleration that each joint needs to make so the end effector moves in the Cartesian space according to that shape?

答:
The image you post is one way that should work. In the image, $\tau$ is the joint torques, and  $x_d(t)$, $\dot{x}_d(t)$, and $\ddot{x}_d(t)$ are the Cartesian shape trajectory.

You mention "whole control system (with the PID controller)". Perhaps you were talking about a motor or joint torque controller?

The control loop image you post assumes that joint torque is more or less perfect (ie it does not care if there is a controller or not) and is wrapping a controller around the Cartesian state of the end point which would generate the shape.

To be pedantic, you are not translating the shape to the position, velocity, and acceleration that each joint makes... You are giving the actual cartesian position, velocity, and acceleration parameters of the shape to the control loop image you post and the $k_v$ and $k_p$ parameters will reduce the error between the measured shape and desired shape.

ContentLicense: CC BY-SA 4.0


问:
PID tuning with methods like GA and PSO
I have recently started reading about PID tuning methods and algorithms, and I encountered the particle swarm optimization algorithm and genetic algorithm.

The problem is, that I don't understand how each particle/chromosome determines his fitness. On real physical system, each particle/chromosome checks his fitness on the system? Wouldn't it take a really long time? I think that I am missing something here... Can those algorithms be implemented on an actual physical system? If so, then how?

答:
Talking especifically of PSO:

PSO is a good method for PID tuning, as you state. This algo is based particles that help find the absolute minimum. Let's think that you tune to get the no overshot.

If you tune a PID you must have a 3 dimension PSO algo, if you tune a PD just two. And for each dimension you can have any amount of particles as you want. In my case, in Scilab 5.4 I tune PD with PSO with 10 or 15 particles and converge quite fast, in a pair of minutes.

A particle represents a Kp value, for instance. If you have 10 particles for each dimension, you will be able to test your Kp with 10 different values at once. Then, the best particle will reveal, and will tell the other nine particles to adapt their value towards that local best particle, and Kp values will readapt till you find the local minimum Kp value that gets the lowest overshot.

Before tuning a PID, I suggest you to try to find the lowest point in a U letter with PSO. My code with Scilab is next:

```<code>   N=10;
   weight=1; //weight of the PSO algorithm
   const_c1=2; //constant of the velocity algorithm.
   const_c2=2; //constant of the velocity algorithm.
   Number_Iter=300; //number of iterations
   dim=1; // dimension

  //Initialize the parameter
  fitness=zeros(N,Number_Iter);
  R1=rand(dim,N); //Random numbers [0 1]
  R2=rand(dim,N); //Random numbers [0 1]
  current_fitness=zeros(N,1); /

  //initializing swarm and velocities and position
  current_position=2*(rand(dim,N));/
  velocity=3*rand(dim,N);
  local_best_position = current_position;

 //evaluate initial population

x1=current_position;
y=x1^2;

current_fitness=y;

 local_best_fitness = current_fitness;
 global_best_fitness=min(local_best_fitness);

for i=1:N
g=find(current_fitness==min(current_fitness));
global_best_position(:,i)=local_best_position(:,g);
 end

//velocity update
velocity = weight*velocity + const_c1*(R1.*(local_best_position-current_position)) + const_c2*(R2.*(global_best_position - current_position));

//swarm update
 current_position = current_position + velocity;

 //evaluate a new swarm
 iter=0;

 while(iter < = Number_Iter)
iter = iter + 1;

    x1=current_position;
    y= x1^2;

    current_fitness=y;
    disp(iter); disp(i);

 for var = 1 : N
if current_fitness(var) < local_best_fitness(var) then
  local_best_fitness(var) = current_fitness(var);
  local_best_position(var) = current_position(var);
end
end

current_glob_bestfitness = min(local_best_fitness);

if (current_glob_bestfitness < global_best_fitness)
      global_best_fitness = current_glob_bestfitness;

  for var2=1:N
         g=find(current_fitness==min(current_fitness));
         global_best_position(var2)=local_best_position(g);

 end
end

velocity = weight * velocity + const_c1*(R1.*(local_best_position - current_position)) + const_c2*(R2.*(global_best_position - current_position));

current_position = current_position + velocity;
plot(x1,y,'or');
y1=min(y);
end
</code>```

Title: PID tuning with methods like GA and PSO

Body:
Talking especifically of PSO:

PSO is a good method for PID tuning, as you state. This algo is based particles that help find the absolute minimum. Let's think that you tune to get the no overshot.

If you tune a PID you must have a 3 dimension PSO algo, if you tune a PD just two. And for each dimension you can have any amount of particles as you want. In my case, in Scilab 5.4 I tune PD with PSO with 10 or 15 particles and converge quite fast, in a pair of minutes.

A particle represents a Kp value, for instance. If you have 10 particles for each dimension, you will be able to test your Kp with 10 different values at once. Then, the best particle will reveal, and will tell the other nine particles to adapt their value towards that local best particle, and Kp values will readapt till you find the local minimum Kp value that gets the lowest overshot.

Before tuning a PID, I suggest you to try to find the lowest point in a U letter with PSO. My code with Scilab is next:

   N=10;
   weight=1; //weight of the PSO algorithm
   const_c1=2; //constant of the velocity algorithm.
   const_c2=2; //constant of the velocity algorithm.
   Number_Iter=300; //number of iterations
   dim=1; // dimension

  //Initialize the parameter
  fitness=zeros(N,Number_Iter);
  R1=rand(dim,N); //Random numbers [0 1]
  R2=rand(dim,N); //Random numbers [0 1]
  current_fitness=zeros(N,1); /

  //initializing swarm and velocities and position
  current_position=2*(rand(dim,N));/
  velocity=3*rand(dim,N);
  local_best_position = current_position;

 //evaluate initial population

x1=current_position;
y=x1^2;

current_fitness=y;

 local_best_fitness = current_fitness;
 global_best_fitness=min(local_best_fitness);

for i=1:N
g=find(current_fitness==min(current_fitness));
global_best_position(:,i)=local_best_position(:,g);
 end

//velocity update
velocity = weight*velocity + const_c1*(R1.*(local_best_position-current_position)) + const_c2*(R2.*(global_best_position - current_position));

//swarm update
 current_position = current_position + velocity;

 //evaluate a new swarm
 iter=0;

 while(iter < = Number_Iter)
iter = iter + 1;

    x1=current_position;
    y= x1^2;

    current_fitness=y;
    disp(iter); disp(i);

 for var = 1 : N
if current_fitness(var) < local_best_fitness(var) then
  local_best_fitness(var) = current_fitness(var);
  local_best_position(var) = current_position(var);
end
end

current_glob_bestfitness = min(local_best_fitness);

if (current_glob_bestfitness < global_best_fitness)
      global_best_fitness = current_glob_bestfitness;

  for var2=1:N
         g=find(current_fitness==min(current_fitness));
         global_best_position(var2)=local_best_position(g);

 end
end

velocity = weight * velocity + const_c1*(R1.*(local_best_position - current_position)) + const_c2*(R2.*(global_best_position - current_position));

current_position = current_position + velocity;
plot(x1,y,'or');
y1=min(y);
end


问:
Building a robotic clamp
If I had a single stepper motor how could I use it to create a robotic clamp that could simply grab hold of something like a plank of wood and release it?

Are there any standard parts that I could use for this? I'm having trouble finding out what the names of the parts would be.

答: Look for "parallel jaw gripper kit."  Ignoring the pneumatic designs, you will find a typical parallel jaw gripper has a set of 1:1 gears which ensure the two jaws travel at equal speeds in opposite directions, connected to parallelogram 4-bar linkages which keep the clamping jaws parallel to each other.  You can find them with or without the actuator.  </p>

Title: Building a robotic clamp


问:
Angle to a circle tangent line
I want to simulate the detection of a moving object by a unicycle type robot. The robot is modelled with position (x,y) and direction theta as the three states. The obstacle is represented as a circle of radius r1 (r_1 in my code). I want to find the angles alpha_1 and alpha_2from the robot's local coordinate frame to the circle, as shown here:

So what I am doing is trying to find the angle from the robot to the line joining the robot and the circle's centre (this angle is called aux_t in my code), then find the angle between the tangent and the same line (called phi_c). Finally I would find the angles I want by adding and subtracting phi_c from aux_t. The diagram I am thinking of is shown:

The problem is that I am getting trouble with my code when I try to find the alpha angles: It starts calculating the angles correctly (though in negative values, not sure if this is causing my trouble) but as both the car and the circle get closer, phi_c becomes larger than aux_t and one of the alphas suddenly change its sign. For example I am getting this:

$$\begin{array}{c c c c}
\text{aux_t} & \text{phi_c} & \text{alpha_1} & \text{alpha_2} \\ \hline
\text{-0.81} & \text{+0.52} & \text{-1.33} & \text{-0.29} \\
\text{-0.74} & \text{+0.61} & \text{-1.35} & \text{-0.12} \\
\text{-0.69} & \text{+0.67} & \text{-1.37} & \text{-0.02} \\
\text{-0.64} & \text{+0.74} & \text{-1.38} & \text{+0.1} \\
\end{array}$$

So basically, the alpha_2 gets wrong form here. I know I am doing something wrong but I'm not sure what, I don't know how to limit the angles from 0 to pi. Is there a better way to find the alpha angles?

答:
```<code>function [boundedAngle] = BoundAngle (unboundedAngle)
while unboundedAngle < -pi
    unboundedAngle = unboundedAngle + 2*pi;
end
while unboundedAngle > pi
    unboundedAngle = unboundedAngle - 2*pi;
end
boundedAngle = unboundedAngle;
return:
</code>```

The above code writes a (Matlab) function to limit angles between +/-pi. You say the angle should be between 0 and pi, but that only means 0-180 degrees. What if the object is behind you? If you want to ignore it, that's your choice, but you can't shift in pi (180 degree) increments and expect to get a valid answer.

Regarding the sign change, that appears to be expected, based on your drawing. I'm not sure what the issue is that you're having with the results.

Title: Angle to a circle tangent line

Body:
function [boundedAngle] = BoundAngle (unboundedAngle)
while unboundedAngle < -pi
    unboundedAngle = unboundedAngle + 2*pi;
end
while unboundedAngle > pi
    unboundedAngle = unboundedAngle - 2*pi;
end
boundedAngle = unboundedAngle;
return:

The above code writes a (Matlab) function to limit angles between +/-pi. You say the angle should be between 0 and pi, but that only means 0-180 degrees. What if the object is behind you? If you want to ignore it, that's your choice, but you can't shift in pi (180 degree) increments and expect to get a valid answer.

Regarding the sign change, that appears to be expected, based on your drawing. I'm not sure what the issue is that you're having with the results.