问:
What type of control law is used in "Reaction Control System" of Apollo Lunar Module or Space Shuttle?
Reaction Control Systems (RCS) on these vehicles are implemented by using small rocket thrusters. For me it looks like these thrusters work in some kind of "pulse" mode. And I can't understand - do they use some optimal control to calculate in advance the required impulse to reach the new desired state of the system OR they use "pulse" mode just for precise magnitude variation of provided thrust (like average voltage in PWM(pulse-width modulation)) in a classic PID control loop?</p>

答:
do they use some optimal control to calculate in advance the required impulse to reach the new desired state of the system

This is a property every stable controlled system has/should have. Figuring out how to get to some other state is the core of control theory.

Doing something in advance is not possible, but knowing it certainly is.
Given that the system is controllable an stable, it should be able to follow a given trajectory. It is a lot easier to calculate a trajectory beforehand instead of generating desired states "on the fly".

The great joy of control theory is that it is <s>only boring mathematical formulas and numbers, entirely unaware of what it's actually going on in the "real world"</s> able to describe very different systems in a common abstract way. So let's substitute the spaceship with a car.

You are standing at the traffic lights. You think about what to do when they turn green. You create a mental image of how the acceleration (and thus velocity and thus position) of the car should change over time.
In a car, that resembles to how hard you should hit the pedal to the metal.

In a multiaxes setup in space, there are many angular accelerations to consider, but it's still the same: how should these values change over time?

There are infinite solutions, but some are favourable. when you are docking in space for a example, you don't want to rotate much at the end of the motion. You want to have pretty much only translational movement between the two docking parts towards each other at the end of the motion. That's why the most part of possibly necessary rotation should happen at the beginning of the motion.

And don't forget that you are in space. finding a trajectory that uses minimal fuel is desirable.

they use "pulse" mode just for precise magnitude variation of provided thrust (like average voltage in PWM(pulse-width modulation)) in a classic PID control loop?

This is not an OR part, but AND. The "pulse" mode is all they have. You can open or close the valve. But the "pulse" is a controlled system in on itself. They measure all kinds of properties of the tanks like temperature and pressure to estimate what one "pulse" will do.

Additionally, the computers know the payload and can calculate the model that's being controlled. In a sense, the system is self aware and can adjust its control accordingly.

Check this document on the RCS which I got a bit of information from.

An attempt to explain the "it's only a pulse" idea:

You are probably familiar with one very common type of spaceship: microwave ovens. (admittedly, they are bound to some big rock by gravity, but still, they are in space (like everything else), so they are clearly spaceships)

There are different kinds of microwave ovens available. They all have the pulsed operation in common.

The simple ones look like this:

It only has two dials: time and power. The power dial adjusts the pulse width and the time dial the overall duration.

With this microwave, a lot of the control algorithm is on you. You cannot put different things into the oven, use the same settings and expect proper results. The frozen chicken and the rasins in the image will look different after 5 minutes at full power. You have to dial in the settings that work for the food you put into the oven.

There are "smarter" microwaves look like this one, with more dials and buttons:

You can tell it what you put inside and what you want to do with it. The oven will then figure out what to do. It might even vary the settings over time, to get better heat penetration, even cooking, etc.

It could be as smart as to first run some defrosting program, then cooking and finally turn on the grill. As it knows that you placed a frozen chicken of a certain weight into it, it will be able to figure out how to do all that, without overheating during defrosting, drying out while cooking or burning while grilling. Well, at least in theory.

As you can see, even something as primitive as a simple on/off pulse can do rather sophisticated things if wrapped into a good control loop.

Would it be even better if they could continuously change values of the valve?
Probably yes, but not by that much as you know from the averaged PWM signal. Additionally an adjustable valve is a more complex part than a simple on/off solenoid valve. Simple stuff fails less often. Stuff failing in space is a bad thing.


问:
Comparing industrial robot arms
I'd like to study the capabilities of industrial robot arms. For example, to answer the question how does price vary with precision, speed, reach and strength?

Is there a database of industrial robot arms including information like the price, precision, speed, reach and strength of each model?

答:
For example, how does price vary with precision, speed, reach and
  strength?

The price vary a lot, from a couple of hundreds of bucks to hundreds of thousands of dollars ( Willow Garage's the one-armrobot PR2 costs \$285,000  and The two-armed  costs  \$400,000 ), it goes up- as you can guess- whenever the robot arm is precise, fast, long, strong, collaborative (i.e. designed to interact with its environment), or have more DoF's (Degrees of Freedom). Also, take into account the flanges, tools, the palette of software they come with, certifications, etc. It really depends.

Is there a database of industrial robot arms including information
  like the price, precision, speed, reach and strength of each model?

I don't know of such a database, but you can find all these information (except prices, these companies are pretty secretive, they usually reveal it to potential customers. I work on KUKA's robots in my company, I didn't know about their price until our PR told me about the deal) on the Robot's manuals available on the companies' websites.
If you want to narrow down your choices, check what's available on the applications you want your robot to perform (if the robot will do repetitive work inside a confined space, there's no need to buy an expensive collaborative robot). I think, the big guys in the industry like Kuka, ABB, or Fanuc have a complete range of robots for different applications and at different sizes.
Check this link out:

http://blog.robotiq.com/bid/63528/What-are-the-different-types-of-industrial-robots

ContentLicense: CC BY-SA 3.0

Title: Comparing industrial robot arms


问:
Estimation of Battery Life Time From PWM Signals in a Quadrotor
Is there any way of estimation the battery life from pwm outputs which goes to motors in microcontroller level. I'm planning to estimate path range with this. Microcontroller, sensor and other electronic device should be neglected.

答:
Battery life is generally measured in amp hours. From a PWM perspective, you are pulsing current at a constant voltage, so you could estimate current output to be (duty cycle)*(rated current) where rated current is the nominal current draw at your operating voltage. Remember too that P=IV, so you could get a rated current by dividing rated power by operating voltage.

So now that you have an estimate for current draw, you can do a simplistic state of charge estimate called "Coulomb counting", which is just current integration.

This means that you take your current and multiply it by whatever your sample time interval is, then add it to the previous measurement.

```<code>spentCapacity = spentCapacity + (dutyCycle*maxCurrent)*dT
</code>```

In this manner you accumulate how much current you have "spent" and can compare that to how much you started with.

This is not super accurate by any means, but if you're interested in a basic setup that will get you in the right ballpark this is it.

If you go this route, better current measurements are an easy way to improve accuracy, but Texas Instruments makes some "battery fuel gage" chips that are pretty slick too.

Body:
Battery life is generally measured in amp hours. From a PWM perspective, you are pulsing current at a constant voltage, so you could estimate current output to be (duty cycle)*(rated current) where rated current is the nominal current draw at your operating voltage. Remember too that P=IV, so you could get a rated current by dividing rated power by operating voltage.

So now that you have an estimate for current draw, you can do a simplistic state of charge estimate called "Coulomb counting", which is just current integration.

This means that you take your current and multiply it by whatever your sample time interval is, then add it to the previous measurement.

spentCapacity = spentCapacity + (dutyCycle*maxCurrent)*dT

In this manner you accumulate how much current you have "spent" and can compare that to how much you started with.

This is not super accurate by any means, but if you're interested in a basic setup that will get you in the right ballpark this is it.

If you go this route, better current measurements are an easy way to improve accuracy, but Texas Instruments makes some "battery fuel gage" chips that are pretty slick too.


问:
Navigating through a Maze using path-planning (Dijkstra)
I'm working on an robot that would be able to navigate through a maze, avoid obstacles and identify some of the objects in it. I have a monochromatic bitmap of the maze, that is supposed to be used in the robot navigation.

Up till now I have processed the bitmap image, and converted it into an adjacency list. I will now use the dijkstra's algorithm to plan the path.

However the problem is that I have to extract the entrance point/node and exit node from the bmp image itself for dijkstra's algorithm to plan the path.

The robots starting position will be slightly different (inch or two before the entrance point) from the entrance point of maze, and I am supposed to move to the entrance point using any "arbitrary method" and then apply dijkstra algorithm to plan path from maze's entrance to exit.

On the way I have to also stop at the "X's" marked in the bmp file I have attached below. These X's are basically boxes in which I have to pot balls. I will plan the path from entrance point to exit point , and not from the entrance to 1st box, then to second, and then to the exit point; because I think the boxes will always be placed at the shortest path.

Since the starting position is different from the entrance point, how will I match my robot's physical location with the coordinates in the program and move it accordingly. Even if the entrance position would have been same as starting position there may have been an error. How should I deal with it? Should I navigate only on the bases of the coordinates provided by dijkstra or use ultrasonics as well to prevent collisions? And if we yes, can you give me an idea how should I use the both (ultrasonics, and coordinates)?

答:
You will probably want to use a combination of encoders to track the distance that you robot travels as well as ultrasonic sensors to detect the walls of your maze and correct for any minor inaccuracies in your robot's driving.

This sounds somewhat similar to the collegiate Micromouse competition that IEEE and other organizations hold in which small wheeled robots compete to first solve a maze and then run through it in the shortest time possible. If it so happens that the boxes aren't placed in the shortest path, you can find the shortest path between all cells (if I can remember correctly) using the floodfill algorithm (Bellman-Ford) described in the second link.

Links:

Wikipedia article: https://en.wikipedia.org/wiki/Micromouse

Algorithms: http://www.robotix.in/rbtx09/tutorials/m4d4


问:
Mathematical Moddeling of Elastic Robots
We can easily compute the rigid robot kinematics and dynamics. There is many resources, simulators and modelling tools about it. But i couldnt find any of these for elastic robots. Can you suggest resources and modelling tools?</p>

答: You can use Finite Element Anlysis (FEA) tools like Abaqus. Also please look this paper. </p>


答:
The original question, how to plan a path from A to B, is well studied, and the Dykstra algorithm is a good start. However, as you are realizing, Dykstra only establishes a series of waypoints and you are expected to maneuver to those waypoints.

If you can be expected to be dropped within a given tolerance of the start coordinates, then you can check physical dimensions to see if that tolerance matters. For example, if each box on your map is 25cm by 25cm in real life and your vehicle is completely contained within a 10cm circle,  you can accept a location mismatch of up to 7.5cm, assuming you do not travel diagonally and you have perfect odometry to dead reckon the rest of the map.

