问:
Gazebo throws "Segmentation fault" after installation from binaries
System info:

OS: Ubuntu 22.04.1 LTS

CPU: AMD Ryzen 7 4800H with Radeon Graphics

GPU: NVIDIA GeForce GTX 1650

NVIDIA driver: 520 (proprietary)

I just installed ROS2 Humble + Gazebo with sudo apt install ros-humble-desktop-full and then if I try to execute ign gazebo shapes.sdf line from official tutorial I get these errors:

```<code>Stack trace (most recent call last):
#31   Object "/lib/x86_64-linux-gnu/libruby-3.0.so.3.0", at 0x7ff8f29ab327, in
#30   Object "/lib/x86_64-linux-gnu/libruby-3.0.so.3.0", at 0x7ff8f2b4031c, in rb_vm_exec
#29   Object "/lib/x86_64-linux-gnu/libruby-3.0.so.3.0", at 0x7ff8f2b3aca6, in
#28   Object "/lib/x86_64-linux-gnu/libruby-3.0.so.3.0", at 0x7ff8f2b37fd5, in
#27   Object "/lib/x86_64-linux-gnu/libruby-3.0.so.3.0", at 0x7ff8f2b35c44, in
#26   Object "/lib/x86_64-linux-gnu/libruby-3.0.so.3.0", at 0x7ff8f2a81a2e, in
#25   Object "/lib/x86_64-linux-gnu/libruby-3.0.so.3.0", at 0x7ff8f29ac9bc, in rb_protect
#24   Object "/lib/x86_64-linux-gnu/libruby-3.0.so.3.0", at 0x7ff8f2b44c71, in rb_yield
#23   Object "/lib/x86_64-linux-gnu/libruby-3.0.so.3.0", at 0x7ff8f2b4031c, in rb_vm_exec
#22   Object "/lib/x86_64-linux-gnu/libruby-3.0.so.3.0", at 0x7ff8f2b3aca6, in
#21   Object "/lib/x86_64-linux-gnu/libruby-3.0.so.3.0", at 0x7ff8f2b37fd5, in
#20   Object "/lib/x86_64-linux-gnu/libruby-3.0.so.3.0", at 0x7ff8f2b35c44, in
#19   Object "/usr/lib/x86_64-linux-gnu/ruby/3.0.0/fiddle.so", at 0x7ff8ee11344b, in
#18   Object "/lib/x86_64-linux-gnu/libruby-3.0.so.3.0", at 0x7ff8f2b03098, in rb_nogvl
#17   Object "/usr/lib/x86_64-linux-gnu/ruby/3.0.0/fiddle.so", at 0x7ff8ee112d6b, in
#16   Object "/lib/x86_64-linux-gnu/libffi.so.8", at 0x7ff8ee0b7492, in
#15   Object "/lib/x86_64-linux-gnu/libffi.so.8", at 0x7ff8ee0bae2d, in
#14   Object "/usr/lib/x86_64-linux-gnu/libignition-gazebo6-ign.so.6.12.0", at 0x7ff8ed61986c, in runGui
#13   Object "/lib/x86_64-linux-gnu/libignition-gazebo6-gui.so.6", at 0x7ff8ed45e917, in ignition::gazebo::v6::gui::runGui(int&, char**, char const*, char const*, int, char const*)
#12   Object "/lib/x86_64-linux-gnu/libignition-gazebo6-gui.so.6", at 0x7ff8ed45c39c, in ignition::gazebo::v6::gui::createGui(int&, char**, char const*, char const*, bool, char const*, int, char const*)
#11   Object "/lib/x86_64-linux-gnu/libignition-gui6.so.6", at 0x7ff8ec1cb048, in ignition::gui::Application::Application(int&, char**, ignition::gui::WindowType)
#10   Object "/lib/x86_64-linux-gnu/libQt5Widgets.so.5", at 0x7ff8ebc4ecec, in QApplicationPrivate::init()
#9    Object "/lib/x86_64-linux-gnu/libQt5Gui.so.5", at 0x7ff8eab36b6f, in QGuiApplicationPrivate::init()
#8    Object "/lib/x86_64-linux-gnu/libQt5Core.so.5", at 0x7ff8ec4f0b16, in QCoreApplicationPrivate::init()
#7    Object "/lib/x86_64-linux-gnu/libQt5Gui.so.5", at 0x7ff8eab33c07, in QGuiApplicationPrivate::createEventDispatcher()
#6    Object "/lib/x86_64-linux-gnu/libQt5Gui.so.5", at 0x7ff8eab325ee, in QGuiApplicationPrivate::createPlatformIntegration()
#5    Object "/usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqxcb.so", at 0x7ff8ee0df522, in
#4    Object "/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5", at 0x7ff8e43cadaf, in QXcbIntegration::QXcbIntegration(QStringList const&, int&, char**)
#3    Object "/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5", at 0x7ff8e43c7722, in QXcbConnection::QXcbConnection(QXcbNativeInterface*, bool, unsigned int, char const*)
#2    Object "/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5", at 0x7ff8e43cdcab, in
#1    Object "/lib/x86_64-linux-gnu/libxkbcommon-x11.so.0", at 0x7ff8e41e18cd, in xkb_x11_keymap_new_from_device
#0    Object "/lib/x86_64-linux-gnu/libxkbcommon-x11.so.0", at 0x7ff8e41e108d, in
Segmentation fault (Address not mapped to object [0x21aa120b8])
</code>```

If I install Gazebo manually with latest docs, I get similar error on gz sim command.

答: The problem was with my terminal emulator (Alacritty) installed with snap. Using default terminal (or re-installation of Alacrity from source) fixed the problem.</p>


问:
Will there be any interference when distance sensors facing each other?
I'm working a robot racing project using small RC toy cars on a premade track and a main goal for the robots to do is to be able to avoid hitting the wall and the racing opponents. Avoiding wall is no biggie but the big one is that if they were to be close or side by side, their sensors would likely interfere one another. So... is there any sensor out there would fit the task? Would using infrared sensors with different wavelength on each robots be an okay solution?

Thanks in advance.

答:
The amount of interference highly depends on the sensor type and how you use them.

One of the worst for this is probably ultrasonic rangers:

These are going out of fashion now, but older robots used to have them all over the place.  Even if they are pointed in different directions, if they are close enough to each other they will cross-talk.  So they are usually only fired one at a time.

That brings me to my first point:  You might want to consider firing the sensor at some known rate, instead of a continuous fashion.  Then the odds of interference are lower.  (Pro-tip, use a slightly different rate for each robot)

Sharp IR distance sensors will probably also interfere.  But should have a narrower beam than ultrasonics.

But I can imagine that they are faster than ultrasonics, so if you can pulse them, the amount of time you need to keep them on is smaller.

A simple IR proximity sensor might work.

They will have a much shorter range than any of the other sensors.  I'm not sure of the scale of everything in your application.  They might only interfere if very close to each other.  But again, they can and probably should be pulsed.  I'm not sure you will be able to find IR emitters / detectors in significantly different wavelengths to avoid interference.  Although, you might be able to use some polarization film to polarize the light horizontally for one robot, and vertically for another robot.  But I've never tried this.

Your best bet is probably to use a time-of-flight sensor like the VL53L0X.

These can easily be pulsed, and should have a pretty narrow field of view.

Another great option is to use something like a laser range finder:

I'm not actually sure how much they will interfere.  But their vertical field of view should be very narrow.  So you can easily mount them at different heights on each robot.

OK, bottom line, these are all "active sensors".  Meaning they emit some light or sound and measure the return in some way.  There will always be some amount of interference with active sensors.  The way to handle this is to have a good model and estimate for what the sensor should normally return at that instant.  And if it is wildly off, then discard it.

To totally eliminate active sensors, then you are going to go for cameras.  Stereo pairs can give you depth information without interference between robots.

But be careful.  The latest trend is to use 3D depth sensors with active IR illumination.  For example this Intel RealSense:

I'm sure these will interfere if pointed at each other.  But it is probably worth reading the datasheet.

As you can see, there are a lot of sensing options.  Only you know what sensors and filtering schemes will work for your application.

ContentLicense: CC BY-SA 4.0


问:
Self localization for 3 wheeled omnidirectional robot
I am trying to self localize a 3 wheeled omni directional robots using just motor encoders
I followed the odometry method mentioned in equations 5,8,9 of https://bibliotecadigital.ipb.pt/bitstream/10198/1897/1/C2_002_Gon%C3%A7alves.pdf

But I cant seem to implement the equations in code, It'll be helpful if anyone help me out with the basic structure of the code or flowchart

答:
I agree that the paper's notation is a little confusing.  I think the confusing part is that they use $K$ for time-step number, and $T$ for delta time.  So equation (5) simply says: your new global angle $\theta$ (the angle at time $K$), equals your last angle (at time $K-1$) plus your angular velocity $w$ times the delta time $T$.

I think this how it should go:

```<code>loop()
{
    Current_Encoders = get_encoder_counts()
    Delta_Encoders = Current_Encoders - Last_Encoders
    Last_Encoders = Current_Encoders

    now = get_time()
    T = now - last_time
    last_time = now

    // time detla * encoder delta = instantaneous wheel velocities
    V_1, V_2, V_3 = T * Delta_Encoders

    // get instantaneous local velocities
    // Note: G is a constant matrix, so this can be turned into 3 equations
    V, V_n, w = G * (V_1, V_2, V_3)

    // get new global theta
    theta = theta + w * T

    // get global velocities
    V_x = V * cos(theta) - V_n * sin(theta)
    V_y = V * sin(theta) + V_n * cos(theta)

    // get new global positions
    x = x + V_x * T
    y = y + V_y * T
}
</code>```

Please pardon my pseudo-code shorthand.

And of course, all variables should be initialized to zero before the loop.  (except the time variables which you might want to initialize to the current time.  And the encoders which might need to be initialized to the encoder count if you have absolute instead of incremental encoders.)

Body:
I agree that the paper's notation is a little confusing.  I think the confusing part is that they use $K$ for time-step number, and $T$ for delta time.  So equation (5) simply says: your new global angle $\theta$ (the angle at time $K$), equals your last angle (at time $K-1$) plus your angular velocity $w$ times the delta time $T$.

I think this how it should go:

