问:
Get rotation of IMU data snapshot
I received snippets of data of an IMU with 9 DoF in motion. For these I wanted to get their rotation by angles relative to the earth frame. My goal is to receive the absolute vertical acceleration, therefore I'd like to know about the sensors rotation.

Thus I was reading about pitch, roll and yaw and also about AHRS Filters like Madgwick- and Complementary-Filter.
Now I have a question about the feasibility and understanding:

Since I only have snippets, I don’t know the initial sensor rotation. Is my understanding correct that the filters are only calculating the rotation relative to the last known rotation, so I‘d always have an offset of the initial orientation regarding to the earth frame? Is it even possible to calculate the rotation having only a random snapshot and if so, what would be the best approach?

Thank you very much.

答:
The best approach is to use the Madgwick filter. The trick is that gravity always points down, and gravity is the only sustainable acceleration. Magnetic North points North (assuming you're not near ferrous/magnetic stuff) and so you can determine the orientation through magnetometer and accelerometer readings in the very long term. Short-term the gyroscopes will give you good motion estimates, but they have biases and so you get angular drift in the long term.

You could write your own complementary filter to join the two, or use a Kalman filter, but the Madgwick filter is even better for IMU sensor fusion and it has implementations that are freely available.

You'll have some time at the start of the data set where the filter is converging, but there's nothing you can do about that. After convergence you should have a remarkably robust orientation estimate.

Title: Get rotation of IMU data snapshot


问:
3D Rigid Body Pose Optimization in flat euclidean space
I am confused about what is the best way to optimize the 3D pose of an object and the best way to parametrize the translation and rotation for optimization in flat euclidean space.

Assume I have a point $\pmb{x^o}$ given in the coordinate system of the Object which pose I want to optimize. I measure the distance between the object and the point through some function $f:\mathbb{R}^3 \to \mathbb{R}$. Goal of the optimization is to minimize this function by optimizing the object pose (translation + orientation).
I can obtain the local spatial gradient of each point in the object coordinate frame $\nabla f \bigg|_{\pmb{x}^o}$.

The pose of the Object is given by the translation vector $\pmb{t}_o^e$ and the rotation matrix $R_o^e$, such that points can be transformed from the object coordinate system into the ego coordinate system through $\pmb{x}^e = R_o^e \pmb{x}^o + \pmb{t}_o^e$ and the the other way around through $\pmb{x}^o = {R_o^e}^\top( \pmb{x}^e - \pmb{t}_o^e)$.

Now for the calculation of the analytic Jacobian w.r.t to the translation $\pmb{t}_o^e$ it is clear to me how it can be obtained by applying the chain rule:
$$
\frac{\partial f(\pmb{x}^o)}{\partial \pmb{t}_o^e} = \nabla f \bigg|_{\pmb{x}^o} \cdot \frac{\partial \pmb{x}^o}{\partial \pmb{t}_o^e} = \nabla f \bigg|_{\pmb{x}^o} \cdot \frac{\partial ({R_o^e}^\top( \pmb{x}^e - \pmb{t}_o^e))}{\partial \pmb{t}_o^e} = \nabla f \bigg|_{\pmb{x}^o} \cdot (- {R_o^e}^\top)
$$
So the result simple means the gradient has to be multiplied with the negative inverse/transposed rotation matrix.

However I am unsure how to do the same for the object orientation and which parametrization to use.
I read that euler angle suffer from their bounds on pitch and roll angles as well as gimbal lock.
I tried using quaternions which are not a minimal parametrization (7 parameters for 6 Degrees-of-Freedom).
This will lead to deriving the rotation matrix after each quaternion parameter, which I have done, but results were not really promising.

I know that the most general and robust solution is using Lie theory and se(3) lie algebra (also known as twist coordinates). However I don't think I can use this here as I don't want to optimize on the manifold but use a Gauss-Newton or BGFS optimizer in flat euclidean space for this problem (the ones offered by scipy.optimize).

Edit:
I noticed this is very broad and its unclear what kind of answer I am looking for. So here my post broken down into some specific questions

What is the recommended parametrization of such a 3D rigid body optimization problem? (e.g. translation+Euler angles, translation+Quaternion, twist coordinates) Follow up is: How is the coordinate system transformation derived after these parameters?

Can twist coordinates be used when I am trying to solve this with the optimization methods provided by pythons scipy package? Do I need to have parameters in the flat euclidean space to apply 'standard' (meaning not 'on manifold') Gauss-Netwon (Non-linear least squares) optimization method with analytic jacobian?

Are there any example where a 3D rigid body optimization is solved using scipy?

I welcome any kind of answer, comment or input.

答: Barfoot (Section 7.1.9, specifically) has a really nice presentation for computing the optimal perturbation that preserves the SE(3) constraint.</p>

ContentLicense: CC BY-SA 4.0


问:
HC-05 not responding to AT Commands from Raspberry Pi Pico
I'm trying to write AT commands to HC-05 module using Raspberry Pi Pico and MicroPython, nothing complicated. But for some reason my module doesn't respond. It works well in data mode and I'm able to send/receive messages from my phone via BT connection.

I've tried doing the same thing but using Arduino and my HC-05 was working. The module is blinking with interval of 2Hz so it's clearly in command mode.

Changing Baud Rate doesn't change anything.

Connecting TX to TX and RX to RX causes the first message to be b'\x00', otherwise nothing is returned.

My Code:

from machine import Pin,UART #importing PIN and PWM
import utime #importing time

#Defining UART channel and Baud Rate
uart = UART(0, 38400)

while True:
    command = input("COMM>")

    uart.write(command)
    utime.sleep(1)  # to make sure that HC-05 has time to respond
    print("checking", uart.any())

    if uart.any(): #Checking if data available
        data=uart.read() #Getting data
        data=str(data) #Converting bytes to str type
        print(data)
```

Ultimately I want to use AT+INQ to retrieve data about RSSI of nearby devices.

答:
I have no idea why I couldn't write AT commands in MicroPython, but when I've switched to Rust everything works as expected. rp-hal is a great tool for embeded Rust on RP2040 microcontrolers.

I suspect that it'd work on C/C++ as well.

I also thank Ezward for trying to help.


问:
Interference between 900 MHz video transmitter and 2.4 GHz control radio
I'm starting to attempt to fly FPV on my quadrotor. I am using a FrSky D8R-II 2.4 GHz frequency hopping diversity receiver (two antennas) for control and recently added a no-name 910 MHz 1.5 watt analog video transmitter for FPV flying:

When the video transmitter is powered up, my control range drops from about 1.5km to under 50m. I'm surprised that the 910 MHz video channel affects my 2.4 GHz control channel this way.

Is this sort of interference expected? Is it because my transmitter is low quality? What changes are recommended — should I switch to a UHF control radio? Or a different frequency (eg 5.8 GHz?) for the video radio? Or just try moving it a few more inches (they are already about 5in apart)?

答: I can say positively that 900Mhz china video transmitters can affect 2.4Ghz frequency range. I experienced this first hand and confirmed interference on my spectrum analyzer, it can cause harmonics on the 2.4Ghz but when the tx and rx are close it appears to have an affect on the noise floor too, using those low pass filter don't seem to help close range either.</p>

ContentLicense: CC BY-SA 3.0


问:
How to choose the correct power switch ratings for robotics?
I am making a hexapod with MG996R servos and according to the specifications, each servo has a running current of 500 - 900 mA and a stall current of 2.5 A at 6 V. Since I am making a 3DOF hexapod, there will be 18 servos (3 servos for each leg). So, it will draw roughly 18 * 2.5 A = 45 A of current at max if somehow all servos stalled.

However, I am having trouble choosing the right power switch to switch off the robot since most switches are rated at around 2 - 20 A and 125 - 250 V. According to How do I determine whether a switch can handle the power/current in a circuit?, the ratings should be considered independently instead of considering it as a power rating (P=IV). That is why I am confused since I wasn't able to find any switches that has rating of more than 45 A that is suitable for robotics.

So I am hoping to see if anyone could give me some advice here. Thanks in advance!

答:
There is a characteristic called ampacity that is defined as

the maximum current, in amperes, that a conductor can carry continuously under the conditions of use without exceeding its temperature rating.

This all comes from the power equation you gave,

$$
P = IV \\
$$

and from Ohm's law:

$$
V = IR \\
$$

which lets you substitute the voltage in the power equation to get:

$$
P = I^2R \\
$$

This form is used to explain the "I-squared R losses" where input power is "consumed" by wiring. Usually it's used for power transmission lines, and this is also why high voltage power lines ARE high voltage - if you can crank voltage up really, really high then you get current to be really, really low for the same power, and then lower current means lower resistive losses in the transmission cables.

So in your case it doesn't really matter what the power rating is for the devices because electrical power doesn't generate heat, current generates heat (by the $I^2R$ losses described above).

I will concede that it's very frustrating to need higher-current ratings on low-voltage devices, because those aren't common use cases and so there aren't many (low cost) options available.

When I search on Digikey (no affiliation) and sort by price for disconnect switches rated >45 A, the least expensive option looks to be about \$25.

You could of course just use something as a switch and hope it doesn't melt, but if that's the approach you're going to take then the very best option would be to use a fuse that's rated slightly lower than your switch rating.

Let's assume you think all servos being stalled is so unlikely that you're willing to replace the fuse if that happens. How many stalled servos would this is a reasonable expectation? If you consider three stalled servos and three at max current, then you wind up with $(9*2.5 + 9*0.9) = 30.6A$ as your current rating. This still isn't getting you any cheaper results on Digikey.

Let's try to think more about your use case. If it's a hexapod (six legs) then maybe only three legs are in motion at a time while the other three legs are supporting the body.

So what if we assume two legs are stalled (six servos at 2.5A), one leg is at max nominal current (three servos at 900 mA) and the other three legs are at the minimum nominal current (nine servos at 500 mA). This now gets you down to 22.2 amps.

Still no good-looking options, so finally one stalled leg, two at max nominal, three at idle. This is $(3*2.5 + 6*0.9 + 9*0.5) = 17.4 A$. Now that the maximum current is less than 21 amps you can look at rocker switches instead of the power disconnect switches, and in that class of switch the cheapest option stocked by Digikey is $3.92.

That switch is rated at 20 A. As discussed above, the "one stalled leg" scenario would be pulling ~17.4 A. The switch is rated to 20 A, so you should be looking at a fuse that's rated higher than your use-case (17.4 A) but lower than your switch rating (20 A). If you can find a fuse rated for 18 or 19 amps then you should be able to operate in the one stalled leg scenario but anything more than that would blow the fuse, ensuring the switch contacts don't melt.

Looking again at Digikey you could get a fuse holder rated to 20 amps for \$1.51 and an 18 amp fast-blow fuse for \$1.88. Be sure to buy spares just in case!

If you find the fuse is blowing frequently then the "one stalled leg" use case is too restrictive and you need to re-evaluate the components you're using.

Remember that current ratings apply to everything in the circuit, notably also the wiring and electrical connectors you're using (spade connectors, etc.) Your fusing should be setup to protect the item with the lowest current rating, and the fuse should be lower than the lowest current rating.


问:
Localization by comparing current lidar scan with previous lidar scan
I have managed to use an ICP algorithm to produce a relative pose difference between a new lidar range scan and the previous lidar scan. When I tested it on individual scan pairs, the results look good and exactly as expected.

I have noisy odometry data [x, y, heading angle] in addition to the lidar range data (2D).

How do I actually use my comparison result to localise the robot? Is this possible to do without a typical SLAM technique like a particle filter ? I tried correcting the current odometry reading based on the comparison result, and setting this as my new position estimate of the robot, but the results do not look good. I know I cannot just use the raw odometry data on its own, but I thought correcting the current odometry readings with my relative pose estimate would be somewhat accurate and make the need for a SLAM filter unnecessary.

答:
So you want to perform sensor fusion. If you are using ROS, you have a bunch of options, two of which are fuse (which uses factor graphs) and robot_localization (which uses an EKF or UKF).

But you should note that both of the data sources you are fusing (wheel odometry and scan-to-scan matching) will have errors associated with each measurement. Over time, those errors will accumulate. So you're not really doing localization per se, but more incremental pose estimation. It may take some time for the pose to drift from reality, but it will.

If you want to keep the robot's error constrained, then you need to localize it by, e.g., matching the laser scans to a static map, like the ROS amcl package does. So you would build the map using a SLAM package, save that map, and then configure amcl to localize from it.


问:
Pipeline for dense reconstruction using pose estimation from orb-slam and stereo camera
I am trying to perform dense reconstruction using a sequence of images from a calibrated stereo camera. I have been using orb-slam3 to give me the camera's pose estimation. I am also generating the disparity map and RGB point cloud given a stereo image pair using available ROS packages. Suppose my sequence of stereo images is circling around a computer desk. Now I thought since I have the pose of the camera, point clouds representing the same region of the scene from different view points of the camera should overlap; however, it does not seem to be the case. The point cloud of the same object is shifted around depending on the location of the camera. I was hoping to get something similar to this:

So I was wondering if there is a component I'm still missing? Is having pose estimation and point clouds from a camera enough to generate a dense 3d map or do I still need to apply an algorithm like ICP?

答:
Small errors and outliers in camera poses will make the reconstruction unprecise, hence you need some refinement.

You have multiple options:

Fuse the point clouds with an ICP-like algorithm.

Use a photogrammetry technique.

Use neural synthesis techniques such as this or this.


问:
How to install Gazebo to use along with ROS2 Humble Hawksbill on Ubuntu 22.04?
I have used ROS noetic before by installing the full desktop version which comes along with gazebo simulator and its plug-ins (gazebo_ros_pkgs) ready to use with ROS directly. Due to some requirements, I have to install ROS2 on Ubuntu 22.04 on a cloud/ virtual machine. I decided to move with ROS2 Humble Hawksbill because as per https://docs.ros.org/en/rolling/Releases.html, this release will be supported for a longer period of time compared to Foxy which will have its EOL next year.

I followed all the installation instructions present on their official website and did the full install using sudo apt install ros-humble-desktop. Publisher/ subscriber, rviz, rqt etc. are working fine but I observed that gazebo did not come along with it.

I am having a tough time figuring out a way to install gazebo and make it work with ROS2 Humble Hawksbill on Ubuntu 22.04.

I tried going through https://classic.gazebosim.org/tutorials?tut=ros2_installing&cat=connect_ros, https://gazebosim.org/docs/fortress/ros2_integration, and https://discourse.ros.org/t/ros-2-humble-hawksbill-released/25729 and observed that one website is saying something and another something else regarding ros2 and gazebo versions compatibility.

Any help in setting up gazebo (which version and how) in this scenario is highly appreciated.

Thanks in advance,

Dev

答:
There was a question about installing Gazebo on Ubuntu 22.04 with ROS2 Humble (after removing the copy installed with the Humble package install), on the Gazebo answers page, see How to install Gazebo for Ubuntu 22.04 with ROS2 Humble. Unfortunately, that content has now been removed (as of July 31 2022), for whatever reason.

However, there is a blog on Ubuntu.com, Install Gazebo for ROS 2 in under a minute, which might help.

With the option --channel, we are explicitly using the track (citadel) and the risk (beta). We will automatically get updates from this channel. If your Linux distribution of choice doesn’t currently support snap, get more details on the installing snapd documentation.

sudo snap install gazebo --channel=citadel/beta
```
<p>After installation, we can execute the freshly installed Gazebo with the command <code>gazebo.gz gazebo</code>.</p>
</blockquote>
<p>You can then test it with</p>
<blockquote>
<pre class="lang-none prettyprint-override"><code>gazebo.gz gazebo shapes.sdf
</code>```

We now see the ‘shapes’ demo
and are able to interact with it:

There are a lot more examples. However, none of this is Humble specific.

Nevertheless, that same page then states at the bottom:

We are planning to release a ROS2 Humble Gazebo Fortress snap soon, so stay tuned!

So, hopefully, there should be an update (and accompanying blog) available soon...

Body:
There was a question about installing Gazebo on Ubuntu 22.04 with ROS2 Humble (after removing the copy installed with the Humble package install), on the Gazebo answers page, see How to install Gazebo for Ubuntu 22.04 with ROS2 Humble. Unfortunately, that content has now been removed (as of July 31 2022), for whatever reason.

However, there is a blog on Ubuntu.com, Install Gazebo for ROS 2 in under a minute, which might help.

With the option --channel, we are explicitly using the track (citadel) and the risk (beta). We will automatically get updates from this channel. If your Linux distribution of choice doesn’t currently support snap, get more details on the installing snapd documentation.

sudo snap install gazebo --channel=citadel/beta

After installation, we can execute the freshly installed Gazebo with the command gazebo.gz gazebo.

You can then test it with

gazebo.gz gazebo shapes.sdf

We now see the ‘shapes’ demo
and are able to interact with it:

There are a lot more examples. However, none of this is Humble specific.

Nevertheless, that same page then states at the bottom:

We are planning to release a ROS2 Humble Gazebo Fortress snap soon, so stay tuned!

So, hopefully, there should be an update (and accompanying blog) available soon...


问:
Motion/System Model for range finder
I have a 1D Time-of-Flight based range finder that returns distance in mm. I am trying to implement a Kalman filter to get outlier-free estimation. The sensor measures the distance to the ground below it while the sensor assembly is mounted on a mobile platform that moves orthogonal to the direction of measurement. The following diagram tries its best to clarify:

I am unable to come up with a motion model for the filter as the measurements are independent of the motion of the assembly. Is Kalman Filter still applicable here ?

答: How are you expecting the surface to appear? Sinusoidal, with random amplitudes? Flat, with random deviations? The technical example on Wikipedia has an example that implements a generic motion model; this would be what I'd start with if I had no knowledge of what the surface was supposed to be.</p>

Title: Motion/System Model for range finder


问:
Why aren't more bipedal (or even quadruped) robots made with joints/articulations similar with those found on atmospheric deep dive suits?
The sole reason I'm making this question is due to the fact that such joints/articulations would allow the electric motors to continuously move while the walking motion is performed, instead of the back and forward movement of our biological counterparts in which such robots were inspired.

I'm assuming that if you keep changing speed in a specific way, you could replicate the same back and forward movement of biomimetic legs without the need to force the electric engines. After all, spinning wheels are supposedly more efficient than legs.

(of course, the examples bellow are for human use in mind, unlike the robots that can be reduced to simple bearings)

The joints/articulations that I'm referring to are the leg ones on these examples:

答:
Why aren't they, you ask? Typically, it would be a worse design.

Atmospheric deep dive suits, and, for that matter, space suits, are designed to maintain constant internal volume. Otherwise the occupant would have to constantly work against external (dive) or internal (space) pressure simply in order to move.

The fancy joints seen in both kinds of suit are a design solution for the constant-volume constraint. In addition, the actuators are people, not motors, and accommodating humans adds a whole new dimension of constraint.

In contrast, robots with walking legs are designed for a thoroughly different set of constraints. Remove those of constant volume and human occupancy. Open up a vast new design space of size, power, speed, battery life, and so on. Include tradeoffs of cost and safety.

Although both applications involve legs, there is little reason to expect a design for one to carry over to the other.


问:
How to calculate uncertainty of encoder velocity
I am doing a project where I have to calculate the uncertainty (and 95 % confidence interval) for velocity measurements from an encoder.

The encoder uses pulse timing method to calculate angular speed by measuring the time interval for one state change. It has quadrature output and 1024 ppr, hence the speed is estimated every (360)/(4*1024) degrees, which is 0.088 degrees of rotation. I understand that there are better methods to estimate speed, but this one is already implemented, and I have to calculate the expected uncertainty bounds.

One source of uncertainty is code wheel graduation errors. I found the datasheet of the code wheel used as shown below :

The typical value of position error is shown as 7 arc min which is 0.1166 deg. Max value is 20 arc min which is 0.33 deg

The resolution of the encoder is 0.088 degrees which would mean that every state change (1 count) will correspond to 0.088 deg right ? But the error is bigger than this value ? What am I missing here ? The maximum error is over 3 times the resolution..I don't understand that. Could someone please explain..

答:
I think you're using the formula (360)/(4*1024) because of the term quad in quadrature encoder, but a quadrature encoder doesn't have anything to do with four, it's from the the use of the term to mean two signals that are offset by 90 degrees.

Your quadrature encoder will have TWO encoder rings (not four), and the resolution is 1024, not some multiple of it. What you'll wind up with are two channels, typically A and B, with each encoder wheel being 512 counts per revolution, and then the wheels are aligned in quadrature, meaning they're offset by 90 degrees.

If I use a to mean channel A is low, and A to mean it's high, and b and B similarly, then you'll get the following readings:

```<code>ab
Ab
AB
aB
ab
</code>```

They're not in phase, or it'd go ab then AB, and they're not 180 degrees out of phase, or it'd go aB then Ab. Only when they're 90 (or 270!) degrees out of phase do you get that sequencing. In the example above, A is leading B - on one step A toggles, then on the next step B transitions to the same state as A.

If the encoder is moving in reverse, then A will follow B, like:

```<code>ab
aB
AB
Ab
ab
</code>```

And so you can get both position and direction by monitoring the encoder counts. Here's a handy graphic from the Wikipedia entry on quadrature encoders:

And so finally, to answer your question, the actual encoder resolution isn't (360)/(4*1024), just 360/1024 = 0.3516 deg. The maximum angle error is very close to (but less than!) this resolution, but I typically would expect anything within +/- the least significant bit to be noise, so it's not a huge deal.

:EDIT:

The terminology in the encoder documentation is very confusing, notably the "bar and window" and "electrical degrees," so I looked for the "bar and window" term and found the following graphic from another encoder manual:

Apparently the "bar and window" refers to the dark and light bands on the encoder wheel. In OP's snippet from the manual:

```<code>1 Cycle = 360 electrical degrees
        = 1 bar and window pair
</code>```

I can only assume they're calling them "electrical degrees" to refer to the cyclical nature of an encoder output, which should be 0011 0011 0011, etc. Each "cycle" is "360 electrical degrees" in that, after a full "cycle," the encoder is back to the initial state. This meshes with the concept of a "state width" in "electrical degrees," where

State Width: The number of electrical degrees between a transition in the output of channel A and the neighboring transition in the output of channel B. There are 4 states per cycle, each nominally 90°e.

Further, if the snippet defines Count as:

Count (N) = The number of bar and window pairs or counts per revolution of the codewheel

then as I mention above, if the inner ring has 512 "bar and window pairs," and the outer ring has another 512 pairs, then there are 1024 pairs in total.

I personally think the whole concept of "electrical degrees" is whack and I'd probably prefer to call them encoder transitions or state transitions, but that's just a personal preference.

Body:
I think you're using the formula (360)/(4*1024) because of the term quad in quadrature encoder, but a quadrature encoder doesn't have anything to do with four, it's from the the use of the term to mean two signals that are offset by 90 degrees.

Your quadrature encoder will have TWO encoder rings (not four), and the resolution is 1024, not some multiple of it. What you'll wind up with are two channels, typically A and B, with each encoder wheel being 512 counts per revolution, and then the wheels are aligned in quadrature, meaning they're offset by 90 degrees.

If I use a to mean channel A is low, and A to mean it's high, and b and B similarly, then you'll get the following readings:

ab
Ab
AB
aB
ab

They're not in phase, or it'd go ab then AB, and they're not 180 degrees out of phase, or it'd go aB then Ab. Only when they're 90 (or 270!) degrees out of phase do you get that sequencing. In the example above, A is leading B - on one step A toggles, then on the next step B transitions to the same state as A.

If the encoder is moving in reverse, then A will follow B, like:

ab
aB
AB
Ab
ab

And so you can get both position and direction by monitoring the encoder counts. Here's a handy graphic from the Wikipedia entry on quadrature encoders:

And so finally, to answer your question, the actual encoder resolution isn't (360)/(4*1024), just 360/1024 = 0.3516 deg. The maximum angle error is very close to (but less than!) this resolution, but I typically would expect anything within +/- the least significant bit to be noise, so it's not a huge deal.

:EDIT:

The terminology in the encoder documentation is very confusing, notably the "bar and window" and "electrical degrees," so I looked for the "bar and window" term and found the following graphic from another encoder manual:

Apparently the "bar and window" refers to the dark and light bands on the encoder wheel. In OP's snippet from the manual:

1 Cycle = 360 electrical degrees
        = 1 bar and window pair

I can only assume they're calling them "electrical degrees" to refer to the cyclical nature of an encoder output, which should be 0011 0011 0011, etc. Each "cycle" is "360 electrical degrees" in that, after a full "cycle," the encoder is back to the initial state. This meshes with the concept of a "state width" in "electrical degrees," where

State Width: The number of electrical degrees between a transition in the output of channel A and the neighboring transition in the output of channel B. There are 4 states per cycle, each nominally 90°e.

Further, if the snippet defines Count as:

Count (N) = The number of bar and window pairs or counts per revolution of the codewheel

then as I mention above, if the inner ring has 512 "bar and window pairs," and the outer ring has another 512 pairs, then there are 1024 pairs in total.

I personally think the whole concept of "electrical degrees" is whack and I'd probably prefer to call them encoder transitions or state transitions, but that's just a personal preference.


问:
Denso 6DOF Industrial Robot Flip vs NonFlip
Hello my fellow roboticists!

I am working on the forward kinematics of the Denso 6DOF vs087 line of serial robots. In their Users' Manual, they categorize the set of joint configurations by three different metrics:

Lefty\Righty

Above\Below

Flip\NonFlip

While the first two are quite straightforward, the Flip/NonFlip is unclear. It has to do with the setup of the 4th, 5th, and 6th joints, in that the gripper pose is the same if they are all flipped by 180 degrees.

But how are the "Flip" vs "NonFlip" configurations mathematically defined? Is there any way they can be categorized using DH parameters and transformation matrices? I tried all sorts of trigonometric inequalities, but none of them gave the correct answer in all cases. Ideas, anyone?

Thanks in advance.

答:
To flip the wrist on a 6 axis robot, rotate joint 4 by 180 degrees. Rotate joint 6 by 180 degrees in the opposite direction. Move joint 5 to mirror of it previous position, that is if joint 5 was at +15 degrees, move it to -15 degrees. The robot's tool will now be at the same coordinates as it was previously.

Which you call flip and which you call no flip is somewhat arbitrary and each robot manufacturer will pick which they want to use.

Other robot suppliers, such as Staubli (the company I work for), uses wrist positive or wrist negative instead of flip and no flip. We also use elbow positive and elbow negative instead above and below.


问:
Spawn robot model using rospy in Gazebo
I am trying to spawn my robot model using rospy in my python interface to Gazebo.
In the launch file, I spawn the robot using:

```<code><node
name="urdf_spawner"
pkg="gazebo_ros"
type="spawn_model"
respawn="false"
output="screen"
ns="<span class="math-container">$(arg robot_name)"
args="-urdf -model $</span>(arg robot_model) -param robot_description -z 1.015"/>
</code>```

What would be the python way of doing the same? I'd be happy to share more details if needed. Thanks in advance!

答:
For resetting the robot to the initial pose - I was able to fix this by using

```<code>import rospy
from gazebo_msgs.srv import SetModelConfiguration

set_model = rospy.ServiceProxy("/gazebo/set_model_configuration", SetModelConfiguration)

joint_names = ['waist', 'shoulder', 'elbow', 'wrist_angle', 'left_finger', 'right_finger'] #example
joint_positions = [0.0, 0.0, 0.0, 0.0, 0.0195, -0.0195]

set_model.call(model_name=robot_name,
               urdf_param_name=robot_description,
               joint_names=joint_names,
               joint_positions=joint_positions)
</code>```

Note, it is important to pause the Gazebo physics before calling set_model and unpause once done.

When launching the robot for the first time in the Gazebo world, I use the gazebo_ros package to spawn the robot using a node of type spawn_model and pass the desired spawn coordinates.

Title: Spawn robot model using rospy in Gazebo

Body:
For resetting the robot to the initial pose - I was able to fix this by using

import rospy
from gazebo_msgs.srv import SetModelConfiguration

set_model = rospy.ServiceProxy("/gazebo/set_model_configuration", SetModelConfiguration)

joint_names = ['waist', 'shoulder', 'elbow', 'wrist_angle', 'left_finger', 'right_finger'] #example
joint_positions = [0.0, 0.0, 0.0, 0.0, 0.0195, -0.0195]

set_model.call(model_name=robot_name,
               urdf_param_name=robot_description,
               joint_names=joint_names,
               joint_positions=joint_positions)

Note, it is important to pause the Gazebo physics before calling set_model and unpause once done.

When launching the robot for the first time in the Gazebo world, I use the gazebo_ros package to spawn the robot using a node of type spawn_model and pass the desired spawn coordinates.


问:
How to check if arm_controller is up and running or not?
I have a Gazebo simulation running with a spawned robot. I also have initialized two trajectory-based controllers using JointEffortInterface for Gazebo-ROS plugin - arm_controller and gripper_controller. I am using MoveIt Group Commander for these two controllers.

I suspect these controllers are shut down at some point in time of the simulation and throw the following error when trying to read /joint_states topic:

```<code>[ERROR]: Didn't receive robot state (joint angles) with recent timestamp within 1 seconds.
Check clock synchronization if your are running ROS across multiple machines!
</code>```

Is there a way I can check if these controllers are enabled and running at any time during the simulation?

答:
I was able to keep a track of the controllers and their states using:</p>
```<code>import rospy
from controller_manager_msgs.srv import ListControllers

__list_controllers = rospy.ServiceProxy("/controller_manager/list_controllers", ListControllers)

__list_controllers.call() #whenever required
</code>```

Body:
I was able to keep a track of the controllers and their states using:

import rospy
from controller_manager_msgs.srv import ListControllers

__list_controllers = rospy.ServiceProxy("/controller_manager/list_controllers", ListControllers)

__list_controllers.call() #whenever required


问:
Arduino problem
I am actually doing an obstacle avoiding car. So, I bought Arduino UNO and L293D motor driver and four motors, servo motor and ultrasonic sensor. After the connections I have kept 10v li-ion battery. My problem the servo and sensor and motors are not working. BUT, the LED is glowing on both UNO and motor driver. I don't understand what's the problem?

(WHILE CONNECTING THROUGH USB CABLE THE MOTOR IS WORKING GOOD.)

Here my code,

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

#define TRIG_PIN A0
#define ECHO_PIN A1
#define MAX_DISTANCE 100
#define MAX_SPEED 150
#define MAX_SPEED_OFFSET 20

NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);

AF_DCMotor motor1(1, MOTOR12_64KHZ);
AF_DCMotor motor2(2, MOTOR12_64KHZ);
AF_DCMotor motor3(3, MOTOR34_64KHZ);
AF_DCMotor motor4(4, MOTOR34_64KHZ);
Servo myservo;

boolean goesForward=false;
int distance = 100;
int speedSet = 0;

void setup() {

  myservo.attach(10);
  myservo.write(115);
  delay(2000);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
}

void loop() {
 int distanceR = 0;
 int distanceL = 0;
 delay(40);

 if(distance<=25)
 {
  moveStop();
  delay(100);
  moveBackward();
  delay(200);
  moveStop();
  delay(200);
  distanceR = lookRight();
  delay(200);
  distanceL = lookLeft();
  delay(200);

  if(distanceR>=distanceL)
  {
    turnRight();
    moveStop();
  }

  else

  {
    turnLeft();
    moveStop();
  }
 }

 else
 {
  moveForward();
 }
 distance = readPing();
}

int lookRight()
{
    myservo.write(50);
    delay(500);
    int distance = readPing();
    delay(100);
    myservo.write(115);
    return distance;
}

int lookLeft()
{
    myservo.write(170);
    delay(500);
    int distance = readPing();
    delay(100);
    myservo.write(115);
    return distance;
    delay(100);
}

int readPing() {
  delay(100);
  int cm = sonar.ping_cm();
  if(cm==0)
  {
    cm = 250;
  }
  return cm;
}

void moveStop() {
  motor1.run(RELEASE);
  motor2.run(RELEASE);
  motor3.run(RELEASE);
  motor4.run(RELEASE);
  }

void moveForward() {

 if(!goesForward)
  {
    goesForward=true;
    motor1.run(FORWARD);
    motor2.run(FORWARD);
    motor3.run(FORWARD);
    motor4.run(FORWARD);
   for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2)
   {
    motor1.setSpeed(speedSet);
    motor2.setSpeed(speedSet);
    motor3.setSpeed(speedSet);
    motor4.setSpeed(speedSet);
    delay(5);
   }
  }
}

void moveBackward() {
    goesForward=false;
    motor1.run(BACKWARD);
    motor2.run(BACKWARD);
    motor3.run(BACKWARD);
    motor4.run(BACKWARD);
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2)
  {
    motor1.setSpeed(speedSet);
    motor2.setSpeed(speedSet);
    motor3.setSpeed(speedSet);
    motor4.setSpeed(speedSet);
    delay(5);
  }
}

void turnRight() {
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(BACKWARD);
  motor4.run(BACKWARD);
  delay(500);
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}

void turnLeft() {
  motor1.run(BACKWARD);
  motor2.run(BACKWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
  delay(500);
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}

  [1]: https://i.stack.imgur.com/9Sxy6.jpg
</code>```

答:
A skim through the code shows no obvious problems. The several likely problems with the electrical system suggest investigating there first.

Voltage

The 10 V you cite is an eyebrow-raiser. In my experience, the tiny, cheap electronics inside hobby servos will NOT operate reliably at more than 6 volts.

Also, if you are using the common TT motors, they are rated at 3 to 6 volts. They will be unhappy at much more than that. As with all motors, the degree of "unhappy" can range from erratic behavior to reduced life to catastrophic damage (= life reduced to zero).

Current

When your motor is working hard, it will draw a lot of current. You should compare that current against what your battery or USB can provide. You should expect trouble if you are anywhere near the limits.

When you draw current from a battery, the voltage it actually delivers will drop below what you would measure at open circuit. The more current you draw, the more it will drop, and even more so when the battery is nearly discharged. This is commonly attributed to "internal resistance", although the electrochemistry is a lot more complicated than that. You should measure the voltage at the motor when you think it should be working but is not.

A USB source has a voltage regulator which tries to keep the voltage at 5.0 volts. But a heavy motor load, even a transient one, can exceed the regulator's ability to maintain the proper voltage, causing things to misbehave. Often we try to power motors from a different source than powers the electronics.

Electrical noise

Brushed DC motors are notorious for spewing indiscriminate electrical noise that is more than capable of scrambling nearby electronics. Similarly, I would be leery of powering a PWM motor controller off the same supply as my electronics. Servos, with both buitin electronics and brushed DC motors, seem to survive their own noise, but they have builtin error correction and, typically, human controllers who expect erratic behavior.

Temporary solution

Just to get things working on the bench, I would suggest that you separate the potential issues. Get four AA batteries (4 x 1.5V = 6V) to power your motors and L293D. Use your USB to power the Arduino (getting the ground connections right!). Get the car wheels off the floor. Then test and debug the parts without them hiding each other's problems. With the car wheels off the floor, you can even test its behavior by approaching it with "obstacles" while it's still wired up in the operating room.

Good luck, you're on a good path. Autonomous behavior, even when simple, is the difference between a robot and an RC car.

Title: Arduino problem


问:
Designing S-Curve velocity profile for given Distance
I'm trying to create a high-level API for controlling a drone, where I tell it how far I want it to go (eg. moveForward(10)). The SDK allows me to give the drone an instantaneous velocity at 10 Hz (every 100ms) to control it. Currently, I have a naive solution of fixing a velocity (say $v = 1 ms^{-1}$) and then computing time as $t=\text{distance}/\text{velocity}$, then sending it the command of v velocity for t seconds every 100ms and after t seconds, I send it a command of 0 velocity. As expected, this causes a highly jerky motion, since the drone accelerates to the given speed instantly and then decelerates immediately to 0 at the end of t seconds.

I want to create a more smooth motion, with a lesser jerk. Reading around, I found out about S-curve profiles. I have gone through some math, and currently have the following equations to build an S-curve profile:

sigmoid = lambda x,a,c: 1/(1+exp(-a*(x-c))
for t in timesteps:
    v1 = sigmoid(t,a,c1)
    v2 = sigmoid(t,d,c2)
    v[i] = abs(v1 - v2) * v_max
```

Here a is the acceleration, d is the deceleration, c1 is the time at which the curve first becomes flat, c2 is the time at which the curve is flat for the last time and v_max is the maximum allowed velocity.

In mathematical notation:

$$
v(t) = V\left|\dfrac{1}{\mathrm{e}^{-D\cdot\left(t-C_2\right)}+1}-\dfrac{1}{\mathrm{e}^{-A\cdot\left(t-C_1\right)}+1}\right|
$$

One of the curves generated this way is for example:

I can also get the position curve verses time using scipy's numeric integration on the array of velocities:

I wanted an analytical equation for position versus time, so I used an online anti-derivative calculator and got the analytical equation for the position. This equation is correct, since I compared it against the numerical solution and they are nearly identical. It is pretty dense, so not sure if I'm digressing here:

$$
P(t) = -\dfrac{V\cdot\left(\mathrm{e}^{D\cdot\left(t-C_2\right)}-\mathrm{e}^{A\cdot\left(t-C_1\right)}\right)\left(-A\ln\left(\mathrm{e}^{Dt}+\mathrm{e}^{C_2D}\right)+D\ln\left(\mathrm{e}^{-At}\cdot\left(\mathrm{e}^{At}+\mathrm{e}^{AC_1}\right)\right)+ADt\right)}{AD\left|\mathrm{e}^{D\cdot\left(t-C_2\right)}-\mathrm{e}^{A\cdot\left(t-C_1\right)}\right|} + C
$$

Here C would be the integration constant, which I think is -P(0), since I want to consider the initial position to be $0$.

Even after all of this, the problem is not addressed, since I actually need to find t for which the final position is equal to the distance I tell the drone to travel. I thought of taking an inverse of $P(t) = k$ as $t = P^{-1}(k)$, but this approach comes with its own problems:

The inverse of this function is going to be quite complex, and something I would like to avoid as much as possible.

I am currently computing c1 and c2 as functions of t, namely c1 = 0.1*t and c2=0.9*t. I can probably replace c1 and c2 in the $v(t)$ equation as a function of time to get a purely time-based function, but again, that further makes the equation more complex.

While this is my current approach to solving the problem, I am not too happy with it. Is there another, simpler way to get the s-curve velocity profile for a given distance, where the time taken to complete the trajectory is flexible, or is there a way to simplify my current approach?

Edit 1: Trying to replace c1 and c2 as functions of t doesn't work because c1 and c2 are functions of the total time T and not the current timestep t, and T is what I need to solve for.

答:
You were probably trying to avoid this and generate some kind of closed form solution, but as you show this is really burdensome.

They way I would solve this (which might not be the best way) would be to work in the discrete time domain:

$$
v[n] = v(nT;V,A,D,C_1,C_2)
$$

$$
x[n] = \sum_{m=0}^{n}v[m]\,T
$$

where $T$ is the discrete time (e.g. sampling) interval.

Then you want

$$
x[N] = \sum_{m=0}^{N}v[m]\,T
$$

So just do an exhaustive search for the $N$ that yields $x[N]$ closest to some desired $x_{final}$.

Sorry in advance if I am missing something.


问:
Compensating for Yaw in Lateral Quadcopter Movement
I'm trying to make a quadcopter move laterally at a certain angle. I've been able to find the proper roll and pitch angles for this (that work with a yaw of 0°); how would I adjust these values to compensate for a different yaw?</p>

答:
This is just basic trigonometry; you'll covert your world-relative calculations of roll and pitch ($\phi$ and $\theta$) into vehicle-relative values, based on yaw ($\psi$).

Just so we're on the same page, I'm assuming measurements like the following, with roll, pitch, and yaw being zero when levelly flying North:

$$\phi_{vehicle} = \phi_{world}\cos(\psi) - \theta_{world}\sin(\psi)$$
$$\theta_{vehicle} = \phi_{world}\sin(\psi) + \theta_{world}\cos(\psi)$$


问:
Joint limits detection
I am pretty new to robotics and I am prototyping my own custom design of a robot with different types of joints controlled by ROS.

I have a custom joint activated by a DC motor and direct drive gears with limited motion range (minimum and maximum positions are reached by rotation and each direction).

What sensors (or mechanical stops) can be used to detect the ending positions of the motion?

I understand that servo motor will be the best choice - but the force I need is pretty high.

Thank you

答:
To know when a joint has reached a limit you usually use what are known as limit switches. There are lots of different technologies which are used for this. The simplest are mechanical switches but non contact optical ones are common as they are less prone to wear out over time.

You can also use an physical endstop and detect higher torque in the motor, but that's ambiguous in case of the device begging blocked by something else. Or you can use a pressure sensor on the endstop but that's usually more expensive.

There's lots of options and it's really about finding the best one for your application.

Title: Joint limits detection


答:
I was able to derive a piecewise continuous velocity function that satisfied my needs, by going back to the basics (Newton's equations of motion). First, we need to analyse the curve that needs to be designed. The S-curve velocity can be broken down into 7 phases (and the corresponding accelerations in those phases):

As mentioned, we use Newton's equations of motion, but with the third derivative of displacement (constant jerk $j$):

$$
a = a_0 + jt\\
v = v_0 + a_0t + \frac{1}{2}jt^2\\
x = x_0 + v_0t + \frac{1}{2}a_0t^2 + \frac{1}{6}jt^3
$$

If interested, you can find the full derivation here.

Basically, the idea is to compute the time taken and distance covered in each phase. Phases 1, 3, 5 and 7 are constrained by the value of jerk and the maximum acceleration. Phases 2 and 6 are constrained by the value of acceleration, and Phase 4 has no constraints. As such, we can say whatever distance is not covered in phases 1,2,3,5,6 and 7, must be covered with constant velocity $v_{max}$ in phase 4. Using this approach, we can ensure the total distance covered is the same as the desired distance. Further, computing the time for each phase allows us to add up the times for all the phases and get the total time of flight. A detailed derivation can be found in the link above.

Skipping the derivation here, the final velocity curve obtained is a piecewise function depending on which time phase we are currently in:

$$
v(t)=\begin{cases}
\frac{1}{2} jt^2 \qquad \text{in Phase 1}\\
v_{f_1} + a_{max}(t-t_1)\qquad \text{in Phase 2}\\
v_{f_2} + a_{max}(t - \sum_{i=1}^2 t_i) - \frac{1}{2}j (t-\sum_{i=1}^2t_i)^2\qquad \text{in Phase 3}\\
v_{f_3}\qquad \text{in Phase 4}\\
v_{f_4} - \frac{1}{2}j(t-\sum_{i=1}^4t_i)^2\qquad \text{in Phase 5}\\
v_{f_5} -a_{max}(t-\sum_{i=1}^5t_i)\qquad \text{in Phase 6}\\
v_{f_6} - a_{max}(t-\sum_{i=1}^6t_i) + \frac{1}{2}j(t-\sum_{i=1}^6t_i)^2\qquad \text{in Phase 7}
\end{cases}
$$

Here, $v_{f_i}$ is the velocity at the end of phase $i$ and $t_i$ is the time taken in phase $i$. The respective values are:

Velocities

$v_{f_1} = \frac{a_{max}^2}{2j}$

$v_{f_2} = v_{max} - \frac{a_{max}^2}{2j}$

$v_{f_3} = v_{max}$

$v_{f_4} = v_{max}$

$v_{f_5} = v_{max} - \frac{a_{max}^2}{2j}$

$v_{f_6} = \frac{a_{max}^2}{2j}$

Times

$t_1 = \frac{a_{max}}{j}$

$t_2 = \frac{(v_{f_2} - v_{f_1})}{a_{max}}$

$t_3 = \frac{a_{max}}{j}$

$t_4 = \frac{(a_{max}jD) - (v_{max}a_{max}^2) - (jv_{max}^2)}{ja_{max}v_{max}}$

$t_5 = \frac{a_{max}}{j}$

$t_6 = \frac{(v_{f_5} - v_{f_6})}{a_{max}}$

$t_7 = \frac{a_{max}}{j}$

How these values came to be can be found in the derivation.

Finally, based on the constraints of maximum velocity, acceleration and constant jerk, the created piecewise curve has a definite integral from $0$ to $T$ equal to the desired distance to cover $D$, where $T$ is the total time of flight, computed as $T = \sum_{i=1}^7 t_i$.

The idea for this approach came from this article.

Title: Designing S-Curve velocity profile for given Distance

Body:
I'm trying to create a high-level API for controlling a drone, where I tell it how far I want it to go (eg. moveForward(10)). The SDK allows me to give the drone an instantaneous velocity at 10 Hz (every 100ms) to control it. Currently, I have a naive solution of fixing a velocity (say $v = 1 ms^{-1}$) and then computing time as $t=\text{distance}/\text{velocity}$, then sending it the command of v velocity for t seconds every 100ms and after t seconds, I send it a command of 0 velocity. As expected, this causes a highly jerky motion, since the drone accelerates to the given speed instantly and then decelerates immediately to 0 at the end of t seconds.

I want to create a more smooth motion, with a lesser jerk. Reading around, I found out about S-curve profiles. I have gone through some math, and currently have the following equations to build an S-curve profile:

sigmoid = lambda x,a,c: 1/(1+exp(-a*(x-c))
for t in timesteps:
    v1 = sigmoid(t,a,c1)
    v2 = sigmoid(t,d,c2)
    v[i] = abs(v1 - v2) * v_max
```

Here a is the acceleration, d is the deceleration, c1 is the time at which the curve first becomes flat, c2 is the time at which the curve is flat for the last time and v_max is the maximum allowed velocity.

In mathematical notation:

$$
v(t) = V\left|\dfrac{1}{\mathrm{e}^{-D\cdot\left(t-C_2\right)}+1}-\dfrac{1}{\mathrm{e}^{-A\cdot\left(t-C_1\right)}+1}\right|
$$

One of the curves generated this way is for example:

I can also get the position curve verses time using scipy's numeric integration on the array of velocities:

I wanted an analytical equation for position versus time, so I used an online anti-derivative calculator and got the analytical equation for the position. This equation is correct, since I compared it against the numerical solution and they are nearly identical. It is pretty dense, so not sure if I'm digressing here:

$$
P(t) = -\dfrac{V\cdot\left(\mathrm{e}^{D\cdot\left(t-C_2\right)}-\mathrm{e}^{A\cdot\left(t-C_1\right)}\right)\left(-A\ln\left(\mathrm{e}^{Dt}+\mathrm{e}^{C_2D}\right)+D\ln\left(\mathrm{e}^{-At}\cdot\left(\mathrm{e}^{At}+\mathrm{e}^{AC_1}\right)\right)+ADt\right)}{AD\left|\mathrm{e}^{D\cdot\left(t-C_2\right)}-\mathrm{e}^{A\cdot\left(t-C_1\right)}\right|} + C
$$

Here C would be the integration constant, which I think is -P(0), since I want to consider the initial position to be $0$.

Even after all of this, the problem is not addressed, since I actually need to find t for which the final position is equal to the distance I tell the drone to travel. I thought of taking an inverse of $P(t) = k$ as $t = P^{-1}(k)$, but this approach comes with its own problems:

The inverse of this function is going to be quite complex, and something I would like to avoid as much as possible.

I am currently computing c1 and c2 as functions of t, namely c1 = 0.1*t and c2=0.9*t. I can probably replace c1 and c2 in the $v(t)$ equation as a function of time to get a purely time-based function, but again, that further makes the equation more complex.

While this is my current approach to solving the problem, I am not too happy with it. Is there another, simpler way to get the s-curve velocity profile for a given distance, where the time taken to complete the trajectory is flexible, or is there a way to simplify my current approach?

Edit 1: Trying to replace c1 and c2 as functions of t doesn't work because c1 and c2 are functions of the total time T and not the current timestep t, and T is what I need to solve for.


问:
Record and playback stepservo backdrive
I have a stepservo  motor with a high precision encoder. I'd like to use it in "teach" mode where I can move it around with my hand (backdriving), and then playback whatever motion I did.

What kind of "mode" do you want to put the stepper in to achieve this? Where you can move it around, but there is still some holding force.

答:
I can't comment on your specific hardware but I will try to answer the question more generally.  I assume this is for some sort of robot arm, (you don't actually say what your application is).

You might call this behavior "gravity compensation".  Where the arm knows exactly what configuration is it in, and how much torque is required at each joint to hold the arm in this "static equilibrium".  And if it senses any deviation in torque, it adjusts.

Typically, this is hard to achieve with highly geared down motors and stiff drive-trains.  It is best to use direct-drive motors.  But I believe this effect can be achieved with good sensing.  Note that you will need to measure the torque exerted on the arm.  This can be achieved with a "series elastic" member.  The compliance can be stiff.  For example, the Baxter robot had a horseshoe piece of sheet metal with a strain gauge on it for their torque sensing.

You will also find that the heavier the arm, the more difficult it is to achieve this effect.  Because the mass and CG of your arm may be slightly off, and there is always some noise in the torque measurement, so you will need a small dead-band before the arm will "feel" your push.  The heavier the arm, the larger push is required to get out of the dead-band.

Experiment with a single joint to get an understanding of how it works before moving onto the full arm.

See these other questions for more info:

Static equilibrium for 7 dof manipulator

What is the technology used for no-resistance robot arms?

Title: Record and playback stepservo backdrive


问:
Is there a way to control the roomba i7 actuators and sensors?
I would like to write my own program for controlling sensors and actuators of Roomba i7. For previous robots it was possible with some minor hacks.
Is there a way to flash an opensource firmware or a library to directly control the robot's behaviour?</p>

答:
No, unfortunately there is no way for a user to control the Roomba i7.  Instead, you should use the Create 3.

Disclaimer: I work at iRobot where I am developing the next generation of consumer robots. However, my postings on this site are my own and don't necessarily represent iRobot's positions, strategies, or opinions.


问:
Stabilizing water bucket with two retractable cables and motors
I am trying to design a system in which a bucket of water is held by two cables, lifted up/down while remaining stable. The cables can be retracted/detracted by two individual motors, controlled by their own PID system. The distance the cables travel is measured by an encoder that provides a discrete signal.

However, when I set a target distance (e.g., lift 10 cm), the output of the PID system controlling the motor speeds are different due to a difference in load on each motor. As a result, the bucket is destabilizing and water is leaking out.

What is the best way to ensure that the distance traveled by the bucket follows a smooth curve (i.e. no large changes in motor speed) and still remains stable? I am not looking for a complete solution to my problem, just a direction of terms and theory to look for. Thank you.

答:
There's several different ways that you could approach this problem.

You can make the motors more consistent by making sure that they are more deterministic in their response. This might involve making them stronger such that they are less effected by the weight. This can also be done by using a higher gear ratio.

The other approach to making them more robust to loading concerns is to control them simultaneously such that they can respond to the load of the other cable. The simplest way is to slow the progress of the less loaded motor until the faster moving one catches up.
But in general you need more feedback on the system than your two independent PID controllers.

Lastly, you mention going up and down, but not side to side, so by far the simplest solution would be to directly couple the cables on one shaft and only use one motor. This will guarantee to keep the cables level.


问:
Can we show converenge for a variant of inverse dynamics controller?
I was wondering if it is possible to show that a variant of the inverse dynamics controller

$$\tau = \mathbf{M}(q)\ddot{q}^\mathrm{des} + \mathbf{K}_pe + \mathbf{K}_d\dot{e} + \mathbf{h}(q, \dot{q})$$

is able to stabilize the system

$$\mathbf{M}(q)\ddot{q} + \mathbf{h}(q, \dot{q}) = \tau$$

答:
This answer is inspired by Ryszard Szwarc's answer in: https://math.stackexchange.com/questions/4509062/how-to-show-that-the-matrix-0-i-m-1k-p-m-1k-d-has-eigenvalues.

The dynamics of the system is in the form of
\begin{equation}
    \mathbf{M}(\mathbf{q})\ddot{\mathbf{q}} + \mathbf{h}(\mathbf{q}, \dot{\mathbf{q}}) = \tau
\end{equation}
and a variant of the inverse dynamics controller is in the form of
\begin{equation}
    \tau = \mathbf{M}(\mathbf{q})\ddot{\mathbf{q}}^\mathrm{des} + \mathbf{K}_p\Delta\mathbf{q} + \mathbf{K}_d\Delta\dot{\mathbf{q}} + \mathbf{h}(\mathbf{q}, \dot{\mathbf{q}}).
\end{equation}
Inputting the control into the dynamics gives us
\begin{align*}
    \mathbf{M}(\mathbf{q})\ddot{\mathbf{q}} + \mathbf{h}(\mathbf{q}, \dot{\mathbf{q}}) &= \mathbf{M}(\mathbf{q})\ddot{\mathbf{q}}^\mathrm{des} + \mathbf{K}_p\Delta\mathbf{q} + \mathbf{K}_d\Delta\dot{\mathbf{q}} + \mathbf{h}(\mathbf{q}, \dot{\mathbf{q}})\\
    \mathbf{M}(\mathbf{q})\ddot{\mathbf{q}} &= \mathbf{M}(\mathbf{q})\ddot{\mathbf{q}}^\mathrm{des} + \mathbf{K}_p\Delta\mathbf{q} + \mathbf{K}_d\Delta\dot{\mathbf{q}}\\
    -\mathbf{M}(\mathbf{q})\Delta{\ddot{\mathbf{q}}} &= \mathbf{K}_p\Delta\mathbf{q} + \mathbf{K}_d\Delta\dot{\mathbf{q}}
\end{align*}
which can be written as
\begin{equation}
    \begin{bmatrix}
        \Delta\dot{\mathbf{q}}\\
        \Delta\ddot{\mathbf{q}}
    \end{bmatrix} = \underbrace{\begin{bmatrix}
        0 & \mathbf{I}\\
        -\mathbf{M}(\mathbf{q})^{-1}\mathbf{K}_p & -\mathbf{M}(\mathbf{q})^{-1}\mathbf{K}_d
    \end{bmatrix}}_{\mathbf{A}(\mathbf{q})}\begin{bmatrix}
        \Delta\mathbf{q}\\
        \Delta\dot{\mathbf{q}}
    \end{bmatrix}.
\end{equation}
First, we show that $\mathbf{A}(\mathbf{q})$ is full rank, which leads to having non-zero eigenvalues. Using the property that elementary operations do not change the rank of a matrix, instead of investigating the rank of $\mathbf{A}(\mathbf{q})$, we look at the rank of
\begin{equation}
    \hat{\mathbf{A}}(\mathbf{q}) = \begin{bmatrix}
        \mathbf{I} & 0\\
        -\mathbf{M}(\mathbf{q})^{-1}\mathbf{K}_d & -\mathbf{M}(\mathbf{q})^{-1}\mathbf{K}_p
    \end{bmatrix}
\end{equation}
Then, by using Schur's complement, we have
\begin{equation}
    \det\Bigg(\begin{bmatrix}
        \mathbf{I} & 0\\
        -\mathbf{M}(\mathbf{q})^{-1}\mathbf{K}_d & -\mathbf{M}(\mathbf{q})^{-1}\mathbf{K}_p
    \end{bmatrix}\Bigg) = \det(\mathbf{I})\det(-\mathbf{M}(\mathbf{q})^{-1}\mathbf{K}_p) = \det(-\mathbf{M}(\mathbf{q})^{-1}\mathbf{K}_p).
\end{equation}
Using another property
\begin{equation}
    \mathrm{rank}(\mathbf{C}\mathbf{D}) \leq \min\{\mathrm{rank}(\mathbf{C}), \mathrm{rank}(\mathbf{D})\}
\end{equation}
if we see $\mathbf{D} = -\mathbf{M}(\mathbf{q})^{-1}\mathbf{K}_p$ and $\mathbf{C} = \mathbf{M}(\mathbf{q})$, then we have
\begin{equation}
    \mathrm{rank}(-\mathbf{K}_p) \leq \min\{\mathrm{rank}(\mathbf{M}(\mathbf{q})), \mathrm{rank}(-\mathbf{M}(\mathbf{q})^{-1}\mathbf{K}_p)\}
\end{equation}
which leads to the conclusion that $-\mathbf{M}(\mathbf{q})^{-1}\mathbf{K}_p$ is full rank with a non-zero determinant. Then, we have $\hat{\mathbf{A}}(\mathbf{q})$ have a non-zero determinant and full rank, which finally gives us the conclusion that $\mathbf{A}(\mathbf{q})$ is full rank. We then have the eigenvalues and eigenvectors of $\mathbf{A}(\mathbf{q})$ satisfying
\begin{equation}
    \begin{bmatrix}
        0 & \mathbf{I}\\
        -\mathbf{M}(\mathbf{q})^{-1}\mathbf{K}_p & -\mathbf{M}(\mathbf{q})^{-1}\mathbf{K}_d
    \end{bmatrix}\begin{bmatrix}
        \mathbf{v}_1\\
        \mathbf{v}_2
    \end{bmatrix} = \lambda\begin{bmatrix}
        \mathbf{v}_1\\
        \mathbf{v}_2
    \end{bmatrix}
\end{equation}
with $\lambda \neq 0$, which gives us the relationship
\begin{align}
    \mathbf{v}_2 &= \lambda\mathbf{v}_1\\
    -\mathbf{M}(\mathbf{q})^{-1}(\mathbf{K}_p\mathbf{v}_1 + \mathbf{K}_d\mathbf{v}_2) &= \lambda\mathbf{v}_2
\end{align}
This also tells us that $\mathbf{v}_1$ and $\mathbf{v}_2$ cannot be zero vectors. If one of them is the zero vector, then both of them will be zero, which gives a trivial solution to the equation above. Inputting the first equation into the second gives us
\begin{equation}
    -\mathbf{M}(\mathbf{q})^{-1}(\mathbf{K}_p + \lambda\mathbf{K}_d)\mathbf{v}_1 = \lambda^2\mathbf{v}_1
\end{equation}
then, by multiplying $\mathbf{M}(\mathbf{q})$ on both sides, we have
\begin{equation}
    -\mathbf{K}_p\mathbf{v}_1 - \lambda\mathbf{K}_d\mathbf{v}_1 = \lambda^2\mathbf{M}(\mathbf{q})\mathbf{v}_1\quad\rightarrow\quad\lambda^2\mathbf{M}(\mathbf{q})\mathbf{v}_1 + \lambda\mathbf{K}_d\mathbf{v}_1 + \mathbf{K}_p\mathbf{v}_1 = 0
\end{equation}
then, if we multiply $\mathbf{v}_1^T$ on the left, we have
\begin{equation}
\label{eq:final_eq}
    (\mathbf{v}_1^T\mathbf{M}(\mathbf{q})\mathbf{v}_1)\lambda^2 + (\mathbf{v}_1^T\mathbf{K}_d\mathbf{v}_1)\lambda + \mathbf{v}_1^T\mathbf{K}_p\mathbf{v}_1 = 0.
\end{equation}
We know that all of the coefficients are positive, then from the quadratic root formula
\begin{equation}
    \frac{-b\pm\sqrt{b^2-4ac}}{2a}
\end{equation}
we can determine all of the roots of the above equation have negative real parts.

Thus, we can show that $\mathbf{A}(\mathbf{q})$ is a Hurwitz matrix, which means the system of $\Delta{\mathbf{q}}$ and $\Delta{\dot{\mathbf{q}}}$ is stable. This tells us the controller $\tau$ can stabilize the system to zero error.


答:
This would be too long for a comment, so I will add some work as an answer:

The proof of $A(\mathbf{q})$ being invertible is not perfect. First, add some structure to the $K_p$ and $K_d$ matrices. Assuming they are gain matrices, they should probably be positive definite and diagonal (thus invertible). In this case $M(\mathbf{q})^{-1} K_p$ and $M(\mathbf{q})^{-1} K_d$ are very easily shown to be full rank. $\text{det}(AB) = \text{det}(A)\text{det}(B)$. We also know that $M(q)$, $K_p$, and $K_d$ are all invertible and thus have nonzero determinant. To finalize the argument you could still use Schur's complement to show that $A(\mathbf{q})$ is invertible as $\text{det}(I)\text{det}(-M(\mathbf{q})^{-1} K_p)$ is nonzero.

To touch on adding structure to your variables before making arguments, there is technically no reason $\mathbf{v}_{1}^{T}K_{d}\mathbf{v}_{1}$ and $\mathbf{v}_{1}^{T}K_{p}\mathbf{v}_{1}$ would be guaranteed to be positive - unless you state it beforehand that $K_d$ and $K_p$ are positive definite! This may be well known to those familiar with PD control, but it is still good to explicitly mention this. Likewise, we do not know that $-M(\mathbf{q})^{-1}K_{p}$ is invertible as $K_p$ is not necessarily invertible unless some underlying assumptions are made.

As far as I can tell everything else looks good!

Title: Can we show converenge for a variant of inverse dynamics controller?

Body:
I was wondering if it is possible to show that a variant of the inverse dynamics controller

$$\tau = \mathbf{M}(q)\ddot{q}^\mathrm{des} + \mathbf{K}_pe + \mathbf{K}_d\dot{e} + \mathbf{h}(q, \dot{q})$$

is able to stabilize the system

$$\mathbf{M}(q)\ddot{q} + \mathbf{h}(q, \dot{q}) = \tau$$


问:
Understanding the readings of Force Torque sensor based on accuracy and precision

I am working with a 6-axis force-torque sensor to measure the thrust and moments of a model jet engine. I want to understand the significance of the accuracy (measurement uncertainty) and precision (resolution) of these sensors. Note: I understand the textbook definitions well, I want to understand how these translate to real-world applications.

A realistic sample problem is as follows:

There are 2 sensors in the market.

Say both have the Maximum calibration for Fz as 1000N.

Both have the maximum measurement uncertainty as 1% of the Full-Scale calibration.

And say the first one has a resolution capacity of 0.1N and the second one has a resolution of 0.2N.

Here is what I understand:

The results of measurements will be accurate within 1% of 1000N which is $\pm$10N.

The resolution of the measured value for the first sensor is 0.1N and for the second 0.2N.

So if the measured thrust is 100.4N then I should report my measurement as 100.4N $\pm$10N.

The questions:

What is the significance of resolution here?
Since accuracy is 10N which is more than resolution isn't resolution insignificant here?

Both force sensors seem to be giving almost the same information. Both the first and second sensor say my value will be something within the range 90.4N to 110.4N. How does resolution come into play here?

A better resolution than accuracy seems to be useless.

Does resolution come into play when talking about repeatability? For eg: When I do the measurement again the first sensor is expected to give me a value of 100.4N $\pm$ 0.1N whereas, the second sensor is expected to give a value of 100.4N $\pm$ 0.2N?

Please provide me with an explanation on the same.

Thanks!

答:
One could separately model several reasons for limited accuracy. A system might suffer several at the same time. This is common to many instruments, besides force-torque sensors.

All instruments perfectly manufactured, to a flawed design. Repeatable from measurement to measurement, and from instrument to instrument. Careful calibration against a better standard can remove this.

Instruments variably manufactured. One instrument repeatably shows the same measurement, but its siblings and colleagues show something different. Calibration of each individual unit can remove this. Measurements by several different units or models might address this, depending on how you model the unit-to-unit variability — for instance, averaging can't fix systematic bias.

Instrument readings vary in a known way on some external factor(s), such as temperature. Measure that(them) and rely on even more calibration.

Instrument readings slowly vary because of something unknown. This is the hardest one. It even leads to folklore and superstition (phase of the moon). As a young electrical engineer I was told (jokingly, I hope) to never measure anything twice, because then you have to explain why the readings are different!

Instrument readings vary at "medium" rate. What you could do depends on your statistical model of the "noise" and what you're measuring. If multiple readings are independently inaccurate, you could combine them with mean, median, RMS, etc., as @guero64 points out.

Instrument readings vary at "fast" rate. Think noise, hum, jitter. Combine, as above, except your real-time software does the computation. Actually, the right amount of the right kind of noise can sometimes be your friend — think superresolution and dithering.

The above points touch on things to do with the data once the measuring is over. But of course there can be ways to improve the process leading to measurement. Think electrical shielding, shock mounts, temperature controls, etc.


问:
H bridge duty cycle vs maximum voltage
I've just burnt out an L298n H bridge, not surprising, but I thought it'd be ok for low load testing. Apparently not.

I'm considering ordering these to replace them - Hilitand DC 5-12V Motor Controller, Dual-channel H bridge Motor, Driver Board Module 0A-30A

Only problem is my chassis is running on a 4S pack - maximum voltage 16.8 V and these are limited to 12 V.

My theory is that if I limit the duty cycle to 71.5% they should work...

However, I know that PWM duty cycle is not actually the same as an analogue out. My question is, does the community think these will get burnt out too?

答:
The L298 part is rated at 50V abs max so hitting it with 4S is probably not why it burnt out. The peak output current rating is 2A abs max (continuous; 2.5A at 80% duty cycle). You didn't say what was your load, but I'd hazard the guess that it was sustained overcurrent that did the damage. Bear in mind that abs max ratings are not suggested design points.

However, the Hilitand part that you cited is rated for 13V, 14.6V max (if we can rely on what was published on Amazon). That's the max you can apply to the device, not the max voltage you deliver to your load. So, limiting the duty cycle won't work. If you hit it with your 16.8V 4S, I would expect a failure before long.

While on the Hilitand page, I noticed that it shows 30A max, far greater than the 2A L298. When I see an order-of-magnitude change in my designs, I reflexively look for a mistake.

Title: H bridge duty cycle vs maximum voltage


问:
ROS: frame transformation (tf) + TimeSynchronizer?
How to get a frame transformation using TimeSynchronizer?

I am developing some 3D recognition application for a mobile robot. The robot has an RGB camera, depth camera, and uses rtabmap for SLAM, so I have colored point cloud as a map.

My application takes an input data for each moment of time, processes it, and outputs a segmented/labelled point cloud.
The input data is following:

RGB image

Depth map

Cumulative colored point cloud corresponding to this point in time

Corresponding position of the robot (actually, camera) in the point cloud (item 3). I need it to project the point cloud to an image and make some operations.

A screenshot from Rviz to illustrate the input data (except the position of the robot):

To get all this data at once, I am trying to write a callback function using message_filters.ApproximateTimeSynchronizer. But I can't figure out how to get the position data. When I try to use tf.TransformListener() along with other subscribers and a synchronizer, I get the error: AttributeError: 'TransformListener' object has no attribute 'registerCallback'

My code (simplified):

class SaveSyncedAll:

    def __init__(self):
        self.bridge = CvBridge()
        self.sub_rgb = message_filters.Subscriber("/raw_frontal_camera/color/image_raw", Image)
        self.sub_d = message_filters.Subscriber("/raw_frontal_camera/depth/image_rect_raw", Image)
        self.sub_gsm = message_filters.Subscriber(
            "/cloud_map", PointCloud2, queue_size=1, buff_size=52428800
        )
        self.listener = tf.TransformListener(cache_time=rospy.Duration(0.01))
        # === THE METHOD BELOW LEADS TO AN ERROR ===
        ts = message_filters.ApproximateTimeSynchronizer(
            [self.sub_rgb, self.sub_d, self.sub_gsm, self.listener], queue_size=10, slop=0.01
        )
        ts.registerCallback(self.callback_all)
        # where to save data
        self.dataset_dir = "/home/3Drecognition/data_samples/All-1"
        # we need only each 10th frame
        self.frame_freq = 10
        self.frame_n = 0

    def callback_all(self, data_rgb, data_d, data_pc):
        # get rgb image
        try:
            cv_image_rgb = self.bridge.imgmsg_to_cv2(data_rgb, "bgr8")
        except CvBridgeError as e:
            print(e)
            return

        # get depth image
        try:
            cv_image_d = self.bridge.imgmsg_to_cv2(data_d, desired_encoding='passthrough')
        except CvBridgeError as e:
            print(e)
            return

        # get depth image
        try:
            (trans_d, rot_d) = self.listener.lookupTransform(
                '/map', '/frontal_camera_depth_optical_frame', rospy.Time(0)
            )
            (trans_rgb, rot_rgb) = self.listener.lookupTransform(
                '/map', '/frontal_camera_rgb_optical_frame', rospy.Time(0)
            )
        except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException):
            return

        # get colored point cloud
        xyz, rgb = unpack_pc2_data_1D(data_pc)

        # save obtained data sample to try my algorithm on it later
        # <.. some code here ..>