Now, if you don't know the tolerance on position, or if you do but it's so large that it impacts your ability to navigate, but your heading is known,  then you again have an easy fix.  Measure the distance from your actual start location to the nearest wall, then move back/forward until you are in the correct position, then turn 90 degrees and do it again. Return to the original heading, knowing now that you are in the correct starting position, then proceed to maneuver.

The last case is the worst case - your starting position variation is unknown or too large OR your starting heading is unknown. If this is the case you need to determine your location and heading, and this is typically done via an algorithm called SLAM - simultaneous localization and mapping. My only comments here are to point you in the right direction and wish you luck as I have no practical experience with SLAM algorithms.

So, to summarize, either:
1. The starting tolerance is known AND small enough to not matter AND starting heading is known - do nothing =OR=
2. The starting tolerance is unknown OR too large AND your heading is known - localize with 1D rangefinders =OR=
3. The starting tolerance is unknown, too large, or your heading is unknown - use a SLAM technique.

Title: Navigating through a Maze using path-planning (Dijkstra)

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

Up till now I have processed the bitmap image, and converted it into an adjacency list. I will now use the dijkstra's algorithm to plan the path.

However the problem is that I have to extract the entrance point/node and exit node from the bmp image itself for dijkstra's algorithm to plan the path.

The robots starting position will be slightly different (inch or two before the entrance point) from the entrance point of maze, and I am supposed to move to the entrance point using any "arbitrary method" and then apply dijkstra algorithm to plan path from maze's entrance to exit.

On the way I have to also stop at the "X's" marked in the bmp file I have attached below. These X's are basically boxes in which I have to pot balls. I will plan the path from entrance point to exit point , and not from the entrance to 1st box, then to second, and then to the exit point; because I think the boxes will always be placed at the shortest path.

Since the starting position is different from the entrance point, how will I match my robot's physical location with the coordinates in the program and move it accordingly. Even if the entrance position would have been same as starting position there may have been an error. How should I deal with it? Should I navigate only on the bases of the coordinates provided by dijkstra or use ultrasonics as well to prevent collisions? And if we yes, can you give me an idea how should I use the both (ultrasonics, and coordinates)?


答:
You should use multi body simulation https://en.m.wikipedia.org/wiki/Multibody_system. There is also modelling software for this. Finite elements are more for structural verification.

For modelling, you could use python's pydy module: https://www.pydy.org/. There are also other open source software tools: http://www.cs.rpi.edu/~trink/sim_packages.html.

Title: Mathematical Moddeling of Elastic Robots

Body: We can easily compute the rigid robot kinematics and dynamics. There is many resources, simulators and modelling tools about it. But i couldnt find any of these for elastic robots. Can you suggest resources and modelling tools?</p>


问:
Building parts, and keeping laser alignment steady
I am building a laser gun for pentathlon targets (also doing one).
I would like to know how build a part of the gun and if I can count on a steady laser if it is attached to a motor.

The question is about the laser. I want it maybe attached to a small-(servo)motor to try to implement some cheat just for fun. Assuming the motor has a good torque, can I assume that the laser will not move (not the sightliest bit) when the motor is turned off? (I don't have any to test)
This is for precision shooting, so small vibrations and a moving pointer would be really prejudicial.
In case it does, what can I do to minimize the problem? Is it all about ordering the motor with the highest torque?

I also have a second question which is slightly off-topic, yet related, and robotics people usually have solutions for such problems.
I also need to build the sights. Here's a gun:

As you can tell, its sights are a fixed plastic point in the front, and an adjustable large back. There are two bolts, one on each side. One makes the sight higher or lower, and the other makes it point more to the right or left.
How can such part be built with simple tools?

Thanls

答:
The two questions are quite unrelated so it would be best to ask two questions. Otherwise responds will probably fall short on one of them.

About Q1: I understand that you are looking at using a servo (RC controlled?) to shift the laser boresight so the laser will shoot a bit up-down or left-right when commanded and, when not commanded, it will shoot normal, all without giving a hint that the laser is moving.

A servo would probably work in this sense, maybe a DC motor + gears could also work; you're not trying to paint art with the laser. Fitting the servo, the RC receiver, and the battery into the gun would be a challenge. And also, because the gun gets heavier, your friend could tell the joke if he touches a second one or if the extra weight is easily recognized.

About Q2: The question needs more data (material, dimensions, 2d drawings, schematics). Manufacturing is not my expertise.


问:
Is it possible to simulate vision (perception) in Gazebo (or other simulators)
Vision is important part of robotics and frequently it is unavoidable component of control loop. E.g. many clothes/garment handling algorithms rely on visual cues in deciding how to proceed. The question is - does simulation environments (Gazebo or some others) allow one to design world with robot and garment and simulate not only garment dynamics but simulate also what robot sees, how robot perceives garment in each simulation step? If it is not possible to simulate vision then how to simulate algorithms with vision as component of control loop?

Maybe simulation of vision can be good research theme? Are here some trend or good articles about it? Some initial projects that could be expanded?

Actually - it can be stated as more general question - is it possible to simulate sensors in Gazebo? E.g. food handling (soft-body handling) can involve tactile sensors. In principle Gazebo can calculate deformation and forces of soft-body and format these data as the simulated values of sensor readings. Maybe similar mechanism can be used for simulation of vision as well?

答:
While Gazebo - and most other simulators - will allow you to simulate sensors, you have to realize that this the "weak" part of realtime simulators. Making an accurate simulated camera is really difficult. The result would therefore be great to test your integration and basic control algorithm behaviour (for instance that you move right when you should), but very limited to test the vision-based algorithm itself, as well as test fine print of the control laws.

The strategy I follow in these cases is to (1) create a "simulated component simulation" to test the control system in the simulator and (2) use log replay to test the vision component:

Create a "vision component simulator". This component would output what the vision part of your system should output, but within the simulated environment and WITHOUT processing any image. Add noise / outliers as necessary in the simulated output.

Use a framework that allows you to log data and replay it offline (as Rock or ROS do). You would then have test cases for your vision component that would test its behaviour in way that the simulator could never dream to achieve.


问:
How to make door opening to the top
I need to make this construction (door is closed by default, door is opened to the top). This is the scheme:

Red rectangle on the picture is the aperture, blue rectangle is the door (weight is about 0.5 kg), which moves top when door need to be opened. Green stripe on the picture is the rail for the door.

Which electrical engine should I use?

Estimated time of door opening is about 10 seconds, I want to send signal to up the door, it should be drop down when power is lost or I should send a signal to drop it down.

答:
Could be done in a number of ways. Your ultimate aim is the linear motion of the door.

You could use an elevator style counter-weight mechanism where a cable is strung over a couple of pulleys and a motor rotates one of these pulleys. This is pretty power efficient, doesn't need to take up a lot of physical space and can be done very cheaply.

Alternatively you could attach a toothed rack to the side of the door and use a rack and pinion setup but this can be a bit costly since gears are expensive.

Either way, the core of your design will most likely be a rotary motor - most likely a servo motor or a stepper motor. Control one of these with an Arduino and you're set. Arduino have online documentation to get you up and running and you can buy stuff from Pololu.

Title: How to make door opening to the top


问:
Calculus in robotics

I am still in high school and am a part of the robotics club that competes in the FTC (First Tech Challenge). I am just about finishing my first Calculus class (Calc 1), and would be ecstatic to be able to apply this someway in a real world example such as robotics. [Besides PID. It seems like only approximations anyways]

So far, I've only been working with "fabricated" math problems. Would deriving an equation from real life situations be too complicated?

Thank you!

答:
It all depends on how good you want your system to be and how much effort you're willing to put in. An over-designed robot with good performance can generally be done evaluating the robot on a per-joint basis and usually applying PID control at each joint.

A highly optimized robot with stellar performance will be designed as a system. Here you have to look at:

kinematics - if this joint turns 20 degrees, how far does that thing move?,

physics - what is the moment of inertia and equivalent point mass for that thing?,

dynamics - knowing moment of inertia and how far that thing is moving, what's its relationship between power and acceleration?

datsheets - is this joint's actuator capable of delivering enough physical power for my desired accelerations? What control signal to this joint achieves a given joint acceleration?

control theory - knowing now how this joint's rotation affects that thing and what control signal gives me a desired joint acceleration, what should my desired acceleration be to get that thing to do what I want?

Note that control theory may involve another branch called inverse kinematics, and while basic control theory may involve "just" PID, if you have anything more complicated than a single input single output (SISO) system you will probably wind up doing some more complex control like state-space, which is also capable of handling inter-actuator effects.

Physics and control theory are where you will use most of your calculus, but it is useful to know it for everything else as well so you can see why and when one formula is applicable when another is not. This is usually due to simplifying assumptions used when solving the base differential equation.

Title: Calculus in robotics


问:
Getting started with robotic arm design
I would like to design a robotic arm to hold a weight X at length Y (in my case I want to hold X=2.5 lbs at Y = 4 inches). Starting out simply, I would like try building an arm with a gripper plus one servo joint.

[Servo Joint] ----- Y ------ [Gripper]

When designing an arm, would I want to say that the gripper has to have enough torque to hold the desired weight (e.g. 2.5 lbs) at a minimal distance (however long the fingers are) then design the servo joint to bear the weight of the gripper + the load?

I would like to be able to hold the object at full extension

答:
You have the right idea, just be sure to design for the servo to bear the moment force (aka torque) generated by the load at Y = 4 inches from the joint, not the 2.5 pounds of what you're trying to hold.

$\tau = r*F*\sin(\theta)$

Where:

r is the displacement (your 4 inch arm)

F is the magnitude of the force (2.5 pounds + the gripper)

Theta is the angle between the force vector (gravity, pointing down) and the lever arm

You also want to account for the torque exerted by the weight of the 4-inch arm itself. The displacement you use to calculate this is not 4 inches, but the distance from the servo to the center of mass of the arm (probably 2 inches).

Title: Getting started with robotic arm design


答:
I think the vast majority of compliant or "elastic" robots you will find have rigid links, but compliant joints.  I believe robots with flexible links is still a topic of active research.  So your best bet is to look through academic papers.  It is not a simple solution.  I found some old papers to get you started:

Control Of Flexible Robot Arm by J.D. Lee, L. S. Hayna, Ben Li Wang, and KwangHornp Tsai.

Havlik, S., "Structural compliance of flexible robot arms: analysis, synthesis and control aspects," Advanced Robotics, 1991. 'Robots in Unstructured Environments', 91 ICAR., Fifth International Conference on , vol., no., pp.1622,1625 vol.2, 19-22 June 1991


问:
Need help calculating the thrust on quadcopter motors
I'm trying to calculate the lifting capability of my four quadcopter motors. I tried using eCalc but it doesn't have battery I'm using. Are there any equations to keep in mind for doing these calculations? Here are some relevant details:

Battery: 2200mAh 3S 25~50C LiPo

ESC: 25A

Motor: 1240kV Brushless

Propeller: 8x4

Any help would be much appreciated, thanks!

答:
Here is the equation I was able to come up with:

THRUST (kg) =  ((2.83 x 10-12) * (RPM^2) * (DIAMETER^4) * (((AIR DENSITY) * 23.936) / 29.92) * CF) / 2.2

where
*RPM is motor kv multiplied by battery voltage
*DIAMETER is total length of propellers
*AIR DENSITY has to be looked up or calculated separately
*CF changes based on prop type but should just be "1" for your calculations

Hope this helps


问:
Drone Battery Question
Background:

6 propeller drone w 20C 3s 6400 mAh 11.1 liPO battery

4 propeller drone w 25C 2s 5000 mAh 7.40 liPO battery

Behavior:

Drone 1 flies with ease

Drone 2 struggles hover 2-3 inches above ground

Question:

The microcontroller, all props, ESCs, and motors are the same. I'm thinking the reason the drones are flying so differently is because of the difference in batteries. IF the batteries are the reason, what would be the property that is most responsible for the difference in flight?

答:
Power Law:

Power = Current x Voltage

The voltage of the batteries plays a huge difference in whether electronics function properly.

Each of them is built to run using a particular voltage - 3.3V, 5V, 6V, 7.2V, 11.1V, 12V, 19V and 24V are some common operating voltages for electronics. Some devices have a voltage regulator that shift input voltages to a safe level. This allows you to use a higher voltage power supply to power your robot/computer/sensor. For example, the Arduino Uno has a voltage regulator that accepts voltages between 7-30V and converts them to the 5V that the microprocessor runs at.

From a motor standpoint, decreased voltage means lower power output, which means that either your motors won't turn as fast or they won't be able to output as much torque.

The best thing for you to do right now is look up the datasheets online for your quadcopter or the individual components and find out what voltage each of the parts run at. If your second quadcopter needs anything higher than 7.2V, then there's your problem. If you have trouble deciphering the datasheets, you're welcome to edit your post to include the links and we'll try to help you understand them.

Title: Drone Battery Question


问:
Duty cycle mapping
I need to build a conversion/mapping algorithm from a controller (PID etc.) output to the duty cycle in order to command my bldc motor via esc. I couldn't do it yet because l think l dont know the meaning of controller output. Anybody highlights my way?</p>

答:
Usually you would use a PID controller's output as a "substitute" for your (the operator's) output. If you bypassed the PID controller, what signal would you be providing to the ESC? It is easiest to put the input to the PID controller and the feedback to the PID controller in the same units as you would like the output to be. </p>

