答:
This does not appear to be breaking your tree, but creating an additional detached tree.

The tree will only connect if they share a common ancestor. As pointed out by @Chuck you appear to have two links that have base in the name. But since they are not exactly the same the links don't connect to each other.

Looking at your second tree, the first guess is that a1_gazebo::base should match the existing base link. Whatever you're launching or running should have a parameter to set the base link.

Title: sensor breaks tf tree in ROS

Body:
I am currently trying to add sensor(lidar) into my robot. I made base for a sensor, link to which sensor is attached through gazebo reference.

The problem is that adding a  tag for some reason creates another one tf tree, with 2 nodes, where my lidar is attached. Whereas there still exists another tf tree with my robot and sensor base.

If i remove  (in fact removing this tag removes sensor, but still keeps the link to which this sensor is attached) the tree becomes well defined.

I want to know how to fix this and to get the single tf tree.

What i add is the following(taken from livox github):

```<code><gazebo reference="<span class="math-container">${name}">
      <sensor type="ray" name="$</span>{name}">
          <pose>0 0 0 0 0 0</pose>
          <visualize><span class="math-container">${visualize}</visualize>
          <update_rate>$</span>{update_rate}</update_rate>
          <!-- This ray plgin is only for visualization. -->
          <plugin name="gazebo_ros_laser_controller" filename="liblivox_laser_simulation.so">
        <ray>
          <scan>
          <horizontal>
          <samples>100</samples>
          <resolution>1</resolution>
          <min_angle><span class="math-container">${-horizontal_fov/360*M_PI}</min_angle>
          <max_angle>$</span>{horizontal_fov/360*M_PI}</max_angle>
          </horizontal>
          <vertical>
          <samples>50</samples>
          <resolution>1</resolution>
          <min_angle><span class="math-container">${-vertical_fov/360*M_PI}</min_angle>
          <max_angle>$</span>{vertical_fov/360*M_PI}</max_angle>
          </vertical>
          </scan>
          <range>
          <min><span class="math-container">${laser_min_range}</min>
          <max>$</span>{laser_max_range}</max>
          <resolution><span class="math-container">${resolution}</resolution>
          </range>
          <noise>
          <type>gaussian</type>
          <mean>$</span>{noise_mean}</mean>
          <stddev><span class="math-container">${noise_stddev}</stddev>
          </noise>
        </ray>
            <visualize>$</span>{visualize}</visualize>
        <samples><span class="math-container">${samples}</samples>
        <downsample>$</span>{downsample}</downsample>
        <csv_file_name>package://livox_laser_simulation/scan_mode/avia.csv</csv_file_name>
        <ros_topic>${ros_topic}</ros_topic>
          </plugin>
      </sensor>
    </gazebo>
</code>```

Here is the part of the urdf which connects lidar to trunk link:

```<code>  <joint name="scan_joint" type="fixed">
    <parent link="trunk"/>
    <child link="livox_base"/>
    <origin rpy="0 0 0" xyz="0.2 0.0 0.1"/>
  </joint>
  <material name="blue_custom">
    <color rgba="0 0 0.8 1"/>
  </material>
  <!-- <xacro:Livox_AVIA name="livox"/>
  <xacro:include filename="/home/ramil/catkin_ws/src/livox_laser_simulation/urdf/standardrobots_oasis300.xacro"/>
  <xacro:link_oasis name="oasis"/> -->
  <gazebo reference="livox">
    <sensor name="livox" type="ray">
      <pose>0 0 0 0 0 0</pose>
      <visualize>True</visualize>
      <update_rate>10</update_rate>
      <!-- This ray plgin is only for visualization. -->
      <plugin filename="liblivox_laser_simulation.so" name="gazebo_ros_laser_controller">
        <ray>
          <scan>
            <horizontal>
              <samples>100</samples>
              <resolution>1</resolution>
              <min_angle>-0.614355377778</min_angle>
              <max_angle>0.614355377778</max_angle>
            </horizontal>
            <vertical>
              <samples>50</samples>
              <resolution>1</resolution>
              <min_angle>-0.673696522222</min_angle>
              <max_angle>0.673696522222</max_angle>
            </vertical>
          </scan>
          <range>
            <min>0.1</min>
            <max>200.0</max>
            <resolution>0.002</resolution>
          </range>
          <noise>
            <type>gaussian</type>
            <mean>0.0</mean>
            <stddev>0.01</stddev>
          </noise>
        </ray>
        <visualize>True</visualize>
        <samples>24000</samples>
        <downsample>1</downsample>
        <csv_file_name>package://livox_laser_simulation/scan_mode/avia.csv</csv_file_name>
        <ros_topic>scan</ros_topic>
      </plugin>
    </sensor>
  </gazebo>
  <link name="livox_base">
    <inertial>
      <mass value="0.1"/>
      <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
    </inertial>
    <visual>
      <origin rpy="0 0 0" xyz="0.00 0 0.00"/>
      <geometry>
        <mesh filename="package://livox_laser_simulation/meshes/livox_mid40.dae">
          </mesh>
      </geometry>
      <material name="blue_custom"/>
    </visual>
    <collision>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://livox_laser_simulation/meshes/livox_mid40.dae">
          </mesh>
      </geometry>
    </collision>
  </link>
  <!-- <xacro:Livox_Mid_gazebo_sensor name="livox" visualize="True"/> -->
  <link name="livox">
    <inertial>
      <mass value="0.1"/>
      <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
    </inertial>
  </link>
  <joint name="base_to_livox_joint" type="fixed">
    <parent link="livox_base"/>
    <child link="livox"/>
    <origin rpy="0 0 0" xyz="0.0 0.0 0.0"/>
  </joint>
</code>```


问:
How does the "rated torque" for a gear relate to the maximum torque?
I have just sized the DC motors I want to use (corresponding to my robot and its intended applications - my figures include a 50% uncertainty factor to account for friction in reducers and other losses). Now I need to actually choose the exact motors I want to buy from the manufacturer (I am targeting maxon motors as I am not an expert and want no problem). I have a few down to earth questions about linking the mechanical needs to the electrical characteristics, among them:

Question #5:

What is the "rated torque" mentioned when choosing a gear? I guess it is related to the maximum torque the gear can support... But now, I know my input torque (torque on the motor side) and my output torque (torque on the system side), does that correspond to any of these two?

答:
Rated torque relates to the lifetime of the gear.  You will need to read the manufacturer's guide in more detail to confirm for an individual model, but generally the rated torque  refers to the output (not input) torque at which 10% of units tested are expected to fail after 1 billion continuous input cycles.  The 1 billion input cycle limit in this case would be denoted by $L_{10}$ - referred to as the "L10 lifetime".

A more important torque spec might be the maximum repeated torque or maximum repeated peak torque.  This usually (but not always) refers to the torque which results in a L10 lifetime of 100 million input cycles (i.e. a factor of 10 less than that of the rated torque).

Also important is the momentary peak torque.  This is an "abnormal" torque that occurs that one might expect due to a collision of a robot arm or some other unusual event.  The L10 for momentary peak torque is another order of magnitude lower - e.g. 10 million input cycles in this case.

Harmonic Drive Systems has the clearest explanation of what these torque specs mean and how they relate, in my opinion. See graphs below (from here) as they relate to a harmonic drive.

One interesting aspect of this is the torque vs. L10 lifetime curve.  You will notice from the graph that the the lifetime decreases by a factor of 10 for every doubling of torque.  In the linear domain this implies that the gear fatigue lifetime is roughly proportional to the cube of the torque.  This is an interesting empirical relationship, touched on in more detail here.

ContentLicense: CC BY-SA 3.0

ContentLicense: CC BY-SA 4.0


问:
DC motor modelling with Bond Graph
I am trying to construct an equation that describes the output torque as a function of lambda  and omega
I have obtained the following bond graph but I am unsure of how to proceed.

答:
It might help to organize the equations a little in steps.  I think you have all this above:

Output torque of system:

$\tau_F$

Output torque at motor:

$\tau_0 = \tau_F/N$

Motor output speed:

$\omega_a = N\omega_M$

Motor torque speed relationship$^{*}$:

$\displaystyle{\frac{K_m}{R}}V_{in} = \frac{L}{R}\displaystyle{\frac{d\tau_0}{dt}} + \displaystyle{\frac{K_m^2}{R}}\omega_a$

I think it is also correct to state that:

$\lambda = LI_a$

This doesn't quite answer your question, but maybe gives you some new ideas.

$^{*}$ See, e.g., Harry Asada, Introduction to Robotics, Chapter 2

Title: DC motor modelling with Bond Graph


问:
Determining required torque for DC motor

How to determine the required torque while choosing a DC motor?

Here is a simple scenario. Think of a 4WD or 2WD vehicle. The max load the vehicle will have is 100kg.

Q1. How do I determine the required torque for the motor?

Q2. Should the Rated Torque(Kg-cm) more than 100 or the Stall Torque more than 100

Q3. And if use 2 Motor rated at 50kg-cm torque can it carry a load of 100kg?

答:
I believe this is the right way to approach the problem (see this post on ResearchGate):

Need to specify how much you will be accelerating the vehicle.  Let's call this $a$. For example, you could decide that you eventually want the vehicle to travel 1 m/s and you want to get to that velocity from a complete stop in 10 s.  That means you will need to support an acceleration of 0.1 m/s$^2$.

Once we have $a$, we know that the force required to accelerate the vehicle will be $F = ma$, where $m$ is the vehicle weight.

The torque applied to each wheel will be $T = Fr$, where $r$ is the wheel radius.

You also need to specify the final speed you wish the vehicle to travel at.  Let's call it $v_f$.