loop()
{
    Current_Encoders = get_encoder_counts()
    Delta_Encoders = Current_Encoders - Last_Encoders
    Last_Encoders = Current_Encoders

    now = get_time()
    T = now - last_time
    last_time = now

    // time detla * encoder delta = instantaneous wheel velocities
    V_1, V_2, V_3 = T * Delta_Encoders

    // get instantaneous local velocities
    // Note: G is a constant matrix, so this can be turned into 3 equations
    V, V_n, w = G * (V_1, V_2, V_3)

    // get new global theta
    theta = theta + w * T

    // get global velocities
    V_x = V * cos(theta) - V_n * sin(theta)
    V_y = V * sin(theta) + V_n * cos(theta)

    // get new global positions
    x = x + V_x * T
    y = y + V_y * T
}

Please pardon my pseudo-code shorthand.

And of course, all variables should be initialized to zero before the loop.  (except the time variables which you might want to initialize to the current time.  And the encoders which might need to be initialized to the encoder count if you have absolute instead of incremental encoders.)


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

答:
The Kinova Jaco arm has some joints on a 45 degree angle.

This arm is specifically designed to aid people with disabilities.  I believe they used these joints to eliminate pinch points wile still maintaining range of motion.

When I was designing a new humanoid arm I did a study on the best arrangement of joints, I looked at off-axis joints like this too.  I quickly found that they are not very good.  You get a lot more "bang for your buck" with orthogonal joints.  i.e. more range of motion and better manipulability workspace.


问:
LIDAR solutions
I am surprised by the price range of Lidar applications considering the simplicity of the design. I try to make a simple project that requires lidar for object recognitions etc. I wouldn't like to use Visual Recognition such as OpenCV.

Regardless of that I am trying to understand why Lidar solutions are so expensive you can see
that this
http://velodynelidar.com/lidar/hdlproducts/hdl32e.aspx
Small lidar sensor goes for 20,000$.

I strongly believe that Lidar is the next step in robotic applications but I am not sure why it is so EXCLUSIVE.

I have seen few projects that go for around 200$ but their performance is very bad.

I hope you can answer what makes a Lidar so expensive and what are some cheap systems a hobbyist can afford.

答:
LIDAR are expensive because it normally relies on Time-of-Flight of the light for measuring each point distance. They are simple in theory of working, in practice it requires a good design in electronics and the sensors.

I don't think LIDAR is the next step, but stereo vision could be. This is not related to OpenCV, and most optical vision system designers forget the basics that is a good camera with good optics. This is your source of information, if you have a bad one, you difficultly get good results. This means at least ~$200,00 for camera and lenses, with RAW protocol for images, and goes on.

ContentLicense: CC BY-SA 3.0

Title: LIDAR solutions


问:
Can MoveIT framework be used separately from ROS, i.e. "as a standalone library"?
As far as I understand, MoveIT can act as a IK/FK solver one can supply input into (i.e. end-effector xyz) and get an output (joint angle values).

I'd like to utilize this aspect of MoveIT (version 1) in a personal project without having to install and run the entire ROS middleware environment. Is there a way to use MoveIT and its C++/Python API as a separate, command-line app or a linked library? Similar to how OpenCV can be used outside ROS, i.e "import OpenCV"

答:
The entire ROS ecosystem is made up of CMake C++ (and Python) packages. These CMake packages are simply C++ libraries compiled via CMake. It sounds like what the question is asking for is can they create a CMake C++ library that does not depend on ros.h or rclcpp.hpp or a library that depends on these dependencies. This means that the message files must also not be used. I suggest going to the git repository (usually github hosts them) for the the ROS package and look for where there are references to ROS. Simply re-write the functions that use ROS messages and ROS transport mechanisms so that you don't need to use ROS.

Honestly, though, it is probably better if you learn to build ROS2 from source so that you learn from experience how all of these packages depend on each other, even if you don't need ROS. Why the hard requirement to not use ROS? ROS is simply a data transport layer that is tailored to the robotics hardware ecosystem. MoveIt has many dependencies and separating ROS from the libraries would not get you closer to solving your problem. I suggest creating a Dockerfile to build ROS2 from source starting from a Ubuntu 20.04 docker image.


问:
Doubt regarding publishing of robot in a journal or to be applicable for a presentation
i was just curious about publishing an abstract or stuff like that about a robot I've made all by myself .

Do i really need to make a working model of it or 3d solid works or cad will be enough ? .

I have good machining skills . I can do turning , boring, reaming and stuff on the milling as well to cut rectangular parts from blocks of metal , gears as well from the indexing head .

Do i really need to build the robot , if i want to present my robot in a journal or any conference?

. The work I'm primarily focussed on  a robot like making french fries from peeled potatoes , pulling curtains on sensing or not sensing enough sunlight is based on linkages , gear trains just like that in a gear box to amplify the motion obtained from a prime mover and so on .