<p>In your case, I would use a input and feedback as speeds in percent, then the output of the PID controller should be speed in percent, which is easy to provide in PWM form. If you try to compare speeds in km/hr or m/s or something else like that, then you wind up having to convert that speed into a percentage anyways because you don't send "2 m/s" to a speed controller, you send a speed setpoint - either in rpm or percentage. Again, whatever units the ESC is using are the units you should be using for your PID control. </p>

Title: Duty cycle mapping

Body:
Usually you would use a PID controller's output as a "substitute" for your (the operator's) output. If you bypassed the PID controller, what signal would you be providing to the ESC? It is easiest to put the input to the PID controller and the feedback to the PID controller in the same units as you would like the output to be.

In your case, I would use a input and feedback as speeds in percent, then the output of the PID controller should be speed in percent, which is easy to provide in PWM form. If you try to compare speeds in km/hr or m/s or something else like that, then you wind up having to convert that speed into a percentage anyways because you don't send "2 m/s" to a speed controller, you send a speed setpoint - either in rpm or percentage. Again, whatever units the ESC is using are the units you should be using for your PID control.


问:
Create a simple C++ client Application to control KUKA's Robot-arm LBR iiwa via FRI
Until now I have been programming the robot using Java on KUKA's IDE "KUKA Sunrise.Workbench", what I want to do is control the robot arm via my C++.Net application (I would use a camera or Kinect to get commands).
I'm reading the documents provided by Kuka, but as I'm a bit in hurry, I want to understand how a C++ client application (running on my laptop) can send/receive information to/from the robot's controller "KUKA Sunrise Cabinet" (running the server application) via FRI. I still have issues grasping the whole mechanism.

A simple application (Server/Client) source code with explanation (or a schematic) would be more than helpful .

答:
I have a library called grl which integrates control of a KUKA iiwa in C++.

Right now the most reliable mechanism I've found for control is to receive state over FRI, then send state via Java. All the tools necessary to do this are integrated into grl.

While I've been able to receive state over FRI nicely, sending FRI commands so the robot drives reliably has proven more complicated. I'm close to a working implementation and I have a few simple test applications that move a single joint correctly. Once the bugs are worked out it should be very easy to use, and I'm hopeful it will work well. For a specific function controlling FRI see KukaFRIClientDataDriver.cpp.

Unfortunately I've found the direct API KUKA provides to be a bit difficult to use as well, so I'm implementing functions that communicate over the underlying protobuf network messages and UDP.

While this isn't a 100% answer, it is a solution that is 90% of the way to completion.

Update: FRI based control using grl is now working with the Sunrise Connectivity Suite 1.7.

Here is an example of how to use it in the simplest case of KukaFRIClientDataDriverTest.cpp:

```<code>// Library includes
#include <string>
#include <ostream>
#include <iostream>
#include <memory>

#include "grl/KukaFRI.hpp"
#include "grl/KukaFriClientData.hpp"
#include <boost/log/trivial.hpp>

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>
#include <vector>
#include <iostream>

using boost::asio::ip::udp;

#include <chrono>

/// @see https://stackoverflow.com/questions/2808398/easily-measure-elapsed-time
template<typename TimeT = std::chrono::milliseconds>
struct periodic
{
    periodic():start(std::chrono::system_clock::now()){};

    template<typename F, typename ...Args>
    typename TimeT::rep execution(F func, Args&&... args)
    {
        auto duration = std::chrono::duration_cast< TimeT>
                            (std::chrono::system_clock::now() - start);
        auto count = duration.count();
        if(count > previous_count) func(std::forward<Args>(args)...);
        previous_count = count;
        return count;
    }

    std::chrono::time_point<std::chrono::system_clock> start;
    std::size_t previous_count;
};

enum { max_length = 1024 };

int main(int argc, char* argv[])
{

  periodic<> callIfMinPeriodPassed;

  try
  {
    std::string localhost("192.170.10.100");
    std::string localport("30200");
    std::string remotehost("192.170.10.2");
    std::string remoteport("30200");

    std::cout << "argc: " << argc << "\n";
    if (argc !=5 && argc !=1)
    {
      std::cerr << "Usage: " << argv[0] << " <localip> <localport> <remoteip> <remoteport>\n";
      return 1;
    }

    if(argc ==5){
      localhost = std::string(argv[1]);
      localport = std::string(argv[2]);
      remotehost = std::string(argv[3]);
      remoteport = std::string(argv[4]);
    }

      std::cout << "using: "  << argv[0] << " " <<  localhost << " " << localport << " " <<  remotehost << " " << remoteport << "\n";

    boost::asio::io_service io_service;

    std::shared_ptr<KUKA::FRI::ClientData> friData(std::make_shared<KUKA::FRI::ClientData>(7));
    std::chrono::time_point<std::chrono::high_resolution_clock> startTime;

    BOOST_VERIFY(friData);

    double delta = -0.0001;
    /// consider moving joint angles based on time
    int joint_to_move = 6;
    BOOST_LOG_TRIVIAL(warning) << "WARNING: YOU COULD DAMAGE OR DESTROY YOUR KUKA ROBOT "
                               << "if joint angle delta variable is too large with respect to "
                               << "the time it takes to go around the loop and change it. "
                               << "Current delta (radians/update): " << delta << " Joint to move: " << joint_to_move << "\n";

    std::vector<double> ipoJointPos(7,0);
    std::vector<double> offsetFromipoJointPos(7,0); // length 7, value 0
    std::vector<double> jointStateToCommand(7,0);

    grl::robot::arm::KukaFRIClientDataDriver driver(io_service,
        std::make_tuple(localhost,localport,remotehost,remoteport,grl::robot::arm::KukaFRIClientDataDriver::run_automatically)
    );

    for (std::size_t i = 0;;++i) {

        /// use the interpolated joint position from the previous update as the base
        if(i!=0 && friData) grl::robot::arm::copy(friData->monitoringMsg,ipoJointPos.begin(),grl::revolute_joint_angle_interpolated_open_chain_state_tag());

        /// perform the update step, receiving and sending data to/from the arm
        boost::system::error_code send_ec, recv_ec;
        std::size_t send_bytes_transferred = 0, recv_bytes_transferred = 0;
        bool haveNewData = !driver.update_state(friData, recv_ec, recv_bytes_transferred, send_ec, send_bytes_transferred);

        // if data didn't arrive correctly, skip and try again
        if(send_ec || recv_ec )
        {
           std::cout  << "receive error: " << recv_ec << "receive bytes: " << recv_bytes_transferred << " send error: " << send_ec << " send bytes: " << send_bytes_transferred <<  " iteration: "<< i << "\n";
           std::this_thread::sleep_for(std::chrono::milliseconds(1));
           continue;
        }

        // If we didn't receive anything new that is normal behavior,
        // but we can't process the new data so try updating again immediately.
        if(!haveNewData)
        {
           std::this_thread::sleep_for(std::chrono::milliseconds(1));
           continue;
        }

        /// use the interpolated joint position from the previous update as the base
        /// @todo why is this?
        if(i!=0 && friData) grl::robot::arm::copy(friData->monitoringMsg,ipoJointPos.begin(),grl::revolute_joint_angle_interpolated_open_chain_state_tag());

        if (grl::robot::arm::get(friData->monitoringMsg,KUKA::FRI::ESessionState()) == KUKA::FRI::COMMANDING_ACTIVE)
        {
#if 1 // disabling this block causes the robot to simply sit in place, which seems to work correctly. Enabling it causes the joint to rotate.
            callIfMinPeriodPassed.execution( [&offsetFromipoJointPos,&delta,joint_to_move]()
            {
                    offsetFromipoJointPos[joint_to_move]+=delta;
                    // swap directions when a half circle was completed
                    if (
                         (offsetFromipoJointPos[joint_to_move] >  0.2 && delta > 0) ||
                         (offsetFromipoJointPos[joint_to_move] < -0.2 && delta < 0)
                       )
                    {
                       delta *=-1;
                    }
            });

#endif
        }

            KUKA::FRI::ESessionState sessionState = grl::robot::arm::get(friData->monitoringMsg,KUKA::FRI::ESessionState());
        // copy current joint position to commanded position
        if (sessionState == KUKA::FRI::COMMANDING_WAIT || sessionState == KUKA::FRI::COMMANDING_ACTIVE)
        {
            boost::transform ( ipoJointPos, offsetFromipoJointPos, jointStateToCommand.begin(), std::plus<double>());
            grl::robot::arm::set(friData->commandMsg, jointStateToCommand, grl::revolute_joint_angle_open_chain_command_tag());
        }

        // vector addition between ipoJointPosition and ipoJointPositionOffsets, copying the result into jointStateToCommand
        /// @todo should we take the current joint state into consideration?

        //BOOST_LOG_TRIVIAL(trace) << "position: " << state.position << " us: " << std::chrono::duration_cast<std::chrono::microseconds>(state.timestamp - startTime).count() << " connectionQuality: " << state.connectionQuality << " operationMode: " << state.operationMode << " sessionState: " << state.sessionState << " driveState: " << state.driveState << " ipoJointPosition: " << state.ipoJointPosition << " ipoJointPositionOffsets: " << state.ipoJointPositionOffsets << "\n";
    }
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}
</code>```