If $r$ is the wheel radius, then $C = 2\pi r$ is the circumference of the wheel.  The vehicle will travel a distance of $C$ per each wheel revolution.  If $w$ is the wheel rotation rate, then $v_f = C\omega = 2\pi r\omega$.

Supposing that each wheel uses a gear with ratio $N$, the final rotation rate of the motor at each wheel is $\omega_m = Nv_f/2\pi r$.

Start off assuming $N=1$ (i.e. no gear - direct drive by motor) and look for a motor that can support a repeated peak torque of $T$ and rated output speed of $w_m$.

If $N=1$ doesn't work, try $N=2$, $N=4$, ... up to $N=160$ or so. Look for a motor that can support a repeated peak torque of $T/N$ and rated output speed of $w_m$ and make sure that the gear can support the repeated output torque of $T$. Above that gear ratio (if you really need to go that high) you aren't likely to find many solutions.


问:
How to loop over each timestep in rosbags using Python?
I am using rosbag api to record rgb, depth and imu data coming off a robot. For an offline Visual Odometry experiment, I am in need of synchronizing RGB data with the imu data at the correct timesteps. This is because the IMU in our robot updated much faster than the RGB camera thus we have over 1000 entries for IMU data whereas we have only 136 images recorded within the same duration.

These are the information on the rosbag collected

Number of topics - 3 /rgb_image, /depth, imu

Time - 20s

I plan on iterating over each timestep and extracting the IMU data that is closest to the chosen picture's timestep. The end goal is to create a new rosbag with the synchronized data.

My question is how do I iterate over each image in the correct time order from the rosbag file using Python?

答:
The rosbag code API page includes an example of how to use the Python API to read messages out of a bag. It's a simple 5-line program.

You need to replace line 4 (the print statement) with your own code that iterates over all messages in the bag, pulling out the RGB messages and writing them to the new bag while also pulling out the IMU messages and finding the one closest to each RGB message.

Something like this should get you started. Note that this code uses the most recent IMU message, which is not necessarily the closest in time if the one that comes after the RGB message is closer.

```<code>import rosbag

input_bag = rosbag.Bag('input.bag')
output_bag = rosbag.Bag('output.bag', 'w')

most_recent_imu = None
for topic, msg, t in input_bag.read_messages(topics=['rgb_image', 'depth', 'imu']):
    # Store the most recent IMU message
    if topic == 'imu':
        most_recent_imu = msg
    elif topic == 'rgb_image':
        output_bag.write('rgb_image', msg)
        output_bag.write('imu', most_recent_imu)

output_bag.close()
input_bag.close()
</code>```

Body:
The rosbag code API page includes an example of how to use the Python API to read messages out of a bag. It's a simple 5-line program.

You need to replace line 4 (the print statement) with your own code that iterates over all messages in the bag, pulling out the RGB messages and writing them to the new bag while also pulling out the IMU messages and finding the one closest to each RGB message.

Something like this should get you started. Note that this code uses the most recent IMU message, which is not necessarily the closest in time if the one that comes after the RGB message is closer.

import rosbag

input_bag = rosbag.Bag('input.bag')
output_bag = rosbag.Bag('output.bag', 'w')

most_recent_imu = None
for topic, msg, t in input_bag.read_messages(topics=['rgb_image', 'depth', 'imu']):
    # Store the most recent IMU message
    if topic == 'imu':
        most_recent_imu = msg
    elif topic == 'rgb_image':
        output_bag.write('rgb_image', msg)
        output_bag.write('imu', most_recent_imu)

output_bag.close()
input_bag.close()


问:
Which type of actuator will be suitable for a very strong robot arm?
I wish to build a robotic arm that can lift a useful amount of weight (such as 3-6 kg on an arm that can extend to approx 1.25 meters). What actuators are available to accomplish this? The main factors and design points are:

Not Expensive

5 to 6 DOF

to be mounted on a yet to be designed mobile platform

battery powered

stronger than hobby servos (at least for the 'shoulder' and 'elbow' joints)

not slow to actuate

答:
You will want to choose low-weight, high torque density actuators for your arms, otherwise the actuators themselves will weigh down your arms and limit performance.

Harmonic drives provide the highest torque per unit weight currently on the market.  If you are doing this on a budget, you can probably find some good solutions on eBay.  Expect to pay at least $500 or so per joint though.  Companies like Harmonic Drive and Leaderdrive manufacture fully integrated actuators, complete with motor, encoder, and gear drive.


问:
How to add precise amounts of ingredients in my beverage making robot?
I am currently in the process of making a robot that can make a cup of tea, when It receives the command to do so. The general idea is as follows:

checks if saucepan is placed

checks if milk is available

checks if tea leaves are available

Hot plate is turned on using a relay

Pours milk from the refrigerated container using a pump

Drops tea leaves and sugar into saucepan

Waits a set amount of time during which tea is mixed(not sure how)

Chai is pumped from saucepan into cup, or is left in saucepan.

Hot plate relay is turned off and user is notified through blynk or IFTT

I have figured out how to go about most of the steps, but I cant seem to find a reliable way to add the desired amounts of sugar and tea. I have thought of a few ways:

Using a screw conveyer powered by a simple servo moter. I found this CAD model which i could replicate The Thingiverse link

Using plastic bottles filled with sugar or tea leaves. The opening of the bottle could be opened or closed with a servo moter, allowing the sugar or tea leaves to drop into the saucepan. This video shows what i mean, The video

With both possibilities the issue is how I would control the amount of ingredients. I want to choose the amount in tea spoons to add. How would I be able to add the exact desired amount? With the milk i thought i would first calculate the rate in L/M of my pump then turn on the pump for exactly the required amount of time in code. Please let me know if you think is a good way to go about it and if you have any idea how i could control amount of substance added and how.

答:
You could have a spoon (or spoons) attached to a belt or chain in a loop. Sort of like an old-style grain elevator scoop conveyor. But instead of a continuous chain of buckets, have a discrete number of teaspoons (maybe even just one), with enough distance between spoons for your controller to count and stop the motion when done.

I haven't found a compelling way to sketch this without using animation, so I'll try with mere words.

Consider making the spoon handles parallel to the belt surface, such that they are remain parallel to the roller axis. The spoon has to travel below the surface of the sugar in order to scoop some up. Ideally it would disturb only the sugar it will lift — pushing anything else around is wasted energy. So you would want to minimize the distance the bowl travels while under the surface. If you were to use an actual spoon, you wouldn't want its bowl sticking way out like a paddle -- which it would if the handle were perpendicular to the belt surface. That also suggests that the radius of the lower belt roller should be as small as feasible.

Also consider what happens at the top of its circuit. I picture the spoon bowl(s) sticking off the edge of the belt. That way, it can dump its load into a chute. But if the bowl hugs the belt, it can only spill onto itself.

One supposes even the milk could be measured by similarly traveling cups.

There is something satisfying about controlling teaspoons of stuff by counting spoons instead of counting seconds. Easier? That depends. Does "easier" override other considerations? That depends too. Pumping sugar is harder than pumping milk. Scooping milk seems harder than pouring or pumping it, but it just might share engineering with the sugar scoop machinery.


问:
Val3 Programming Stäubli
can anyone help in the "FROMBINARY" in Val3 Prgramming? I want to send a number for example 3 from Python, but after sending the Number it is not converting it from  Binary to a number.

Thanks a lot

答:
The "fromBinary" instruction in VAL 3 has 4 parameters. The first is a number of bytes in the data array you are converting. if you have only 1 byte of data it will be 1, if you have 4 bytes it will be 4. You may have more than 1 number in the array of bytes. The second parameter is how many number are in the array of bytes. So if you have three number each of which takes two bytes the first parameter will be 6 and second will be 3. if you have one number in a in a one byte array, then the first two parameters will be 1 and 2.