if __name__ == '__main__':
    rospy.init_node('save_synced_all', anonymous=True)
    ip = SaveSyncedAll()
    rospy.spin()
```

I'm using ROS Noetic.

答:
AttributeError: 'TransformListener' object has no attribute 'registerCallback' does not correlate with the line that you're calling out in the code:

```<code>ts = message_filters.ApproximateTimeSynchronizer(
        [self.sub_rgb, self.sub_d, self.sub_gsm, self.listener], queue_size=10, slop=0.01
    )
</code>```

It looks like it's related to the next line ts.registerCallback(self.callback_all) and the object appears to be a TransformListener object not the expected synchronizer.

Please make sure that you're simplified version actually runs and gives the error you're seeing. Also make sure that you give the full traceback. Just one error doesn't give enough info to understand what's happening.

I also see a problem that you aren't saving your synchronizer, ts in the object (aka self.ts = ...) which means it will go out of scope at the end of the __init__ and never trigger the callback.

Body:
AttributeError: 'TransformListener' object has no attribute 'registerCallback' does not correlate with the line that you're calling out in the code:

ts = message_filters.ApproximateTimeSynchronizer(
        [self.sub_rgb, self.sub_d, self.sub_gsm, self.listener], queue_size=10, slop=0.01
    )

It looks like it's related to the next line ts.registerCallback(self.callback_all) and the object appears to be a TransformListener object not the expected synchronizer.

Please make sure that you're simplified version actually runs and gives the error you're seeing. Also make sure that you give the full traceback. Just one error doesn't give enough info to understand what's happening.

I also see a problem that you aren't saving your synchronizer, ts in the object (aka self.ts = ...) which means it will go out of scope at the end of the __init__ and never trigger the callback.


问:
odom frame behaves mischievously in rviz when Configuring Robot Localization with error message TF_OLD_DATA
I am trying to learn ros2 nav2 localization  link

but when I add the ekf.yaml to launch description rviz behaves mischievously

to be specific: odom frame moves in rviz randomly and this is the error message it shows

Error message
Warning: TF_OLD_DATA ignoring data from the past for frame base_link at time 100.100000 according to authority Authority undetectable

so according to the ros wiki page link

I captured tf_frames and the image is attached as shown

答:
If you are working on a real-robot, set use_sim_time to False for each node, otherwise set it to True. Can you please try setting this and see if it works?

I faced an issue related to odom frame for my project and got this response from ROS answers which was very helpful. The explanation is wrt to my project but it should apply to anything in general.

Important part from the link: RViz will look at that timestamp (present in the message), then ask the transform tree where the sensor was located at that time, then render the sensor message at that position based in the fixed frame you are currently in.

So, I think that the sensor message's time and tf_tree timings are not matching.

Can't visualize in rviz2 with 'odom' as 'Fixed Frame'


问:
Are Artificial Intelligence and Robotics Different?
I need help in differentiating between AI and Robotics. Are AI and Robotics two different fields or is robotics a subject in AI?

I want to pursue a career in AI and Robotics. So I need your valuable suggestion. I searched the web and also some universities that I want to apply and I cannot find any such thing that I am searching for.

答:
Use of a classification system:

For input the robot would gauge, sense/sensor, and trip through methodology. (Standard logic studies).

For input the AI would gauge, sense/sensor, and apply logical methodology. (Advanced robotics and high level programming).

For input the human would gauge, sense, and react through methodology. (Awareness studies).

Continue
(For output... Continue).
(For process... Continue).
(For memory... Continue).
(For feedback... Continue).
(For control... Continue).

Living examples:
Ants although having life would generally trip through methodology too - a little robotic.
Animals having intelligence would generally apply a set of traits - slightly artificial. The baboon with the hand stuck in the tree when the farmer comes with the gun is a logical exploitation showing incorrect informers being used to master the required reaction. Lower IQ humans can display similar difficulties. At low points in a day you may notice similar difficulties emerging.

About Results
Humans are not all-powerful, and so could equally be outmaneuvered by lesser or higher complexity. The results are therefore organic when a variety of complexities are instantiated into a progression of activity. e.g. Ant's plot out strange pathways!

Extensible Usage of the Academic/Semantic Paradigm
A robotic construct could be extended into a bigger set of activities, but doesn't automatically prove itself advanced enough to be considered any kind of intelligence. It is (a topic) noted for large organizational studies, and in studies for comparisons to insect organizations. Simple exploitation not being enough to satisfy the development of higher order intelligence.

*Not considered in this answer: is the evolved design. As studied in plants and art (for example).

Research

Questioning intelligence: http://media.johnwiley.com.au/product_data/excerpt/40/11183378/1118337840-238.pdf

Examples of complexity defeated by lower order intelligence:
...hal.archives-ouvertes.fr/hal-00917542/

Studying evolved performance in limited individuals:
.../trends/neurosciences//retrieve/pii/S0166223613000039?cc=y

Pretty much find anything by searching: "behavior intelligence + {keyword/specialty}":
http://scholar.google.com/scholar?q=behavior+intelligence+robot&btnG=&hl=en&as_sdt=0%2C5&as_ylo=2013


问:
ROS - RViz reports "No transform from [kinect] to [world]" when URDF appears correct
I have specified a URDF relating the world with a table and a Microsoft Kinect mounted on a pole attached to this table.

The URDF parses successfully with check_urdf:

```<code>---------- Successfully Parsed XML ---------------
root Link: world has 1 child(ren)
    child(1):  table
        child(1):  kinect_mount
            child(1):  kinect