Here is the Java side of the application:

```<code>package friCommunication;

import static com.kuka.roboticsAPI.motionModel.BasicMotions.positionHold;
import static com.kuka.roboticsAPI.motionModel.BasicMotions.ptp;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import com.kuka.connectivity.fri.FRIConfiguration;
import com.kuka.connectivity.fri.FRIJointOverlay;
import com.kuka.connectivity.fri.FRISession;
import com.kuka.roboticsAPI.applicationModel.RoboticsAPIApplication;
import com.kuka.roboticsAPI.controllerModel.Controller;
import com.kuka.roboticsAPI.deviceModel.LBR;
import com.kuka.roboticsAPI.geometricModel.CartDOF;
import com.kuka.roboticsAPI.motionModel.controlModeModel.CartesianImpedanceControlMode;

/**
 * Creates a FRI Session.
 */
public class FRIHoldsPosition_Command extends RoboticsAPIApplication
{
    private Controller _lbrController;
    private LBR _lbr;
    private String _hostName;

    @Override
    public void initialize()
    {
        _lbrController = (Controller) getContext().getControllers().toArray()[0];
        _lbr = (LBR) _lbrController.getDevices().toArray()[0];
        // **********************************************************************
        // *** change next line to the FRIClient's IP address                 ***
        // **********************************************************************
        _hostName = "192.170.10.100";
    }

    @Override
    public void run()
    {
        // configure and start FRI session
        FRIConfiguration friConfiguration = FRIConfiguration.createRemoteConfiguration(_lbr, _hostName);
        friConfiguration.setSendPeriodMilliSec(4);
        FRISession friSession = new FRISession(friConfiguration);
        FRIJointOverlay motionOverlay = new FRIJointOverlay(friSession);
         try {
            friSession.await(10, TimeUnit.SECONDS);
        } catch (TimeoutException e) {
            // TODO Automatisch generierter Erfassungsblock
            e.printStackTrace();
            friSession.close();
            return;
        }
        CartesianImpedanceControlMode controlMode = new CartesianImpedanceControlMode();
        controlMode.parametrize(CartDOF.X).setStiffness(100.0);
        controlMode.parametrize(CartDOF.ALL).setDamping(0.7);

        // TODO: remove default start pose
        // move to default start pose
        _lbr.move(ptp(Math.toRadians(10), Math.toRadians(10), Math.toRadians(10), Math.toRadians(-90), Math.toRadians(10), Math.toRadians(10),Math.toRadians(10)));

        // sync move for infinite time with overlay ...
        _lbr.move(positionHold(controlMode, -1, TimeUnit.SECONDS).addMotionOverlay(motionOverlay));
        //_lbr.moveAsync(ptp(Math.toRadians(-90), .0, .0, Math.toRadians(90), .0, Math.toRadians(-90), .0));

        // TODO: remove default start pose
        // move to default start pose
        _lbr.move(ptp(Math.toRadians(10), Math.toRadians(10), Math.toRadians(10), Math.toRadians(-90), Math.toRadians(10), Math.toRadians(10),Math.toRadians(10)));

        // done
        friSession.close();
    }

    /**
     * main.
     *
     * @param args
     *            args
     */
    public static void main(final String[] args)
    {
        final FRIHoldsPosition_Command app = new FRIHoldsPosition_Command();
        app.runApplication();
    }

}
</code>```

Body:
I have a library called grl which integrates control of a KUKA iiwa in C++.

Right now the most reliable mechanism I've found for control is to receive state over FRI, then send state via Java. All the tools necessary to do this are integrated into grl.

While I've been able to receive state over FRI nicely, sending FRI commands so the robot drives reliably has proven more complicated. I'm close to a working implementation and I have a few simple test applications that move a single joint correctly. Once the bugs are worked out it should be very easy to use, and I'm hopeful it will work well. For a specific function controlling FRI see KukaFRIClientDataDriver.cpp.

Unfortunately I've found the direct API KUKA provides to be a bit difficult to use as well, so I'm implementing functions that communicate over the underlying protobuf network messages and UDP.

While this isn't a 100% answer, it is a solution that is 90% of the way to completion.

Update: FRI based control using grl is now working with the Sunrise Connectivity Suite 1.7.

Here is an example of how to use it in the simplest case of KukaFRIClientDataDriverTest.cpp:

// Library includes
#include <string>
#include <ostream>
#include <iostream>
#include <memory>

#include "grl/KukaFRI.hpp"
#include "grl/KukaFriClientData.hpp"
#include <boost/log/trivial.hpp>

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>
#include <vector>
#include <iostream>

using boost::asio::ip::udp;

#include <chrono>

/// @see https://stackoverflow.com/questions/2808398/easily-measure-elapsed-time
template<typename TimeT = std::chrono::milliseconds>
struct periodic
{
    periodic():start(std::chrono::system_clock::now()){};

    template<typename F, typename ...Args>
    typename TimeT::rep execution(F func, Args&&... args)
    {
        auto duration = std::chrono::duration_cast< TimeT>
                            (std::chrono::system_clock::now() - start);
        auto count = duration.count();
        if(count > previous_count) func(std::forward<Args>(args)...);
        previous_count = count;
        return count;
    }

    std::chrono::time_point<std::chrono::system_clock> start;
    std::size_t previous_count;
};

enum { max_length = 1024 };