The third parameter is a format used to encode the number a single unsigned byte will have a format of "1". If the byte is signed (the first bit indicates positive or negative, it will be "-1". When there is more than one byte you have two methods commonly called big endian and little endian. in some case the most significant byte is first in other cases the least significant byte is first. so we have "2b", "2l", "-2b", and "-2l". There are also 4 byte encodings, "4b", "4l", "-4b", and "-4l".

For floating point single precision (4 bytes), we use "4.0b" and "4.0l". for floating point double precision (8 bytes), we use "8.0b", and "8.0l". floating point are always signed so we do add the "-"

The formats are strings, not numbers.

In you case if it is a single unsigned byte, use "1".

The final parameter is a numeric array holding the numbers from the array of bytes.

The instruction will return how many numbers were found.

So if your single unsigned byte is in variable, "nByte" and I want the number to go into the num variable "nNum" I do

fromBinary(nByte, 1, "1", nNum)

the instruction should return a 1 since it found 1 number.

Title: Val3 Programming Stäubli


问:
control over changing data
I am trying out different control algorithms, in my practice on the state space models and control. Now I have the following system with the following states and state transitions with time.
Position variation with time:
$$
\begin{equation}
\begin{bmatrix}
x_t\\ y_t \\ \theta_t
\end{bmatrix} =
\begin{bmatrix}
x_{t-1} + v_{t-1}cos(\theta_{t-1}) \delta t \\
y_{t-1} + v_{t-1}sin(\theta_{t-1}) \delta t \\
\theta_{t-1} + \omega_{t-1} \delta t
\end{bmatrix}
\end{equation}
$$
x and y are coordinates in the world, $\theta$ is the bearing of my robot. v is its velocity and dt is the change in time.
In order to have to robot go somewhere, I linearized the above system into the form, $X_t = A_{t-1}X_{t-1} + B_{t-1}u_{t-1}$, using the linear and angular velocities as inputs to control the position of the robot to have it go to desired location. Using the LQR algorithm. Current state is position and desired state is in form of position as well at the moment. My questions are,

What changes do I have to (or need to make), to have the robot not move to a stationary position but track a moving point? Assuming i retrieve the state information from sensors periodically. Am a bit confused here because, when calculating the discrete ricatti equation, I have something like this:

For i = N, …, 1

P[i-1] = Q + ATP[i]A – (ATP[i]B)(R + BTP[i]B)-1(BTP[i]A)

I am doing it in python by the way, for what its worth.

How do my matrices change, if I choose to move in one direction, say get rid of the y coordinate. So my robot moves in a straight line?

What effects does changing the current and desired state from position (coordinates), to something constant, say distance? Is this even advisable? if not, why not? Still i will forward distance to controller as state over time, and controller will give me velocity.  How do my matrices change according to the distance set up?

Which of the two approaches is more accurate? Assuming all robots are on the ground.

Below are my A and B matrices
$$
\begin{equation}
A =
\begin{bmatrix}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 1
\end{bmatrix},
B =
\begin{bmatrix}
cos(\theta_{t-1}) \delta t & 0 \\
sin(\theta_{t-1}) \delta t & 0 \\
0 & \delta t
\end{bmatrix}
\end{equation}
$$

Thanks a lot in advance.

答:
Trying to address your questions one at a time:

What changes do I have to (or need to make), to [...] track a moving point?

In the state-space representation I think this is typically done with reference tracking in the form of "Integral Control" or "Integral Action." You essentially wrap an integral controller around your state feedback controller and pass the integral error. If I recall correctly you extend your state vector to include integral error, and then the state feedback controller drives all states to zero, including the integral error, et voila.

How do my matrices change, if I choose to move in one direction, say get rid of the y coordinate. So my robot moves in a straight line?

You don't get to selectively butcher your state vectors. They're either the states, or they're not. Use your B matrix to map your inputs to state derivatives, use your C (and D) matrices) to map your states back to outputs, but you can't "get rid of" one of the states.

What effects does changing the current and desired state from position (coordinates), to something constant, say distance? Is this even advisable? if not, why not? Still i will forward distance to controller as state over time, and controller will give me velocity. How do my matrices change according to the distance set up?

Well you can't really do that, right? If it's a constant input then are you actually controlling anything? The mechanism you might be tempted to use would be the almost-always-zero D matrix, which maps INPUTS directly to y/output, but that's not the "kind" of output you would use for control. The y outputs are those that are the measurable outputs, so for example if you had vehicle speed as a state but you only had wheel encoders, the wheel encoder reading should depend on the vehicle speed - the C matrix would contain the math that converts from vehicle speed to wheel encoder speed so you can do some comparisons between y and your sensor feedback. Y is not the control output.

What you're looking for instead is a kind of feed-forward control, but again I don't think what you're asking about is what you actually want.

Which of the two approaches is more accurate? Assuming all robots are on the ground.

I don't understand this question.

In general, I think you've got kind of the wrong approach here in trying to do speed and heading together in one controller. If it were me, I'd split them out into a heading controller and a speed controller, then I'd set the poles on the heading controller to be (arbitrarily) 5 to 10x faster than the poles on the speed controller, so you get to heading faster than you get to position, which is kind of required if you're ever going to get to the correct position. Then you can have your inputs as r/$\theta$. Your control outputs for the heading controller would be some $\ddot{\theta}$ that in turn maps symmetrically to the left and right wheels, such that v_L = (-v_R).

The output of the speed controller would pipe to each wheel, and then you sum the outputs of both controllers to get the complete system.

Title: control over changing data


答:
I find the idea of the screw conveyer quite promising. I would use a self-made scale to weigh this. For example, a strain gauge with a sort of bowl fixed on it. Put this self-made scale on a 90 degrees servo to enable pouring into the mug of tea (or water at this stage).
Then have both the tea screw and the sugar screw pouring on the scale.

For how it works:

Pour sugar on the scale using the sugar screw, until the controller detects the desired weight of sugar.

Pour the scale content (sugar) into the mug.

Repeat with the tea.

More generally, I would use the same thing for all ingredients. You could also weigh the amount of water/milk you add.

Hope it helps!

Title: How to add precise amounts of ingredients in my beverage making robot?

Body:
I am currently in the process of making a robot that can make a cup of tea, when It receives the command to do so. The general idea is as follows:

checks if saucepan is placed

checks if milk is available

checks if tea leaves are available

Hot plate is turned on using a relay

Pours milk from the refrigerated container using a pump

Drops tea leaves and sugar into saucepan

Waits a set amount of time during which tea is mixed(not sure how)

Chai is pumped from saucepan into cup, or is left in saucepan.

Hot plate relay is turned off and user is notified through blynk or IFTT

I have figured out how to go about most of the steps, but I cant seem to find a reliable way to add the desired amounts of sugar and tea. I have thought of a few ways:

Using a screw conveyer powered by a simple servo moter. I found this CAD model which i could replicate The Thingiverse link

Using plastic bottles filled with sugar or tea leaves. The opening of the bottle could be opened or closed with a servo moter, allowing the sugar or tea leaves to drop into the saucepan. This video shows what i mean, The video

With both possibilities the issue is how I would control the amount of ingredients. I want to choose the amount in tea spoons to add. How would I be able to add the exact desired amount? With the milk i thought i would first calculate the rate in L/M of my pump then turn on the pump for exactly the required amount of time in code. Please let me know if you think is a good way to go about it and if you have any idea how i could control amount of substance added and how.


问:
I'm trying to understand an equation from a motor simulation $\dot w_i (u_ i  ,w_i,l _i  , \dot l _ i  )$
I have a simulated motor and I'm not understanding the math to control it.

This is the equation for the force of the motor, also called an 'actuator'.

$\dot w_i (u_ i  ,w_i,l _i  , \dot l _ i  )$

w is the "vector of actuator activations". I don't know what the dot mean from one to w to the other.

u is the "scalar control".

l is the "scalar length".

I see the words but I don't know what w, u, and l are here. Is this an area of physics math you might be able to point me in?

In the software, which I won't go into in depth, I can control the dynamic, which makes the motor move. I can set the Newton Meters. I can set a bias. I can set a gain. I don't know how this correlates, or is represented in the equation.

I asked the developer of the software (MuJoCo) about my motor simulation gaining higher and higher for torque for some reason and he said.
"It builds up because the actuator has a state.
That is what <general dyntype=... does, it gives your actuator an internal state.
This state is "remembering" the previous actions because it is an integral defined by the first equation in the section."

He's talking about the equation I am posting about here. Now there is a "state" involved. Please help me understand.

The link to this documentation is here

The full text is here

"Actuation model
MuJoCo provides a flexible actuator model. All actuators are single-input-single-output (SISO). The input to actuator ii is a scalar control u_iu
i

specified by the user. The output is a scalar force p_ip
i

which is mapped to joint coordinates by a vector of moment arms determined by the transmission. An actuator can also have activation state w_iw
i

with its own dynamics. The control inputs for all actuators are stored in mjData.ctrl, the force outputs are stored in mjData.actuator_force, and the activation states (if any) are stored in mjData.act.

These three components of an actuator - transmission, activation dynamics, and force generation - determine how the actuator works. The user can set them independently for maximum flexibility, or use Actuator shortcuts which instantiate common actuator types.

Transmission
Each actuator has a scalar length l_i(q)l
i

(q) defined by the type of transmission and its parameters. The gradient \nabla l_i∇l
i

is an n_Vn
V

-dimensional column vector of moment arms. It determines the mapping from scalar actuator force to joint force. The transmission properties are determined by the MuJoCo object to which the actuator is attached; the possible attachment object types are joint, tendon, site and slider-crank. The latter can also be modeled explicitly by creating MuJoCo bodies and coupling them with equality constraints to the rest of the system, but that would be less efficient.

Activation dynamics
Some actuators such as pneumatic and hydraulic cylinders as well as biological muscles have an internal state called “activation”. This is a true dynamic state, beyond the joint positions qq and velocities vv. Including such actuators in the model results in 3rd-order dynamics. We denote the vector of actuator activations ww. They have some first-order dynamics"

答:
The equation is just a general equation dynamic equation saying that the variation of the actuator activation  ($\dot{w}$) depends on the input (u), the current actuator activation state (w), the scalar length (l) and the variation of the scalar length ($\dot{l}$).

Then the l is related to physical length converting the torque to forces "It determines the mapping from scalar actuator force to joint force" (from doc)

For w, it says "This is a true dynamic state, beyond the joint positions q and velocities v." This is quite unclear what is included, but if it's a dynamic state then it includes accelerations and masses/inertia or the actuators.


问:
Tips for designing an optical eight channel read head for a DIY rotary encoder
I'm thinking of using the gray code optical encoder disc design described at TeX Stack Exchange to sense the base rotation of a robot arm. Being able to vary the disc to suit the physical aspects of the particular situation is attractive.

I've subsequently been thinking about putting together a matching 8 track reading head. Probably using something like these miniature reflective IR optical sensors.

Can anyone point me towards good resources for figuring out a read head design? Any tips for avoiding interference between tracks?

At the moment I'm just thinking about mounting them as close together as I can on prototyping board and printing the tracks on the disc to be the same width as a single sensor.

答:
I ended up going with the linear photo sensor array idea suggested by @r-bryan, and selected a Pololu QTR-HD-09RC Reflectance Sensor Array: 9-Channel, 4mm Pitch, RC Output. I’ll update this answer with Tex code for printing a matching Gray code wheel when available.

I’ve initially chosen a digital output array. I’ve yet to read through the supplied Arduino library to check for  a non-blocking solution. I may switch to the analog version if this becomes an issue after testing.


问:
Unable to find my robot with an error
This question and the docs pointed me to $GAZEBO_MODEL_PATH as being the environment variable to change to include models in a gazebo world. However, I am getting an error.

This is my current tree structure:

```<code>.
├── CMakeLists.txt
├── model
│   └── robot
│       ├── model.config
│       └── model.sdf
├── script
│   └── hello.cpp
└── worlds
    ├── empty.world
    └── myworld
</code>```

My GAZEBO_MODEL_PATH is:

```<code>$ $ echo $GAZEBO_MODEL_PATH
:/home/self/workspace/build_my_world/model/robot:
</code>```

But when I run gazebo I get an error.

```<code>$ gazebo worlds/myworld
Error [parser.cc:652] Could not find model.config or manifest.xml for the model
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
</code>```

This is what I have in myworld file:

```<code>   1 <sdf version='1.6'>
   2   <world name='default'>
   3
   4     <include>
   5       <pose frame=''>0 0 30 0 0 0</pose>
   6       <uri>model://model</uri>
   7     </include>
   8
</code>```

The final problem is that even if I remove the model in the world file, entering gazebo doesn't launch the application. There's NO output either.

答:
If you don't want to mess things up editing .bashrc variables, I suggest you to use gazebo_ros, and you can edit package.xml file to tell gazebo to where to look for models. A simple example would be;

```<code><depend>gazebo_ros</depend>

<export>
      <gazebo_ros gazebo_model_path="<span class="math-container">${prefix}/models"/>
      <gazebo_ros gazebo_media_path="$</span>{prefix}/worlds"/>
</export><span class="math-container">```
```

Title: Unable to find my robot with an error

Body:
If you don't want to mess things up editing .bashrc variables, I suggest you to use gazebo_ros, and you can edit package.xml file to tell gazebo to where to look for models. A simple example would be;

<depend>gazebo_ros</depend>

<export>
      <gazebo_ros gazebo_model_path="${prefix}/models"/>
      <gazebo_ros gazebo_media_path="${prefix}/worlds"/>
</export>```


问:
ROS 2: rqt vs rqt_graph
In ROS 2, what is the difference between the rqt and rqt_graph commands?  They both seem to bring up the rqt visualizer, which works great.  Is there actually a difference?  Does one simlink to the other?  I'm using Ubuntu 20.04 if that matters.

答:
rqt is a generic visualizer which has a plugin interface. The rqt generic executable is provided by the rqt_gui package.

rqt_graph is a specific plugin for rqt that provides a convenience command line executable with the same name to launch the visualizer specifically configured with that plugin loaded.

Title: ROS 2: rqt vs rqt_graph


问:
Do IMU have value in SLAM?
IMU are often used in theoretical models involving SLAM.

I'm a bit confused on their practical value since error accumulation is so bad that after a couple seconds you need to completely ignore it.

What is the reason to use and IMU and when should they be used?

More generally, how do you handle the horrible accumulation of error making the item essentially useless for localization?

答:
The IMU should be used for what it does best : measure accelerations and angular velocities. As you guessed, the IMU integration is poor (not usable for navigation purpose) and the attitude estimation may also need some other source of speed to remain reliable.

But the real improvement is in the combination of both :

the IMU (especially the measure of angular speed) can provides nice clues for the SLAM to better estimate the ego motion between two frames and speed up drastically the point matching.

As a feedback, the odometry extracted from the SLAM can be used to unbias the gyros and acceleros

And the combination of both gives an improved SLAM and an improved inertial navigation. Win Win

Title: Do IMU have value in SLAM?


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

答:
Both, robotics and artificial intelligence, are strongly overlapping fields. But none of them is the subset of the other.

For example, robotics cover hardware design, which normally* does not involve artificial intelligence. On the other hand, artificial intelligence covers a lot of big data fields that aren't connected to robotics, like predicting weather or stock markets. Shared fields of both disciplines are computer vision, natural language processing, path finding, behavior planning, decision making.

I am interested in a robotics career, too. The advice I got many times is to dive into artificial intelligence as it is the biggest challenge in robotics today. In most robotic projects, mechanical or electronic design is not the border, but software is.

Human kind already solved most hardware problems. Research is still needed for optimizations but in artificial intelligence, there might happen a breakthrough. Even though such a breakthrough is controversial, it still is the more evolving field.

* Using artificial intelligence in hardware design would be interesting though. I don't know if someone already did that.


问:
How dangerous are HASEL artificial muscles with its Kv requirements?
So, I don't know much about electricity and this kind of stuff, so I hope I don't make too many misconceptions.

What are HASEL artificial muscles? It is a “Hydraulically amplified self-healing electrostatics (HASEL) actuator”, in a simple way: it is two electromagnetic materials sandwiching a liquid material (normally oil), once an electric current pass through the plates, they attract each other, forcing the entire package to decrease its volume, simulating a muscular contraction.

So, the problem is that they require around 10-20 Kv to be able to contract, at first I thought that this muscle may be dangerous to just play around with. But there is the saying that "What kills you isn't the voltage, but the current", so maybe I'm picturing everything incorrectly.

The problem is: I couldn't find anything besides the Kv information, no amps or watts (not even in their official online store). Here is the link to the article.

I probably missed something in the article or simply misread it, but still, whatever current requirement this Artificial Muscle is, it is high enough to be dangerous?

答:
So first, always take precautions when dealing with electricity. Discharging capacitors, removing metal jewelry, safety glasses, insulated tools, etc. If it's a commercially available product then I would expect it to come with specific instructions for what's appropriate for the device, and you should comply with all written safety procedures.

That said, yes static electric shocks are about 10kV, but you are correct that it doesn't do permanent damage because the current is low.

That said, mechanical actuators capable of appreciable motion could probably draw enough instantaneous power to be very dangerous. I wouldn't put my hand near an exposed automotive 12V window regulator winch system and I likewise wouldn't want to put my hand near an exposed high voltage actuator either.

If you look at it and think, wow, this could mangle my hand, don't touch it.


问:
How do I call Matlab code into Simulink for doing a simulation for doing plots?
I have built a simulink model for performing cartesian regulation on a unicycle:

and plot the results with a Matlab code

but, I am not very confident with Simulink and so I don't know how to call these codes into my Simulink model.

Can somebody please help me?

答: If you're wanting your data to be plotted at the end then you can use a To Workspace block and send the data out that way and plot from the console or script after the Simulink project finishes</p>


问:
How can I input joint angles to transformation matrix to get position in matlab?
I am trying to get the forward kinematics for a robot model in matlab (rigid body tree).
I created a 4 x4 transformation matrix from the base to the end-effector using the gettransform() function. I have 4 different joint angles to control. But how do I multiply the joint angles with the transformation matrix so that I get the correct orientation and position output of the end-effector?

Is there otherwise a better option to get the forward kinematics?

Thanks!

Body: transform = getTransform(robot,s,'L1','L4')


问:
Stepper motor connector identification
I'm trying to identify a connector on a stepper motor so I can purchase a replacement for the missing female connector. Just to be clear, I'm not asking where to buy the part (since I can probably find it once I identify it, but I wouldn't throw away a link if given one), I just need to figure out what kind of connector it is, at the moment. (I wouldn't mind a wiring diagram, but I'm sure I can figure that out by looking at how the other motor connectors are wired and by applying a multimeter to the motor itself.)

The motor is off a Light Machines Corporation SpectraLight small vertical mill. It's probably 20+ years old. These mini-machines were often used in classrooms, which is where this one was used. I got it cheap and am doing some basic repairs and moderate upgrades.

The User's Manual isn't any help. Here's an eBay listing for a similar machine/model, if it helps you.

I can find information about 4, 5, 6, and 8 pin stepper motors, but not 7 pin steppers.

This is a different angle of the same motor, just the protective sticker is still on the back of it.

This looks like a fairly standard NEMA 23 sized motor. I could just replace the motor, but I don't want to spend much more money on the machine right now, and I'd rather use the presumably working motor I already have. Most of my repairs and even upgrades are with parts I already own.

Here's a pic of the only identifying marks/numbers on the motor. I've removed another motor and the handwritten number is 16 and instead of T3995 26, it says T3995 24. The whole body is the same textured black enamel paint you see in the other pics.

I've searched for T3995 stepper motors, but evidently that's a fairly common designation with AC and DC motors as well as stepper motors. There's just too many options to sort through without some more specific search term.

I'm posting here because other Stacks don't seem to allow parts identifying questions, and a CNC machine is technically a robot. Plus I figure people who could recognize a stepper motor by sight would be here.

The dimensions of the connector are 9.2mm deep, 24.4mm wide, 8.5mm tall, and the sidewall is 1.8mm thick, with the pins at a standard 2.54 mm spacing. There are labels A-H for the pins on the plastic. One long edge of the plastic has 2 perpendicular slits in it to presumably act as a key and a catch.

Here are some close ups.

Here are some pics of the connectors I have.

In case you are unable to make out the markings, it says "Pull Here" and "1-87175-7".

答:
As it turns out, this isn't what I would call an "off the shelf" part, but rather a hodgepodge of 2 off-the-shelf parts.

With the number "1-87175-7", I was able to find the standard 8 pin connector, sans pin plug, that's currently used on my machine. There's also a boot around the plug, making it look more like a custom-built plug.

Example: https://www.digikey.com/en/products/detail/te-connectivity-amp-connectors/1-87175-7/291456

The 2 slits perpendicular to each other on one side made me think there was a keyed clip on the connector to make sure it didn't fall off and was always attached the correct direction. Maybe there still is a connector like this around, but I can use a 2.54mm 8 pin connector for now.

Title: Stepper motor connector identification


问:
Is it possible to achieve fully autonomous route following using PX4FMU module?
I have a quadcopter equipped with PX4FMU board. You may download its datasheet from HERE.
I wonder whether it is possible to program the quadcopter to autonomously follow a path like circular motion without any human interference. Are the built-in sensors enough for this task?
I also wonder how accurate the built-in GPS is? I read that it gives coordinates with a radius of 5m as error.</p>

答:
I think the answer depends upon the degree of autonomy you require. If, by "fully autonomous route", you mean just the ability to "autonomously follow a path like circular motion without any human interference"... then yes, that kind of function has been built into quadcopters with even less processing power and with almost identical sensor suite. But if your definition of autonomous route following widens, it is hard to say. </p>

<p>Btw... most GPS typically have an error radius of +/- 5m. </p>

Body:
I think the answer depends upon the degree of autonomy you require. If, by "fully autonomous route", you mean just the ability to "autonomously follow a path like circular motion without any human interference"... then yes, that kind of function has been built into quadcopters with even less processing power and with almost identical sensor suite. But if your definition of autonomous route following widens, it is hard to say.

Btw... most GPS typically have an error radius of +/- 5m.


问:
Why are Euler angles used for drones
I know this question is asked before, but the reason why was still not clear to me.

If you've a 6-DOF IMU, the gyroscope measures is degrees/s or radian/s.

Why do we want to convert the body rates to Euler rates. If you could measure the gyroscope angle by multiply it by dt. Than the starting point is the reference for the object. So this calculates the angle with respect to the body frame with a reference to the starting point. Why bother using the Euler rates?

I know Euler angles describe the orientation of an object with respect to a fixed coordinate system, the problems that Eulers angles has like gimbal lock and how to solve those with quaternions. But what are the advantages/ difference of using Euler angles and why instead of multiply the output of the gyroscope by elapsed time (dt).

Theoretically the drone would be able to fly in both cases.

答:
You can read about how a MEMS gyroscope works here, but the key concept I'd like to point out is that a gyroscope measures angular rate.

It's not measuring an angle and dividing that by some sample time, it's actually measuring the angular speed.

You can try to get more information about the drone by using a gyroscope for each of the three axes of motion, which then gives you your Euler rates.

You can integrate those Euler rates to get Euler angles. It's not that people use Euler angles because they're a good representation for orientation, but because they're "easy" (at-a-glance).

Title: Why are Euler angles used for drones


问:
Training Multiple Robots for different tasks at the same time using Deep Reinforcement Learning
I'm wondering if a single agent can train multiple robots to perform different tasks simultaneously. If possible, can you please recommend me some research papers and implementations that I can take a look at?

I was hoping we could create two gym environments like env1 = gym.make("robot1-task1") and env2 = gym.make("robot2-task2") then use a single agent to sample experience from both environments at the same time and generalize for both tasks.

答:
Maybe.

Assuming what you are looking for here is some sort of actor-critic deep reinforcement learning setup, this will be tricky. I will try to list out the pitfalls I see, and maybe that will help you decide if this is worth it or not.

$\textit{Deep networks are smooth functions}$. This means that if two inputs $x_1$ and $x_2$ satisfy $|x_1 - x_2| \le \epsilon$ for some $\epsilon$, then $|f(x_1) - f(x_2)| \le \delta$ for some $\delta$, where $f(\cdot)$ is the output of your neural network. Let's frame this in terms of your actor network - the same argument would apply for a critic, but it's a bit more complicated yet does not add much to the discussion. So, you learn some policy $\pi(s)$, where $s$ is your current state. Assuming both robots have the same structure or at least the same number of actuators (we'll get into this later), the stated goal would be to produce two distinct (not necessarily different) sequence of activations. This is where things get hairy. Let's assume robot one is in state $s_1$ and robot two is in state $s_2$ and $s_1 \approx s_2$. It is reasonable to assume that robot one might maximize rewards by moving "left" and robot two by moving "right", thus one or both of the robots will clearly make an un-optimal move as the neural network activation will be very similar for the two states. Now if the two states are the same, we end up in an even worse case where, theoretically (chaos saves us here), both robots will have identical trajectories no matter what. How do we avoid this problem? You could perhaps add an additional state parameter to indicate which robot you are working with - in essence creating two distinct subspaces in your input space allowing your network to "decide" actions based on which task is being performed. This will likely require a large network though, and would probably still be hard to actually have the two robots perform distinct tasks. To frame the problem mathematically, you're essentially trying to learn something like a homotopy between two functions - which you are also trying to learn.

$\textit{Different tasks presumably have very different reward functions}$. Just to touch on issues with the critic network, the smooth nature of neural networks is even more detrimental here. It is reasonable to imagine the topology of different desired actuator activations are similar for different tasks. Take for example a torque activation of two similar robotic manipulators. The act of accounting for gravity for both manipulators is going to require similar torques given their similar structure. However, the rewards of different tasks are arbitrarily complicated and may or may not explicitly rely on manipulator structure (i.e. joint control vs. cartesian control). Thus learning the "homotopy" between the two reward functions will likely require even more neurons than the actor network did - with less guarantee of really being possible.

$\textit{The structure of your robots will need to be almost identical}$. This is basically a continuation of the previous two arguments. To learn separate tasks for the same manipulator via one set of networks $\textit{might}$ be possible. Learning these tasks with one distinct structure per task would likely require so many additional neurons that it would be hard to imagine a good reason for using this approach would exist.

My personal opinion on the matter would be to use a different set of networks for each task. If your wanting to switch between the two tasks for the same robot - develop a deterministic control sequence (i.e. hard-coded) way to do so. I guess you could even try to make a third RL structure to learn when to switch between the tasks if you wanted to. If you are concerned about training times and/or parallelism, I would say you probably won't lose much performance using two different network structures sequentially vs. one much, much larger network that still requires both environments to be run sequentially.


问:
Include information on the environment in map-aware particle filter
I have a robot equipped with some sensors for estimating the movement in a 2D environment (IMU, odometer). The robot is free to move within an area delimited by some walls. The map of the environment (i.e. the polygon given by the walls position) is known. The environment is represented by a 2D grid and a reference mask $M_{ref}$ is computed such that the mask is equal to 1 inside the polygon and 0 outside. The starting position of the robot is not known.

I am implementing a (kind of) particle filter to estimate the robot position given the reference mask. First, a mask $M$ is initialized equal to $M_{ref}$. This mask represents the probability for the mower to be in a certain cell. When the robot moves, the sensors estimate the translation, $dx$ and $dy$, and the intersection between $M_{ref}$ and the translated version of $M$ is computed. The intersection is then assigned to $M$ and the rest of the mask is set to 0. After some movements, the intersection shrinks around the real position.

Now, suppose that other elements of the environment are known, such as slopes, landmarks and so on, and the robot is able to detect them. This could greatly help but I don't know how to integrate this information in my method. Are there similar solution in the literature?

答:
Answer

Create a new "probability grid" for each sensing modality and combine them after you have estimated the position of the robot in each of the many different grids.

In short, you have a mask for "Where I am now that I've moved" already, and now need to create a separate one for "where I am given I measured a slope of X", and one for "where I am given I measured I am 10 feet from landmark L" and so on. Yes, one mask for each landmark is fine.

Each grid represents a discretized probability map of p(robot_position| that_sensor). To combine and get p(robot_position| that_sensor & some_other_sensor & etc), you can multiply all masks (cells) together, and normalize back so that the sum of all cells is equal to one. Be careful of very small probability values that will be essentially zero.

This is not a particle filter, mind you. It is a simple probability grid, but is a perfectly reasonable thing to do for bounded environments.

Bonus comment

Having said that, examining your setup, you say that the intersection of the robot positions shrinks down to be centered at the real position. I am suspicious if you are only using IMU / motion data. As time goes on and the robot moves, it should in fact eventually become a "uniform" probability, that is you'll see the same probability in each cell of the discretzied polygon. Simply translating the "most likely cell" to the new mask is incorrect, you need to "spread out" the probability by sampling many different possible motions given what the IMU says you did. How to do this is well covered by books like Probabilistic Robotics, or any particle filter tutorial.

To avoid this, you need some global information. Slope, landmarks, etc can help.


问:
Robot moving sideways in RVIZ ROS

Hi,

I have a wheeled-legged robot as you can see in the picture. When I simulate it in ROS-Gazebo it works fine, however at the same time in Rviz it moves sideways instead of forward or backwards. I have no idea why it is behaving like this. Would greatly appreciate if someone can give me some clue here.

答:
So I have the same problem, only I have mistakenly taken the front side of the robot as the back side ;( So now front side of my robot faces -y axis.

I have the base_footprint joint origin yaw as +90 degrees, so front of my robot now faces +x axis. In addition I switched right and left wheels convention (since it is a diff drive robot), so used to be left wheels are now right and vice versa. Also the wheels' joint axis needed to be the negative sign, so that forward command actually drives the robot forward.

My related question is that could having this set up create problems later when navigation stack etc etc are included for navigating my robot?

Title: Robot moving sideways in RVIZ ROS


问:
How to move the robot using Raspberry Pi?
I used a Raspberry Pi 3 model B and a camera to make a robot detect fire, after watching Train a custom object detection model using your data.

However I am not sure how to make this robot move after it detects fire. The L298N motor driver (DC motors are connected to this motor driver) and a Logitech camera of this robot are connected to the Raspberry Pi of this robot. I know that it maybe better to use fire sensors to detect fire, however for my project I decided to use a camera.

My last lines of code in the Raspberry Pi terminal are (these are same as the lines of code at about 10:41 in the YouTube link above except instead of using android.tflite, fire.tflite is used):

```<code>source tflite/bin/activate
cd examples/lite/examples/object_detection/raspberry_pi/
cp ~/Downloads/fire.tflite .
python detect.py --model fire.tflite
</code>```

So is there a way to make the robot move using raspberry pi each time it detects fire?

The following is a more detailed description of the problem (Note if non of the links below work remove the full stop at the end of the link and try again):

Hardware setup

The pin configuration of the Raspberry Pi (RPi) 3 model B is at Raspberry Pi Pinout Diagram | Circuit Notes

The IN3, IN4 and ENB pins of the L298N motor driver is connected to GPIO 17, GPIO 27 and GPIO 22 respectively of the RPi model B. The OUT 3 and OUT 4 pins of the L298N motor driver is connected to a DC motor. A male to female jumper wire is connected to the ground pin of the L298N motor driver and to the ground at the GPIO header 6 at Raspberry Pi Pinout Diagram | Circuit Notes. A male to male jumper wire is also connected to the ground pin of the L298N motor driver and to the ground of a 11.1V battery. A male to male jumper wire is connected to the +12V pin of the L298N motor driver and to the other pin of the 11.1V battery.  The display connector of the RPi is connected to a mini display.

Software setup

I took about 70 images of fire to be used as training data. Then I took about 10 images of fire to used as validation data. Then I annotated the fire in each of the images of the training data and validation data using the LabelImg (or labelimg) software. Then I went to the following Google Colab (GC) link on Raspberry Pi: Train a custom object detection model with TensorFlow Lite Model Maker This link was in the video description at Train a custom object detection model using your data.

In the GC link above I logged in, then selected “runtime”, then selected “change runtime type”, then selected “GPU” as the “Hardware accelerator” and then selected “Save”. Then I uploaded my previously annotated images of training data and validation data in a zip folder called “fire_detectororigpics5.zip” to GC by using the upload option on the left side of GC. Within this zip folder there is a folder named “fire_detectororigpics5” then within this “fire_detectororigpics5” folder there are two folders one folder named “train” which contains the training data and another folder named “validate” which contains the validation data. Then I selected connect in GC which is that same as about 5:22 in the youtube link (YL) above. Then in GC under “Preparation” I selected the play button which is the same as about 5:30 it the YL above. Then in GC under “Import the required packages” I selected the play button which is the same as about 5:38 it the YL above. Next under the “We start with downloading the dataset” in GC I remove the following code:

!wget https://storage.googleapis.com/download.tensorflow.org/data/android_figurine.zip
!unzip -q android_figurine.zip
```
<p>Which is shown at about 5:56 in the YL above and replaced this code with</p>
```!unzip -q fire_detectororigpics5.zip
```
<p>Then I selected the play button to the left of this <code>!unzip -q fire_detectororigpics5.zip</code> code</p>
<p>Then under the “Train the object detection model” at GC I replace</p>
```train_data = object_detector.DataLoader.from_pascal_voc(
    'android_figurine/train',
    'android_figurine/train',
    ['android', 'pig_android']
)

val_data = object_detector.DataLoader.from_pascal_voc(
    'android_figurine/validate',
    'android_figurine/validate',
    ['android', 'pig_android']
)
```
<p>as shown at about 6:11 in the YL above, with</p>
```train_data = object_detector.DataLoader.from_pascal_voc(
    'fire_detectororigpics5/train',
    'fire_detectororigpics5/train',
    ['fire']
)

val_data = object_detector.DataLoader.from_pascal_voc(
    'fire_detectororigpics5/validate',
    'fire_detectororigpics5/validate',
    ['fire']
)
```
<p>Then I selected the play button to the left of this</p>
```train_data = object_detector.DataLoader.from_pascal_voc(
    'fire_detectororigpics5/train',
    'fire_detectororigpics5/train',
    ['fire']
)

val_data = object_detector.DataLoader.from_pascal_voc(
    'fire_detectororigpics5/validate',
    'fire_detectororigpics5/validate',
    ['fire']
)
```
<p>code. Then under the “Step 2: Select a model architecture” in GC, I pressed the play button to the left of <code>spec = model_spec.get('efficientdet_lite0')</code>
code which is the same as about 6:35 in the YL above.</p>
<p>Next under “Step 3: Train the TensorFlow model with the training data” in GC, I pressed the play button to the left of the following code:</p>
```model = object_detector.create(train_data, model_spec=spec, batch_size=4, train_whole_model=True, epochs=20, validation_data=val_data)
```
<p>which is the same as about 6:40 in the YL above. After this, under “Step 4” in GC, I selected the play button to the left of the following code</p>
```model.evaluate(val_data)
```
<p>which is the same as about 7:23 in the YL above.</p>
<p>Next under “Step 5” in GC, I replaced the code that is</p>
```model.export(export_dir='.', tflite_filename='android.tflite')
```
<p>which is the same code as shown about 8:04 in the YL above, with</p>
``` model.export(export_dir='.', tflite_filename='fire.tflite')
```
<p>Then I selected the play button to the left of this</p>
```model.export(export_dir='.', tflite_filename='fire.tflite')
```
<p>Then under “Step 6” in GC,  I replaced</p>
```!unzip -q fire_detectororigpics5.zip
```0
<p>which is the same as about 8:15 in the YL above, with</p>
```!unzip -q fire_detectororigpics5.zip
```1
<p>then I selected the play button to the left of</p>
```!unzip -q fire_detectororigpics5.zip
```2
<p>Next I selected the “Files” tab on the left of GC, then right clicked the document named “fire.tflite”, then selected “Download”.</p>
<p>Then I opened the Raspberry Pi terminal and entered the following code:</p>
```source tflite/bin/activate
cd examples/lite/examples/object_detection/raspberry_pi/
cp ~/Downloads/fire.tflite .
python detect.py --model fire.tflite
```

The preceding four lines of code opens the Logitech webcam connected to the Raspberry Pi and detects fire whenever fire is put in front of this camera

So is there a way to make the robot move using Raspberry Pi each time it detects fire?

答:
Your question is quite vague as we do not know what your setup is. But in general, if you want to make your robot move you will need a controller to decide where and how to move your robot.
This controller will receive some input from the camera (giving for example the location of the fire) and decide on an action (e.g., move towards the fire). Then you will have a lower level controller that will send a command to your driver to input x volts to motor1 and y volts to motor2.

If you are able to detect fire, all you have to do is send this info to a controller script that will decide whether to move or not. For this, as suggested in @chuck's answer, I also suggest using ROS to make scripts communicate.

One script will detect the fire, and send a signal that it detected fire. Another script will receive this message and decide whether and where to move based on this info, and send a message to another script telling it where to move. This last script will control the position (for example) of your robot and enable IN3, IN4 or ENB depending on how you need to move.


答:
Right now you're running detect.py. You need to have a script that calls that instead and manages the communication between detect.py and a hypothetical move.py. Then, instead of

```<code>python detect.py --model fire.tflite
</code>```

you would call

```<code>python detect_and_move.py --model fire.tflite
</code>```

Then your detect_and_move.py script forwards the model value to the detect script, gets a callback from the move script, and passes that callback to the detect script.

Then, in some hypothetical OnFireDetected method in your detect script, you would call the Move() callback, which invokes the move method in the move.py script.

Title: How to move the robot using Raspberry Pi?

Body:
I used a Raspberry Pi 3 model B and a camera to make a robot detect fire, after watching Train a custom object detection model using your data.

However I am not sure how to make this robot move after it detects fire. The L298N motor driver (DC motors are connected to this motor driver) and a Logitech camera of this robot are connected to the Raspberry Pi of this robot. I know that it maybe better to use fire sensors to detect fire, however for my project I decided to use a camera.

My last lines of code in the Raspberry Pi terminal are (these are same as the lines of code at about 10:41 in the YouTube link above except instead of using android.tflite, fire.tflite is used):

```<code>source tflite/bin/activate
cd examples/lite/examples/object_detection/raspberry_pi/
cp ~/Downloads/fire.tflite .
python detect.py --model fire.tflite
</code>```

So is there a way to make the robot move using raspberry pi each time it detects fire?

The following is a more detailed description of the problem (Note if non of the links below work remove the full stop at the end of the link and try again):

Hardware setup

The pin configuration of the Raspberry Pi (RPi) 3 model B is at Raspberry Pi Pinout Diagram | Circuit Notes

The IN3, IN4 and ENB pins of the L298N motor driver is connected to GPIO 17, GPIO 27 and GPIO 22 respectively of the RPi model B. The OUT 3 and OUT 4 pins of the L298N motor driver is connected to a DC motor. A male to female jumper wire is connected to the ground pin of the L298N motor driver and to the ground at the GPIO header 6 at Raspberry Pi Pinout Diagram | Circuit Notes. A male to male jumper wire is also connected to the ground pin of the L298N motor driver and to the ground of a 11.1V battery. A male to male jumper wire is connected to the +12V pin of the L298N motor driver and to the other pin of the 11.1V battery.  The display connector of the RPi is connected to a mini display.

Software setup

I took about 70 images of fire to be used as training data. Then I took about 10 images of fire to used as validation data. Then I annotated the fire in each of the images of the training data and validation data using the LabelImg (or labelimg) software. Then I went to the following Google Colab (GC) link on Raspberry Pi: Train a custom object detection model with TensorFlow Lite Model Maker This link was in the video description at Train a custom object detection model using your data.

In the GC link above I logged in, then selected “runtime”, then selected “change runtime type”, then selected “GPU” as the “Hardware accelerator” and then selected “Save”. Then I uploaded my previously annotated images of training data and validation data in a zip folder called “fire_detectororigpics5.zip” to GC by using the upload option on the left side of GC. Within this zip folder there is a folder named “fire_detectororigpics5” then within this “fire_detectororigpics5” folder there are two folders one folder named “train” which contains the training data and another folder named “validate” which contains the validation data. Then I selected connect in GC which is that same as about 5:22 in the youtube link (YL) above. Then in GC under “Preparation” I selected the play button which is the same as about 5:30 it the YL above. Then in GC under “Import the required packages” I selected the play button which is the same as about 5:38 it the YL above. Next under the “We start with downloading the dataset” in GC I remove the following code:

!wget https://storage.googleapis.com/download.tensorflow.org/data/android_figurine.zip
!unzip -q android_figurine.zip
```
<p>Which is shown at about 5:56 in the YL above and replaced this code with</p>
```!unzip -q fire_detectororigpics5.zip
```
<p>Then I selected the play button to the left of this <code>!unzip -q fire_detectororigpics5.zip</code> code</p>
<p>Then under the “Train the object detection model” at GC I replace</p>
```train_data = object_detector.DataLoader.from_pascal_voc(
    'android_figurine/train',
    'android_figurine/train',
    ['android', 'pig_android']
)

val_data = object_detector.DataLoader.from_pascal_voc(
    'android_figurine/validate',
    'android_figurine/validate',
    ['android', 'pig_android']
)
```
<p>as shown at about 6:11 in the YL above, with</p>
```train_data = object_detector.DataLoader.from_pascal_voc(
    'fire_detectororigpics5/train',
    'fire_detectororigpics5/train',
    ['fire']
)

val_data = object_detector.DataLoader.from_pascal_voc(
    'fire_detectororigpics5/validate',
    'fire_detectororigpics5/validate',
    ['fire']
)
```
<p>Then I selected the play button to the left of this</p>
```train_data = object_detector.DataLoader.from_pascal_voc(
    'fire_detectororigpics5/train',
    'fire_detectororigpics5/train',
    ['fire']
)

val_data = object_detector.DataLoader.from_pascal_voc(
    'fire_detectororigpics5/validate',
    'fire_detectororigpics5/validate',
    ['fire']
)
```
<p>code. Then under the “Step 2: Select a model architecture” in GC, I pressed the play button to the left of <code>spec = model_spec.get('efficientdet_lite0')</code>
code which is the same as about 6:35 in the YL above.</p>
<p>Next under “Step 3: Train the TensorFlow model with the training data” in GC, I pressed the play button to the left of the following code:</p>
```model = object_detector.create(train_data, model_spec=spec, batch_size=4, train_whole_model=True, epochs=20, validation_data=val_data)
```
<p>which is the same as about 6:40 in the YL above. After this, under “Step 4” in GC, I selected the play button to the left of the following code</p>
```model.evaluate(val_data)
```
<p>which is the same as about 7:23 in the YL above.</p>
<p>Next under “Step 5” in GC, I replaced the code that is</p>
```model.export(export_dir='.', tflite_filename='android.tflite')
```
<p>which is the same code as shown about 8:04 in the YL above, with</p>
``` model.export(export_dir='.', tflite_filename='fire.tflite')
```
<p>Then I selected the play button to the left of this</p>
```model.export(export_dir='.', tflite_filename='fire.tflite')
```
<p>Then under “Step 6” in GC,  I replaced</p>
```!unzip -q fire_detectororigpics5.zip
```0
<p>which is the same as about 8:15 in the YL above, with</p>
```!unzip -q fire_detectororigpics5.zip
```1
<p>then I selected the play button to the left of</p>
```!unzip -q fire_detectororigpics5.zip
```2
<p>Next I selected the “Files” tab on the left of GC, then right clicked the document named “fire.tflite”, then selected “Download”.</p>
<p>Then I opened the Raspberry Pi terminal and entered the following code:</p>
```source tflite/bin/activate
cd examples/lite/examples/object_detection/raspberry_pi/
cp ~/Downloads/fire.tflite .
python detect.py --model fire.tflite
```

The preceding four lines of code opens the Logitech webcam connected to the Raspberry Pi and detects fire whenever fire is put in front of this camera

So is there a way to make the robot move using Raspberry Pi each time it detects fire?

Body:
Right now you're running detect.py. You need to have a script that calls that instead and manages the communication between detect.py and a hypothetical move.py. Then, instead of

python detect.py --model fire.tflite

you would call

python detect_and_move.py --model fire.tflite

Then your detect_and_move.py script forwards the model value to the detect script, gets a callback from the move script, and passes that callback to the detect script.

Then, in some hypothetical OnFireDetected method in your detect script, you would call the Move() callback, which invokes the move method in the move.py script.


问:
Solving inverse kinematics with non-linear optimization libraries
Is it a good idea to solve inverse kinematics with non-linear optimization libraries such as Ceres?

I've seen examples of Ceres being used to solve IK and it provides elegant, concise solution.

But my concerns are:

IK problem is highly non-linear by its nature and solver may get stuck in local minima easily.

How can we represent the obstacles in optimization problem?

Can it be used to plan a joint trajectory?

答:
Is it a good idea to solve inverse kinematics with non-linear optimization libraries such as Ceres?

Yes, definitely!
The trend in literature during the last years is to walk away from the traditional Jacobian-based methods and adopt optimization techniques, instead, as they have become really powerful and very quick so that they can be implemented in real-time.

Check out the following resources too:

Solving Inverse Kinematics with Non-Linear Least Squares

How to apply Inverse Kinematics with angle constrained servos?

Ceres is very good but implements an unconstrained optimization approach. Other tools like Ipopt, KNITRO, TRACK-IK do implement constrained nonlinear optimization, which turn out to be particularly useful when dealing with obstacles.

IK problem is highly non-linear by its nature and solver may get stuck in local minima easily.

True, but this holds for whatever method you aim to employ. Anyway, the optimization tools I mentioned above are very sophisticated and apply lots of internal techniques to mitigate the problem of local minima. Also, adding up further obstacles and/or secondary tasks helps quite a lot to prevent the solver from getting trapped locally.

How can we represent the obstacles in optimization problem?

Obstacles can be easily represented in form of nonlinear functions $g(\cdot)$ (constraints) along with minimum and maximum bounds, which you can add to the problem at hand: these tools can natively handle such constraints. Obstacles can be equivalently described either in the joint space (JS) or in the operational space (OS):

$$
min_{JS} < g_{JS} \left( \mathbf{q} \right) < max_{JS} \\
min_{OS} < g_{OS} \left( \mathbf{x} \right) < max_{OS}
$$

Can it be used to plan a joint trajectory?

Sure, as long as you can describe your objective in terms of an optimization problem. For example, the trajectory may be encoded resorting to some coefficients. These coefficients can be thought of as the set of the independent variables of the optimization problem whose cost and constraints may be expressed as a collection of properties (e.g., starting and ending points, smoothness, covered distance...).


答:
There is everything on that board that you'd need for basic autonomous flight:

A gyro (MPU6000) + an accelerometer (L3GD20) + a compass/magnetometer (HMC5883L) to measure your roll, pitch and yaw angles and a barometric pressure sensor (MS5611) to measure the altitude.

There is no GPS sensor though - Only the connector to use easily add one. You're right though, GPS will only give you 5/10 meter resolution (but that's not due to the sensor being in accurate, but rather the technique/method itself - Don't forget that it's using satellite in space (!) to do that measurement, so it's pretty good really!)

What that means is that GPS is only good for large scale flight path. Achieving  autonomous motion like this is a lot more difficult of course (in the video, they are "cheating", as they have cameras up in the ceiling watching down and tracking exactly where the quad is located).

The board comes will lots of other goodies such as a buzzer, GPIO ports... but if you don't care about these, you're probably better off getting each sensors separately.

Title: Is it possible to achieve fully autonomous route following using PX4FMU module?

Body:
I have a quadcopter equipped with PX4FMU board. You may download its datasheet from HERE.
I wonder whether it is possible to program the quadcopter to autonomously follow a path like circular motion without any human interference. Are the built-in sensors enough for this task?
I also wonder how accurate the built-in GPS is? I read that it gives coordinates with a radius of 5m as error.</p>


问:
How to make gmapping dynamic, or advise any other methods to create mapping of a dynamic environment
it is a general question.

Gmapping seems to be used only for creating a map of the static environment. Once created, it doesn't account for any changes - you add a new object, but it's being ignored and not reflected in the map.

Is there any way to modify gmapping so it can be used for changing environments? What other methods can be used in this case?

I don't care about localization, only need mapping of the dynamically changing environment.

Any thoughts or comments are very welcome!

答:
The concept that you're looking for is lifelong mapping. It's an active area of research and there are experimental versions in newer SLAM implementations such as slam_toolbox.

gmapping's implementation will need a significant update to consider supporting these more recent developments as it was not designed with this feature in mind.


问:
Dynamic mapping without localization in ROS
I have a /scan topic coming from a 2D lidar scanner.

The task is to receive a mapping of the dynamic environment. It is assumed that the position of the scanner is always known, so localization is not required. Another simplification is that the scanner only moves along the straight line. The laser is suspended and moves to scan the surface under it in 2D plane, then the 2D plane is converted to 1D array of object heights.

I successfully used SLAM packages like gmapping and slam_toolbox to receive /map topic. But the functionality they provide appears to be superfluous for this application. In fact, the main problem it solves to localize robot and build a map is absolutely redundant in this application. Plus, gmapping provides a static map, and slam_toolbox life-long mapping is in experimental stage. Another solution was to create a map from point cloud of the raw scan, but I don't want to reinvent the wheel and deal with potential complications like noise, etc.

I'm looking for any ideas for algorithms, or ready to go packages. The final result should be a 2D array or /map topic (if there is an implementation in ROS).

Any ideas, concepts or references are very welcome!

答:
It sounds like you are just looking to aggregate the laser scans into point clouds and then run your analysis on that. There are tools   such as laser_assembler that do this exact sort of thing.

You have tagged this for ROS 2 so you may need to port it forward. I'm sure the maintainers would appreciate some help.


问:
How can I control a fast (200Hz) realtime system with a slow (30Hz) system?
We are currently designing a mobile robot + mounted arm with multiple controlled degrees of freedom and sensors.

I am considering an architecture in two parts:

A set of realtime controllers (either Raspeberry Pis running an RTOS such as Xenomai or bare metal microcontrollers) to control the arm motors and encoders.  Let us call these machines RTx, with x=1,2,3… depending on the number of microcontrollers.  This control loop will run at 200Hz.

A powerful vanilla linux machine running ROS to compute SLAM, mocap, and execute high-level logic (decide the robot’s task and compute the motors' desired position and speed).  This control loop will run at 30Hz.

I know my framework needs to be scalable to account for more motors, more sensors, more PCs (eg. for external mocap).

My main problem is to decide how to have the different RTx communicate with PC1. I have looked at papers related to robots architecture (e.g. HRP2), most often they describe the high level control architecture but I have yet to find information on how to have the low level communicate with the high level and in a scalable way. Did I miss something?

In order to connect the fast RT machines ensuring the motor control with PC1, I have considered TCP/IP, CAN and UART:

TCP/IP: not deterministic but easy to put in place. Is non determinism a real issue (as it will only be used at at slow speed 30Hz anyways)?

CAN: slow, very reliable, targeted to cars ( have seen there are some exemples using CAN with robots but it looked exotic)

UART: if I had only had one RT machine for motor control I would have considered UART but I guess this port does not scale well with many RTx
Is TCP/IP really a no go because of its non-deterministic characteristics? It is so easy to use…

At the moment no solution really seems obvious to me. And as I can find no serious robot example using a specific reliable and scalable solution, I do not feel confident to make a choice.

Does anyone have a clear view on this point or literature to point to?  Are there typical or mainstream communication solutions used on robots?

答:
You seem to have 2 separate (but related) problems you are trying to solve at once. Let's break down your conundrum into smaller pieces:

How do I communicate commands from a slow system (30Hz) to a fast controller (200Hz), and how do I communicate data being received at 200Hz back to my 30Hz thinktank?

How do I control what is happening at 200Hz, when I can only tell the robot what to do at 30Hz?

Item 1 can be solved in hardware as your original question seems to point- you can queue up data at 200Hz and send the packet at 30Hz to your higher level system. You can do this with TCP/IP, or possibly CAN depending on how much data you want to send. Different hardware has different max data rates.  Adding an architecture level like ROS to act as communication bridge/arbiter as suggested in other posts may also help.

Item 2 is a control theory problem that can't be solved with hardware alone. The SLAM, position and speed determinations, and task determination that you want will need to be smarter since they send and receive information less often. You will probably want 2 control loops: 1 at 200Hz and 1 at 30Hz.

There's lots of other questions that cover feed-forward, feed-back, and PID control loops, but you specifically asked about scaleability- the way most giant systems scale is by layering control loops and logic so that the minimal necessary information goes across whatever hardware you end up with. For example, your top level controller might only give goal position points and an average goal speed to the lower level one, not change the speed 30 times a second.


问:
Best way to generate a configuration space for a 6 DOF robot
I'm currently working on a motion planner for a 6 DOF robot but I can't figure of a good method to generate a configuration space.

The most basic way would be to test every position possible if there is an obstacle, but it seems like a lot of calculus, especially with a lot of DOF

Is there an optimized method to achieve this ?

答:
A good start here might be the RRT algorithm (https://en.wikipedia.org/wiki/Rapidly-exploring_random_tree) or one of its many, many variations. Let's assume you're doing this in the configuration space (perhaps the motivation will become clear later on).

How the algorithm works (basically):

Start with some initial configuration $q_0$, goal configuration $q_d$, and some step size $\Delta$

Initialize an empty graph $G$

Pick some random configuration $q_r$

Create a new configuration $q_n$ such that $q_n = \frac{q_0 - q_r}{|q_0 - q_r|}*\Delta$

Check to see if $f(q_n)$, where $f(\cdot)$ is your forward kinematics function, results in a collision for any of your robot's links

Yes? Discard $q_n$

No? Keep $q_n$ and store the edge $(q_0, q_n)$ in $G$

Repeat this process using a random $q_i \in V(G)$, where $V(G)$ denotes the vertices of $G$, as the initial starting point and execute until a $q_n$ is found such that $|q_n - q_d| \le \Delta$ (or until some max number of iterations have concluded)

The solution given by the algorithm is then the shortest path from $q_0$ to $q_d$. More recent modifications to the algorithm do a much better job at being sample efficient as well. Furthermore, keep in mind that collisions will be easier to calculate if you have the actuator configuration already, as opposed to computing it via the inverse kinematics function. However, if the number of actuators your robot has is $\gg 6$, it could end up being more efficient to sample in the workspace and perform inverse kinematics as necessary.


问:
Sensor bridge runtime framework
I'm currently using LGSVL and trying to implement ROS and YOLO there. What does the sensor bridge runtime framework mean?</p>

答:
I am going to be a little indirect as it appears you are new to ROS and robotics (the unknown-unknowns paradigm).

You have not specified what sensor bridge you are talking about, so I am assuming you mean the ROS sensor bridge (and its associated packages).
Ros is simply a collection of C++ and python packages to connect sensors or computers together. In other words, ROS is just a glue framework to make things talk to each other that normally don't talk to each other. The sensor bridge is simply a metapackage that contains ROS messages for transporting data relating to sensors, like IMUs, lidars, stereocameras, etc.

If I had to guess, what you mean to do is take a camera input video stream from a ROS node, send the image to YOLO (inside of your ROS node or through another ROS node), and then take the resultant classification from YOLO and change the state of your simulation. ROS has the image_transport package to handle sending images between ROS nodes. This is as much as I can say with the minimal information provided as well as the broad nature of the question.

Title: Sensor bridge runtime framework


问:
Inverse kinematics for a 4 DOF arm
I am working with the openMANIPULATOR-X robotic arm and I am trying to implement inverse kinematics for it. I have found this article that talks about kinematic modelling:

https://pdfs.semanticscholar.org/56a0/9731772199fe77bcb0dbff3a69f1c623e0c7.pdf

But when I implemented it in matlab, theta_3 had a complex number indicating that it is not possible for the robotic arm which does not make sense. I understand how everything is derived in the paper but it seems I am missing something. Could anyone help me?

答:
There are smart ways of approaching this problem, and there are silly ways of approaching this problem.

One option of getting around Matlab imaginary joint values is to implement the code in python with regular floating point values and then import the package into matlab. That way, Python will throw errors when complex joint values are returned (rather than propagate complex values through the solver).

A more correct solution to your problem would be to implement datatype checking all throughout the solver. Each step of the Ik solver should check if you have imaginary values. Then, once you have found the imaginary value, you can figure out where the imaginary values are being generated. The most common problem in my experience comes from the use of inverse trig functions being given values outside of their domain. When I get imaginary values, I am passing a value of magnitude great than 1 into an inverse trigonometric functions like acos(). Matlab handles this problem by returning complex values, and that does not help in debugging. That is why I recommend moving to python (or better yet, C++). You might also be running into division by 0, but the most likely issue is that you are calling trig and inverse trig functions with improper inputs.

Title: Inverse kinematics for a 4 DOF arm


问:
slam_toolbox mapping is not life-long?
I've tested slam_toolbox producing life-long environment mapping, and not quite satisfied with the results.

Below you can see a fragment of the mapping. I used a 1x0.5m case to test the changing map of the environment. In the first iteration, I moved the lidar laser to the area where the 1m side of the case was facing the scanner. Then, moved the laser away from the scanner.

In the second iteration, I moved the case so that the laser will be facing the 0.5m side of the case. Then, the scanner was moved to the area. In this case, I was expecting that the old footprint would disappear and would be replaced with the 0.5m side of the case. But, as you can see in the pic below, it didn't happen?

Interesting enough, I came to conclusion that the new obstacles are being added to the map, but the old ones are not being removed?

I experimented with two slam_toolbox modes: online_async and lifelong. Both showed the same result.

Please share if you had similar experience. Am I missing something here?

The slam_toolbox repo clearly tells that the life-long mapping is intended, though it mentions that it's kind of experimental.

https://github.com/SteveMacenski/slam_toolbox - Slam Toolbox for lifelong mapping and localization in potentially massive maps with ROS

答:
They are removed, but it takes some data to do so. We store a set of hit vs misses for each cell in the grid. If you went over it and laser scans saw it in lets say 10 iterations, it would take at least 10 iterations to remove so that probabilistic speaking the ratio of hits to misses reaches back below a threshold that we should clear that particular cell.

Its not immediate, nor would you want it to be, or else the map quality would drop substantially due to minor delocalization creating repeating parallel walls / obstacles due to minor deviations.

I believe the ratio is 0.65, so you need to see hits/(misses + hits) to be lower than that for a given cell to be marked as free if previously marked as occupied.

Title: slam_toolbox mapping is not life-long?