</code>```

However, loading this URDF with robot_state_publisher and then checking RViz, the relationships do not appear to work correctly. Whatever link I set as the fixed frame shows with "Transform OK", but it cannot determine transforms for the other links:

The position of the links reported in RViz also does not match what is set in the URDF:

I am new to URDF but this example is largely copied from an existing tutorial online, where no such errors were described by the author. I have attached the full URDF and launch file respectively below:

```<code><?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="robot">

    <!-- World declaration -->
    <link name="world"></link>

    <!-- World to table -->
    <joint name="table_to_world" type="fixed">
        <origin xyz="1.5 1.0 0" rpy="0 0 0"/>
        <parent link="world"/>
        <child link="table"/>
    </joint>

    <link name="table">
        <visual>
            <origin xyz="0 0 0.05" rpy="0 0 0"/>
            <geometry>
                <box size="2.5 1.5 0.1"/>
            </geometry>
            <material name="green">
                <color rgba="0.2 1 0.2 1"/>
            </material>
        </visual>
        <!-- <inertial>
            <mass value="1"/>
            <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
        </inertial> -->
    </link>

    <!-- Table to Kinect mount -->
    <joint name="table_to_kinect_mount" type="fixed">
        <origin xyz="1.5 1.0 0" rpy="0 0 0"/>
        <parent link="table"/>
        <child link="kinect_mount"/>
    </joint>

    <link name="kinect_mount">
        <visual>
            <origin xyz="-1.25 0 0.1" rpy="0 0 0"/>
            <geometry>
                <box size="0.1 0.1 0.1"/>
            </geometry>
            <material name="green">
                <color rgba="0.2 1 0.2 1"/>
            </material>
        </visual>
        <!-- <inertial>
            <mass value="1"/>
            <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
        </inertial> -->
    </link>

    <!-- Kinect mount to Kinect -->
    <joint name="kinect_to_kinect_mount" type="fixed">
        <origin xyz="0 0 0" rpy="0 0 0"/>
        <parent link="kinect_mount"/>
        <child link="kinect"/>
    </joint>

    <link name="kinect">
        <visual>
            <geometry>
                <sphere radius="0.05"/>
            </geometry>
        </visual>
    </link>