int main(int argc, char* argv[])
{

  periodic<> callIfMinPeriodPassed;

  try
  {
    std::string localhost("192.170.10.100");
    std::string localport("30200");
    std::string remotehost("192.170.10.2");
    std::string remoteport("30200");

    std::cout << "argc: " << argc << "\n";
    if (argc !=5 && argc !=1)
    {
      std::cerr << "Usage: " << argv[0] << " <localip> <localport> <remoteip> <remoteport>\n";
      return 1;
    }

    if(argc ==5){
      localhost = std::string(argv[1]);
      localport = std::string(argv[2]);
      remotehost = std::string(argv[3]);
      remoteport = std::string(argv[4]);
    }

      std::cout << "using: "  << argv[0] << " " <<  localhost << " " << localport << " " <<  remotehost << " " << remoteport << "\n";

    boost::asio::io_service io_service;

    std::shared_ptr<KUKA::FRI::ClientData> friData(std::make_shared<KUKA::FRI::ClientData>(7));
    std::chrono::time_point<std::chrono::high_resolution_clock> startTime;

    BOOST_VERIFY(friData);

    double delta = -0.0001;
    /// consider moving joint angles based on time
    int joint_to_move = 6;
    BOOST_LOG_TRIVIAL(warning) << "WARNING: YOU COULD DAMAGE OR DESTROY YOUR KUKA ROBOT "
                               << "if joint angle delta variable is too large with respect to "
                               << "the time it takes to go around the loop and change it. "
                               << "Current delta (radians/update): " << delta << " Joint to move: " << joint_to_move << "\n";

    std::vector<double> ipoJointPos(7,0);
    std::vector<double> offsetFromipoJointPos(7,0); // length 7, value 0
    std::vector<double> jointStateToCommand(7,0);

    grl::robot::arm::KukaFRIClientDataDriver driver(io_service,
        std::make_tuple(localhost,localport,remotehost,remoteport,grl::robot::arm::KukaFRIClientDataDriver::run_automatically)
    );

    for (std::size_t i = 0;;++i) {

        /// use the interpolated joint position from the previous update as the base
        if(i!=0 && friData) grl::robot::arm::copy(friData->monitoringMsg,ipoJointPos.begin(),grl::revolute_joint_angle_interpolated_open_chain_state_tag());

        /// perform the update step, receiving and sending data to/from the arm
        boost::system::error_code send_ec, recv_ec;
        std::size_t send_bytes_transferred = 0, recv_bytes_transferred = 0;
        bool haveNewData = !driver.update_state(friData, recv_ec, recv_bytes_transferred, send_ec, send_bytes_transferred);

        // if data didn't arrive correctly, skip and try again
        if(send_ec || recv_ec )
        {
           std::cout  << "receive error: " << recv_ec << "receive bytes: " << recv_bytes_transferred << " send error: " << send_ec << " send bytes: " << send_bytes_transferred <<  " iteration: "<< i << "\n";
           std::this_thread::sleep_for(std::chrono::milliseconds(1));
           continue;
        }

        // If we didn't receive anything new that is normal behavior,
        // but we can't process the new data so try updating again immediately.
        if(!haveNewData)
        {
           std::this_thread::sleep_for(std::chrono::milliseconds(1));
           continue;
        }

        /// use the interpolated joint position from the previous update as the base
        /// @todo why is this?
        if(i!=0 && friData) grl::robot::arm::copy(friData->monitoringMsg,ipoJointPos.begin(),grl::revolute_joint_angle_interpolated_open_chain_state_tag());

        if (grl::robot::arm::get(friData->monitoringMsg,KUKA::FRI::ESessionState()) == KUKA::FRI::COMMANDING_ACTIVE)
        {
#if 1 // disabling this block causes the robot to simply sit in place, which seems to work correctly. Enabling it causes the joint to rotate.
            callIfMinPeriodPassed.execution( [&offsetFromipoJointPos,&delta,joint_to_move]()
            {
                    offsetFromipoJointPos[joint_to_move]+=delta;
                    // swap directions when a half circle was completed
                    if (
                         (offsetFromipoJointPos[joint_to_move] >  0.2 && delta > 0) ||
                         (offsetFromipoJointPos[joint_to_move] < -0.2 && delta < 0)
                       )
                    {
                       delta *=-1;
                    }
            });

#endif
        }

            KUKA::FRI::ESessionState sessionState = grl::robot::arm::get(friData->monitoringMsg,KUKA::FRI::ESessionState());
        // copy current joint position to commanded position
        if (sessionState == KUKA::FRI::COMMANDING_WAIT || sessionState == KUKA::FRI::COMMANDING_ACTIVE)
        {
            boost::transform ( ipoJointPos, offsetFromipoJointPos, jointStateToCommand.begin(), std::plus<double>());
            grl::robot::arm::set(friData->commandMsg, jointStateToCommand, grl::revolute_joint_angle_open_chain_command_tag());
        }

        // vector addition between ipoJointPosition and ipoJointPositionOffsets, copying the result into jointStateToCommand
        /// @todo should we take the current joint state into consideration?

        //BOOST_LOG_TRIVIAL(trace) << "position: " << state.position << " us: " << std::chrono::duration_cast<std::chrono::microseconds>(state.timestamp - startTime).count() << " connectionQuality: " << state.connectionQuality << " operationMode: " << state.operationMode << " sessionState: " << state.sessionState << " driveState: " << state.driveState << " ipoJointPosition: " << state.ipoJointPosition << " ipoJointPositionOffsets: " << state.ipoJointPositionOffsets << "\n";
    }
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}

Here is the Java side of the application:

package friCommunication;

import static com.kuka.roboticsAPI.motionModel.BasicMotions.positionHold;
import static com.kuka.roboticsAPI.motionModel.BasicMotions.ptp;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import com.kuka.connectivity.fri.FRIConfiguration;
import com.kuka.connectivity.fri.FRIJointOverlay;
import com.kuka.connectivity.fri.FRISession;
import com.kuka.roboticsAPI.applicationModel.RoboticsAPIApplication;
import com.kuka.roboticsAPI.controllerModel.Controller;
import com.kuka.roboticsAPI.deviceModel.LBR;
import com.kuka.roboticsAPI.geometricModel.CartDOF;
import com.kuka.roboticsAPI.motionModel.controlModeModel.CartesianImpedanceControlMode;

/**
 * Creates a FRI Session.
 */
public class FRIHoldsPosition_Command extends RoboticsAPIApplication
{
    private Controller _lbrController;
    private LBR _lbr;
    private String _hostName;

    @Override
    public void initialize()
    {
        _lbrController = (Controller) getContext().getControllers().toArray()[0];
        _lbr = (LBR) _lbrController.getDevices().toArray()[0];
        // **********************************************************************
        // *** change next line to the FRIClient's IP address                 ***
        // **********************************************************************
        _hostName = "192.170.10.100";
    }

    @Override
    public void run()
    {
        // configure and start FRI session
        FRIConfiguration friConfiguration = FRIConfiguration.createRemoteConfiguration(_lbr, _hostName);
        friConfiguration.setSendPeriodMilliSec(4);
        FRISession friSession = new FRISession(friConfiguration);
        FRIJointOverlay motionOverlay = new FRIJointOverlay(friSession);
         try {
            friSession.await(10, TimeUnit.SECONDS);
        } catch (TimeoutException e) {
            // TODO Automatisch generierter Erfassungsblock
            e.printStackTrace();
            friSession.close();
            return;
        }
        CartesianImpedanceControlMode controlMode = new CartesianImpedanceControlMode();
        controlMode.parametrize(CartDOF.X).setStiffness(100.0);
        controlMode.parametrize(CartDOF.ALL).setDamping(0.7);

        // TODO: remove default start pose
        // move to default start pose
        _lbr.move(ptp(Math.toRadians(10), Math.toRadians(10), Math.toRadians(10), Math.toRadians(-90), Math.toRadians(10), Math.toRadians(10),Math.toRadians(10)));

        // sync move for infinite time with overlay ...
        _lbr.move(positionHold(controlMode, -1, TimeUnit.SECONDS).addMotionOverlay(motionOverlay));
        //_lbr.moveAsync(ptp(Math.toRadians(-90), .0, .0, Math.toRadians(90), .0, Math.toRadians(-90), .0));

        // TODO: remove default start pose
        // move to default start pose
        _lbr.move(ptp(Math.toRadians(10), Math.toRadians(10), Math.toRadians(10), Math.toRadians(-90), Math.toRadians(10), Math.toRadians(10),Math.toRadians(10)));

        // done
        friSession.close();
    }

    /**
     * main.
     *
     * @param args
     *            args
     */
    public static void main(final String[] args)
    {
        final FRIHoldsPosition_Command app = new FRIHoldsPosition_Command();
        app.runApplication();
    }

}


问:
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.

答:
Do you have a picture of the other side of the board? Typically, when you have a broken wire like this, either (1) the wire pulls out of a cold solder joint and leaves a hole, or (2) the wire breaks and leaves a little piece of wire embedded in a (good) solder joint. </p>

<p>Given the fact that there is so little bare wire exposed, I think that you're in case (2), where I would bet the wire broke off at whatever joint in which it was originally soldered. If this is the case, you should see a little copper-colored bit sticking out of a solder blob or a via in the circuit board. I don't see this, or the hole from case (1), anywhere on the surface of the board you've shown, which, coupled with the fact that the other end of the wire being under the board, leads me to believe your problem point is on the bottom of the board. </p>

Body:
Do you have a picture of the other side of the board? Typically, when you have a broken wire like this, either (1) the wire pulls out of a cold solder joint and leaves a hole, or (2) the wire breaks and leaves a little piece of wire embedded in a (good) solder joint.

Given the fact that there is so little bare wire exposed, I think that you're in case (2), where I would bet the wire broke off at whatever joint in which it was originally soldered. If this is the case, you should see a little copper-colored bit sticking out of a solder blob or a via in the circuit board. I don't see this, or the hole from case (1), anywhere on the surface of the board you've shown, which, coupled with the fact that the other end of the wire being under the board, leads me to believe your problem point is on the bottom of the board.


问:
Modeling a robot to find its position
The task of the robot is as follows.
My robot should catch another robot in the arena, which is trying to escape. The exact position of that robot is sent to my robot at 5Hz. Other than that I can use sonsor to identify that robot.
Is that possible to estimate the next position of other robot using a mathematical model. If so, can anyone recommend tutorials or books to refer..?</p>

答:
Assuming a constant update of 5Hz, your sample time is (1/5) = 0.2s.

Get one position of the target, p1.
Get a second position of the target, p2.

Target speed is the difference in position divided by difference in time:
$$
v = (p_2 - p_1)/dT \\
v = (p_2 - p_1)/0.2
$$

Now predict where they will be in the future, where future is $x$ seconds from now:

$$
p_{\mbox{future}} = p_2 + v*x
$$
where again, $p_2$ is the current point of the target, $v$ is the target's calculated speed, and $x$ is how far in the future you want to predict, in seconds.

You can do a number of things from here such as filtering a number of samples in the past, you could try curve fitting, etc., but this is a simple method of predicting future location based on known position updates.

If you knew more about the path or potential paths your target could take you could optimize the prediction or provide a series of cases, but assuming relatively linear motion this model should hold.

Title: Modeling a robot to find its position


问:
How to cut throttle signal to ESC properly?
I have a 16 Channel Servo Driver board from Adafruit (see here), and I communicate to it via I2C using a Raspberry Pi. The servo board is controlling a Qbrain by sending a PWM pulse between 1ms to 2ms and it works great.

Problem is, I'm trying to create a kill switch such that the signal from the servo board would cease, and the ESC would stop because it detects no PWM signal. I have placed a toggle switch that cuts the VCC to the servo board, so technically it should no longer produce any PWM signal, however when the power is cut, the ESC jumps to 100% throttle, I can only assume this is because the ESC believes the signal is 100% duty cycle, but how do I solve this?

答:
The problem you have is that you're not sending any PWM signal, so the ESC is behaving erratically. You could try to do code to correct for this, but you could have any number of issues.

What I do any time I need to implement a kill switch like this is to use a power relay. You can drive the relay coil from the microcontroller with a transistor as depicted in my crude schematic below.

In this circuit, you have a power switch to turn on the microcontroller board, but then you have to also send HIGH to whatever pin you assign "ESC Enable" in order to close the contacts in the load relay.

Now, with this setup, you can setup a heartbeat. The transmitter sends a packet that sets a heartbeat bit HIGH in the receiver. The receiver uses an interrupt to poll the heartbeat bit and, if it's HIGH, clears the bit. If it is LOW, then you have the option to either kill power on the spot (set ESC Enable to LOW) or you could wait for N heartbeats to be LOW.

As a final note, be sure that you enable, add, configure, etc. a pulldown resistor to the ESC Enable pin to ensure that the pin is LOW any time it would otherwise be floating.


问:
Has a robot ever taken a complete IQ test?
And if so, what was the highest score so far?

Some news articles suggest only parts of tests were aced.

Update since people censored this question and closed it. There was an AI that has taken an IQ test and scored similar to a 4 year old.

http://phys.org/news/2015-10-ai-machine-iq-score-young.html

The AI system which they used is ConceptNet, an open-source project run by the MIT Common Sense Computing Initiative.
Results: It scored a WPPSI-III VIQ that is average for a four-year-old child, but below average for 5 to 7 year-olds

Abstract

We administered the Verbal IQ (VIQ) part of the Wechsler Preschool and Primary Scale of Intelligence (WPPSI-III) to the ConceptNet 4 AI system. The test questions (e.g., "Why do we shake hands?") were translated into ConceptNet 4 inputs using a combination of the simple natural language processing tools that come with ConceptNet together with short Python programs that we wrote. The question answering used a version of ConceptNet based on spectral methods. The ConceptNet system scored a WPPSI-III VIQ that is average for a four-year-old child, but below average for 5 to 7 year-olds. Large variations among subtests indicate potential areas of improvement. In particular, results were strongest for the Vocabulary and Similarities subtests, intermediate for the Information subtest, and lowest for the Comprehension and Word Reasoning subtests. Comprehension is the subtest most strongly associated with common sense. The large variations among subtests and ordinary common sense strongly suggest that the WPPSI-III VIQ results do not show that "ConceptNet has the verbal abilities a four-year-old." Rather, children's IQ tests offer one objective metric for the evaluation and comparison of AI systems. Also, this work continues previous research on Psychometric AI.

Update. A robot has passed the Japanese college entrance test and has an 80% chance of being accepted. Since it scored more than the average, that would make the IQ > 100, especially since college applicants have an IQ greater than average, and especially since Japanese are smarter than average humans. http://gizmodo.com/an-ai-program-in-japan-just-passed-a-college-entrance-e-1742758286

The Wall Street Journal reports that the program, developed by Japan’s National Institute of Informatics, took a multi-subject college entrance exam and passed with an above-average score of 511 points out of a possible 950. (The national average is 416.) With scores like that, it has an 8 out of 10 chance of being admitted to 441 private institutions in Japan, and 33 national ones.

答: I've created an AI, which solves given IQ tests. You may test it on http://iqsolver.eu</p>


问:
Electric Motor Speed Control - PWM vs analog voltage?
I'm working on a 2-wheeled robot and have connected up a raspberry pi to an L298N motor driver.

I'm sending the enable pin of a particular motor a software-generated PWM signal at 100Hz with a 50% duty cycle.  I observe with an osciloscope:

a fairly clean square wave going into the enable pin as expected.

a fairly dirty square wave across the output motor terminals.

The motor turns at about 50% speed/torque as expected.

I find myself wondering if it would be better to control the speed of the motor by placing a flat lower constant voltage across its terminals, rather than oscillating a square wave.  ie to do 50% speed/torque - instead of oscilating between 0V and 5V - just put a constant 2.5V across the motor terminals.  I wonder if the oscillation is a waste of power/energy.

Is this true?  Or doesn't it make any difference?  Do high-end motor drivers use a variable flat analog voltage to control speed/torque, or do they use a PWM?  If a PWM, does the frequency make any difference?

答:
(I'd prefer this to be a commment but I don't have enough rep ;( )

Good question!  Here are a few resources that might help:

Look at this for the PWM frequency question: https://electronics.stackexchange.com/questions/67663/criteria-behind-selecting-pwm-frequency-for-speed-control-of-a-dc-motor

-> Essentially the motor acts as a filter and can average out the pwm wave to create an analog voltage, so you want to look for a frequency that does this best. PWM can also effect the sound of your motors.

Look at this for PWM vs Analog: https://electronics.stackexchange.com/questions/87103/why-is-pwm-used-to-control-dc-motor-speed-instead-of-using-a-variable-resistance

-> It's more efficient to use PWM compared to, say, a resistor in series, as a lot power is dissipated through the resistor. It's also much easier to output a PWM pulse and is typically built into microcontroller's hardware nowadays.


问:
Building a controllable "knob"
I am trying to build a semi-analog timer. Something like those old egg timers that you rotate the face of. I want a knob that I can turn that can be read by a microcontroller, and I also want the microcontroller to be able to position the knob. I'd like to implement "stops" by letting the microcontroller push the knob towards certain positions. As it runs down, the knob should turn. This is my first project of this kind; I've built small robots in the past, but it's been many years.

I've considered hacking a servo motor to read its position, but the small hobby servos I've tried are too hard to turn, very noisy, and pick up too much momentum when turned. They don't act like a good knob.

I'm now considering a rotary encoder connected to a motor, but after hunting at several sites (SparkFun, ServoCity, DigiKey, Trossen, and some others), I haven't been able to find anything that seemed appropriate. I'm not certain how to find a motor that's going to have the right kind of low torque.

This seems like it shouldn't be a really uncommon problem. Is there a fairly normal approach to creating a knob that can be adjusted both by the user and a microcontroller?

答:
I don't know if there is a normal approach to this, but you should definitely check out a video I found years ago and still blows my mind: The Secret Knock Detecting Lock. Basically the guy built an Arduino-based device you can hook up to your door and setup a secret knock that will trigger it to open... Awesome!

I'm sure just the video would be pretty good for inspiration (it's the first thing that came to my mind as I read the title of your question), but after a quick Google search I also found the instructable page that explains it all.

This is a part of the instructable page where he says the motor he uses and gives out some recommendations:

1  5v Gear reduction motor.  The higher torque the better.  Here's a
  good one. (14-16mm diameter is ideal because it fits inside of 1/2"
  PVC pipe.) I recommend one with at least 15oz/in (11 N-cm) of torque
  at 5v to turn a basic lock.

Title: Building a controllable "knob"


答:
Essentially, PWM supplies full rated voltage to a component and effectively varies the current supplied by turning the component on and off very quickly.

For some things, like an LED, which has a bias voltage that must be surpassed for the LED to turn on, you must supply a voltage greater than the bias voltage. If you try to use an analog voltage supplied to the LED as a means of brightness control, you can only dim to a point, where you hit the bias voltage, at which point the LED turns off completely.

For other things, like your motor, there is great cost to generating an analog voltage. How are you intending to do it? A linear regulator uses essentially a voltage divider to create the analog voltage. This means if you want to supply 50% voltage to your motor, the other 50% of that voltage is being "burned off" by a large resistor in the form of heat.

The PWM output is supplying rated voltage to the motor, but the inductance (coil) in the motor creates a time constant in your circuit which is acting like (is, actually) a filter, which is why you are seeing a "dirty" square wave. There is very very little power loss in doing switching (PWM) power supply because the inductance and reactance in the load that causes the filtering effect are both imaginary loads; whatever power they "consume" while the capacitor/inductor is charging is paid back when they discharge; this is why you get the shark fin look on a square wave.

So, your options are to use PWM to provide a switching power supply directly to the motor, or send a PWM signal to 3rd party power supply to it can provide a switching power supply to the motor, or use a linear regulator and suffer the consequences

Title: Electric Motor Speed Control - PWM vs analog voltage?

Body:
I'm working on a 2-wheeled robot and have connected up a raspberry pi to an L298N motor driver.

I'm sending the enable pin of a particular motor a software-generated PWM signal at 100Hz with a 50% duty cycle.  I observe with an osciloscope:

a fairly clean square wave going into the enable pin as expected.

a fairly dirty square wave across the output motor terminals.

The motor turns at about 50% speed/torque as expected.

I find myself wondering if it would be better to control the speed of the motor by placing a flat lower constant voltage across its terminals, rather than oscillating a square wave.  ie to do 50% speed/torque - instead of oscilating between 0V and 5V - just put a constant 2.5V across the motor terminals.  I wonder if the oscillation is a waste of power/energy.

Is this true?  Or doesn't it make any difference?  Do high-end motor drivers use a variable flat analog voltage to control speed/torque, or do they use a PWM?  If a PWM, does the frequency make any difference?


问:
How do I decide the size of the time steps between sensing and control actuation?
My Background:

My experience is in solid mechanics and FEA.  So I have zero experience in robotics/controls.

Problem Description

I'm developing a control strategy to stabilize a complicated 6-legged dynamical system.  Torques Ti from each leg's joints will be used to create a net moment M on the body, stabilizing the system.  This moment M is known from the pre-determined control strategy.  (Side note: the dynamical solver is of the nonlinear computational type)

Due to my lack of background, I have a fundamental confusion with the dynamical system.  I want to use joint torques Ti to create this known net moment M on the body.  This moment M is a function of the

current positions/angles of all the leg segments

reaction forces and moments (that cannot be controlled) of each leg

controllable joint torques Ti of each leg

time

$(*)$ At a given time $(n-1)\Delta$t:

--From the control strategy, the desired net moment M is computed/known

--One can read/sense the legs' positions, angles, reaction forces, and reaction moments (say, from well placed sensors), at this time $t = (n-1)\Delta$t.

--From this information, vector algebra easily yields the desired joint torques Ti required to create the net moment M

$(**)$ At the time $(n)\Delta$t:

--one applies the previously determined joint torques Ti (determined at $t=(n-1)\Delta$t) to create the desired moment M

--of course these torques Ti are applied at the immediate proceeding time step because they cannot be applied instantaneously

So this is exactly where my fundamental confusion exists.  The torques Ti were calculated in $(*)$, based on data of angles/positions/reactions in $(*)$, with the objective to create moment M.  However, these torques Ti are applied in $(**)$, where the data (angles/positions/reactions) are now different - thus the desired net moment M can never be created (unless you an magically apply actuation at the instantaneous time of sensing).  Am I understanding the controls problem correctly?

Questions

Am I understanding the robotics problem correctly?  What are the terms and strategies around this dilemma?

Of course I could create the time steps between the sensing and the actuation to be infinitely small, but this would be unrealistic/dishonest.  What is the balance between a realistic time step, but also performs the task well?

答:
Regarding point 1, yes you are understanding the problem correctly.

Regarding points 1 and 2, I believe what you are looking for is the Nyquist-Shannon sampling theory. This theory says that your sampling frequency should be greater than 2x your "highest frequency of interest". This is to prevent aliasing, where you can incorrectly measure a high-frequency signal as low frequency.

The image above is from Wikipedia. So, you have your robot with all its joints and limbs and such - how fast can those limbs move? Your moments and torques will all cause accelerations at the joints; what is the top rotational speed at a joint? Or, put another way, what's the peak moment you would expect and how long would it be applied? You can calculate a speed from that as well.

You want to sample your joints fast enough that you can capture the full dynamics of the system. That's the sampling threshold (minimum!) I would set for my own robotics project for sensing. For control, most , reputable , sources , say 5-10 times the frequency of interest.

Your peak accelerations, from your peak torques and moments, are going to be limited by the mass (moment of inertia) of your limbs. The limbs that limit your accelerations are also going to act as a low-pass filter to keep the system relatively constant between samples such that the fact that you're off by one sample shouldn't matter too much.

Hope this helps!


问:
Is it possible to do SLAM with few IR sensors like Buddy?
I saw Buddy's page and want to purchase for my SLAM research. However, I wonder is it possible to program Buddy for SLAM?

According to Buddy's spec, they're only few IR's, sonars and a camera. As I know, most SLAM algorithms are implemented with powerful sensors such as RGBD/stereo camera, or even laser range finder.

Are there any pepers mention about IR-based SLAM?

答:
I did casually search for something like this a year or two ago. "Sparse sensing" or "sensing limited" were the sort of phrases that cropped up.

Kris Beevers has some interesting publications in this sort of area, such as SLAM With Sparse Sensing. His general approach was to maintain previous sensor readings while changing the direction of the robot, to build up a "scan" comprising several sets of readings. This approach might be sensitive to encoder errors or any other movement inaccuracies during the scan, but still worth investigating.


问:
Absolute positioning without GPS
Using an IMU a robot can estimate its current position relative to its starting position, but this incurs error over time. GPS is especially useful for providing position information not biased by local error accumulation. But GPS cannot be used indoors, and even outdoors it can be spotty.

So what are some methods or sensors that a robot can use to localize (relative to some frame of reference) without using GPS?

答:
Optical flow sensors (such as those used in computer mouses) are good for this situation. Most will give output in terms of translation.

Alternatively, you can just use a basic camera and run some optical flow algorithms on the data. This will give you the same basic information. It might be easier when doing it this way, to adapt an algorithm that will offer rotational motion as well as translation.

Some optical flow ICs do have the ability to give you the image data (eg the ADNS-3080), which you can further analyse for rotational information.

Title: Absolute positioning without GPS


问:
Which joints to discretize for IK
I am using ikfast in OpenRave for my inverse kinematics.  This is an analytical solver, so if your robot's DOF matches the IK type's DOF, then you get all possible solutions.  But if your robot has more DOFs, then you need to pick some joints to have a constant value.  (However, if you use OpenRave's Python interface it will discretize that joint for you.  i.e. give you a set of solutions for every 0.1 radians of that joint.  But my question holds for either interface.)  I have a 7 DOF anthropomorphic arm with joints: Roll-Pitch-Roll-Pitch-Roll-Pitch-Yaw as seen in this image:

The discretized joints are call "free joints" in OpenRave's terminology.  If I let ikfast decide, it picks joint 3 (upper arm roll) to be the free joint.  However, I have been using joint 4 (elbow) to be the free joint because it is easier for me to think about.  But then I realized that perhaps joint 5, 6, or 7 would be better to discretize because they are closer to the end of the chain.  Won't the IK solutions suffer if joints closer to the start of the chain have a large discretization?  Or is OpenRave picking the optimal joint to discretize?

I was just wondering if there is some standard practices or known conventions for this sort of thing.

Put simply: I want a set of IK solutions for the end-effector at some pose.  I will fix a joint either near the start or end of the kinematic chain.  And what i set it to isn't going to be perfect.  Lets say it is off from some "ideal" position by some epsilon.  Now you can imagine that if i want the hand in-front of the robot, and I pick a bad angle for the shoulder (like straight up for example), the rest of the joints will have a hard time getting the end-effector to the target pose, if at all.  But If I fix the wrist to be at some awkward angle, there is still a good chance of getting the end-effector there, or at lease close.  What kind of trade-offs are there?  Which will have a "better" set of solutions?

答:
So I have some experience with kinematic models, but I'm by no means an expert. What do you mean you are "discretizing" a joint? From the documentation you linked:

```<code>For chains containing more degrees of freedom (DOF) than the IK type requires, the user can set arbitrary values of a subset of the joints until the number of unknown joints matches the degrees of freedom of the IK type.
</code>```

This makes sense to me. You have an end effector for which you want six degrees of freedom, so you get enough joints chained together for six degrees of freedom. If you have more than six degrees of freedom, you fix ("set arbitrary values of") the excess joints, eliminating degrees of freedom until you're left with what "fits" in the IK solver.

So what I'm not sure about is what you mean by "discretizing". As I read their documentation (I couldn't seem to find an in-depth guide at a glance), and as conceptually makes sense to me, you must fix the extra joints, and you must fix them at whatever "arbitrary value" you chose when configuring the IK solver.

For my reasoning on this, consider a thought experiment: You want to model how your hands move when you bend your elbow, and you make the assumption that your hands are out in front of you and your palms are down. Your model shows your hands move in toward your body. Now you run a test, with your palms up. Should you be surprised that your model didn't predict your hands moving toward your face?

It sounds like the IK solver is returning closed solutions to the inverse kinematics. How can you expect it to account for a motion you don't model, or a joint position/location that's incorrect because your "arbitrary value" doesn't match how it's actually configured?

Can you link to documentation that shows a procedure for discretizing a joint? I didn't see anything on a preliminary search.

I'm assuming this is related to your other question, I think my advice from there still stands - measure your physical robot and check that it matches your model. In this case, with the information you gave, I would look squarely at whatever joint you dicretized and check that it is both fixed and in the orientation you gave in the IK model configuration.

Title: Which joints to discretize for IK

Body:
So I have some experience with kinematic models, but I'm by no means an expert. What do you mean you are "discretizing" a joint? From the documentation you linked:

For chains containing more degrees of freedom (DOF) than the IK type requires, the user can set arbitrary values of a subset of the joints until the number of unknown joints matches the degrees of freedom of the IK type.

This makes sense to me. You have an end effector for which you want six degrees of freedom, so you get enough joints chained together for six degrees of freedom. If you have more than six degrees of freedom, you fix ("set arbitrary values of") the excess joints, eliminating degrees of freedom until you're left with what "fits" in the IK solver.

So what I'm not sure about is what you mean by "discretizing". As I read their documentation (I couldn't seem to find an in-depth guide at a glance), and as conceptually makes sense to me, you must fix the extra joints, and you must fix them at whatever "arbitrary value" you chose when configuring the IK solver.

