问:
Adjusting the PWM frequency and duty cycle to achieve the desired angular velocity in differential drive robots
I am practicing C++ and intro to robotics using a simple differential drive robot and a raspberry pi.  Also following along the GA Tech course on control of mobile robotics.

The implementation I am trying firstly is the Proportional part of a PID controller for a Go-to-goal behavior robot, where I have a known state of [x , y , theta] and I have a desired [x_desired , y_desired , theta_desired].

Assuming a constant velocity, then the only control signal I can affect is the rotation rate omega, such that:

```<code>error = theta_desired - theta;
omega = PID(atan2(sin(e), cos(e))); // where Ki and Kd are zero
</code>```

Using a wheel encoder and basic odometry, I am able to calculate the distance traveled by each wheel and its rotation rate as follows:

```<code>const double& CalculateDistanceTraveled()
{
  distance_traveled_ = (2.0 * M_PI *
            (static_cast<double>(wheel_encoder_.get_total_ticks()) / num_slots_)
            * wheel_radius_m_); // in meters
  return distance_traveled_ ;

}

void CalculateRotationRate()
{
  while (this->is_running_)
    {
      current_distance_ = std::copy(this->CalculateDistanceTraveled());

      // rotate rate = distance / 100 ms * (1000 ms / 1 second)
      rotation_rate_ = (current_distance_ - prev_distance_) * 10. // in seconds
      prev_distance_ = current_distance_;

      std::this_thread::sleep_for( time_window_ ); // 100 milliseconds
    }
}
</code>```

Then I can update the robot's position and calculate the required omega as follows:

```<code>d_right_ = encoder_r_.CalculateDistanceTraveled();
d_left_  = encoder_l_.CalculateDistanceTraveled();

d_center_ = (d_left + d_right) / 2.0;

//d_baseline is distance between the two wheels
theta = (d_right - d_left) / d_baseline_;

// update (x,y) position based on distance & orientation
x_ += (d_center * cos(theta_rad_)); // prev heading
y_ += (d_center * sin(theta_rad_));

// update heading
theta_rad += theta;
</code>```

Now I can calculate the error based on the difference between current state and target state assuming constant velocity and using only propotional gain for now

```<code>double e = target.theta_rad_ - current.theta_rad_;
// ensure error is between -Pi and +Pi
e_prime_ = atan2(sin(e), cos(e));
omega_ = kp_ * e_prime_;

// velocity is constant and pre-defined
double w_r = ((2 * v_) + (omega * d_baseline_)) / (2 * wheel_radius_m);

 // velocity is constant and pre-defined
double w_l = ((2 * v_) - (omega * odometry_.d_baseline_)) / (2 * wheel_radius_m);
</code>```

Now that I have the required w_l and w_r I need to turn them to pwm frequency and duty cycle values.

However, AFAIK there is no such equation (since battery charges deplete, etc, etc) which is why we use encoders in the first place.