My friends told me that only new inventions and stuff like ( finding an entire new species of birds from the jungle ). Get published in a journal . I have done the position , velocity and acceleration analysis of the linkage i would work upon. But whenever I want to discuss my application with my friends they start off by saying....( How would your mechanism replace the best , if not it's not worth getting published ) . Is that true as I've seen robots making french fries and curtain pulling robots before but they're really complex and cost a lot even for maintenance . But I'm sure that my robot and my linkages have not been used before ( almost) .

My final querry is maybe , if i can get my robot published if i dont invent the type of robot used in expensive factories ? how will my work be respected and accepted ?

答: How do you know for sure your robot is special without actually building it? Building the experiment in a repeatable fashion for other readers to replicate (or purchase) is part of the scientific process. If the point of the paper is to write a new Inverse Kinematics (IK) solver, you can demonstrate the kinematics in a simulator with minimal realism to prove the math works. If a robot is supposed to be cheaper to buy and maintain, the only way to prove that is by building and testing your new robot yourself and then presenting a methodology to replicate the construction and programming process (at a high level since you don't get many pages). There isn't enough contextual information to say any more other than it depends.


问:
Recommendations for a robot for scanning in a 2D plane
I'm new to robots and struggling to find information (buy) and sources on what we're looking for (or what we are trying to accomplish) for an idea (proof of concept) we want to test.  We really don't want to build this ourselves, but we aren't willing to spend a lot since it's a proof of concept.

What we were looking to accomplish is to have a robot hold a scanning probe in a specific orientation as it scans through a 2D plane in space (no touch). Low noise and vibration are solid requirements. Speed is less important. We would like something that has some reach, maybe 4ftx4ft but its a POC...

I think there are a couple of designs that could accomplish this. For example, two linear systems for a simple xy positioning. More advanced would be 2 axis arm using servos or a multi-axis arm.

Ideally, some simple software to control it (motion planning where the operator can specify the size to measure and the number of scans in each axis - e.g. 30" by 30" with 30 vertical and 10 horizontal passes.

Everything I've seen is production ready and expensive so we're wondering if anyone is aware of a simple cost-effective system that might allow trying a few things?

Thanks in advance!
PV

答:
TL;DR: Robots are expensive.

The bigger the robot, the more expensive to build and maintain. The 4x4ft build volume is large for a static robot. Bigger robots endure higher stresses and require better building materials. Better building materials require better tools. If I had to guess, you probably saw a commercial robot that fit your needs north of ~\$30K to ~\$40K for an industrial robot with a 4x4 foot reach. You aren't going to get around that. Your best bet is to build a simple Scara style robot using parts from your local hardware store and motors from 3d printers (nema 23 steppers might have enough torque for your requirements). You might be able to make something for around ~\$1-2K if you do your research and shop for the best bang for your buck. Then, there is the lidar sensor itself. A good, basic lidar with good accuracy and repeatability and longevity will cost you at a minimum around ~\$1-2K, so you are looking at a budget of around ~\$5K just to get a hacked together prototype, assuming there is a minimal cost surprise. This also assumes you already own the tools and have the time to embark on such a project (not to mention consumables involved in construction). If you are new to robotics, your best bet is to find somebody near you that has more knowledge in the field to show you what to do. I am purposefully glossing over some of the ways you can minimize cost with component swaps, but then you risk your robot failing because it was built poorly from the start. All your design decisions have tradeoffs.

There is a glimmer of hope though.
Some companies donate parts to educational institutions for student projects. I suggest you take advantage of this.


答:
Publishing about something in a journal is typically for new advances or for confirming/refuting other journal articles. If you've designed a better robot that just works better (nothing novel, just better optimized, etc.) then you typically sell those ideas. You're going to need to build it to prove it, though. Speculation is easy, but there are usually tons of practical challenges that get overlooked until it comes time to fabricate, assemble, and test. Once you've created the prototype French fry machine then you can take it to a restaurant, let them try it for some time, then offer to sell them one. Then you're in business.

If you think your idea has some optimization or other improvement that is not obvious but maybe also not a novel technique then you can try to patent that idea. You do not need a functioning device to file a patent, but patents are quite expensive for regular people to file, probably in the neighborhood of \$10,000 to \$25,000. You'll probably want to build the device just to prove to yourself that it works before you sink that money into the patent, but it's your money to spend how you see fit.

Title: Doubt regarding publishing of robot in a journal or to be applicable for a presentation

Body:
i was just curious about publishing an abstract or stuff like that about a robot I've made all by myself .

Do i really need to make a working model of it or 3d solid works or cad will be enough ? .

I have good machining skills . I can do turning , boring, reaming and stuff on the milling as well to cut rectangular parts from blocks of metal , gears as well from the indexing head .

Do i really need to build the robot , if i want to present my robot in a journal or any conference?

. The work I'm primarily focussed on  a robot like making french fries from peeled potatoes , pulling curtains on sensing or not sensing enough sunlight is based on linkages , gear trains just like that in a gear box to amplify the motion obtained from a prime mover and so on .

My friends told me that only new inventions and stuff like ( finding an entire new species of birds from the jungle ). Get published in a journal . I have done the position , velocity and acceleration analysis of the linkage i would work upon. But whenever I want to discuss my application with my friends they start off by saying....( How would your mechanism replace the best , if not it's not worth getting published ) . Is that true as I've seen robots making french fries and curtain pulling robots before but they're really complex and cost a lot even for maintenance . But I'm sure that my robot and my linkages have not been used before ( almost) .

My final querry is maybe , if i can get my robot published if i dont invent the type of robot used in expensive factories ? how will my work be respected and accepted ?


问:
Inverse Kinematics with SE(3) Target Derivation

Why are there square brackets around [V_b] when deriving it, but not when using it in the update?

答: The vertical pipes denote the magnitude. It looks like the magnitude of the velocity vector must be above a threshold value (epsilon) for the robot to be considered in motion. The square brackets denote vector/matrix. Then, in the equation denoted with 1., you are multiplying a matrix with a vector, so no brackets or pipes are necessary.


问:
ROS2 URDF: How to have multicolored things in URDF?
It seems that only the first material clause in a link is used for the whole link.

For example for a simple Minion Dave with blue overalls and yellow "body":

```<code> <!-- DAVE -->
  <link name="dave_link">
    <visual name="bottom_half_dave" >
      <origin xyz="0 0 0" rpy="0 0 0" />
      <geometry>
        <cylinder length="0.045" radius="0.0375" />
      </geometry>
      <material name="solid_blue" />
    </visual>

    <visual name="top_half_dave" >
      <origin xyz="0 0 0.045" rpy="0 0 0" />
      <geometry>
        <cylinder length="0.045" radius="0.0375" />
      </geometry>
      <material name="solid_yellow" />
    </visual>

    <visual name="head_dave" >
      <origin xyz="0 0 0.625" rpy="0 0 0" />
      <geometry>
        <sphere radius="0.0375" />
      </geometry>
      <material name="solid_yellow" />
    </visual>

  </link>

  <joint name="joint_dave" type="fixed">
    <parent link="base_link"/>
    <child link="dave_link"/>
    <origin xyz="-0.04 0 0.250" rpy="0 0 0" />
  </joint>
</code>```

Will always use the solid_blue of the bottom half for the other two visual objects in the dave_link.

Is there a way (other than making each part a separate link with joints)?

答:
Unfortunately, it looks like this is a bug that was reported in 2015 and is still unresolved. The URDF link documentation here says, in part:

Note: multiple instances of  tags can exist for the same link. The union of the geometry they define forms the visual representation of the link.

I don't know if the rviz bug is truly a bug or if it's supposed to be treating all visuals within a link as one fused object, but your options seem to be to either split out your colored components into their own links or make your own mesh and apply a texture.


问:
Generic name for two-motor wheeled/tracked robots?
Is there a generic name for the category of robots that move using two opposing wheels or tank-like treads?</p>

答: Robots with two opposing wheels and usually a castor wheel for balancing reasons (no motor attached) are called Differential Drive Robots.


问:
what exactly is 'observation model' for a robot
In my journey to understand the Kalman filter, I understood how a state model representation is derived for a robot and why(to get the robot state for a given input u)  it is required.

$$
\boldsymbol{x_t} = A_{t-1} \boldsymbol{x_{t-1}} + B_{t-1} \boldsymbol{u_{t-1}}
$$

But I didn't get the essence of the observation model(H), to my understanding, this represents the theoretical sensor behavior of a robot.But I didn't get how the observation model helps me as a layman. Does it give something if I give something to it?

why a sensor model is required?
Aren't the sensors(IMU, GPS..etc) have a standard model for each?
Observation model is for a sensor/ all sensors in the system(robot)?
How to derive H for a mobile robot with sensors imu,GPS,wheel odometry?

答:
An observation model is what relates your measurement to your states. For example, you might have a state that is vehicle speed, but the only thing you can measure is tire RPM. Tire RPM is not vehicle speed, but you could use information like wheel radius to calculate speed from tire RPM.

Similarly, you might not be able to directly measure the steering angle for the front wheels, but you could calculate it based on steering wheel angle, steering gearbox ratio, and steering knuckle geometry.

In practice, usually you're able to just measure the states directly, and your $H$ matrix winds up being a lot of ones.


问:
[Raspberry Pi]: ROS 2 Humble on Ubuntu 22.04 Server: v4l2_camera reports "Failed stream start: Invalid argument (22)"
I have ROS2 Humble installed on Ubuntu 22.04 Server (64-bit) on a Raspberry Pi4.

When I run the v4l2_camera node it finds my Pi Camera (v1.3) but then complains:

Failed stream start: Invalid argument (22)

```<code>$ ros2 run v4l2_camera v4l2_camera_node -ros-args --params-file /home/ubuntu/ros2ws/v4l2_camera_params.yaml
[INFO] [1667398998.222438071] [v4l2_camera]: Driver: unicam
[INFO] [1667398998.223092209] [v4l2_camera]: Version: 331580
[INFO] [1667398998.223198373] [v4l2_camera]: Device: unicam
[INFO] [1667398998.223268817] [v4l2_camera]: Location: platform:fe801000.csi
[INFO] [1667398998.223331871] [v4l2_camera]: Capabilities:
[INFO] [1667398998.223396278] [v4l2_camera]:   Read/write: YES
[INFO] [1667398998.223460721] [v4l2_camera]:   Streaming: YES
[INFO] [1667398998.223542720] [v4l2_camera]: Current pixel format: pgAA @ 2592x1944
[INFO] [1667398998.223637940] [v4l2_camera]: Available pixel formats:
[INFO] [1667398998.223709587] [v4l2_camera]: Available controls:
[INFO] [1667398998.225908478] [v4l2_camera]: Requesting format: 2592x1944 YUYV
[INFO] [1667398998.226086845] [v4l2_camera]: Success
[INFO] [1667398998.226256139] [v4l2_camera]: Requesting format: 640x480 YUYV
[INFO] [1667398998.226385618] [v4l2_camera]: Success
[INFO] [1667398998.226483839] [v4l2_camera]: Starting camera
[ERROR] [1667398998.245779840] [v4l2_camera]: Failed stream start: Invalid argument (22)
</code>```

This is my params file:

```<code>/**:
  ros__parameters:
    video_device: /dev/video0
    pixel_format: YUYV
    output_encoding: rgb8
    image_size: [640, 480]
    time_per_frame: [1, 30]
    camera_frame_id: camera_optical_frame
</code>```

I noticed that the startup does not list any "Available pixel formats" but do not know if that could be contributing.

How do I find out what is the "Invalid argument (22)" in the error message?

答:
Have you tried leaving off the parameters file? It looks to me like you're specifying the default values, but you're also specifying items I'm not seeing as available for selection, like time_per_frame and camera_frame_id. This is in a look at the README here. The Invalid Argument (22) is coming from cerrno, where error 22 is Invalid argument.

As far as determining which argument is bad, if using the defaults doesn't work for you then you would need to attach a debugger and watch what's being evaluated when the error is thrown.

Lastly, when I search for time_per_frame the only result I'm seeing is in the changelog, and that from August 6th of this year. I can't tell how it's processed or what the appropriate values should be, but it looks like a pretty recent change so if your project is out of date then you might be trying to use functionality that doesn't yet exist in your project.


问:
Why have EKF and PF slam algorithms been abandoned?
As far as I know all current 3d SLAM systems use pose graph optimization, both local and global. EKF and particle filter algorithms are not used or referenced at all as far as I can tell and the estimate of feature locations is deterministic at the output, not probabilistic.

Why is this? Is it purely because of computational constraints or is there another reason?

答:
Particle filters while not abandoned have become quite rare. Nowadays they are really only used to solve localization problems. The reason being that they are quite expensive (each particle essentially stores the entire state) so 50 particles would be 50 times as expensive as an EKF. Also its other two benefits

Being able to handle non gaussian noise distributions

Handling multi modal distributions

Just don't end up being so important in practice. At least not worth the additional computation cost.

EKF's ,however, nowadays are still used a bunch. Typically they are paired together with a pose graph optimization algorithm. Where the EKF part estimates the current pose(and usually some sort of sliding window of past poses), and those then get fed into backend of all past poses(this is almost always solved with factor graph/optimization based approaches).

An example of this is approach is OpenVINS when paired with ov_secondary.

You still have some papers that solve the whole SLAM problem local and global in one EKF framework such as https://arxiv.org/pdf/1903.08636.pdf.


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

答:
As one of the options, you could use a version of the formula from Cye Waldman that I have changed to constrain maximum velocity and acceleration:

$$f\left( t, p \right)=\frac{1}{2}\left[ 1+\text{sgn} (x)\,\frac{B\left( {1}/{2}\;,p+1,{t^2} \right)}{B\left( {1}/{2}\;,p+1 \right)} \right],$$

$$motionTime(robotVmax, robotAmax,motionRange)=\\
max\left[\frac{2\cdot3^{3/4}}{\sqrt{\pi}}\cdot\sqrt\frac{motionRange}{robotAmax},\frac{32}{5\pi}\cdot\frac{motionRange}{robotVmax}\right],$$

$$position(t,robotVmax,robotAmax,motionRange)=\\
motionRange\cdot f\left(\frac{2 t}{motionTime}-1,2.5\right),$$

where sgn(x) is Sign function, numerator and denominator s are the incomplete and complete beta functions, respectively, robotVmax is the maximum velocity, robotAmax is the maximum acceleration and motionRange is the absolute value of the motion (from start to end).

Here are 2 examples of motion planning with $motionRange=2$:

The advantage of this method is continuity in every derivative (including jerk) and very low values of jerk.

The disadvantage is the large motions will take longer time.

You can see more examples on the page of my python package s-curve-beta that implements this method:


答:
It depends on what you mean by "published".

Academic Paper

The two main robotics conferences are probably ICRA and RSS, but there are a lot of them.  And no, you don't have to physically have built a robot.  There are lots of theoretical papers, math papers, simulation papers, etc.  However, these are peer-reviewed academic journals.  So in order to get published, you typically need to show that your work builds upon the existing research.  Rarely, if ever, is there a paper along the lines of "look at this cool thing I made".

Maybe watch some of the talks from these conferences, and read some papers to see if this is the route you want to go down.

Patent

Obtaining a patent is considered "publishing" it.  Although the legal process for obtaining a patent is long and costly.  Although you never need to physically show the thing to the patent office, I believe one of the requirements of getting a patent is to "put it into practice".  i.e. The thing needs to be described in sufficient detail that someone else can build it.

Book / Website

Publishing your designs in a book or website is considered publishing.  But I'm not sure why you would want to go that route.  It doesn't have the same clout as an academic paper, and doesn't provide legal protections like a patent.

Other thoughts

What the "best" mechanism is is often a matter of opinion.  There are always tradeoffs between manufacturing costs, maintenance, speed, power, size, dependability, and the list goes on.  So there is likely a good reason the creators of the existing products used the things they did.

If you think you discovered a new type of linkage or mechanism, then that is certainly patent-able, and publishable.  But there are a lot of them out there.  Check out this book: Mechanisms and Mechanical devices Sourcebook by Neil Sclater


问:
Motion Model for Holonomic Robot
We are working with an holonomic robot equipped with three (120 degree shifted) omnidirectional wheels. The relative movement is estimated by dead reckoning using wheel encoders. To improve this estimation we installed an gyroscope to measure the change in orientation. Furthermore the robot has a 270 degree laser range finder.

In order to solve the kidnapped robot problem we implemented a particle filter. In every step each particle is updated according to the odometry and gyroscope readings. Since these readings are distorted by noise we need a motion model to include these errors. As described in Probabilistic Robotics by Thrun (Page 118 - 143) there are two commonly used motion models (velocity motion model and odometry motion model). However these models seem to describe the behavior of differential drive robots not omnidirectional robots. I base this thesis on the fact that the error in relative y-direction is proportional to the error in orientation as far as the motion models by Thrun are concerned. This is appropriate for differential drive robots as the orientation and the heading of the robot are identical. For omnidirectional robots this assumption can not be made since the heading and the orientation are completely independent. Even if we assume perfect information about the robots orientation we can still obtain error in relative y-direction.

I would like to discuss if my assumption - that the velocity/odometry motion model fails for omnididrectional robots - is correct or not as i am not sure about that. Furthermore  i am curious if there are any other motion models for omnidirectional robots that might fit better.

答:
I found a paper (Learning probabilistic motion models for mobile robots) which examines the constraints of the motion models introduced by Thrun and presents a more general model.

Abstract:

Machine learning methods are often applied to the problem of learning a map from a robot's sensor data, but they are rarely applied to the problem of learning a robot's motion model. The motion model, which can be influenced by robot idiosyncrasies and terrain properties, is a crucial aspect of current algorithms for Simultaneous Localization and Mapping (SLAM). In this paper we concentrate on generating the correct motion model for a robot by applying EM methods in conjunction with a current SLAM algorithm. In contrast to previous calibration approaches, we not only estimate the mean of the motion, but also the interdependencies between motion terms, and the variances in these terms. This can be used to provide a more focused proposal distribution to a particle filter used in a SLAM algorithm, which can reduce the resources needed for localization while decreasing the chance of losing track of the robot's position. We validate this approach by recovering a good motion model despite initialization with a poor one. Further experiments validate the generality of the learned model in similar circumstances.

Title: Motion Model for Holonomic Robot


问:
google cartographer
can we use google cartographer without installing ros, like only using c++ or python?

I have tried looking for c++ but did not get how to use, but in some website it is shown we can see it without ros

答:
TL;DR yes

All ROS packages are simply CMake packages or colcon packages that use the ROS messaging ecosystem. You can use Google Cartographer as a generic C++ library that is compiled from CMake files. You can tell it is a CMake project looking at their CMake files as well as their installation scripts. This begs the question: why do you want to use cartographer without ROS? Do you already have a sensor and data processing pipeline suite set up? What is your desired application? Are you struggling with building ROS from source for your platform?  I suggest you learn CMake, Colcon, and ROS before making the judgement that you don't want ROS. I am making assumptions in this response, but it appears to me you don't have the context to know the benefits and drawbacks of including ROS in a project given the format of the question. I suggest you do some more research and understand how ROS is build and configured before deciding you don't want ROS.

Title: google cartographer


答:
Yes, Google cartographer is released as a standalone library. See their homepage https://google-cartographer.readthedocs.io/en/latest/

Cartographer is a standalone C++ library. To get started quickly, use our ROS integration.

The releases are on GitHub here.

The ROS bindings are the quickest way to get started. But you don't need them. If you're not familiar with how to download and use the package that they're making available. It may be easier for you to get started with the ROS packages.

Title: google cartographer

Body:
can we use google cartographer without installing ros, like only using c++ or python?

I have tried looking for c++ but did not get how to use, but in some website it is shown we can see it without ros


问:
geometric meaning of rotation matrices related to different frames
Consider the following rotation matrices:

$^{a}R_{b}$, $^{a}R_{c}$ and $^{a}R_{d}$

in which

$^{x}R_{y} \in SO(3)$ describes the orientation of a generic frame $y$ wrt the coordinates system of another frame $x$

$a$ represents the fixed world frame

$b$, $c$ are two different fixed

$d$ is a rotating frame

all frames shares the same origin $o \in R_{3}$ (i.e. no translations involved)

$$$$
What is the geometric meaning, if any, of computing the following operation:
$\overline{R} \text{ } = \text{ } ^{a}R_{b} \text{ } \cdot \text{ } ^{c}R_{d}$ ?

( $^{c}R_{d} \text{ } = \text{ } ^{a}R_{c}^{T} \text{ } \cdot \text{ } ^{a}R_{d}$ )

$$$$
Can we say that $\overline{R}$ represents the orientation of frame $d$ wrt world frame $a$, computed considering that the change in orientation between $c$ and $d$ is the same change in orientation as between $b$ and $d$?

Does this make any sense from a mathematical and/or geometric point of view?

答:
Using the notation you have given, the intuitive geometric meaning of rotation matrix multiplication is most clear when the subscript of the first matrix is equal to the superscript of the second (i.e. ${}^{x}R_{a} \cdot {}^{a}R_{y}$). If the column vectors of a rotation matrix ${}^{0}R_{1}$ represent the x, y, and z-axes of frame $1$ in frame $0$, then multiplying that matrix with another rotation matrix will rotate those axis vectors to represent frame $1$ in frame $x$ (whatever frame you just rotated "into").

So, what intuition do we have for ${}^{a}R_{b} \cdot {}^{c}R_{d}$? Short answer, not a lot.

We might put words to this equation as "rotating the axes vectors of frame $d$ represented in frame $c$ by the rotation of frame $b$ relative to frame $a$". Since there is no clear relationship between $b$ and $c$, it is hard to intuit anything useful from this.

Now, from the information you have given, there is enough to "connect" the rotation you described. define ${}^{b}R_{c} \triangleq {}^{a}R_{b}^{T} \cdot {}^{a}R_{c}$, then you have:

$\bar{R} = {}^{a}R_{b} \cdot {}^{b}R_{c} \cdot {}^{c}R_{d}$

for whatever that's worth!

As a final note, I think the last portion here conveniently summed up your question about relating the fixed frames - although that's not necessarily what I had intended. Since frame $b$ and frame $c$ are both fixed frames, the rotation matrix you gave as $\bar{R}$ is only one rotation away from expressing $d$ in the $a$ frame, That rotation being $({}^{a}R_{c} \cdot {}^{a}R_{b}^{T}) \cdot \bar{R}$ (this being the $\bar{R}$ you have defined).


问:
How to test moveit handeye calibration?
I have a KUKA iiwa 14 and a realsense D435i camera. I calibrated the system using a hand-to-eye configuration in Moveit! Hand-eye calibration package. But I would now like to test the accuracy of the calibration. Any idea how this can be done? Do I need to manually feed in different known points in space and command the robot to move to it? How could I calculate the error between desired location and where the robot reached in this case?</p>

答:
I recommend you check the information "howto" here:
enter link description here</p>

Title: How to test moveit handeye calibration?


答: I believe your question regarding the geometric meaning of rotation matrices to different frames I explain on Medium</p>

Title: geometric meaning of rotation matrices related to different frames

Body:
Consider the following rotation matrices:

$^{a}R_{b}$, $^{a}R_{c}$ and $^{a}R_{d}$

in which

$^{x}R_{y} \in SO(3)$ describes the orientation of a generic frame $y$ wrt the coordinates system of another frame $x$

$a$ represents the fixed world frame

$b$, $c$ are two different fixed

$d$ is a rotating frame

all frames shares the same origin $o \in R_{3}$ (i.e. no translations involved)

$$$$
What is the geometric meaning, if any, of computing the following operation:
$\overline{R} \text{ } = \text{ } ^{a}R_{b} \text{ } \cdot \text{ } ^{c}R_{d}$ ?

( $^{c}R_{d} \text{ } = \text{ } ^{a}R_{c}^{T} \text{ } \cdot \text{ } ^{a}R_{d}$ )

$$$$
Can we say that $\overline{R}$ represents the orientation of frame $d$ wrt world frame $a$, computed considering that the change in orientation between $c$ and $d$ is the same change in orientation as between $b$ and $d$?

Does this make any sense from a mathematical and/or geometric point of view?


答: To append Demetris answer, if it has tank-like treads or even 4 fixed wheels, then you can also call it a skid steer vehicle.

Title: Generic name for two-motor wheeled/tracked robots?

Body: Is there a generic name for the category of robots that move using two opposing wheels or tank-like treads?</p>


问:
DRV8833 Motor driver connected to four raspberrypi zero V1.3 GPIO pins causes motor movement to fluctuate despite setting all pins to OFF
I have a raspberrypi zero V1.3 which I connected to multiple DRV8833 motor drivers. the DRV8833 chip is a motor driver that allows bidirectional movement of brushless motors by setting the two pins that a single motor is connected to. So setting both pins to 0 causes the motors to stand still, setting one to 1 and the other to zero causes it to turn in one direction and vice versa. I am using the raspberrypi GPIO pins to control my motors.

Before starting my program that controls the GPIO pins, some of the connected motors already start performing "micro movements", as in they try to move into a direction and quickly move back and forth. This behavious is exacerbated when I move the raspberry pi around alongside all the connected motor drivers and motors. When I then run my program that does something along the lines of

```<code>import RPi.GPIO as GPIO
from time import sleep

GPIO.setmode(GPIO.BCM)

for i in my_selected_gpio_pins:
    GPIO.setup(i, GPIO.OUT)
    GPIO.output(i, False)

while True:
    sleep(1)
</code>```

most of the motors stand still for most of the time, but some of the motors still sometimes make this fluctuating movement, especially when I move the raspberrypi around.

What is a good way of figuring out what might be causing this problem?

I already tried switching out the raspberry pi models but still experience the same behaviour.

EDIT: attaching a capacitor to each of the outputs of the motor drivers seems to have solved this problem. Is there also a way to prevent this from happening in the first place, e.g. by making modifications to the raspberrypi oder the inputs to the motor driver?

答:
This sounds like you're bringing the chip out of sleep mode before your GPIO pins are set up. Until they are set up, their behaviour will be undefined.

The nSLEEP pin is pulled low with a 500k$\Omega$ internal resistor, so the driver should be disabled until it is enabled by a GPIO pin on the Raspberry Pi.

If you're only connecting the DRV8833 control pins to the Raspberry Pi GPIO pins, and have connected nSLEEP to the a 3.3V or 5V PWR pin to enable it all of the time, then I would suggest that you connect nSLEEP to another GPIO pin and only enable the driver chip after all other pins are set up and zeroed.


问:
Robotics Stack Exchange and Robotics Meta Stack Exchange difference
I am here because of the ROS Answers migration, but I'm new to Stack Exchange and I realized there is Robotics Stack Exchange and Robotics Meta Stack Exchange, can someone explain the difference between the two? Thanks in advance.</p>

答:
This is a question that's suited for the Robotics Meta site, because this is a question about the site itself and not a question about a Robotics topic.

If you had a question about why another question was closed, or how to add a tag to the site, or what privileges you get at various reputation levels, or have any other public Q&A about the site itself, those all go on the meta portion.

Everything about robots, ROS, etc. all go on the "regular" Robotics Stack Exchange.


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

答:
Theoretically,

See the main OGM concepts here : (Wurm et al., 2010; Moravec, 1996)
It is to obtain consistent maps, even in environmental changes. The map’s ability to adapt to dynamics is achieved through the occupancy update procedure:
As new measurement samples become available, the inconsistent parts of the model are updated and corrected, as demonstrated in the figure below.
The occupancy
the map is not, however, a model of dynamic environments as understood in dynamic mapping literature in two dimensions (Arbuckle et al., 2002; Biber and Duckett, 2005; Wolf and Sukhatme, 2005; Mitsou and Tzafestas, 2007; Meyer-Delius Di Vasto, 2011; Saarinen et al., 2012),

Practically,
My suggestion is to check the Gmapping code; It is a simplified way to implement the Logg-Odds Inverse model for mapping.

Or Check this Repo

Please, Let me know if that would be useful.


问:
Confused with EKF Localization
I have been trying to understand EKF localization from Probabilistic Robotics by Thrun Burgard and Fox.

There the covariance prediction is given by
$$\overline{\Sigma }_t=G_t\Sigma_{t-1}G^T_t+V_tM_{t-1}V^T$$

Where $G_t$ is the Jacobian matrix of the motion model $g(x_{t-1},u_t)$ with respect to $x_{t-1}$ and evaluated at $(\mu_{t-1},u_t)$ and $V_t$ is the Jacobian matrix of the motion model $g(x_{t-1},u_t)$ with respect to $u_{t}$ and evaluated at $(\mu_{t-1},u_t)$ and $M_t$ is the covariance motion noise which is a function of the actions.

I have been trying to relate that covariance prediction equation with the original equation derived earlier in the book
$$\overline{\Sigma }_t=G_t\Sigma_{t-1}G^T_t+R_t$$
with no success.

The authors mention that we used the first formulation because we had to map the noise from the control space to the state space but I don't see how it follows from the original EKF derived earlier.

What further confuses me is that there are other EKF formulations which assume that $g$ could be nonlinear in the noise and replace $V$ with the Jacobian matrix of $g(x_{t-1},u_t)$ with respect to the noise (and not the actions as in here.)

I'm really confused. Any help is appreciated.

答:
Like any good engineering formula you can use derive formulations that are appropriate to many different situations.  Let's take a rock simple example that doesn't need an EKF at all but is sufficient to illustrate the point.

Take the simplest model possible

$x = 100 * u$

Let's say you know the variance of u and it is .1, what is the variance of x? Well, we have

$100 (.01) 100^T$ = 1000.

If instead I'd observed my overall system, I'd have observed the variance of x and see that it would be 1000 and I'd use the formula with R.

Put another way if I just blindly used the variance of u for x I'd be off by 3 orders of magnitude, not great.  So that is the mapping between control and state space.  The state space formulation above also handles spaces of different dimensions u and x don't need to be the same and states that depend on complex ways on the input.

Title: Confused with EKF Localization


问:
What is the right approach to write the spin controller for a soccer robot?
Imagine programming a 3 wheel soccer robot. What type of controller would you use for spinning it? P? PID?

The goal for this controller is that it should make the robot stand in a defined angle ( 0 degree ) and turn back if rotated by hand or other robot.

I use stepper motors for my robot and not servos so I need to implement this in my software!

I have written a sample P type controller already and the movement is fairly good. But I would like to make it better if possible. The code is as follows:

```<code>void spinSpeed(int devidedValue, int addedValue, int correction) {

    if(degree<correction && degree>-correction) {
        motorSpeed = 0;
    } else {
        if(degree > 0) {
            motorSpeed = ((degree)/(devidedValue) + (addedValue));
        } else {
            motorSpeed = ((degree)/(devidedValue) - (addedValue));
        }
    }
}
</code>```

correction is a range , in which robot has no movement.
degree is a number between -127 and 128 which is returned from the compass.
motorSpeed is a number between 0 and 255 which is applied to the PWM.

答:
The important thing to remember about a PID control loop is that each term is intended to dominate control at different times during a move.

The proportional term is intended to dominate and provide a larger torque (or in your case speed) the further you are away from your target position.

The derivative term is intended to dominate during the 'cruise' phase of your typical trapezoidal move. It helps to reign back a very high proportional term and limit runaway acceleration when you are far from your destination, but it can also help increase the speed at which you converge on your destination when you get close to it and the proportional term contributes much less.

If you are using a velocity controller rather than a torque controller then the derivative term may actually be hidden inside your speed controller and not directly accessible to your PID loop. This can make control simpler (typically it will just accelerate as quickly as it can up to the desired speed or maximum speed, whichever is lower) but it can also make it less predictable. Often an overly aggressive D (or P) term can result in getting into a limit cycle (often incorrectly called resonance or oscillation due to the sound of the motors humming or even screaming in this state, though limit-cycle is a much more accurate description).

The integral term is there to correct for residual steady-state error, that is where there is a persistent, long term difference between where you are being asked to go and where you actually are. Your current correction (really just tolerance) value works like the opposite of an integral term, it cuts the motor entirely when you are within a deadband around the desired position.

Due to these factors, you will gain little from implementing a full PID loop unless you also plan in a velocity profile with a distinct accelerate, cruise & decelerate phases.

Also bear in mind that the deadband and lack of I term will mean that the final position will always be somewhat random and will most likely differ depending on which direction you approach the desired position. As such, your bi-directional repeatability could be much worse than your standard repeatability.

For more information on the difference between accuracy, repeatability and resolution, see this excellent description. In your case, your resolution is your compass sensor, while both accuracy, repeatability are most likely limited by your correction value, since if the correction value is larger than your compass resolution, you are throwing away some of your positional accuracy in return for being able to turn off your motor when you are close.


问:
What frequency does my quadcopter output-sense-calculate-output update loop need to stay stable?
With a 600 mm (2 foot) motor-to-motor quadcopter, what frequency does my output-sense-calculate-output update loop need to stay stable?

I'm estimating a total takeoff weight of very roughly 2 pounds ( 0.9 kg ),
which I expect to be mostly motors and batteries.

答: 50-200Hz is pretty normal as we can see in the open source projects.  You have to consider that in most cases the inertia of the motors and communication with the ESCs is the limiting factor.</p>


问:
How can I start programming proto X quad
I have bought a really small proto X quad (it has a joystick which navigates the device) and I am looking for a way to send a signal to this thing from my computer.

So can anyone point me how can I turn on one of the propellers of this quad using my laptop (I have a decent knowledge in python/matlab/C# but hardware is a completely new world to me).

答:
You won't be able to do this with a Proto X, since (a) you don't have access to the board firmware, and (b) the hardware cannot be modified.

If you wish to experiment with this, a good first step will be to get a Flip 1.5 board and bluetooth module.  For $24, this will give you a complete open source system that includes PC or Android bluetooth or USB communication.


问:
How do you automate fixing formatting errors found by ament_cpplint?
I'm working on a PR for rclcpp, and when I run the tests, I get formatting errors about white space from cpplint. Is there any automated way to fix these? Here is an example:</p>
```<code>- rclcpp.cpplint whitespace/comments [2] (/home/tyler/code/ws_ros2/src/rclcpp/rclcpp/include/rclcpp/subscription_options.hpp:188)
  <<< failure message
    At least two spaces is best between code and comments
  >>>
</code>```

答:
Recently, I've had some success running ament_uncrustify --reformat for fixing issues found by ament_cpplint, since these tools (largely) agree.

Not the answer I like, but ament_cpplint has no similar option unfortunately.


问:
Simulate Wind in Gazebo - physics_msgs
I am trying to simulate a drone inside an environment with constant wind. I have found a good plugin (link below) and I have done the following to integrate this plugin in my system:

include the gazebo_wind_plugin.cpp file in my src folder

include the header file (gazebo_wind_plugin.h) in the include folder

edit the CmakeLists.txt to include this plugin

https://github.com/PX4/PX4-SITL_gazebo/blob/master/src/gazebo_wind_plugin.cpp

However, I get errors during catkin_make showing the following:

How should I install/integrate physics_msgs? Kindly advice if any other issue is present.

答: You don't have to compile these files with your plugin. You should include the already existing wind plugin in to your world file. Check this example file and how you should use the wind plugin. The Gazebo physics will be on charge of applying the wind to your drone.

Title: Simulate Wind in Gazebo - physics_msgs


问:
Is it possible to use coordinates to modify the floor into a polygon in Webots?
I'm using Webots to model an irregular polygon floor for a coverage problem. I want to define the floor using the coordinates of the vertices.
So far I have been able to generate an irregular polygon with desired coordinates using polygons.wbt. But I'm not sure if this would function correctly as the "floor" or "ground" for the robot to go over.</p>

答:
I would recommend you to use (or take inspiration from) the UnevenTerrain proto included in the recent versions of Webots. See a demo on webots.cloud. This proto file will generate a random uneven terrain, suitable for robots to move on. If you want a pre-defined, e.g., non random terrain, you can probably take inspiration from this proto to create your own from a Solid node containing an ElevationGrid node with custom size and height values.

Note: polygon.wbt is not the best example for this as it relies on the IndexedFaceSet node which is not the best option to create terrains, because the quality and efficiency of collisions is not as good as with the ElevationGrid.


问:
Spdlog linker error with ROS2 packages
Good afternoon!

We are a company that has a pretty big robotic framework and we are currently working in a transition into ROS2. We are first creating the structure that all of our packages will follow. Until now, these were separate modules in the same CMake project. Now, as we are starting to test the transition we encountered an issue.

Explain the problem

As we are moving all of our framework, we have our own logger that is being used in our development. Transitioning into the ROS2 logger in all of our modules is not feasible right now. Both loggers use Spdlog under the hood (ROS2 logger and our logger). The conversion of this module is correct and everything works great downstream. However when we try to create a package that has a dependency in ROS (for the creation of a ROS node) we encounter some linker errors.

This error appears only when linking executables that depend on ROS2. If we compile executables that exclusively depend on our modules (No ROS2 dependencies) then everything works correctly

Our Spdlog installation is built from source with version v1.9.2, while I believe ROS uses the binary installation of libspdlog-dev which has version v1.5.0. I've tried to upgrade and downgrade our version with no effect and also simply installing the ROS version to no effect.

All of these linker errors refer to the fmt library which Spdlog depends on.

Linker Error

This is the linker error in question. It's repeated in the terminal quite a few times. I've changed the names of the home paths and files names but the rest is as shown.

```<code>/path/ros2_galactic/ros2-linux/include/spdlog/fmt/bundled/format.h:1051: undefined reference to `fmt::v7::detail::assert_fail(char const*, int, char const*)'
/usr/bin/ld: CMakeFiles/ProjectSample.dir/samples/ProjectSample.cpp.o: in function `spdlog::details::elapsed_formatter<spdlog::details::null_scoped_padder, std::chrono::duration<long, std::ratio<1l, 1000000l> > >::format(spdlog::details::log_msg const&, tm const&, fmt::v7::basic_memory_buffer<char, 250ul, std::allocator<char> >&)':
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:34: undefined reference to `fmt::v7::detail::basic_data<void>::digits'
/usr/bin/ld: CMakeFiles/ProjectSample.dir/samples/ProjectSample.cpp.o: in function `std::make_unsigned<long>::type fmt::v7::detail::to_unsigned<long>(long)':
/path/ros2_galactic/ros2-linux/include/spdlog/fmt/bundled/core.h:326: undefined reference to `fmt::v7::detail::assert_fail(char const*, int, char const*)'
/usr/bin/ld: CMakeFiles/ProjectSample.dir/samples/ProjectSample.cpp.o: in function `fmt::v7::detail::count_digits(unsigned long)':
/path/ros2_galactic/ros2-linux/include/spdlog/fmt/bundled/format.h:924: undefined reference to `fmt::v7::detail::basic_data<void>::zero_or_powers_of_10_64_new'
/usr/bin/ld: CMakeFiles/ProjectSample.dir/samples/ProjectSample.cpp.o: in function `spdlog::details::elapsed_formatter<spdlog::details::null_scoped_padder, std::chrono::duration<long, std::ratio<1l, 1l> > >::format(spdlog::details::log_msg const&, tm const&, fmt::v7::basic_memory_buffer<char, 250ul, std::allocator<char> >&)':
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:34: undefined reference to `fmt::v7::detail::basic_data<void>::digits'
/usr/bin/ld: CMakeFiles/ProjectSample.dir/samples/ProjectSample.cpp.o: in function `fmt::v7::detail::count_digits(unsigned long)':
/path/ros2_galactic/ros2-linux/include/spdlog/fmt/bundled/format.h:924: undefined reference to `fmt::v7::detail::basic_data<void>::zero_or_powers_of_10_64_new'
/usr/bin/ld: CMakeFiles/ProjectSample.dir/samples/ProjectSample.cpp.o: in function `fmt::v7::detail::format_decimal_result<char*> fmt::v7::detail::format_decimal<char, unsigned long>(char*, unsigned long, int)':
</code>```

It seems to come from "/path/ros2_galactic/ros2-linux/include/spdlog/fmt/bundled/", thus we guessed the problem comes from the Spdlog installed from ROS. I was wondering if someone has faced this issue and/or maybe knows why it's caused or has any idea on how to solve it.

Tried solutions

As I've said, we tried installing different versions of spdlog and removing ours just to have the ROS2 one but the error persists.

We've also tried making changes to the CMake but the linkage seems correct and follows the instructions of spdlog. I would prefer not to show the CMake files unless needed as they are sensitive and can't be shared as they are.

EDIT

Hello, to try to understand a bit better my structure I've added the basic CMake structure of the packages that I'm doing

```<code>cmake_minimum_required(VERSION 3.11...3.24)

project(
    moduleName
    VERSION 1.0.0
    DESCRIPTION "Add a short description of your module"
    LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

# Declare options
option(BUILD_TESTS "Build the Tests of the module" ON)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    set(COMPILER_FLAGS -Wall -Wextra -Wpedantic -Wshadow -pthread)
endif()

if (NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Debug")
endif()

include(GNUInstallDirs)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmakeutilities/CMakeFunctions.cmake)

if(<span class="math-container">${CMAKE_BUILD_TYPE} STREQUAL "Debug")
add_compile_options($</span>{COMPILER_FLAGS} -O -g)
else()
    add_compile_options(${COMPILER_FLAGS} -O2)
endif()

set(EXPORT_NAME "${PROJECT_NAME}_export")

find_package(ament_cmake REQUIRED)

################
# Dependencies #
################

find_package(dependency1 REQUIRED)
find_package(dependency2 REQUIRED)
find_package(dependency3 REQUIRED)

set(MODULE_DEPENDENCIES
    dependency1
    dependency2
    dependency3
)

#################
# Build library #
#################

add_library(<span class="math-container">${PROJECT_NAME} SHARED
./src/ModuleSource.cpp)
target_include_directories($</span>{PROJECT_NAME}
    PUBLIC
        <span class="math-container">$<BUILD_INTERFACE:$</span>{CMAKE_CURRENT_SOURCE_DIR}/include>
        <span class="math-container">$<BUILD_INTERFACE:$</span>{CMAKE_BINARY_DIR}>
        <span class="math-container">$<INSTALL_INTERFACE:$</span>{CMAKE_INSTALL_INCLUDEDIR}>
    PRIVATE
        ${CMAKE_CURRENT_LIST_DIR}
)

###################
# Install Library #
###################

# Linking
ament_target_dependencies(<span class="math-container">${PROJECT_NAME} $</span>{MODULE_DEPENDENCIES})

set_target_properties(<span class="math-container">${PROJECT_NAME}
PROPERTIES VERSION $</span>{PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}
)

# Install Library Target
install(
    TARGETS <span class="math-container">${PROJECT_NAME}
EXPORT $</span>{EXPORT_NAME}
    LIBRARY DESTINATION <span class="math-container">${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION $</span>{CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION <span class="math-container">${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION $</span>{CMAKE_INSTALL_INCLUDEDIR}
)

# Install Headers
install(
    DIRECTORY <span class="math-container">${PROJECT_SOURCE_DIR}/include/
DESTINATION $</span>{CMAKE_INSTALL_INCLUDEDIR}
)

###############
# Executables #
###############

add_executable(ModuleSample samples/ModuleSample.cpp)
target_link_libraries(ModuleSample ${PROJECT_NAME})

install(
    TARGETS ModuleSample
    DESTINATION <span class="math-container">${CMAKE_INSTALL_LIBDIR}/$</span>{PROJECT_NAME}
)

##############
# Test Suite #
##############

if((BUILD_TESTING OR BUILD_TESTS) AND LIBRARY_HAS_TESTS)
    find_package(ament_lint_auto REQUIRED)
    find_package(ament_cmake_gmock REQUIRED)
    #ament_lint_auto_find_test_dependencies()

    ament_add_gmock(ut-<span class="math-container">${PROJECT_NAME}
    ./tests/ModuleTests.cpp)
target_link_libraries(ut-$</span>{PROJECT_NAME} ${PROJECT_NAME})
endif()

##################
# Export Targets #
##################

ament_export_dependencies(<span class="math-container">${MODULE_DEPENDENCIES})
ament_export_targets($</span>{EXPORT_NAME} HAS_LIBRARY_TARGET)
ament_export_include_directories(include)

ament_package()

</code>```

Edit 2

Hello! The full structure would be something like the following. I have two packages. The first one is my own custom logger and the CMake structure is as follows:

```<code>cmake_minimum_required(VERSION 3.11...3.24)

project(
    customLogger
    VERSION 1.0.0
    DESCRIPTION "Add a short description of your module"
    LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

# Declare options
option(BUILD_TESTS "Build the Tests of the module" ON)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    set(COMPILER_FLAGS -Wall -Wextra -Wpedantic -Wshadow -pthread)
endif()

if (NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Debug")
endif()

include(GNUInstallDirs)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmakeutilities/CMakeFunctions.cmake)

if(<span class="math-container">${CMAKE_BUILD_TYPE} STREQUAL "Debug")
add_compile_options($</span>{COMPILER_FLAGS} -O -g)
else()
    add_compile_options(${COMPILER_FLAGS} -O2)
endif()

set(EXPORT_NAME "${PROJECT_NAME}_export")

find_package(ament_cmake REQUIRED)

################
# Dependencies #
################

find_package(spdlog REQUIRED)

#################
# Build library #
#################

add_library(<span class="math-container">${PROJECT_NAME} SHARED
./src/ModuleSource.cpp)
target_include_directories($</span>{PROJECT_NAME}
    PUBLIC
        <span class="math-container">$<BUILD_INTERFACE:$</span>{CMAKE_CURRENT_SOURCE_DIR}/include>
        <span class="math-container">$<BUILD_INTERFACE:$</span>{CMAKE_BINARY_DIR}>
        <span class="math-container">$<INSTALL_INTERFACE:$</span>{CMAKE_INSTALL_INCLUDEDIR}>
    PRIVATE
        ${CMAKE_CURRENT_LIST_DIR}
)

###################
# Install Library #
###################

# Linking
ament_target_dependencies(${PROJECT_NAME} spdlog)

set_target_properties(<span class="math-container">${PROJECT_NAME}
PROPERTIES VERSION $</span>{PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}
)

# Install Library Target
install(
    TARGETS <span class="math-container">${PROJECT_NAME}
EXPORT $</span>{EXPORT_NAME}
    LIBRARY DESTINATION <span class="math-container">${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION $</span>{CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION <span class="math-container">${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION $</span>{CMAKE_INSTALL_INCLUDEDIR}
)

# Install Headers
install(
    DIRECTORY <span class="math-container">${PROJECT_SOURCE_DIR}/include/
DESTINATION $</span>{CMAKE_INSTALL_INCLUDEDIR}
)

###############
# Executables #
###############

add_executable(ModuleSample samples/ModuleSample.cpp)
target_link_libraries(ModuleSample ${PROJECT_NAME})

install(
    TARGETS ModuleSample
    DESTINATION <span class="math-container">${CMAKE_INSTALL_LIBDIR}/$</span>{PROJECT_NAME}
)

##############
# Test Suite #
##############

if((BUILD_TESTING OR BUILD_TESTS) AND LIBRARY_HAS_TESTS)
    find_package(ament_lint_auto REQUIRED)
    find_package(ament_cmake_gmock REQUIRED)
    #ament_lint_auto_find_test_dependencies()

    ament_add_gmock(ut-<span class="math-container">${PROJECT_NAME}
    ./tests/ModuleTests.cpp)
target_link_libraries(ut-$</span>{PROJECT_NAME} ${PROJECT_NAME})
endif()

##################
# Export Targets #
##################

ament_export_dependencies(<span class="math-container">${MODULE_DEPENDENCIES})
ament_export_targets($</span>{EXPORT_NAME} HAS_LIBRARY_TARGET)
ament_export_include_directories(include)

ament_package()

</code>```

The CMake from the second package is identical to the first one except that it depends on the custom logger:

```<code>find_package(customLogger REQUIRE)

ament_target_dependencies(${PROJECT_NAME} customLogger)
</code>```

If, instead of:

```<code>ament_target_dependencies(${PROJECT_NAME} spdlog)
</code>```

We write:

```<code>target_link_libraries(${PROJECT_NAME} spdlog::spdlog)
</code>```

Then we get a different linker error:

```<code>/ros2_galactic/ros2-linux/include/spdlog/logger.h:168: undefined reference to `spdlog::details::log_msg::log_msg(spdlog::source_loc, fmt::v7::basic_string_view<char>, spdlog::level::level_enum, fmt::v7::basic_string_view<char>)'
/usr/bin/ld: /path/ros2_galactic/ros2-linux/include/spdlog/logger.h:168: undefined reference to `spdlog::details::log_msg::log_msg(spdlog::source_loc, fmt::v7::basic_string_view<char>, spdlog::level::level_enum, fmt::v7::basic_string_view<char>)'
/usr/bin/ld: /path/ros2_galactic/ros2-linux/include/spdlog/logger.h:168: undefined reference to `spdlog::details::log_msg::log_msg(spdlog::source_loc, fmt::v7::basic_string_view<char>, spdlog::level::level_enum, fmt::v7::basic_string_view<char>)'
</code>```

Still, it seems to be finding the spdlog installation of ROS2 instead of the one we use.

Changing the find package into:

```<code>find_package(spdlog 1.9.2 REQUIRED)
</code>```

makes it so that it finally finds our installation instead of the ROS2 one but downstream it does not seem to find it anymore and it keeps throwing the same linker errors.

答:
I don't see where you're actually referencing spdlog in your CMakeLists.txt file. I would expect an entry like the following:</p>
```<code># spdlog
find_package(spdlog 1.9.2 REQUIRED)

target_link_libraries (your_project_name ${catkin_LIBRARIES} spdlog::spdlog)
</code>```

Title: Spdlog linker error with ROS2 packages

Body:
I don't see where you're actually referencing spdlog in your CMakeLists.txt file. I would expect an entry like the following:

# spdlog
find_package(spdlog 1.9.2 REQUIRED)

target_link_libraries (your_project_name ${catkin_LIBRARIES} spdlog::spdlog)


问:
Programmatically set joint friction in Gazebo Fortress (previosly Ignition Fortress)
I have a plugin for classic Gazebo to control a vehicle that used the solution from the following question to implement braking:

https://answers.gazebosim.org/question/16442/how-to-programatically-set-joint-friction-torque/

I have now ported this plugin over to Ignition Gazebo (Fortress), as a System plugin, but am unable to get braking working in a similar way. My attempt looks like the following:

    void VehicleInterface::PreUpdate(
      const ignition::gazebo::UpdateInfo & _info, ignition::gazebo::EntityComponentManager & _ecm)
    {
        auto joint_entity = this->my_model.JointByName(_ecm, this->wheel_joint_name);

        auto axis = _ecm.Component<ignition::gazebo::components::JointAxis>(joint_entity);
        axis->Data().SetFriction(friction);
    }
```

But the friction does not seem to have any effect. I guess you can only request the current value of the friction this way, not actually update it. This is confirmed when I look through the gz-physics source, and can't find any place where the friction from the JointAxis is used, beyond at the beginning when the initial model is created.

Is there any way to achieve this?

答:
You are correct that gz-physics doesn't yet have a Feature for setting these properties at runtime. I've opened a feature request to implement it in gz-physics#449.

A similar Feature was requested for setting joint limits at runtime in gz-physics#96 and implemented in gz-physics#260.


问:
Maximum angle between the camera pose to correctly estimate homography
I want to capture two views of same scene. The scene consists of a set of objects kept on a table. From the two views, I wish to calculate homography for image matching. I want to know what is the maximum angle between the two views  such that the homography can be accurately calculated. Right now, I am capturing the images at around 60 degrees of angle, but unable to construct homography accurately.</p>

答:
I don't think the degree of distance, which I assume you mean rotation between cameras, is relevant to computing the homography. Could you clarify what you mean by degrees of distance? The only requirement to compute a homography between two cameras is that there are at least 4 point correspondences (aka matching points) between the two images captured by the two cameras. The 4 point requirement has to do with the number of unknowns in the homography matrix, which because it's defined up to scale and is a 3x3 matrix, turns out to be 9 elements in matrix - 1 up to scale variable = 8 unknowns. Since we're dealing with planes, we have 2D points (x,y), so each point has 2 values, and thus 4 points give us 8 values.

Edit - After a lengthy chat discussion and some example images, it turned out the images were in fact rotated too far to obtain satisfactory point correspondences between frames using conventional methods. What ended up working was increasing the sampling rate by taking more pictures at smaller rotations (30 deg instead of 60 deg), which allowed us to track correspondences across multiple frames so the 60 degree frame could be matched with the 0 degree frame by using the 30 deg frame as a link. Let me know if I missed anything!


问:
What is the difference between a Bayes Net and a Factor Graph
I am just getting started on understanding Factor Graphs, by going through the excellent guide Factor Graph For Robot Perception by Dallaert and Kaess

While I am familiar with the SLAM problem, and have a fair understanding of the probability and statistics involved, I fail to understand why a Factor Graph is a better representation compared to a Bayes net.

To me, they seem to be the same thing. In the Bayes Net, you visualize functions (factors) by incoming and outgoing edges, while in a factor graph, you represent it by a bridge (node) between nodes. However, the underlying principle is the same, i.e. MAP and MLE, yielding the same computation.

Thus, fundamentally, what is the difference between a Bayes Net and a Factor Graph. (I understand what they are, but cannot really seem to point out the difference between them). And consequently, in what way does a Bayes Net fail to capture the SLAM problem, that a Factor Graph can?

Any explanation with examples would be appreciated!

答:
I realize this answer is probably coming too late, but I think it is important, so I will try to give some exposition here.

At a high level, both Bayesian networks and factor graphs can be used to graphically represent probability distributions. This is the application we encounter in robot perception.

First, note that any distribution represented by a Bayesian network admits an equivalent representation as a factor graph. To see this, suppose we have a Bayesian network $\mathcal{N} \triangleq \{\mathcal{V}, \vec{\mathcal{E}}\}$ with variable nodes $\mathcal{V} \triangleq \{v_1, \ldots, v_N\}$ (the domain of each variable $v_i$ does not affect the equivalence) and directed edges $\vec{\mathcal{E}}$. Then the probability distribution $p(\mathcal{V})$ modeled by the network $\mathcal{N}$ is:
\begin{equation}
    p(\mathcal{V}) = \prod_{i=1}^N p(v_i \mid \mathrm{Pa}(v_i)),
\end{equation}
where $\mathrm{Pa}(v_i)$ denotes the set of parents of the variable node $v_i$ (i.e. the set of nodes with outgoing edges in $\vec{\mathcal{E}}$ that are incident to $v_i$). Recall that a factor graph $\mathcal{G} = \{\mathcal{V}, \mathcal{F}, \mathcal{E}\}$ with variable nodes $\mathcal{V}$ (as before), factor nodes $\mathcal{F} \triangleq \{f_1, \ldots, f_M\}$ and undirected edges $\mathcal{E}$ encodes a factorization of a function $f$ as:
\begin{equation}
    f(\mathcal{V}) = \prod_{j=1}^M f_j(\mathcal{V}_j), \quad \mathcal{V}_j \triangleq \mathrm{Neigh}(f_j) \subseteq \mathcal{V},
\end{equation}
where $\mathrm{Neigh}(f_j)$ denotes the set of neighbors of $f_j$ (i.e. the variable nodes adjacent to $f_j$ in $\mathcal{G}$). As an aside, note that factor graph representations of functions are not unique; multiple distinct factor graphs can encode the same function. To see this, simply consider the trivial factor graph containing a single factor connected to all variables; this is always a valid factorization, but isn't necessarily the only valid factorization. We like to use specifically factor graph representations that explicate the conditional independence structure of $f$.

From this, we can see that a factor graph representation of $p(\mathcal{V})$ from the Bayesian network above can be immediately obtained as:
\begin{equation}
    p(\mathcal{V}) = \prod_{i=1}^N f_i(v_i, \mathrm{Pa}(v_i)),
\end{equation}
where
\begin{equation}
    f_i(v_i, \mathrm{Pa}(v_i)) \triangleq p(v_i \mid \mathrm{Pa}(v_i)).
\end{equation}
Going the other direction: we can obtain a Bayesian network from a factor graph representation of a probability distribution by eliminating variables in a particular order (as you may have encountered in the reference text, this is a key procedure for the tree construction steps that show up in iSAM2).

I suspect the fact that we can represent the same probabilistic model in different ways may be part of the confusion. At the end of the day, mathematical operations (like summation or maximization) can be performed on variables in the model whether you think about it as a factor graph or a Bayesian network. From a practical standpoint, however, it may be simpler to implement these operations with one representation than the other. In robot perception, Bayes nets most commonly appear as a tool for writing down probabilistic models. This is because they allow us to explicitly encode the direction of dependence relations (e.g. the probability of a measurement given the robot's state) that appear in the measurement models we specify.

When we want to perform computations with these models (like MAP inference or marginalization), we often encode them as factor graphs. One reason for this is that conditional independence relations are very easy to determine in factor graphs. Specifically, if we have a factor graph representation of $p(\mathcal{V})$ in which there exists a set $\mathcal{S} \subset \mathcal{V}$ of variable nodes such that all paths from one node $v_i \in \mathcal{V}\setminus\mathcal{S}$ to another node $v_j \in \mathcal{V}\setminus\mathcal{S}$ must go through some variable in $\mathcal{S}$, then we know immediately (it's a good exercise to verify this) that $v_i$ and $v_j$ are independent  given $\mathcal{S}$. Formally: $p(v_i, v_j \mid \mathcal{S}) = p(v_i \mid \mathcal{S})p(v_j \mid \mathcal{S})$. It's possible to determine these sorts of conditional independence relations from a Bayesian network, too, but the procedure is a little bit more involved (see d-separation).

It turns out that since the models that show up in SLAM often admit representations as sparse factor graphs, the independence relations explicated by the factor graph structure can be quite useful in the construction of (approximate) inference algorithms (particularly since in robot perception and navigation we are often very concerned with computational efficiency). Practical applications of this property include "smart factors" [Carlone et al. 2014] and (my own work) discrete-continuous smoothing and mapping (DC-SAM) [Doherty et al. 2022].

There is much more that could be said on this topic, but hopefully this helps contextualize some of the ideas in Frank Dellaert and Michael Kaess' book :)


问:
What is the type of electric motor that can lift 1.6 kg just like micro servos, but without the reduction gear?
Micro servo motors, normally the 9g type can lift 1,6kg with a reduction box made of nylon.

However, I'm interested on lifting this amount of weight (1,6 kg) in a faster rate in the axis of rotation (no mechanical levers).

I tried to see what kind of DC electric motor fits in this specification so I can project what kind of setup I will need, but for some reason google just don't stop showing shopping ads about super heavy duty induction motors.

答:
One of the ways to calculate power is torque times speed. For a given mechanical power, you must reduce the speed to increase the output torque.

When you say you want to keep the motor the same, keep the torque the same, and increase the speed, that's not possible.

Ultimately what you're really wanting is a shopping question - you're asking us to find a product that meets your needs - but I wanted to give this answer to point out what you're asking for is not going to exist.


问:
Stabilising 3d cameras for mapping outdoors - mechanical or programmatic
I am preparing to mount Intel Realsense and Zed and Oak-d cameras onto a 4 wheel mobility scooter to do mapping of my local area.

I'm not looking for recommendations but rather an understanding of mechanical and programmatic vibration removal techniques. Terrain will be combination of roads paths and grass.

答:
That's a very tricky problem for vision-based SLAM systems. But if you are using the depth camera just for depth sensing and perception, I guess that might be ignorable under the condition that the exposure time is short enough.

But you still might want to consider some solutions for vibration removal.

Removing the motion blur after it happened is almost meaning less if you are looking for a real-time solution. There are sensors that support HW level stabilization but that is not for your situation if you are using off the shelf depth camera. In all of them, CMOS sensor and lens are fixed on PCB. So you should consider an external stabilizer.

I highly recommend using mechanical vibration dampers like the following.

Off the shelf damper


问:
How to create a vector of message_filters::Subscriber?
When I try to create a vector of message_filters::Subscriber like so:

```<code>#include <message_filters/subscriber.h>
#include "sensor_msgs/msg/point_cloud2.hpp"

int main(int argc, char * argv[]) {
    std::vector<message_filters::Subscriber<sensor_msgs::msg::PointCloud2>> pc_subscribers_;
    message_filters::Subscriber<sensor_msgs::msg::PointCloud2> sub;
    pc_subscribers_.push_back(sub);
    return 0;
}
</code>```

I get the following error:

```<code>...
/home/sam/work/radar_ws/src/radar_velocity_cpp/src/publisher_radar_ego_comp.cpp:56:31:   required from here
/usr/include/c++/9/ext/new_allocator.h:146:4: error: use of deleted function ‘message_filters::Subscriber<sensor_msgs::msg::PointCloud2_<std::allocator<void> > >::Subscriber(const message_filters::Subscriber<sensor_msgs::msg::PointCloud2_<std::allocator<void> > >&)’
  146 |  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
      |    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/sam/work/radar_ws/src/radar_velocity_cpp/src/publisher_radar_ego_comp.cpp:3:
/opt/ros/foxy/include/message_filters/subscriber.h:102:7: note: ‘message_filters::Subscriber<sensor_msgs::msg::PointCloud2_<std::allocator<void> > >::Subscriber(const message_filters::Subscriber<sensor_msgs::msg::PointCloud2_<std::allocator<void> > >&)’ is implicitly deleted because the default definition would be ill-formed:
  102 | class Subscriber : public SubscriberBase, public SimpleFilter<M>
...
</code>```

答:
The way that you're invoking this you would be creating a copy of the Subscription object. You don't want to do this as Subscriptions are stateful. Two copies of the subscription would mean that you'd get two invocations of each incoming message. Instead you should use a SharedPtr and store it in your vector instead of copying the subscription object into your vector.

The message_filter::Subscription contains a rclcpp::Subscription internally, so I'm talking more about the internal capability but the higher level one displays the same traits because of the internal storage.

In general we recommend storing and using SharedPtrs instead of the raw datatype to avoid this sort of issue. For example how to subscribe


问:
How to read the map output file generated by a project using Cartographer without ROS
Currently I can successfully generate the map output file but I have no idea how to display it in practice. Basically, it should be a 2D SLAM map.

The project I'm using is available at the following link on Github. This project basically uses Google Cartographer 2D SLAM without ROS.

Compiling the project I get an output file called "map_output" but it seems to be completely raw: it's not even binary. How can I convert or read it in a viewable format?

Inside the main file, specifically inside the main function, it can be seen how data consisting of inertial measurements (IMU) is taken as input and processed to provide an output map.

Update: map_output file as requested is available here. (IMU data file is available here.) I'm pretty sure both can be read and/or represented in the same way.

答:
From hexdump I see a lot the two rows of 16 bytes each that don't match the next rows which are mostly 0xff:

```<code>hexdump -C map_output  | more
00000000  46 00 00 00 dc 00 00 00  00 00 00 d4 cc cc fc bf  |F...............|
00000010  00 00 40 6b 66 66 23 c0  00 00 00 a0 99 99 a9 3f  |..@kff#........?|
00000020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
...
00000350  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000370  ff ff ff ff ff ff ff 36  2e 31 ff ff ff ff ff ff  |.......6.1......|
00000380  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff 30 ff  |..............0.|
00000390  30 ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |0...............|
000003a0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
</code>```

The file size is 15432 bytes, so 15400 bytes without that header, width * height = 154300 - so find factors using https://stackoverflow.com/a/70924583/603653

It looks like you can open it in the gimp by checking Show All Files then select Raw Image Data :

You then have to input the width and height manually, image type indexed, and set the offset to 32:

If that looks completely wrong then maybe some other import settings will work, but to me it looks a little like a 2D laser scan from a fixed location.

Body:
From hexdump I see a lot the two rows of 16 bytes each that don't match the next rows which are mostly 0xff:

hexdump -C map_output  | more
00000000  46 00 00 00 dc 00 00 00  00 00 00 d4 cc cc fc bf  |F...............|
00000010  00 00 40 6b 66 66 23 c0  00 00 00 a0 99 99 a9 3f  |..@kff#........?|
00000020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
...
00000350  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000370  ff ff ff ff ff ff ff 36  2e 31 ff ff ff ff ff ff  |.......6.1......|
00000380  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff 30 ff  |..............0.|
00000390  30 ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |0...............|
000003a0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

The file size is 15432 bytes, so 15400 bytes without that header, width * height = 154300 - so find factors using https://stackoverflow.com/a/70924583/603653

It looks like you can open it in the gimp by checking Show All Files then select Raw Image Data :

You then have to input the width and height manually, image type indexed, and set the offset to 32:

If that looks completely wrong then maybe some other import settings will work, but to me it looks a little like a 2D laser scan from a fixed location.


答:
The map file from that executable is written out here in the code  It looks to be populated from the CartoModule::paint_map function here in the code.

This appears to be an undocumented custom implementation from the project that you're linking to so you'll have to read the code there to find out why/how to interpret it.

Title: How to read the map output file generated by a project using Cartographer without ROS

Body:
Currently I can successfully generate the map output file but I have no idea how to display it in practice. Basically, it should be a 2D SLAM map.

The project I'm using is available at the following link on Github. This project basically uses Google Cartographer 2D SLAM without ROS.

Compiling the project I get an output file called "map_output" but it seems to be completely raw: it's not even binary. How can I convert or read it in a viewable format?

Inside the main file, specifically inside the main function, it can be seen how data consisting of inertial measurements (IMU) is taken as input and processed to provide an output map.

Update: map_output file as requested is available here. (IMU data file is available here.) I'm pretty sure both can be read and/or represented in the same way.