</robot>
</code>```

launch (please note this runs inside an ephemeral container where the xacro file is converted to pure URDF as part of the container build stage):

```<code><launch>
    <!-- Load the urdf into the parameter server -->
    <param name="robot_description" textfile="/app/urdf/robot.urdf"/>

    <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher">
    </node>
</launch>
</code>```

Any suggestions are much appreciated!

答: Solved; it was an issue with the container networking configuration. I am testing with RViz outside of the container and only port 11311 was forwarded. rosnode ping robot_state_publisher failed, so I switched it to host networking for testing, and all the transforms work.


问:
In Dynamic Motion Primitives, why we need to approximate f if f_target is given?
I seem to misunderstand something crucial regarding finding the force vector in the process of DMPs:
The way I understand it, I should come up with a dataset of trajectories $\{y_i\}_{i=1}^n$, and calculate a set of "True-labels" that are the forces associated with those trajectories: $\{f_i | f_i=\ddot y_i - \alpha_y(\beta_y(g-y_i)-\dot y_i)\}_{i=1}^n$. Next, I can minimize the squared differences between the approximation $\hat{f_i}$ (which is a linear combination of Gaussians) and $f_i$.

If this is all correct, why do I even need the approximation $\hat{f}$? don't I always have the values of the real force $f$, as I can always calculate it given the equation of motion? In other words, If I want to follow a trajectory $y$, then I need to apply the force $f(y)$, which is given by an $O(1)$ computation

Perhaps my error revolves around the idea that $\hat{f}$ is some generalization of all the different $f_i$'s? as in that $\hat{f}$ contains the information of all forces that are possible. If that is the case - I think for example of a robotic bird. A robotic bird does not have a set of common trajectories - in some cases, it may go in circles, and in other cases, it may go straight up. In that case, how can the DMP process generalize the force to account for all possible movements of the bird? I find it hard to believe that a linear representation of the forces of the wing could contain all that information

Thank you for your answers!

答:
The idea of Dynamic movement primitives is to encode a target motion into a flexible machinery that can quickly generalise to new instances, but still imitating the overall shape of the target motion. To get the new trajectories, it can be enough to specify few parameters, for instance the initial and final cartesian positions, and the DMP weights will tell you the entire new trajectory.

In the language of machine learning, the DMP weights are the neural network weights, the initial trajectories are the training dataset, and the new parameters are a test instance. It is not an exact analogy, since training and test sets are not from the same distribution here, but I find it helpful.

Regarding your last paragraph, DMPs cannot generalise too much. You can "train" a DMP with $\hat{f_i}$ from a single $y_i$, where $y_i$ is the path to be imitated. So you can get a DMP with $\hat{f_1}$ for a circular movement and a DMP with $\hat{f_2}$ for a linear movement. The whole idea is that even complicated movements can be composed into a basis (as in linear algebra) of a reasonably small number of primitive action building blocks.

If you know in advance the exact trajectory $y$ that you want to perform, you don't need to use this formalism. But this is rarely a realistic assumption, since slight variation in your environment means that every trajectory (e.g. for a walking robot) will be different. Indeed computing this new trajectory in real time may be time consuming, it's much faster to adapt an existing DMP to generate a new trajectory, while only fixing few parameters (rescale factor, or endpoints). This has the added benefit of making your trajectories all consistent with the path you are imitating, which may have been recorded to be particularly harmonious.

See this blog for more info.


问:
Kuka youBot melodic ros installation
I'm wondering if one can install Kuka youBot (i.e. the simulation part not the real hardware) in melodic ros. It seems there is no melodic-devel when I try to clone it from their github. When I try it  with kinetic-devel, I get this error

```<code>-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
-- Could NOT find brics_actuator (missing: brics_actuator_DIR)
-- Could not find the required component 'brics_actuator'. The following CMake error indicates that you either need to install the package with the same name or change your environment so that it can be found.
CMake Error at /opt/ros/melodic/share/catkin/cmake/catkinConfig.cmake:83 (find_package):
  Could not find a package configuration file provided by "brics_actuator"
  with any of the following names:

    brics_actuatorConfig.cmake
    brics_actuator-config.cmake

  Add the installation prefix of "brics_actuator" to CMAKE_PREFIX_PATH or set
  "brics_actuator_DIR" to a directory containing one of the above files.  If
  "brics_actuator" provides a separate development package or SDK, be sure it
  has been installed.