So the only way I can think of is to use the CalculateRotationRate function, and continuously update the pwm frequency and duty cycle until I get near the required w_r and w_l (as they also change based on the robot's state changing).

At first thought, continuously checking and updating is probably going to introduce oscillations. I can use PID for this, but it seems like a round-about-way of doing it.

I am wondering if my approach for this last part is correct?  To be clear, I am not looking for how to code-up pulse width modulation, but rather how to go from desired w_l to PWM frequency and duty cycle values that will achieve the desired w_l and w_r.

答:
At first,  I did not go trough your code to check for errors in the formulas but from a high level perspective this seems ok. Therefore, your position controller is fine.

What you lack is a lowlevel controller for the PWM signal.
This controller should take the error of w_l - e.g. e_w_l - and w_r and provide a duty cycle accordingly.

For that you should use a PID as well. The resulting system will be a cascaded control loop where the outer (slower) loop corresponds to the position control and the inner loop to the PWM controller (fast).

\begin{align} \text{dutyCycle}_{w} = K_p \cdot e_{w} + K_i \sum_{n=0}^{t} e_w (t) \cdot \Delta t + K_d \frac{e_{w}-e_{w,prev}}{\Delta t} \end{align}

I would start with only a P controller.

INFO: If you desicide to use a I part as well, make sure you also use a Anti-Reset-Windup since the output is strictly limited to 100% dutycycle.

INFO: In order to calculate e_w_{r,l}- or also want to use a D-gain - you need the most recent and the previous measurement. The acquisition of the timestamp is in most cases not super accurate neither deterministic. Therefore, your errors - or D-Part - will become very noisy. This might also be the source for oscillations. A lowpass filter might help you out at that point, when you can live with the delay it introduces.

INFO: Always tune the fast loop - i.e. PWM contoller - first!


问:
Any slam simulator without using ROS?
I found there are STDR and Stage simulators on ROS for SLAM and mobile robot simulation. But I’m trying to run simulations on my laptop that has really limited space, when I tried to install Stage, it requires Gazebo which is 30GBs. Are there standalone simulators? I do have Matlab if that matters.</p>

答: If you have MATLAB you can try out this SLAM Toolbox. There is also a more modern one that also might help.</p>

ContentLicense: CC BY-SA 4.0

Title: Any slam simulator without using ROS?


答:
I doubt if you need simulators that very specific to SLAM applications for mobile robot simulation as most of them generally tend to extend over all possible robot applications.

V-REP is good open-source simulator with support for umpteen number of robots including mobile robots. It can be directly used via its API available in several languages and it has plugins for ROS that could be handy.

The Webots simulator is another similar platform for robot simulation and supports several features including ROS plugins.

Finally, there is CARLA, a car simulation platform for autonomous driving research and you could use it for SLAM applications as well.

Title: Any slam simulator without using ROS?

Body: I found there are STDR and Stage simulators on ROS for SLAM and mobile robot simulation. But I’m trying to run simulations on my laptop that has really limited space, when I tried to install Stage, it requires Gazebo which is 30GBs. Are there standalone simulators? I do have Matlab if that matters.</p>


答:
The Robotics Toolbox for MATLAB has a simple EKF SLAM class, and the source code is open.  A video animation is here:

Demonstration of EKF SLAM using Robotics Toolbox for MATLAB.

The whole example is fairly concise:

```<code>% Creating the vehicle.  First we define the covariance of the vehicles's odometry
% which reports distance travelled and change in heading angle

V = diag([0.005, 0.5*pi/180].^2);

% then use this to create an instance of a Bicycle class
veh = Bicycle('covar', V);

% and then add a "driver" to move it between random waypoints in a square
% region with dimensions from -10 to +10

veh.add_driver( RandomPath(10) );

% Creating the map.  The map covers a square region with dimensions from
% -10 to +10 and contains 20 randomly placed landmarks
map = LandmarkMap(20, 10);

% Creating the sensor.  We firstly define the covariance of the sensor measurements
% which report distance and bearing angle
W = diag([0.1, 1*pi/180].^2);

% and then use this to create an instance of the Sensor class.
sensor = RangeBearingSensor(veh, map, 'covar', W, 'animate', 'angle', [-pi/2 pi/2], 'range', 5);
% Note that the sensor is mounted on the moving robot and observes the features
% in the world so it is connected to the already created Vehicle and Map objects.

% Create the filter.  First we need to determine the initial covariance of the
% vehicle, this is our uncertainty about its pose (x, y, theta)
P0 = diag([0.005, 0.005, 0.001].^2)*1000;

% Now we create an instance of the EKF filter class
ekf = EKF(veh, V, P0, sensor, W, []);
% and connect it to the vehicle and the sensor and give estimates of the vehicle
% and sensor covariance (we never know this is practice).

% Now we will run the filter for 1000 time steps.  At each step the vehicle
% moves, reports its odometry and the sensor measurements and the filter updates
% its estimate of the vehicle's pose
ekf.run(500, 'plot', 'movie', 'ekfslam.mp4');
% all the results of the simulation are stored within the EKF object

%% First let's plot the map
map.plot()
% and then overlay the path actually taken by the vehicle
veh.plot_xy('b');
% and then overlay the path estimated by the filter
ekf.plot_xy('r');
% which we see are pretty close

% Now let's plot the error in estimating the pose
figure
ekf.plot_error()
% and this is overlaid with the estimated covariance of the error.

% Remember that the SLAM filter has not only estimated the robot's pose, it has
% simultaneously estimated the positions of the landmarks as well.  How well did it
% do at that task?  We will show the landmarks in the map again
figure
map.plot();
% and this time overlay the estimated landmark (with a +) and the 95% confidence
% bounds as green ellipses
ekf.plot_map('g');
</code>```

Title: Any slam simulator without using ROS?

Body:
The Robotics Toolbox for MATLAB has a simple EKF SLAM class, and the source code is open.  A video animation is here:

Demonstration of EKF SLAM using Robotics Toolbox for MATLAB.

The whole example is fairly concise:

% Creating the vehicle.  First we define the covariance of the vehicles's odometry
% which reports distance travelled and change in heading angle

V = diag([0.005, 0.5*pi/180].^2);

% then use this to create an instance of a Bicycle class
veh = Bicycle('covar', V);

% and then add a "driver" to move it between random waypoints in a square
% region with dimensions from -10 to +10

veh.add_driver( RandomPath(10) );

% Creating the map.  The map covers a square region with dimensions from
% -10 to +10 and contains 20 randomly placed landmarks
map = LandmarkMap(20, 10);

% Creating the sensor.  We firstly define the covariance of the sensor measurements
% which report distance and bearing angle
W = diag([0.1, 1*pi/180].^2);

% and then use this to create an instance of the Sensor class.
sensor = RangeBearingSensor(veh, map, 'covar', W, 'animate', 'angle', [-pi/2 pi/2], 'range', 5);
% Note that the sensor is mounted on the moving robot and observes the features
% in the world so it is connected to the already created Vehicle and Map objects.

% Create the filter.  First we need to determine the initial covariance of the
% vehicle, this is our uncertainty about its pose (x, y, theta)
P0 = diag([0.005, 0.005, 0.001].^2)*1000;

% Now we create an instance of the EKF filter class
ekf = EKF(veh, V, P0, sensor, W, []);
% and connect it to the vehicle and the sensor and give estimates of the vehicle
% and sensor covariance (we never know this is practice).

% Now we will run the filter for 1000 time steps.  At each step the vehicle
% moves, reports its odometry and the sensor measurements and the filter updates
% its estimate of the vehicle's pose
ekf.run(500, 'plot', 'movie', 'ekfslam.mp4');
% all the results of the simulation are stored within the EKF object

%% First let's plot the map
map.plot()
% and then overlay the path actually taken by the vehicle
veh.plot_xy('b');
% and then overlay the path estimated by the filter
ekf.plot_xy('r');
% which we see are pretty close

% Now let's plot the error in estimating the pose
figure
ekf.plot_error()
% and this is overlaid with the estimated covariance of the error.

% Remember that the SLAM filter has not only estimated the robot's pose, it has
% simultaneously estimated the positions of the landmarks as well.  How well did it
% do at that task?  We will show the landmarks in the map again
figure
map.plot();
% and this time overlay the estimated landmark (with a +) and the 95% confidence
% bounds as green ellipses
ekf.plot_map('g');


问:
DH parameters for a PPP arm
I found this picture on the web and was working through it to make sure I understood the derivation for a PPP arm. I believe for link 2, alpha_2 ought to be -90 and not +90.

Additionally, I don't understand why theta_3 is -90, give that link_3 is only a translation of link_2.

Am I misunderstanding something or are the provided DH parameters incorrect with respect to the provided drawing?

答:
The DH parameters comes from the common normal between two consecutive Z axes. Every time you're in doubt about the DH parameters, you can follow common guidelines between two consecutive axes.

In this case, $d_i$ is the distance along previous Z starting from the previous origin O to the intersection of the new X and previous Z axis, which is variable in the case of prismatic joints.

$r_i$ (or $a_i$) is the distance in current X starting from current origin O to the intersection between previous Z and current X.

$\theta_i$ is the angle in previous Z to align the previous X with the new X.

$\alpha_i$ is the angle in current X to align previous Z to current Z.

From the picture, starting with link 1:

$d$: The distance from previous O to the intersection of previous Z and current X is variable, so it's d1.

$a$: The distance in current X starting from current O to the intersection between previous Z and current X is 0.

$\theta$: The angle in previous Z to align previous X with the new X is 0.

$\alpha$: The angle in current X to align previous Z to current Z is -90 (right hand rule).

For link 2:

$d$: The distance from previous O to the intersection of previous Z and current X is variable, so it's d2.

$a$: The distance in current X starting from current O to the intersection between previous Z and current X is 0.

$\theta$: The angle in previous Z to align previous X with the new X is 90 (right hand rule).

$\alpha$: The angle in current X to align previous Z to current Z is -90 (right hand rule).

For link 3:

$d$: The distance from previous O to the intersection of previous Z and current X is variable, so it's d3.

$a$: The distance in current X starting from current O to the intersection between previous Z and current X is 0.

$\theta$: The angle in previous Z to align previous X with the new X is 0 (right hand rule).

$\alpha$: The angle in current X to align previous Z to current Z is 0 (right hand rule).

So the correct DH Table for this robot would be:

Link 1:   $a=0$, $\alpha=-90$, $d=d1$, $\theta=0$

Link 2: $a=0$, $\alpha=-90$, $d=d2$, $\theta=90$

Link 3:  $a=0$, $\alpha=0$, $d=d3$, $\theta=0$

You can see some guidelines here.

Title: DH parameters for a PPP arm


问:
Line following robot mathematic model
I'm trying to improve the speed my line following robot. I have made this chassis designs. This is the main prototype I'm working on. Look at the following image.

I'm driving the robot with PID, and with previous robots, I noticed it's quite hard to tune these constants perfectly so I'm trying use MATLAB to tune it.

Is there an equation or function that can describe the motion of the robot provided all the dimensions are known so that I can simulate it in MATLAB?

Thank you for your attention!

答: The robot you're trying to model is known as a Two Wheeled Differential Robot. It's easy to find specific kinematic models for it. You can start here or here.

Title: Line following robot mathematic model


问:
Image based visual servoing for quadrotor forward flight
I'm still trying to understand how to implement image based visual servoing (IBVS) for quadrotor. The control laws seem straightforward if you want to use IBVS to track a feature in the image space at a fixed distance, but I'm trying to extend this to flying towards the target as well.

What I'm confused about is that the control law requires you to track at least 3 features for $\mathbf{e}(t) = \mathbf{s} - \mathbf{s^*} \rightarrow 0$, but I'm unsure of how to set the values of $\mathbf{s^*}$ because the location of those 3 features will not be fixed in the pixel space when the quadrotor is flying forward.

Additional info: my quadrotor is supposed to fly through gates which are identified by 4 infrared markers. The center of these 4 infrared markers determines the target path for my quadrotor to fly through.

答:
A Feature normally is not a single pixel and it's normally defined by a structure of some sort, for example the distance between the Markers. In the case of IBVS, you have to identify these features first, otherwise your robot essentially starts blind.

Once you identify the markers you can use the distance between them compared to the distance expected to know your position in relation to them. The same with rotation. After that you can start the IBVS.


问:
Finding correct RPY for approaching a known point on a plane
I have a robot with 6 DOF that I want to use to grab a hanging sheet at a specific point near its edge. The grip needs to be perpendicular to the edge and co-planar with the point of course.

I have the inverse kinematics and I have the XYZ-coordinate that I want to grab, however, I'm struggling a bit with finding the correct RPY needed to approach the point correctly. I have looked at the post How to calculate roll, pitch and yaw from XYZ coordinates of 3 planar points? on Mathwork Matlab Answers, which helped me find the normal to the plane, but there's something I'm not doing or understanding correctly in regards to the calculation of the RPY.

Here's a sketch of the problem:

P2 is the point I want to grab and the arrow illustrates the angle of approach I want to achieve. I know the angle (theta), but none of my robot's axes align with this axis of rotation so I can't simply add this.

Here:

I tried to follow the instructions in the MathWorks post above, ending up with a sketch of the sheet's coordinate frame looking like this:

(Z points into the plane).

Next I calculate the alpha, beta and gamma values like suggested in the post. But what do I do with these?

If I plug the results into my robot the TCP's angle is not even coplanar. I know I haven't taken the theta angle from the sketch into account yet, but I don't want to consider that until I see the TCP is coplanar with the sheet.

Can anyone give me a clue on what I'm doing wrong or if I'm missing some steps? Maybe there's even a better way of achieving what I want than what I tried here? And let me know if I need to clarify anything - this is my first post here, so please be gentle.

Here's the code I have written to do the calculations. p1t, p2t and p3t are the three homogeneous coordinates P1, P2, and P3 respectively in the robot's frame (what I call the global frame):

```<code>// Transform coordinates from cam to robot
Eigen::Vector4f p1t = H * p1;
Eigen::Vector4f p2t = H * p2;
Eigen::Vector4f p3t = H * p3;

Eigen::Vector3f p1t3D, p2t3D, p3t3D;
p1t3D << p1t(0), p1t(1), p1t(2);
p2t3D << p2t(0), p2t(1), p2t(2);
p3t3D << p3t(0), p3t(1), p3t(2);

Eigen::Vector3f v1, v2;
v1 = p2t3D - p1t3D;
v2 = p3t3D - p1t3D;

Eigen::Vector3f xUnitVec = ((p1t3D + p2t3D)/2) - p3t3D;
xUnitVec.normalize();

Eigen::Vector3f zUnitVec = v1.cross(v2);
zUnitVec.normalize();

Eigen::Vector3f yUnitVec = zUnitVec.cross(xUnitVec);

std::cout << "p2t: \n" << p2t << std::endl;

float x1 = xUnitVec(0);
float y1 = yUnitVec(0);
float z1 = zUnitVec(0);
float z2 = zUnitVec(1);
float z3 = zUnitVec(2);

float alpha = atan2(-z2, z3);
float beta = asin(z1);
float gamma = atan2(-y1, x1);

std::cout << "\nRotations: " << std::endl;
std::cout << "Alpha: " << alpha;
std::cout << ", Beta: " << beta;
std::cout << ", Gamma: " << gamma;

pickPoint.clear();
pickPoint = {p2t(0), p2t(1), p2t(2), alpha, beta, gamma};
</code>```

答:
Using Euclidian Angles normally can be confusing because the order of rotation interfers directly on the final rotation. As said above, Universal Robot series uses a specific order of rotation that you have to match.

Besides, if you're using movel ou movej with the UR5, you have to know that the Rx, Ry and Rz represents an Axis-Angle representation. In modern robots, axis angle or quaternion is normally used instead of Euclidian because of Gimbal lock. I believe you can find the specific code to transform from one to another in the Universal Robot forums (Also in early versions the Axis-Angle you see in the screen is not the same you receive via Ethernet, although they represent the same rotation).

Keep in mind that those positions and angles need to be represented in relation to the UR5 frame.

If you have the angle of the plane and a gripper to get the sheet, you can have the normal axis of the gripper match the normal axis of the sheet, then it becomes a grasping problem.


问:
vision guided robotic arm always required 6d pose of object?
I have an object like attached in image.

It is hanging vertical (its position may change but static object) and I want to grasp it using 6DOF Robotic arm. I am Using camera to detect object.

I am trying to estimate its 6D pose w.r.t to camera. The question is do I need to estimate 6D pose of object in order to grasp it? Is that really required, or is my thinking incorrect?

What are the different ways to grasp it using camera?

Can I use just distance between camera and object (after detection), and tell robot to pick at that distance in the middle by gripper? If this is possible, how can I give value of X;Y;Z; ROLL; PITCH; YAW for the pick?

Can anyone guide me to correct path?

答:
What you're trying to do is also known as Visual Servo. You could do it only with the position of the object, but it's normally not done this way because without the rotation information, you cannot guarantee Force nor Form Closure, which is what you need if you don't want to drop your object, be it because of external forces, slippery, etc.

You first need to transform the information in relation to the camera to information in relation to the robot. To do this, you usually need the transform from the robot to the camera. This is a simple transformation. If you have the robot pose in relation to world, and the camera pose in relation to world, then:

Where T is the homogeneous transformation, and R, C and O represent the Robot, Camera and Object Frame.

If your World frame is the Robot Frame:

Otherwise:

For homogeneous transformation I suggest you take a look at Robotics, Vision and Control Second Edition by Peter Corke.

After that, it becomes a grasping problem.


问:
How is this bicycle model in Robotics Vision & Control derived? And is its equation missing something?
I'm reading Robotics, Vision and Control, on page 108 it has following equations:

$$\rho=\sqrt{\Delta^2_x+\Delta^2_y}$$
$$\alpha = \tan^{-1}\frac{\Delta_y}{\Delta_x}-\theta$$
$$\beta = -\theta-\alpha$$

How does it go from the above to the following equations?

$$\pmatrix{
\dot{\rho}\\
\dot{\alpha}\\
\dot{\beta}} = \pmatrix{
-\cos \alpha & 0\\
\frac{\sin \alpha}{\rho} & -1\\
-\frac{\sin \alpha}{\rho} & 0
}\pmatrix{v \\
\omega
}\text{, if } \alpha \in \left(-\frac{\pi}{2}, -\frac{\pi}{2}\right]
$$

$$v=k_p\rho$$

$$\omega=k_\alpha \alpha+k_\beta \beta$$

$$\pmatrix{
\dot{\rho}\\
\dot{\alpha}\\
\dot{\beta}} = \pmatrix{
-k_\rho \cos \alpha\\
k_\rho \sin\alpha - k_\alpha \alpha -k_\beta \beta\\
-k_\rho \sin \alpha
}
$$

Shouldn't $\dot{\rho} = -k_\rho \rho \cos\alpha$ ?

答:
OK, I'm working from the 1st edition of the book, so section 4.2.4 of my edition starts on page 75, but the text appears otherwise to be the same.

Initially, the book re-writes the equations of motion of the robot, given earlier as Eq. 4.2:

$ \dot x = \nu cos \theta $

$ \dot y = \nu sin \theta $

$ \dot \theta = \frac {\nu}  {L} tan \gamma $

in matrix form:

$
\begin{pmatrix}
  \dot x \\
  \dot y \\
  \dot \theta
\end{pmatrix}
=
\begin{pmatrix}
  cos \theta & 0 \\
  sin \theta & 0 \\
  0 & 1
\end{pmatrix}
\begin{pmatrix}
  \nu \\
  \gamma
 \end{pmatrix}
$

These equations are then transformed into polar coordinate form using the notation from the following figure (figure 4.12 in my edition, yours may vary):

From this figure, we obtain your first set of equations:

$ \rho = \sqrt {\Delta ^{2} _{x} + \Delta ^{2} _{y}} $

$ \alpha = tan ^{-1} \frac {\Delta _{y}}  {\Delta _{x}} - \theta  $

$ \beta = - \theta - \alpha  $

Next, we apply the chain rule. Multiply both sides of Eq 4.2 by the Jacobian of the coordinate transformation, J.

There are a couple of ways to obtain the Jacobian, J. Either differentiate the forward map to get

$
J =
\begin{pmatrix}
 {\frac {\Delta _{x}} {\sqrt {\Delta ^{2} _{x} + \Delta ^{2} _{y}}}} & {\frac {\Delta _{y}} {\sqrt {\Delta ^{2} _{x} + \Delta ^{2} _{y}}}} & 0 \\
 -{\frac {\Delta _{y}} {{\Delta ^{2} _{x} + \Delta ^{2} _{y}}}} & {{\frac {\Delta _{x}} {{\Delta ^{2} _{x} + \Delta ^{2} _{y}}}}} & -1 \\
 {\frac {\Delta _{y}} {{\Delta ^{2} _{x} + \Delta ^{2} _{y}}}} & -{{\frac {\Delta _{x}} {{\Delta ^{2} _{x} + \Delta ^{2} _{y}}}}} & 0
\end{pmatrix}
=
\begin{pmatrix}
 -\cos\beta & \sin\beta & 0 \\
 -{\frac {\sin \beta} {\rho}} & -{\frac {\cos \beta} {\rho}} & -1 \\
 {\frac {\sin \beta} {\rho}} & {\frac {\cos \beta} {\rho}} & 0
\end{pmatrix}
$

Alternatively, since we can write the inverse as:

$ \Delta _{x} = -\rho\cos(-\beta) = -\rho\cos\beta $

$ \Delta _{y} = -\rho\sin(-\beta) = \rho\sin\beta $

$ \theta = -(\alpha + \beta) $

we could write this in matrix form and differentiate to get:

$
\begin{pmatrix}
 -\cos \beta & 0 & \rho \sin \beta \\
 \sin\beta & 0 & \rho \cos \beta \\
 0 & -1 & -1
\end{pmatrix}
$

and then invert to obtain J:

$
J =
\begin{pmatrix}
 -\cos\beta & \sin\beta & 0 \\
 -{\frac {\sin \beta} {\rho}} & -{\frac {\cos \beta} {\rho}} & -1 \\
 {\frac {\sin \beta} {\rho}} & {\frac {\cos \beta} {\rho}} & 0
\end{pmatrix}
$

$
J
\begin{pmatrix}
  cos \theta & 0 \\
  sin \theta & 0 \\
  0 & 1
\end{pmatrix}
\begin{pmatrix}
  \nu \\
  \gamma
 \end{pmatrix}
=
\begin{pmatrix}
 -\cos \beta \cos \theta + \sin \beta \sin \theta & 0 \\
 - \frac {1} {\rho} (\cos \beta \sin \theta + \sin \beta \cos \theta) & -1 \\
 \frac {1} {\rho} (\cos \beta \sin \theta + \sin \beta \cos \theta) & 0
\end{pmatrix}
\begin{pmatrix}
  \nu \\
  \gamma
\end{pmatrix}
$

Simplifying and then substituting $ \theta = -(\alpha + \beta) $ gives:

$
=
\begin{pmatrix}
  - \cos (\beta + \theta) & 0 \\
  - \frac {1} {\rho} \sin (\beta + \theta) & -1 \\
  \frac {1} {\rho} \sin (\beta + \theta) & 0
\end{pmatrix}
\begin{pmatrix}
  \nu \\
  \gamma
\end{pmatrix}
=
\begin{pmatrix}
  - \cos \alpha &0 \\
  {\frac {\sin \alpha} {\rho}} & -1 \\
  - {\frac {\sin \alpha} {\rho}} & 0
\end{pmatrix}
\begin{pmatrix}
  \nu \\
  \gamma
\end{pmatrix}
$

So, we can write:

$
\begin{pmatrix}
  \dot \rho \\
  \dot \alpha \\
  \dot \beta
\end{pmatrix}
=
\begin{pmatrix}
  -cos \alpha & 0 \\
  \frac {sin \alpha} {\rho} & -1 \\
  -\frac {sin \alpha} {\rho} & 0
\end{pmatrix}
\begin{pmatrix}
  \nu \\
  \gamma
 \end{pmatrix},
\text { if }
\alpha \in
\begin{pmatrix}
  -\frac {\pi} {2} , \frac {\pi} {2}
 \end{pmatrix}
$

Which is your second equation.

The equations

$ \nu = k _{\rho}  \rho $

$ \gamma = k _{\alpha} \alpha + k _{\beta} \beta $

are the linear control law which, when applied to the equation we just derived gives us:

$
\begin{pmatrix}
  \dot \rho \\
  \dot \alpha \\
  \dot \beta
\end{pmatrix}
=
\begin{pmatrix}
  - k _{\rho} \rho \cos \alpha \\
  k _{\rho} \rho \sin \alpha - k _{\alpha} \alpha - k _{\beta} \beta \\
  -k _{\rho} \sin \alpha
\end{pmatrix}
$

for the closed-loop system.

And yes, it looks like there may be a typo in the book (on page 76 for the first edition, presumably on page 109 in yours?)

A list of errata for RVC can be found on Peter's website, and this doesn't appear to be listed for either edition.  I've emailed him (using the address on the errata page) to let him know about it  with a link to your question.

Alternatively, Peter has recently started using Robotics:SE, so he may see it here (I've suggested an edit to the title to include the name of the book).


答:
Thanks for the question and great derivation by @sempaiscuba.  I first learnt about this kind of controller from the book by Siegwart etal. but the source is

Exponential Stabilization of a Wheeled Mobile Robot Via Discontinuous Control, A. Astolfi, Journal of Dynamic Systems, Measurement, and Control, March 19999, Vol 121, pp. 121-126.

Yes, there is an error and it should indeed be $\dot{\rho} = -k_p \rho \cos \alpha$.

There is an error in the first edition, and fixed in the second, where I mistakenly have the control inputs as $(v, \gamma)^T$, as used in @sempaiscuba's solution, rather than $(v, \omega)^T$.  This control approach assumes a unicycle rather than a bicycle kino-dynamic model.  The first equation on page 107 of the second edition mistakenly has $\dot{\omega}$ where it should have $\dot{y}$ is the left-hand side.  I will get it right for the third edition...

I have updated the errata for the book.

Title: How is this bicycle model in Robotics Vision & Control derived? And is its equation missing something?

Body:
I'm reading Robotics, Vision and Control, on page 108 it has following equations:

$$\rho=\sqrt{\Delta^2_x+\Delta^2_y}$$
$$\alpha = \tan^{-1}\frac{\Delta_y}{\Delta_x}-\theta$$
$$\beta = -\theta-\alpha$$

How does it go from the above to the following equations?

$$\pmatrix{
\dot{\rho}\\
\dot{\alpha}\\
\dot{\beta}} = \pmatrix{
-\cos \alpha & 0\\
\frac{\sin \alpha}{\rho} & -1\\
-\frac{\sin \alpha}{\rho} & 0
}\pmatrix{v \\
\omega
}\text{, if } \alpha \in \left(-\frac{\pi}{2}, -\frac{\pi}{2}\right]
$$

$$v=k_p\rho$$

$$\omega=k_\alpha \alpha+k_\beta \beta$$

$$\pmatrix{
\dot{\rho}\\
\dot{\alpha}\\
\dot{\beta}} = \pmatrix{
-k_\rho \cos \alpha\\
k_\rho \sin\alpha - k_\alpha \alpha -k_\beta \beta\\
-k_\rho \sin \alpha
}
$$

Shouldn't $\dot{\rho} = -k_\rho \rho \cos\alpha$ ?


问:
How to make sense of IMU (BNO055) data
I have a project that I'm working on that needs data about which directions something has moved and how quickly from a given point (accelerometer and magnetometer?). I have the working python code for the BNO055, I'm just having trouble interpreting it. I guess these are my specific questions:

Is the data from a starting point (doesn't seem likely) or a set time period that continues? If so, what is that time interval? Do I define it by how often I ask for the data?

Is magnetometer and accelerometer data what I should be using for my task?

What is a rough pseudocode outline for how I could convert this data into something easier to understand (i.e. an updating distance or x,y,[z] coord system)

答:
One cheap way to get actual odometer data is to cannibalize an optical computer mouse.

You might want to use a "table cloth" with a regular pattern to improve the mouse's "grip" on reality.

ContentLicense: CC BY-SA 3.0

Title: How to make sense of IMU (BNO055) data


问:
Question about programming approach of a dog like quadruped robot
I and my friends are planning to build a dog like quadruped robot. We have designed  it like MIT Cheetah Mini like legs structure, each leg having 3 Servos, 3rd DOF for rotation. We have calculated inverse kinematics equation for each leg. But I am not able to figure out what our approach should be for programming. We were planning to have trot gait, and to travel on straight path, we planned to find safe distance by each leg and plan next point for each leg on the foot and then just transition legs to that point in trot gait.
But still I don't think it will be a great idea. I need to ask what should be our approach to get the walk done smoothly. </p>

答:
I believe you should start from below and up.

First, validate the inverse kinematics for the 4 legs you build. Remember that small mistakes accumulate over time, so it's best to ensure minimum error beforehand.

After that, work on the dynamics of the robot as a whole to ensure the legs stay on path, there should be plenty of articles about quadrupeds on Elsevier and IEEE Xplore, if you have access to these. Even if it's not the same model, they can work as a basis for it.

And for last, use the quadruped dynamics and the legs inverse kinematics to develop the kinematics for the quadruped in general.

As said above, you can use a harness to test the hardware, but it's good practice to simulate first. You can do that on Gazebo, V-Rep, etc.


问:
How to drive a curve in a maze
im currently programming a robot with 2 wheels and i got the task to let it drive alone for a few minutes in a maze. I just managed to programm a controller that controls the distance to each wall right and left. But now i dont know how to drive to the right and left. I tried but its pretty random if the robot hits one of the walls or drives a perfect curve. I can use the wheel encoder sensors, the infrared sensors and the IMU to navigate the robot. Does anyone of you have an idea how i should program this?
Thanks for your help</p>

答:
im currently programming a robot with 2 wheels and i got the task to
  let it drive alone for a few minutes in a maze.

Some more information would be nice. reasonable options are (1) a differential drive type with castor/casters, or (2) a Segway type balancing robot. I am assuming option (1). This is however still an issue. what kind of wheels? grippy rubber, holomonic, swerve drive? I shall assume grippy rubber wheels. C'mon man.

I just managed to programm a controller that controls the distance to each wall right > and left.

I don't understand you. A controller as in hardware, or as in software? I am assuming you mean that you have written code that is aware of the walls, and their proximity to the device measuring the distance. You have these values available. OK. I am assuming the values are that of distance (ex: float or int types).

But now i dont know how to drive to the right and left.

You need to write a program to control the motors. Since the question is a few days old, and I am sure you know this.

I tried but its pretty random if the robot hits one of the walls or drives a perfect curve.

Good job. Motion is better than no motion. Now you have to debug your code to make it usable. If the code is not repeatable and predictable, then your robot is going to be not as impressive as it could be. My advice when writing code (passed to me from a textbook) is don't write the code as cleverly as you can. Why? Because debugging is twice as hard as writing code in the first place. So if you write as cleverly as you can you are not qualified to debug your code. Make your code very easy to read.

I can use the wheel encoder sensors, the infrared sensors and the IMU to navigate the robot.

That sounds like a reasonably capable unit. How much time are you going to invest into this project? I ask because if you are going to spend a lot of time on this unit I recommend implementing some sort of robotic middleware (ex: ROS). If you just want to do the least amount of work, and just hack out a crappy solution, then implement only the hardware you NEED, and use that to achieve your maze navigation objective. The two approaches will generate a significantly different robot even though the hardware is the same. One robot will be stupid ann simply will not hit walls. The other with some minor additions can start to do mapping, localization, path planning, obstacle avoidance and other very cool stuff.

Does anyone of you have an idea how i should program this? Thanks for your help

hmmmmm. I don't know how to answer your question. It's a bit vague. So here's a vague answer: assess your robotic objective. Then figure out what data you need from sensors. Then figure out how to control the outputs based on the sensor data you collect. Spend time planning out your project. This will save you tons of time later on. First I would implement the motors; make sure they move, and make sure the robot can handle motion in the environment. This validates all your hardware. Then implement the sensors, lastly build your finite state machine.

Good luck.

Title: How to drive a curve in a maze


问:
Technologies needed for indoor and outdoor navigating robot
Before I begin, I should add that I am a complete beginner in robotics and hope that I can figure out where I should start by asking this question.

I am trying to make a robot that is able to navigate both indoor and outdoor. The ultimate aim of the robot is to be able to navigate from the outdoors to the lobby of a building and then to the building's lift.

I intend to direct the robot to the building by giving it GPS location when it is outdoors. Then, it should use computer vision to identify the path to the lift lobby. Once indoors, a floor plan of the building's lobby area will be provided to the robot with the location of the lift marked as the final destination but it will still need to map the indoor area to get to the location of the lift.

I figured that I will be using the following key technologies but I am not sure:

Visual Slam: I came across the Accuware Dragonfly which is a visual SLAM technology that uses only an onboard camera. I intend to write a similar software on my own

ROS: Middleware between the Visual Slam and the Robot hardware

Raspberry Pi

Am I thinking about this the right way or is there a better way to do things?

答:
What you are trying to do is very hard. I know because I am doing it: https://answers.ros.org/question/271819/please-suggest-all-packages-to-achieve-slam-for-robot/.

I would say to you, what is your objective? are you trying to build skills, or are you trying to build a commercial offering? What is your budget? How many people to share the work? These preliminary questions will begin to create constraints that will eliminate various designs, leaving behind a pretty obvious path to achieving your objective.

To help you with your technical question, please consider this:

how do you plan on moving. What kind of motors, drivers, are you planning on using? how are you communicating with them?

How will you do your mechanical drawings? catching issues before you finalize your design is so much cheaper and easier.

what is generating your transformation data? ex: /tf topic in ros?

As well, I would recommend adding a PC to your mix.

overall, you have a decent view of how to do it. start building, and you will learn what else you need.

It's doable, but you have to be committed. really committed.


问:
Robotics flag at start of maze
Just to give u a little background of what I am doing, I am currently programming my vehicle to wall-hug a maze. My idea is that my vehicle does a check at start whether or not it will move in clockwise or anti clockwise direction. The thing I am not so sure about is the placement of my flag in my codes. Some of my friends questioned why I have 2 flags in my code, this made me unsure of whether my codes/logic is right. Refer to my codes for more info. If it is wrong, let me know how I can correct it. Thanks.</p>

```<code> if( g_NavState == NAV_NONE ){ //if vehicle is not moving

    if(state.order.bLeft==TRUE){ //left sensor detects obstacle, moves clockwise.
        g_NavState = NAV_FRONT;
        g_MoveStateCmd = MOVE_FWD;
        flag1 = 1; //Unsure about this flag
    }
    else if(state.order.bRight==TRUE){ //right sensor detects obstacle, moves anti clockwise
        g_NavState = NAV_FRONT;
        g_MoveStateCmd = MOVE_FWD;
        flag2 = 1;//Unsure about this flag
    }
}
else if(g_NavState==NAV_FRONT){ //while going front
    if(state.order.bFrontLeft==FALSE && state.order.bLeft==FALSE && state.order.bBackLeft==FALSE && flag1 == 1){
       for(int iter=0;iter<1000000;iter++){
        }
        g_NavState = NAV_FL;
        g_MoveStateCmd = MOVE_FRONT_LEFT;

    }
    else if(state.order.bFrontRight==FALSE && state.order.bRight==FALSE && state.order.bBackRight==FALSE && flag2 == 1){ /*Anti-Clockwise*/
       for(int iter=0;iter<1000000;iter++){
        }
        g_NavState = NAV_FR;
        g_MoveStateCmd = MOVE_FRONT_RIGHT;

    }
</code>```

答:
You can just use one flag, if the purpose of the flag is solely to indicate whether to turn clockwise or anti-clockwise. Name the flag turn_clockwise, make sure it's true when checking whether to turn clockwise, make sure it's false when checking whether to turn anti-clockwise.

You could also not have a flag and check the left or right sensor in the moment if that fits your application.

Title: Robotics flag at start of maze


问:
Inverse Kinematics "Can not converge" issue
I'm a complete beginner with LabView and I have been practicing forward kinematics with the help of a tutorial I found. It's been a learning curve but I've managed to understand a few things.

However, I have not been able to implement an inverse kinematics vi.

I've been trying to replicate this tutorial but I have been unsuccessful so far.

I'm working with a SCARA serial arm. The image below shows my work-in-progress attempt.

When I run my vi I receive the following error:

```<code>Error -310040 occured at NI_Kinematics.lvlib: Inverse Kinematics (Point).vi->Inverse Kinematics Attempt-1.vi

LabVIEW Robotics: (Hex 0xFFFB44E8) LabVIEW cannot converge to a solution in the number of steps you specified. Make sure that the serial arm can achieve the transform you desire.
</code>```

My objective is to set the X, Y and Z input fields to the values representing a point in space and move the endeffector to that point.

I would really appreciate some guidance?

答:
There could be a few generic reasons.

Ensure that the desired Cartesian pose is actually achievable by the robot, i.e the position is within the workspace.

As the error mentions about max_steps parameter, I believe they are using random restarts for something like a Jacobian pseudoinverse based solver; so indeed try giving more steps because intricate Cartesian poses might need more than normal trials.

Finally, confirm if it is not a singularity which could trouble the computations.

I found the information on IK module for LabView on their webpage Inverse Kinematics VI


问:
Transducer for underwater applications (passive sonar)
I'm kicking around the idea of building a small passive sonar for an autonomous submarine. I've looked through the net for parts and finding a good transducer for converting the sound underwater into an electrical impulse. After looking at parts I got into the piezoelectric materials used for doing this such as barium titanate or Lead zirconate titanate. From what I've read on the web, some of these materials are toxic.

My question is, are there piezoelectric materials that one could to build a sensor from scratch that does not possess the toxic qualities? Something that could preferably thrown in a pool w/ my kids and not give them or me any defects.

答:
In general, the microphone should be covered in some sort of waterproofing material (called "potting") that would prevent its materials from ever coming in contact with the pool water.  So unless you are concerned that the microphone will be smashed to pieces while in your pool, it shouldn't be a problem

That said, there are some other transducer technologies besides piezo.  Ribbon microphones won't suffice, mostly because of their fragility.  Dynamic microphones might also a bad idea, because they are generally larger and require more motion than the others.

I'd recommend trying a cheap electrostatic (also called electret) microphone.  You should be able to cover it in silicone RTV or "plumbing goop" and still get a signal out of it.


问:
RGBD Camera Eye in Hand Calibration
Hello I am new to robotics. So far I have a basic understanding of the camera calibration. One would need rotation and transformation matrices to convert a point from camera coordinate system to robot/arm coordinate system. However; when camera is in hand, as robot moves camera coordinate system will change? I am a bit lost over here as resources are mostly research papers with lots of maths. Any useful links or keywords would be very appreciated! :)</p>

答:
When you get the pose of an object using a camera, you get that position in relation to the camera frame. If you want that pose in relation to the robot frame, first you have to find the pose transformation from the robot to the camera. If the camera is static and the base is static, the object pose in relation to the robot would be:

Now, if the camera is not static, let's say, it's in the robot hand, which is your case, then the transformation is fixed in relation to the hand. In this case, the transformation would be:

the transformation from base to end effector is given by direct kinematics. Once you have the transformation from end effector to camera, you can find the object pose in relation to the robot frame.

Title: RGBD Camera Eye in Hand Calibration


问:
Need suggestions for object recognition
I am tasked with creating a system that will recognize fish pulled out of a lake. The system should be able to identify the type of species of fish. Typically, I turn to Arduino for projects like this. However, based on what I've read about image processing, it's sounding like Arduino doesn't have the processing power. Does anyone have any suggestions for development boards and cameras that can easily interface with the board?

I've look at this option, http://www.finboard.org/videos/introducing-finboard?utm_campaign=Embedded%20Processing%20and%20DSP%20Newsletter%2013-Q3%20NA&utm_medium=email&utm_source=Eloqua. It seems like it would be a nice all in one type of thing. Has anyone used anything like this?

Thanks!

答:
I don't think it would be powerful enough, but you could look into the raspberry pi.  It has an HDMI port and ethernet port, and it allows you to run Linux. The Beaglebone is similar but more powerful. At work when I built an image processing platform for an autonomous ATV we used a miniITX motherboard with an i5 processor and a separate firewire card plugged into the PCIE port (this was for the stereo camera). Computer vision can involve some very intense computation, so I'd probably recommend a similar setup. However, the perception system I built was constantly running in a loop, whereas yours only needs to process one image and it's probably fine if it takes 10+ seconds to operate. When driving an autonomous vehicle, you don't have that kind of time XD. For those reasons, you might be able to get away with the previously mentioned boards.

Here's a video of someone using a webcam to capture video and images (and look at that he's looking at FISH!) with a Beaglebone. He's also using the openCV library, which is something you'd probably want to use as well: http://www.youtube.com/watch?v=8QouvYMfmQo

Title: Need suggestions for object recognition


问:
Why my robot is lying down in gazebo simulator?
this is my first post about ROS and Gazebo also I am new in ROS.
I spawn KUKA robot in Gazebo using urdf file from KUKA github repository
following answer from this question I spawned my urdf file in gazebo simulator and KUKA robot appeared in simulator but problem is that is lying down like is attached on floor for some reason.
Here is picture in Gazebo:

This is my launch file:

```<code><launch>
<!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
<include file="<span class="math-container">$(find gazebo_ros)/launch/empty_world.launch">
  <arg name="paused" value="false"/>
  <arg name="use_sim_time" value="true"/>
  <arg name="gui" value="true"/>
  <arg name="headless" value="false"/>
  <arg name="debug" value="false"/>
</include>
<node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-file $</span>(find kuka_kr210_support)/urdf/kr210l150.urdf -urdf -z 1 -model baxter" />
</launch>
</code>```

EDIT:
I fixed base link for the world, added transmission, controllers for each axis and gazebo plugin. now my urdf file looks like this:

```<code><?xml version="1.0" ?>
<!-- =================================================================================== -->
<!-- |    This document was autogenerated by xacro from kr16_2.xacro                   | -->
<!-- |    EDITING THIS FILE BY HAND IS NOT RECOMMENDED                                 | -->
<!-- =================================================================================== -->
<!--Generates a urdf from the macro in kr16_2_macro.xacro -->
<robot name="kuka_kr16_2" xmlns:xacro="http://wiki.ros.org/xacro">
  <!-- LINKS -->

  <!-- base link -->
  <link name="base_link">
    <inertial>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <mass value="2"/>
      <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
    </inertial>
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://kuka_kr16_support/meshes/kr16_2/visual/base_link.dae"/>
      </geometry>
    </visual>
    <collision>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://kuka_kr16_support/meshes/kr16_2/collision/base_link.stl"/>
      </geometry>
    </collision>
  </link>
  <!-- link 1 (A1) -->
  <link name="link_1">
    <inertial>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <mass value="2"/>
      <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
    </inertial>
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://kuka_kr16_support/meshes/kr16_2/visual/link_1.dae"/>
      </geometry>
    </visual>
    <collision>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://kuka_kr16_support/meshes/kr16_2/collision/link_1.stl"/>
      </geometry>
    </collision>
  </link>
  <!-- link 2 -->
  <link name="link_2">
    <inertial>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <mass value="2"/>
      <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
    </inertial>
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://kuka_kr16_support/meshes/kr16_2/visual/link_2.dae"/>
      </geometry>
    </visual>
    <collision>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://kuka_kr16_support/meshes/kr16_2/collision/link_2.stl"/>
      </geometry>
    </collision>
  </link>
  <!-- link 3 -->
  <link name="link_3">
    <inertial>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <mass value="2"/>
      <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
    </inertial>
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://kuka_kr16_support/meshes/kr16_2/visual/link_3.dae"/>
      </geometry>
    </visual>
    <collision>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://kuka_kr16_support/meshes/kr16_2/collision/link_3.stl"/>
      </geometry>
    </collision>
  </link>
  <!-- link 4 -->
  <link name="link_4">
    <inertial>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <mass value="2"/>
      <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
    </inertial>
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://kuka_kr16_support/meshes/kr16_2/visual/link_4.dae"/>
      </geometry>
    </visual>
    <collision>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://kuka_kr16_support/meshes/kr16_2/collision/link_4.stl"/>
      </geometry>
    </collision>
  </link>
  <!-- link 5 -->
  <link name="link_5">
    <inertial>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <mass value="2"/>
      <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
    </inertial>
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://kuka_kr16_support/meshes/kr16_2/visual/link_5.dae"/>
      </geometry>
    </visual>
    <collision>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://kuka_kr16_support/meshes/kr16_2/collision/link_5.stl"/>
      </geometry>
    </collision>
  </link>
  <!-- link 6 -->
  <link name="link_6">
    <inertial>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <mass value="2"/>
      <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
    </inertial>
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://kuka_kr16_support/meshes/kr16_2/visual/link_6.dae"/>
      </geometry>
    </visual>
    <collision>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://kuka_kr16_support/meshes/kr16_2/collision/link_6.stl"/>
      </geometry>
    </collision>
  </link>
  <!-- tool 0 -->
  <!-- This frame corresponds to the $FLANGE coordinate system in KUKA KRC controllers.
  <link name="tool0"/> -->

  <!-- END LINKS -->
  <!-- JOINTS -->
  <!-- joint 1 (A1) -->
  <joint name="joint_a1" type="revolute">
    <origin rpy="0 0 0" xyz="0 0 0.675"/>
    <parent link="base_link"/>
    <child link="link_1"/>
    <axis xyz="0 0 -1"/>
    <limit effort="0" lower="-3.22885911619" upper="3.22885911619" velocity="2.72271363311"/>
  </joint>

   <transmission name="trans_joint_a1">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="joint_a1">
        <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
      </joint>
      <actuator name="motor_joint_a1">
        <mechanicalReduction>1</mechanicalReduction>
        <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
      </actuator>
   </transmission>

  <!-- joint 2 (A2) -->
  <joint name="joint_a2" type="revolute">
    <origin rpy="0 0 0" xyz="0.26 0 0"/>
    <parent link="link_1"/>
    <child link="link_2"/>
    <axis xyz="0 1 0"/>
    <limit effort="0" lower="-2.70526034059" upper="0.610865238198" velocity="2.72271363311"/>
  </joint>

   <transmission name="trans_joint_a2">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="joint_a2">
        <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
      </joint>
      <actuator name="motor_joint_a2">
        <mechanicalReduction>1</mechanicalReduction>
        <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
      </actuator>
   </transmission>

  <!-- joint 3 (A3) -->
  <joint name="joint_a3" type="revolute">
    <origin rpy="0 0 0" xyz="0.68 0 0"/>
    <parent link="link_2"/>
    <child link="link_3"/>
    <axis xyz="0 1 0"/>
    <limit effort="0" lower="-2.26892802759" upper="2.68780704807" velocity="2.72271363311"/>
  </joint>

   <transmission name="trans_joint_a3">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="joint_a3">
        <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
      </joint>
      <actuator name="motor_joint_a3">
        <mechanicalReduction>1</mechanicalReduction>
        <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
      </actuator>
   </transmission>

  <!-- joint 4 (A4) -->
  <joint name="joint_a4" type="revolute">
    <origin rpy="0 0 0" xyz="0.67 0 -0.035"/>
    <parent link="link_3"/>
    <child link="link_4"/>
    <axis xyz="-1 0 0"/>
    <limit effort="0" lower="-6.10865238198" upper="6.10865238198" velocity="5.75958653158"/>
  </joint>

   <transmission name="trans_joint_a4">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="joint_a4">
        <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
      </joint>
      <actuator name="motor_joint_a4">
        <mechanicalReduction>1</mechanicalReduction>
        <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
      </actuator>
   </transmission>

  <!-- joint 5 (A5) -->
  <joint name="joint_a5" type="revolute">
    <origin rpy="0 0 0" xyz="0 0 0"/>
    <parent link="link_4"/>
    <child link="link_5"/>
    <axis xyz="0 1 0"/>
    <limit effort="0" lower="-2.26892802759" upper="2.26892802759" velocity="5.75958653158"/>
  </joint>

   <transmission name="trans_joint_a5">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="joint_a5">
        <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
      </joint>
      <actuator name="motor_joint_a5">
        <mechanicalReduction>1</mechanicalReduction>
        <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
      </actuator>
   </transmission>

  <!-- joint 6 (A6) -->
  <joint name="joint_a6" type="revolute">
    <origin rpy="0 0 0" xyz="0 0 0"/>
    <parent link="link_5"/>
    <child link="link_6"/>
    <axis xyz="-1 0 0"/>
    <limit effort="0" lower="-6.10865238198" upper="6.10865238198" velocity="10.7337748998"/>
  </joint>

   <transmission name="trans_joint_a6">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="joint_a6">
        <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
      </joint>
      <actuator name="motor_joint_a6">
        <mechanicalReduction>1</mechanicalReduction>
        <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
      </actuator>
   </transmission>

  <!-- tool frame - fixed frame
  <joint name="joint_a6-tool0" type="fixed">
    <parent link="link_6"/>
    <child link="tool0"/>
    <origin rpy="0 1.57079632679 0" xyz="0.158 0 0"/>
  </joint>

   <transmission name="trans_joint_a6-tool0">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="joint_a6-tool0">
        <hardwareInterface>EffortJointInterface</hardwareInterface>
      </joint>
      <actuator name="motor_joint_a6-tool0">
        <mechanicalReduction>1</mechanicalReduction>
        <hardwareInterface>EffortJointInterface</hardwareInterface>
      </actuator>
   </transmission> -->

  <!-- END JOINTS -->
  <!-- ROS base_link to KUKA $ROBROOT coordinate system transform -->
  <link name="base"/>
  <joint name="base_link-base" type="fixed">
    <origin rpy="0 0 0" xyz="0 0 0"/>
    <parent link="base_link"/>
    <child link="base"/>
  </joint>

  <!-- Gazebo world joint -->
  <!-- Used for fixing robot to Gazebo 'base_link' -->
  <link name="world"/>

  <joint name="fixed" type="fixed">
    <parent link="world"/>
    <child link="base_link"/>
  </joint>

<gazebo>
  <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
    <robotNamespace>/kr16_2_gazebo</robotNamespace>
  </plugin>
</gazebo>

</robot>
</code>```

This is controller yaml:

```<code># Publish all joint states -----------------------------------
joint_state_controller:
  type: joint_state_controller/JointStateController
  publish_rate: 50

# Position Controllers ---------------------------------------
joint1_position_controller:
  type: effort_controllers/JointPositionController
  #joint: base_link__link_01
  joint: joint_a1
  pid: {p: 100, i: 100, d: 500.0}
joint2_position_controller:
  type: effort_controllers/JointPositionController
  #joint: link_01__link_02
  joint: joint_a2
  pid: {p: 100.0, i: 100, d: 2000.0}
joint3_position_controller:
  type: effort_controllers/JointPositionController
  #joint: link_02__link_03
  joint: joint_a3
  pid: {p: 100.0, i: 50, d: 1000.0}
joint4_position_controller:
  type: effort_controllers/JointPositionController
  #joint: link_03__link_04
  joint: joint_a4
  pid: {p: 100.0, i: 50, d: 200.0}
joint5_position_controller:
  type: effort_controllers/JointPositionController
  #joint: link_04__link_05
  joint: joint_a5
  pid: {p: 100.0, i: 50, d: 70.0}
joint6_position_controller:
  type: effort_controllers/JointPositionController
  #joint: link_05__link_06
  joint: joint_a6
  pid: {p: 100.0, i: 50, d: 70.0}
tool0_position_controller:
  type: effort_controllers/JointPositionController
  joint: link_06__tool0
  #joint: joint1
  pid: {p: 100.0, i: 50, d: 70.0}
</code>```

and this is my launch file:

```<code><?xml version="1.0"?>
<launch>

  <arg name="paused" default="false"/>
  <arg name="gazebo_gui" default="true"/>
  <arg name="urdf_path" default="$(find kuka_kr16_support)/urdf/kr16_2_gazebo.urdf"/>

  <!-- startup simulated world -->
  <include file="<span class="math-container">$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" default="worlds/empty.world"/>
    <arg name="paused" value="$</span>(arg paused)"/>
    <arg name="gui" value="$(arg gazebo_gui)"/>
  </include>

  <!-- send robot urdf to param server -->
  <param name="robot_description" textfile="$(arg urdf_path)" />

  <!-- Load controllers -->
  <rosparam ns="/kr16_2_gazebo" command="load" file="$(find kuka_kr16_moveit_gazebo)/config/joints.yaml" />

  <!-- push robot_description to factory and spawn robot in gazebo at the origin, change x,y,z arguments to spawn in a different position -->
  <node name="spawn_gazebo_model" pkg="gazebo_ros" type="spawn_model" args="-urdf -param robot_description -model robot -x 0 -y 0 -z 0"
    respawn="false" output="screen" />

  <!-- Controllers -->
  <node name="controller_spawner" pkg="controller_manager" type="spawner"
    respawn="false" output="screen" ns="/kr16_2_gazebo"
    args="--namespace=/kr16_2_gazebo
    joint_state_controller
    joint1_position_controller
    joint2_position_controller
    joint3_position_controller
    joint4_position_controller
    joint5_position_controller
    joint6_position_controller
    --timeout 60">
  </node>

</launch>
</code>```

And when I launch it in terminal this is output:

WARNING: Package name "KUKA_KR16_moveit_Luka1" does not follow the
  naming conventions. It should start with a lower case letter and only
  contain lower case letters, digits, underscores, and dashes. ...
  logging to
  /home/gazebo/.ros/log/133adcf4-5e8d-11e9-8069-000c2911adc8/roslaunch-ubuntu-3085.log
  Checking log directory for disk usage. This may take awhile. Press
  Ctrl-C to interrupt Done checking log file disk usage. Usage is <1GB.

WARNING: Package name "KUKA_KR16_moveit_Luka1" does not follow the
  naming conventions. It should start with a lower case letter and only
  contain lower case letters, digits, underscores, and dashes. started
  roslaunch server http://ubuntu:35047/

SUMMARY

PARAMETERS  * /gazebo/enable_ros_network: True  *
  /kr16_2_gazebo/joint1_position_controller/joint: joint_a1  *
  /kr16_2_gazebo/joint1_position_controller/pid/d: 500.0  *
  /kr16_2_gazebo/joint1_position_controller/pid/i: 100  *
  /kr16_2_gazebo/joint1_position_controller/pid/p: 100  *
  /kr16_2_gazebo/joint1_position_controller/type: effort_controller...
  * /kr16_2_gazebo/joint2_position_controller/joint: joint_a2  * /kr16_2_gazebo/joint2_position_controller/pid/d: 2000.0  *
  /kr16_2_gazebo/joint2_position_controller/pid/i: 100  *
  /kr16_2_gazebo/joint2_position_controller/pid/p: 100.0  *
  /kr16_2_gazebo/joint2_position_controller/type: effort_controller...
  * /kr16_2_gazebo/joint3_position_controller/joint: joint_a3  * /kr16_2_gazebo/joint3_position_controller/pid/d: 1000.0  *
  /kr16_2_gazebo/joint3_position_controller/pid/i: 50  *
  /kr16_2_gazebo/joint3_position_controller/pid/p: 100.0  *
  /kr16_2_gazebo/joint3_position_controller/type: effort_controller...
  * /kr16_2_gazebo/joint4_position_controller/joint: joint_a4  * /kr16_2_gazebo/joint4_position_controller/pid/d: 200.0  *
  /kr16_2_gazebo/joint4_position_controller/pid/i: 50  *
  /kr16_2_gazebo/joint4_position_controller/pid/p: 100.0  *
  /kr16_2_gazebo/joint4_position_controller/type: effort_controller...
  * /kr16_2_gazebo/joint5_position_controller/joint: joint_a5  * /kr16_2_gazebo/joint5_position_controller/pid/d: 70.0  *
  /kr16_2_gazebo/joint5_position_controller/pid/i: 50  *
  /kr16_2_gazebo/joint5_position_controller/pid/p: 100.0  *
  /kr16_2_gazebo/joint5_position_controller/type: effort_controller...
  * /kr16_2_gazebo/joint6_position_controller/joint: joint_a6  * /kr16_2_gazebo/joint6_position_controller/pid/d: 70.0  *
  /kr16_2_gazebo/joint6_position_controller/pid/i: 50  *
  /kr16_2_gazebo/joint6_position_controller/pid/p: 100.0  *
  /kr16_2_gazebo/joint6_position_controller/type: effort_controller...
  * /kr16_2_gazebo/joint_state_controller/publish_rate: 50  * /kr16_2_gazebo/joint_state_controller/type: joint_state_contr...  *
  /kr16_2_gazebo/tool0_position_controller/joint: link_06__tool0  *
  /kr16_2_gazebo/tool0_position_controller/pid/d: 70.0  *
  /kr16_2_gazebo/tool0_position_controller/pid/i: 50  *
  /kr16_2_gazebo/tool0_position_controller/pid/p: 100.0  *
  /kr16_2_gazebo/tool0_position_controller/type: effort_controller...  *
  /robot_description:

NODES   /kr16_2_gazebo/
      controller_spawner (controller_manager/spawner)   /
      gazebo (gazebo_ros/gzserver)
      gazebo_gui (gazebo_ros/gzclient)
      spawn_gazebo_model (gazebo_ros/spawn_model)

auto-starting new master process[master]: started with pid [3096]
  ROS_MASTER_URI=http://localhost:11311

setting /run_id to 133adcf4-5e8d-11e9-8069-000c2911adc8 WARNING:
  Package name "KUKA_KR16_moveit_Luka1" does not follow the naming
  conventions. It should start with a lower case letter and only contain
  lower case letters, digits, underscores, and dashes.
  process[rosout-1]: started with pid [3107] started core service
  [/rosout] process[gazebo-2]: started with pid [3110]
  process[gazebo_gui-3]: started with pid [3119]
  process[spawn_gazebo_model-4]: started with pid [3124]
  process[kr16_2_gazebo/controller_spawner-5]: started with pid [3125]
  WARNING: Package name "KUKA_KR16_moveit_Luka1" does not follow the
  naming conventions. It should start with a lower case letter and only
  contain lower case letters, digits, underscores, and dashes. WARNING:
  Package name "KUKA_KR16_moveit_Luka1" does not follow the naming
  conventions. It should start with a lower case letter and only contain
  lower case letters, digits, underscores, and dashes. WARNING: Package
  name "KUKA_KR16_moveit_Luka1" does not follow the naming conventions.
  It should start with a lower case letter and only contain lower case
  letters, digits, underscores, and dashes. WARNING: Package name
  "KUKA_KR16_moveit_Luka1" does not follow the naming conventions. It
  should start with a lower case letter and only contain lower case
  letters, digits, underscores, and dashes. [INFO] [1555229566.121403,
  0.000000]: Controller Spawner: Waiting for service /kr16_2_gazebo/controller_manager/load_controller [ INFO]
  [1555229567.920658309]: Finished loading Gazebo ROS API Plugin. [
  INFO] [1555229567.922362082]: waitForService: Service
  [/gazebo_gui/set_physics_properties] has not been advertised,
  waiting... [ INFO] [1555229567.927517546]: Finished loading Gazebo ROS
  API Plugin. [ INFO] [1555229567.928969037]: waitForService: Service
  [/gazebo/set_physics_properties] has not been advertised, waiting...
  [INFO] [1555229569.090114, 0.000000]: Loading model XML from ros
  parameter robot_description [INFO] [1555229569.100970, 0.000000]:
  Waiting for service /gazebo/spawn_urdf_model [INFO]
  [1555229569.708130, 0.000000]: Calling service
  /gazebo/spawn_urdf_model [ INFO] [1555229569.740163120, 0.023000000]:
  waitForService: Service [/gazebo/set_physics_properties] is now
  available. [INFO] [1555229570.489737, 0.159000]: Spawn status:
  SpawnModel: Successfully spawned entity [ INFO] [1555229570.502446729,
  0.159000000]: Physics dynamic reconfigure ready. [ INFO] [1555229570.679725950, 0.159000000]: Loading gazebo_ros_control plugin
  [ INFO] [1555229570.680028318, 0.159000000]: Starting
  gazebo_ros_control plugin in namespace: /kr16_2_gazebo [ INFO]
  [1555229570.680620454, 0.159000000]: gazebo_ros_control plugin is
  waiting for model URDF in parameter [/robot_description] on the ROS
  param server. [spawn_gazebo_model-4] process has finished cleanly log
  file:
  /home/gazebo/.ros/log/133adcf4-5e8d-11e9-8069-000c2911adc8/spawn_gazebo_model-4*.log
  [ INFO] [1555229570.868346785, 0.159000000]: Loaded
  gazebo_ros_control. [INFO] [1555229570.971088, 0.255000]: Controller
  Spawner: Waiting for service
  /kr16_2_gazebo/controller_manager/switch_controller [INFO]
  [1555229570.980829, 0.257000]: Controller Spawner: Waiting for service
  /kr16_2_gazebo/controller_manager/unload_controller [INFO]
  [1555229570.987506, 0.263000]: Loading controller:
  joint_state_controller [INFO] [1555229571.017423, 0.294000]: Loading
  controller: joint1_position_controller [INFO] [1555229571.106571,
  0.377000]: Loading controller: joint2_position_controller [INFO] [1555229571.162822, 0.424000]: Loading controller:
  joint3_position_controller [INFO] [1555229571.229486, 0.475000]:
  Loading controller: joint4_position_controller [INFO]
  [1555229571.288503, 0.515000]: Loading controller:
  joint5_position_controller [INFO] [1555229571.361675, 0.563000]:
  Loading controller: joint6_position_controller [INFO]
  [1555229571.418728, 0.607000]: Controller Spawner: Loaded controllers:
  joint_state_controller, joint1_position_controller,
  joint2_position_controller, joint3_position_controller,
  joint4_position_controller, joint5_position_controller,
  joint6_position_controller [INFO] [1555229571.426332, 0.612000]:
  Started controllers: joint_state_controller,
  joint1_position_controller, joint2_position_controller,
  joint3_position_controller, joint4_position_controller,
  joint5_position_controller, joint6_position_controller

From output I can see that all controllers are loaded,to confirm it here is output of rostopic:

```<code>/clock
/gazebo/link_states
/gazebo/model_states
/gazebo/parameter_descriptions
/gazebo/parameter_updates
/gazebo/set_link_state
/gazebo/set_model_state
/kr16_2_gazebo/joint1_position_controller/command
/kr16_2_gazebo/joint1_position_controller/pid/parameter_descriptions
/kr16_2_gazebo/joint1_position_controller/pid/parameter_updates
/kr16_2_gazebo/joint1_position_controller/state
/kr16_2_gazebo/joint2_position_controller/command
/kr16_2_gazebo/joint2_position_controller/pid/parameter_descriptions
/kr16_2_gazebo/joint2_position_controller/pid/parameter_updates
/kr16_2_gazebo/joint2_position_controller/state
/kr16_2_gazebo/joint3_position_controller/command
/kr16_2_gazebo/joint3_position_controller/pid/parameter_descriptions
/kr16_2_gazebo/joint3_position_controller/pid/parameter_updates
/kr16_2_gazebo/joint3_position_controller/state
/kr16_2_gazebo/joint4_position_controller/command
/kr16_2_gazebo/joint4_position_controller/pid/parameter_descriptions
/kr16_2_gazebo/joint4_position_controller/pid/parameter_updates
/kr16_2_gazebo/joint4_position_controller/state
/kr16_2_gazebo/joint5_position_controller/command
/kr16_2_gazebo/joint5_position_controller/pid/parameter_descriptions
/kr16_2_gazebo/joint5_position_controller/pid/parameter_updates
/kr16_2_gazebo/joint5_position_controller/state
/kr16_2_gazebo/joint6_position_controller/command
/kr16_2_gazebo/joint6_position_controller/pid/parameter_descriptions
/kr16_2_gazebo/joint6_position_controller/pid/parameter_updates
/kr16_2_gazebo/joint6_position_controller/state
/kr16_2_gazebo/joint_states
/rosout
/rosout_agg
</code>```

and robot is just like hanging on base link, because base link is only one which has type=fixed and all other have type=revolute.

here is picture of hanging robot:

When I lift and release robot in gazebo using mouse, robot just fall down and axis are just shaking like there is no motor or any force which keeps them fixed.

答:
look at this tutorial. You have to add some gazebo specific tag in URDF file.

http://gazebosim.org/tutorials/?tut=ros_urdf


问:
Is interacting with registers the only way software and hardware interact?
I'm aware that memory mapped addresses that point to registers are sometimes used to control hardware devices. Is that the only way they're controlled? I started asking about how software talks to hardware and most people told me about using registers and memory addresses to talk to devices. Is that the only way software and hardware interact? Thanks! </p>

答:
most people told me about using registers and memory addresses to talk to devices

Shortly, that is the correct answer - if you are interested how software will (ultimately) talk to hardware. How hardware can have an impact on software, things get a lot more complicated.

If you want to understand deeply how things happen, you should study how micro-controllers are implemented. Studying the famous 8051 is a very good start, and there are countless books and articles about it. You will have the chance to understand timers, interrupts, ports, buses...


问:
How can robots communicate, locate and identify each other?
I'm planning to build some simple robotic boats. They will be travelling some distance alone but should also be able to group and physically connect together to form one boat. When they are near each other I want them to be able to "know" that they are near each other, identify each other, communicate and locate each other so that they know how to physically connect to each other.

As an example, let's say that we've got 3 boats: X, Y and Z. Boat X should be able to say for example the following:

```<code>Boat Y is located at 90 degrees and boat Z is located at 210 degrees from me.
</code>```

and similarly, boat Y should be able to say:

```<code>Boat X is at 270 degrees and boat Z is located at 230 degrees from me.
</code>```

My idea was to use bluetooth to make boats identify each other, wifi to communicate and send each other their GPS location to locate each other. I thought it could work like this:

Each boat makes itself permanently discoverable with bluetooth, using a number as bluetooth name (e.g.: boat_1, boat_48, boat_285).

When a boat "sees" at least one other boat with a lower number and no boat with a higher number (i.e.: the boat realizes it's the highest number of the group) it sets up a wifi hotspot to which the other boats can connect. This boat becomes the "master" boat hosting the connections to all the boats that are near.

The master boat then hosts an API endpoint on the internal network to which all boats can post their information and from which they can retrieve the information of the other boats.

All boats continuously post their gps coordinates and continuously retrieve the gps coordinates of the other boats.

Using the GPS coordinates the master boat decides what the physical order will be in which the boats should physically connect with each other. So boat X connects to boat Y and boat Z connects to boat X.

Every boat moves behind the boat to which he is assigned by the master boat and connects to the boat in front of him.

Apart from some obvious security and failover issues, to me this sounds like something that could work. I have no experience with this though, so I wonder whether anybody knows any better ideas to let boat-robots identify, communicate and locate each other when they're near each other? I read about Zigbee Mesh Networks but since I'm familiar with wifi I thought of starting with that.

All tips are welcome!

答:
The idea is very interesting, and I wish you good luck implementing it.

However, it is not (very) simple to implement. Some reasons:

GPS is not at all accurate;

smartphones usually have a positioning error of +- 10 meters (30 feet). Unless your boats are actually some transatlantic beasts, this error is unacceptable;

GPS receivers with (very) high accuracy cost in the thousands of dollars range - each;

it is important to know the alignment of the longitudinal axis of the boat (e.g. its angle to the N-S line); consider that a boat can move sideways (unlike a car), so only the GPS signal is not good enough;

instead of BT you might be able to use NFC (probably losing some range);

to be able to maximize the chances of having a physical connection (between boats), any boat should be able to connect to any boat - an additional level of complexity, but manageable;

option to consider during the design phase: when 2 boats are already connected, they will function like 2 boats, or like one?

are the dimensions of the boats relevant? should they be exactly of the same size?

So the biggest problem in your case might be the accuracy of (x,y) coordinates, given by the GPS. That accuracy is essential in making a connection.

For measuring relative positions, you may use some IR sensor, which can give you some good accuracies. To add tot he coolness factor, the sensor may rotate like a radar, so the robot can map the surroundings better.


问:
Why is the Kalman filter a filter and not a control system?
Why is the Kalman filter a filter and not a control system? The Kalman filter is a recursive filter which can be used to estimate the internal state of a linear dynamic system with noise in the signal(s). Isn't that the same as a traditional feedforward/feedback control structure (figure below)?

The feedforward controller modification uses anticipated results in the form of a mathematical model, predicting. Then the feedback controller would update the state and give feedback, updating.

答:
A Kalman Filter uses a given dynamic model and measurementz to produce a state estimate (as well as a state uncertainty). In that regard, it acts as a filter. </p>

<p>Typically you would take the state estimate and design control laws around that. </p>

Body:
A Kalman Filter uses a given dynamic model and measurementz to produce a state estimate (as well as a state uncertainty). In that regard, it acts as a filter.

Typically you would take the state estimate and design control laws around that.


答:
No. You are talking about memory-mapped I/O. It means that the CPU see the hardware as if it would be some like a memory module.

All the robots have these three components:

a controlling mechanism. It means a collection of chips.

sensors (to know the world around them).

and motors (or, more generally, end-effectors. For example, a robot capable to heat its arms has a non-mechanical end-effector).

(1) gets the data from the sensors (2), and using the collected data, says to (3) what to do.

All the chips have a set of pins. They can send voltage to them, or they can read the voltage on them send by others. The sensors and the end-effectors use electronical (or physical, chemical, anything) means to convert between the voltage on the pins and the external world. This might be quite complex, for example until the $\mu A$, 5V current becomes a regulated 3-phase, 50Hz, 380V current on a large industry robot, the steps are not trivial.

But this all is not important. The only important thing is that the CPU has to communicate somehow with the other chips/devices of the robot, and the only question is, how do we call the pins and what type of pins are on which the communication is going on.

A simple way, with some disadvantages, if the CPU see the hardware, as if it would be a memory block. If you write a data to a specific memory address, you send data to a device.

Another possibility is to have dedicated pins for I/O, it is the port-mapped I/O.

Mainly large mainframes had also specific I/O coprocessors, i.e. mediating chips only for I/O tasks.

Title: Is interacting with registers the only way software and hardware interact?

Body: I'm aware that memory mapped addresses that point to registers are sometimes used to control hardware devices. Is that the only way they're controlled? I started asking about how software talks to hardware and most people told me about using registers and memory addresses to talk to devices. Is that the only way software and hardware interact? Thanks! </p>


问:
Why does degree of freedom only consider continuous values?
In the book Modern Robotics Chapter 2 Configuration space, we are told that degrees of freedom only considers coordinates with real valued continuous range.

Why is this the case?

答:
A degree of freedom doesn't necessarily need to be continuous. We can easily define a system that has a discrete degree of freedom. For example, image a mobile robot in $\mathbb{R}^2$ with a heat sensor. If the temperature is greater than 37 degrees celsius, we consider it to be hot. From 15 degrees to 37, we consider mild, and below 15, cold. In this way we have defined our system's state to be ($\mathbb{R}$, $\mathbb{R}$, {hot, mild, cold}). The third element of our state is a discrete degree of freedom.

Now an important note is that the system needs to be able to navigate in each degree of freedom. We can easily fit this into our example, by considering that the temperature need not be the same for all $\mathbb{R}$.

The book that you reference is not one that I have read, but I am curious to know if the author was rather stating that, for their purposes, they were only considering continuous degrees of freedom.