For my reasoning on this, consider a thought experiment: You want to model how your hands move when you bend your elbow, and you make the assumption that your hands are out in front of you and your palms are down. Your model shows your hands move in toward your body. Now you run a test, with your palms up. Should you be surprised that your model didn't predict your hands moving toward your face?

It sounds like the IK solver is returning closed solutions to the inverse kinematics. How can you expect it to account for a motion you don't model, or a joint position/location that's incorrect because your "arbitrary value" doesn't match how it's actually configured?

Can you link to documentation that shows a procedure for discretizing a joint? I didn't see anything on a preliminary search.

I'm assuming this is related to your other question, I think my advice from there still stands - measure your physical robot and check that it matches your model. In this case, with the information you gave, I would look squarely at whatever joint you dicretized and check that it is both fixed and in the orientation you gave in the IK model configuration.


答:
I have a couple of options for you.

Option 1, build your own servomechanism

As you only need a very low torque to move a knob, a very small motor should do the job nicely. You will probably need to add some friction so that it it doesn't move too easily, or use a small stepper motor with a decent detent torque and a little gearing.

A very cheap way of getting your position feedback is to find an old opto-mechanical mouse.

 Opto-mechanical mouse

Connect up the shaft to your motor/knob shaft and then either roll your own quadrature encoder (taking the A/B phase inputs directly into your microcontroller) or reuse the entire circuit board and hook up the 'mouse' to a serial port and read back the X or Y mouse position through software.