Call Stack (most recent call first):
  youbot_simulation/youbot_gazebo_control/CMakeLists.txt:4 (find_package)

-- Configuring incomplete, errors occurred!
See also "/home/xxxx/Desktop/youBot/catkin_ws/build/CMakeFiles/CMakeOutput.log".
See also "/home/xxxx/Desktop/youBot/catkin_ws/build/CMakeFiles/CMakeError.log".
Makefile:338: recipe for target 'cmake_check_build_system' failed
make: *** [cmake_check_build_system] Error 1
Invoking "make cmake_check_build_system" failed
</code>```

I've cloned [mas-group/youbot_description][2] and [mas-group/youbot_simulation][1] in catkin_ws/src and run catkin_make. It seems the drivers need to be installed but they are for older ros versions. Any suggestions? OS is ubuntu 18.04 and melodic ROS, Gazebo 9.

答:
I've solved the problem by installing
sudo apt-get install ros-melodic-brics-actuator

Title: Kuka youBot melodic ros installation


问:
3D path planning for coverage of a given surface
I have a 3D model of a complex object. I have been able to generate all possible points that are around 1 m away from the surface of any part of the object, so the collision is not possible:

Now my task is to generate a path for a robot that cover the whole area with set distance between scanning paths. Is there any known 3D path planning for coverage algorithm that can be used here? Is there any example of implementation? Picture no. 2 is a simple algorithm connecting dots after sorting and grouping points in given level. Unfortunately it will not work in more complex situations.

答:
maybe what you're looking for can be solved by referring to the solution mentioned in
Implementing a boustrophedon algorithm in a given room with obstacles.

Could you please help me out with how I can place the points on the given surface? Did you use an STL file to generate these points? Also, did you find out some other way to solve this CPP problem? What algorithm did you use for this project


问:
What are the pros and cons of Zip Chain Actuators in robotics?
Well, I just found out about these Zipper Chain Linear Actuators, but I couldn't find much information comparing these types to other types of actuators.

For example, what is the performance of Zip Chain Actuators compared to Linear Screw Actuators?

Of course, these are industrial level types of linear actuators, but you could make then out of 3D printing parts and achieve "good enough" capabilities.

答:
The primary feature of a zip chain actuator is that it does not need extra depth to retract into. A standard linear actuator has a slider that will travel back behind the point of actuation. It will often need as much space behind the actuating surface as in front for its range of motion.

Whereas a zip chain actuator moves the volume to the side or other directions to allow you to have a lower profile actuator housing for a larger displacement distance.

There are other trade-offs, such as stiffness, precision, and other things that may vary between the different actuators that you might choose.


问:
Building a mobile camera platform
I have zero experience with robotics, but I need to build a mobile platform for a streaming camera. The idea is that I'll plug in my Android phone into the pan/tilt unit on my wheeled robot and then drive and look around via WiFi. I have already solved all of the software, interface and controller issues, but I would appreciate some advice on how to build the wheeled platform.

My initial idea was to buy a cheap RC car, remove all electronics and replace them with my own. This approach almost worked. I purchased this New Bright F-150 Truck.  The size is good and there is plenty of storage space:

However, I quickly ran into a problem with this thing. I assumed that the front wheel would be turned by some kind of servo. Instead I found this nonsense:

That small gear shaft is not driven by a servo - it's a conventional motor, which spins until it is jammed at the extremes of travel. The wheels are straightened when power is removed by a small spring on the other side. This means that there is only one angle at which the wheels can be turned, and that angle is way too small for what I need. So using this RC car will not work.

Before I start buying more things, I would like to hear some opinions from more experienced people. Am I on the right track? Do I simply need to get a better RC car, or are they all designed like this? Perhaps there are other options that would be more suitable for what I am doing?

答:
You may replace tgis with an RC servo, but be sure to have enough torque and prefer metal gear.

The steering will involves a lot of mechanic constraints.

Anyway, Diego advice is good and you could also keep the actual mechanism.

Title: Building a mobile camera platform


问:
Need suggestions for wire size, wire connection, etc. for building an autonomous mobile robot
I am a newbie and I want to build an autonomous mobile robot.

I am using 4 brushed DC motor (stall current 5.0A). I am using four MD20A motor drivers (20A continuous, 60A peak).

The wire coming out of the LiPo battery is 12 AWG with an XT60 connector.

I am using a fuse block to control the current flow. I will use four 5A fuse blades.

I need suggestions on whether my choices are correct. Do I need to add any more things to make it secure?

答:
The wire sizes are generous, the motor drivers are more than adequate.  If your motors happen to be 6 V, your control will be squished down at the low end (like 6/14.8) of the range. But no real problems there.

The only thing I wonder about is if the fuse rating is inconveniently conservative. It would be obnoxious if a momentary stall blows a fuse. At 5 A, they are basically thermal protection for the motors against overheating during a protracted stall. (Everything else could tolerate a higher current.) I'm thinking slow-blow, but I have never seen that in blade format, so I don't have a specific recommendation.

Caveat: I'm reasoning from electrical engineering here, not from specific experience...


答:
@Tully's answer is great, but I just wanted to provide some examples.

Most linear actuators need a fair amount of collapsed height.  The ratio of length when extended to collapsed is usually around 2:1.  For example in the lead-screw based actuators in your question.

Of course, you can do better with a telescoping mechanism.  For example this telescoping ladder.  The ratio of extension to collapsed heights for this ladder is about 4.5:1.

However, a zipper mast is similar to a tape measure, where you can achieve a huge extension relative to a very small collapsed height.  The extension ratio of this tape measure is about 64:1.

For stability, the zipper mast is usually constructed from 2 or more "tape measure" like things, that zipper or interlock together.  Because the trade-off for this huge extension ratio is stability.  Also, I believe zipper masts are best at transmitting force in the extension direction.  They are very weak in other directions.  For example, you shouldn't use them horizontally.

One awesome application for a zipper mast is a retractable camera mast on a robot.  For example this demonstration on a PackBot.  https://www.youtube.com/watch?v=TFvwp5vReSw
It would be difficult to achieve such an large height extension with any other type of mechanism because they would require a large stalk on the robot, even when retracted.

Only you can determine the right type of linear actuator and what is "good enough" for your application.

Title: What are the pros and cons of Zip Chain Actuators in robotics?

Body:
Well, I just found out about these Zipper Chain Linear Actuators, but I couldn't find much information comparing these types to other types of actuators.

For example, what is the performance of Zip Chain Actuators compared to Linear Screw Actuators?

Of course, these are industrial level types of linear actuators, but you could make then out of 3D printing parts and achieve "good enough" capabilities.