The article Recycle PS/2 Mice into Rotary Pulse Generators is a nice example of someone doing this.

Option 2, persevere with the RC servo

The reason why your RC servo's are hard to turn is that they have a high ratio gear train to give them the torque they need, and this makes them difficult to backdrive. Take a look at this exploded diagram from the wikipedia Servomechanism page:

 Small R/C servo mechanism

electric motor

position feedback potentiometer

reduction gear

actuator arm

A small turn of the actuator shaft of this RC servo would result in a large (many turn) movement of the motor, if you could get it to move without stripping the gears.

Again, since in your application you only need enough torque to turn the knob, you may be able to get rid of that gearing and use the motor position directly. By removing or reducing the gearing, you should find the motor moves very freely indeed. In fact, you may need to add some friction (or leave some gearing in place) in order to prevent the motor being very jittery.

Title: Building a controllable "knob"

Body:
I am trying to build a semi-analog timer. Something like those old egg timers that you rotate the face of. I want a knob that I can turn that can be read by a microcontroller, and I also want the microcontroller to be able to position the knob. I'd like to implement "stops" by letting the microcontroller push the knob towards certain positions. As it runs down, the knob should turn. This is my first project of this kind; I've built small robots in the past, but it's been many years.

I've considered hacking a servo motor to read its position, but the small hobby servos I've tried are too hard to turn, very noisy, and pick up too much momentum when turned. They don't act like a good knob.

I'm now considering a rotary encoder connected to a motor, but after hunting at several sites (SparkFun, ServoCity, DigiKey, Trossen, and some others), I haven't been able to find anything that seemed appropriate. I'm not certain how to find a motor that's going to have the right kind of low torque.

This seems like it shouldn't be a really uncommon problem. Is there a fairly normal approach to creating a knob that can be adjusted both by the user and a microcontroller?


问:
thrust measurement
I try to find out the relation between rpm vs. thrust for a battery+motor+propeller combination. the image shows my setup and also the measurement result. Can anyone explain how l should use this datas (I know Kv.v gives the rpm but my voltage values decreasing because of P=V.I relation etc.) </p>

答:
Okay I thought I'd move this to an answer because I think this will help clear up some confusion you have.

First, if you are trying to plot RPM vs Thrust, then your battery, ESC, power, etc. have nothing to do with RPM vs Thrust, assuming the battery and ESC are sized correctly to provide adequate current to the motor.

It's like saying you want to measure a car's gas tank to see how much traction a car has at a given speed. As long as you're getting enough fuel (current) to keep the motor running, the size, shape, capacity, or chemistry of the fuel really doesn't matter.

Secondly, your voltage is not lowering because of P=IV. The only way that would work is if you are consuming constant power throughout the range of motor RPM, and this is absolutely not the case. In actuality, your battery voltage drop is more likely due to the fact that a real battery is well modeled by an ideal battery and a battery resistor in series, where that resistor represents internal resistance in the battery (generally a few milliOhms). As output current increases, V=IR, so the voltage drop across the internal resistor increases. Because it is in series with the battery, output (terminal) voltage goes down.

As a side note, P=IV, and V=IR, so you can combine those two to write $P=I^2 R $, where P now represents the power being "burned off" by internal battery resistance - this is why batteries under heavy load get very hot.

You didn't publish your test procedure, so depending on how long you took to do the test, coupled with battery C rating and capacity, your voltage drop may also be influenced by regular voltage-state of charge curves. Try performing your test in reverse (high speed first) and see if you get the same results.

Ultimately, my advice to you is, if you want to know rpm vs thrust, measure those two values and ignore everything else. They shouldn't have any impact.

Title: thrust measurement


问:
Can I connect a UDOO to a PC using a straight-through ethernet cable or do I need a cross over?
Can I connect a UDOO board to a PC using a straight-through ethernet cable? Or do I need a cross-over cable?

As far as I know, most modern devices can use the two interchangeably. However, I am not sure if a UDOO can do that. Anyone with any experience?

Thank you for your help.

(PS: I don't have a UDOO on me at the moment, so I can't test it myself. Couldn't find any information in the documentation either).

答:
It appears that the UDOO should support Auto MDI-X, since the KSZ9031RNX Gigabit Ethernet Transceiver it uses supports it. The only question is whether the driver supports setting MDI auto mode.

Even if it doesn't, only one end of an ethernet link needs to be set up to Auto MDI-X, so if the PC end supports it (most do) then you should be able to set auto mode there and the link work with both straight through and cross over cables.


答:
Rosen Diankov answered this question for me in a separate thread:

That's an excellent question, and actually very difficult to answer.
  The general rule of thumb is that the closer it is to the end effector
  the better, but this is not always the case. For example, there's only
  one set of 3 intersecting axes and that's the final 3 joints, then
  choosing a free joint at the end will mean the resulting IK solver
  cannot exploit the 3 intersecting axis property to simplify the IK.

The only way I've found to truly get the best free joint is to solve
  for all of them and see which one is better

Title: Which joints to discretize for IK

Body:
I am using ikfast in OpenRave for my inverse kinematics.  This is an analytical solver, so if your robot's DOF matches the IK type's DOF, then you get all possible solutions.  But if your robot has more DOFs, then you need to pick some joints to have a constant value.  (However, if you use OpenRave's Python interface it will discretize that joint for you.  i.e. give you a set of solutions for every 0.1 radians of that joint.  But my question holds for either interface.)  I have a 7 DOF anthropomorphic arm with joints: Roll-Pitch-Roll-Pitch-Roll-Pitch-Yaw as seen in this image:

The discretized joints are call "free joints" in OpenRave's terminology.  If I let ikfast decide, it picks joint 3 (upper arm roll) to be the free joint.  However, I have been using joint 4 (elbow) to be the free joint because it is easier for me to think about.  But then I realized that perhaps joint 5, 6, or 7 would be better to discretize because they are closer to the end of the chain.  Won't the IK solutions suffer if joints closer to the start of the chain have a large discretization?  Or is OpenRave picking the optimal joint to discretize?

I was just wondering if there is some standard practices or known conventions for this sort of thing.

Put simply: I want a set of IK solutions for the end-effector at some pose.  I will fix a joint either near the start or end of the kinematic chain.  And what i set it to isn't going to be perfect.  Lets say it is off from some "ideal" position by some epsilon.  Now you can imagine that if i want the hand in-front of the robot, and I pick a bad angle for the shoulder (like straight up for example), the rest of the joints will have a hard time getting the end-effector to the target pose, if at all.  But If I fix the wrist to be at some awkward angle, there is still a good chance of getting the end-effector there, or at lease close.  What kind of trade-offs are there?  Which will have a "better" set of solutions?


问:
Calculating Required Torque
Say I had an object with 4 motors/wheels attached (in a fairly standard arrangement).

I need to calculate the amount of torque required from the motors to be able to move the object of x kilograms consistently (without skipping any steps) at a velocity of y, travelling up a slope of angle z.

I'm guessing this would also depend on factors like the grip of the tyre and such?

答:
This is a standard dynamics problem. Let's use this figure I drew:

Some definitions:

$$
\begin{align}
m & \mbox{, the mass of the vehicle in kg.} \\
\mu_{\mbox{rolling}} & \mbox{, the rolling friction coefficient of your tires.} \\
\theta & \mbox{, the incline of the plane in radians.}\\
g & \mbox{, the gravitational constant, 9.81 } m/s^2 \\
r_{\mbox{tire}} & \mbox{, the radius of the tire in m.}
\end{align}
$$

The normal force of the vehicle against the incline is going to be
$$
f_{\mbox{normal}} = mg \cos{\theta} \\
$$
The normal force is going to play into your frictional force in that
$$
f_{\mbox{friction}} = \mu_{\mbox{rolling}} f_{\mbox{normal}} \\
$$

The force opposing the vehicle, trying to cause it to roll down the slope, is
$$
f_{\mbox{opposing}} = m g \sin{\theta} \\
$$

Now, keep in mind that the opposing force and the frictional forces are both at the point of contact between the wheel and the surface. Also note that frictional coefficients are constant for a given force regardless of contact surface area, so as long as all four tires are equal and evenly loaded, you don't need to worry about the per-tire information yet.

So, you have your forces to overcome; opposing and friction. Now you need to convert those to torques:

$$
\tau = f r_{\mbox{tire}} \sin{\phi}
$$

Where here I've used $\phi$ to help distinguish between the applied force angle and the incline angle $\theta$. Anyways, the force is being applied at a right angle, $\sin{90} = 1$, so you can leave that term off and you're left with

$$
\begin{align}
\tau_{\mbox{ losses}} &= (f_{\mbox{opposing}} + f_{\mbox{rolling friction}}) r_{\mbox{tire}} \\
 &= (mg( \sin{\theta}+\cos{\theta}  \mu_{\mbox{rolling}})) r_{\mbox{tire}} \\
\end{align}
$$

Now your speed comes into play, with the formula:

$$
P_{\mbox{rotating}} = \tau_{\mbox{applied}} \omega \\
$$
where $P_{\mbox{rotating}}$ is the rotational power output in Watts, $\tau_{\mbox{applied}}$ is the torque applied in Nm, and $\omega$ is the rotational velocity in rad/s. Your vehicle's linear speed, in $\frac{m}{s}$, is given by:

$$
v = r_{\mbox{tire}} \omega \\
$$
so
$$
\omega = \frac{v}{r_{\mbox{tire}}} \\
$$

Putting it all together:

$$
\begin{align}
P_{\mbox{rotating}} &= (mg (\sin{\theta} + \cos{\theta} \mu_{\mbox{rolling}})) r_{\mbox{tire}} \frac{v}{r_{\mbox{tire}}} \\
 &= v m g(\sin{\theta} +\cos{\theta} \mu_{\mbox{rolling}})) \\
\end{align}
$$

Now, finally, this is the rotating power required to move the entire vehicle. At this point, however many (equally sized and loaded) tires you use needs to contribute a corresponding fraction of this power; 4 tires = each one needs to deliver at least 1/4 of the power given above.

Title: Calculating Required Torque


答:
Which will have a "better" set of solutions?

I could think of some requirements so "better" becomes a measurable value. A better solution:

exists: As you say, fixing a joint in one position can make it difficult for other joints to reach the position, but it could also become impossible. This may or may not be a real problem, but I think keeping the possibility in mind that there might be no solution due to the choice of a fixed joint is important.

is reached quickly: Each actuator has to move a certain distance (angle). Given that some actuators move quicker than others the time it takes to reach the target position can be optimised. It seems desireable to distribute the motion in a way that minimises the overall time it takes to reach the target position.

is efficient: The first joint has to hold all other parts. It might require more torque/force to move it instead of several other joints. Maybe the joint has a built in break/clamping mechanism that allows it to stay steady without power consumption. If it has no break, how much power is required to stay in the target position? Is there a target position that minimises the overall consumed power (due to different power consumption of joints and/or loads they have to hold in that position)? Power is consumed during the motion and while holding the target position. Given that the target position is only held for a certain amount of time, there could be a trade-off between how to move and what target position to reach in terms of overall power consumption.

is precise: How precise is the motion of the joints? Maybe the last joint has a smaller actuator and is more precise than the first joint (or any other) Is precision necessary?

is aware of the application: Let's not forget that there's a hand at the end of the arm that's supposed to do something. If each joint can apply different amount of force/torque, a certain motion of all the joints might cause a minimum load that the hand can hold. Take your own hand as an example: consider how much force (in x,y,z direction) your hand can hold. Now keep your hand steady and move your arm. The values probably changed.

happens in minimum/appropriate space: Requiring less space to perform a motion is generally desirable. Are there solutions that keep the overall bounding box of the robot small?

That list is probably incomplete. As you see, there is a lot of maybe, could, should, probably, in this answer. I guess that a lot of these points are not even worth considering, but then you might have an application that does have very strict requirements.

Depending on the available computational power and time you have for the IK calculation, run the algorithm for every joint. You can then compare different solutions depending on your requirements. Give each requirement a weight so each solution has a certain score, pick the solution with the highest score.

Title: Which joints to discretize for IK


答: Recent advances in monocular vision based SLAM (ORB_SLAM, LSD_SLAM, SVO) have made it possible to determine a camera's pose w.r.t. an arbitrarily scaled and rotated initial frame. If you combine this information with an IMU and EKF system such as the one from ETH (ethzasl_msf) you can obtain a position estimate even when there is no GPS available. Even better, you can combine a number of pose/position/attitude/etc. sensors in the MSF. </p>

Title: Absolute positioning without GPS

Body:
Using an IMU a robot can estimate its current position relative to its starting position, but this incurs error over time. GPS is especially useful for providing position information not biased by local error accumulation. But GPS cannot be used indoors, and even outdoors it can be spotty.

So what are some methods or sensors that a robot can use to localize (relative to some frame of reference) without using GPS?