问:
How to develop Teach pandent for robotic arm
I am working in the development of 5 DOF robotic arm, The Controller will be consisted of 5 Serad Intelligent  Servo Motion control drives, and I am working for HMI development currently, The Teach pandent as kuka uses in its KR C4 controller with its own processor, I want to do that on windows , I want to know which software will be best for this purpose for doing all necessary features which Kuka does</p>

答:
As it (almost) always, there is no best in (software) engineering. There are only trade-offs.
For a windows based pendant, there are 2 main decisions groups to make. (1) The UI Framework you will be using and (2) the programming language editor features (assuming yout robot will have possibility to write an "application program").

Alongside the software, teach pendants (subject to local laws and standards) require an e-stop and a deadmansswitch (a 3 position enable button). These are subject to a risk-analysis (!) and are connected to a safety controller (again subject to a risk analysis!).  The importance of knowing and respecting local laws/regulations and (safety) standards when making anything capable of endangering humans cannot be emphasised enough!!!

I guess step 0 is to come up with a UI concept and draw it on paper, in Powerpoint, in Visio, in Adobe XD or in Figma to have a concept what you can implement.

UI Frameworks help you create windows, icons, input fields, labels, etc. all Graphical related thing you see on screen. The first choice here is to decide if you want a web-based UI, displayed only in a browser, a native UI for windows (or should it be cross platform, this way you can avoid the need for win license for every pendant) or both.

You can look into web bases UI Frameworks like Vue, Angular, React, Svelte

You can look into the .net UI Framework (Windows Forms, but this see being deprecated), or something Linux/Mac/Win cross platform like .net MAUI (I assume this will be the successor of WinForms), Electron, React Native (with React Native for Windows) or qt

You can use something that (should/will) work anywhere like Flutter

I think with the exception of winForms and qt all other frameworks are bound to a certain programming language (not accounting for javascript/typescript difference). If you have a concept you can create the UI in the chosen Framework.

The next step would be to add functionality to the UI. As the UI is only graphics there will be absolutely no robot related functionality behind it. You need an interface to the robot controller (you can choose from HTTP Rest, MQTT, AMQP, ROS, protobuf, cap'n proto, gRPC, WebSockets). Please note that the interface alone also does not provide actual functionality only message exchange. Make sure that the selected interface has libraries both for the programing language used on the controller and on the pendant.

On the pendant side, all functionality that is needed is somewhat straight forward to implement compared to the programming language editor part.
That is the most complex task on the pendant (assuming you want syntax highlighting and intelligent code completion ("intellisense") integrated in the UI).

For Syntax highlighting you need a syntax of a programming language. You can consider copying an existing language (like KRL), but I do not know if that is legal. Anyways, once you have a language, you need (at least a partial) interpreter (parser+lexer) for the language you use to program your robot. By partial interpreter, I mean at least a lexer which can color the words (tokens) you type,

For good "intellisense" you probably need a parser also. You can use an interpreter generator like ANTLR, or yacc to generate your interpreter based on the syntax of the programming language you are using. This interpreter will also come in handy, when you are actually interpreting the program you  wrote on the pendant, when you execute it on the controller.


问:
IMU Change of reference frame
Im trying to rotate one accelerometer vector from body frame to ned frame, but i cant found what im doing wrong. For now, im using an online dataset that provides me roll, pitch and heading information, where heading is 0 rad when alligned with east axis, not north axis, the dataset also provides accelereration in x, y, z. For making the rotation im using a direct cossine matrix, like this below:

The x axis of the imu is alligned with the movement of the car, the y axis with the lateral acceleration, and z axis with gravity. What im doing is first change the heading angle to get an orientation with respect of north, after this, multiply the DCM with the acceleration [Ax,-Ay,Az] in this order, Ay is negated because the dataset gives me acceleration positive in the left axis.  Im expecting to have the NED acceleration. But the answer seems wrong. The IMU used in this dataset is one oxts rt3003.

答:
The IMU senses deviations from gravity within the inertial frame.

Essentially, IMU measures the specific force $f_b$ given in the base frame as:
$$
f_b = R^{bn}(a_{ii}^n-g^n),
$$
where $g^n$ is the gravity in the navigation frame (NED), $a_{ii}^n$ is the inertial acceleration expressed in NED frame and, finally, $R^{bn}$ is the rotation matrix from NED to the body frame.

Further, it holds that the acceleration we are interested in, that is $a_{nn}^n$ given in the NED frame, can be expressed in relation to $a_{ii}^n$ through the centrifugal and Coriolis terms:
$$
a_{ii}^n=a_{nn}^n + 2\omega_{ie}^n \times v_n^n + \omega_{ie}^n \times \omega_{ie}^n \times p^n.
$$

Usually, both centrifugal and Coriolis contributions can be neglected, thus: $a_{nn}^n \approx a_{ii}^n$.

Thereby, it comes out:
$$
a_{nn}^n=R^{nb}f_b+g^n.
$$

Most likely, you are not considering the contribution of $g^n$ in your transformation above.

I warmly recommend that you refer to Section 2.3 "Using Inertial Sensors for Position
and Orientation Estimation" by M. Kok, et al.

ContentLicense: CC BY-SA 4.0

Title: IMU Change of reference frame


问:
Deburring Robot (Plastic Box)
For a university course I have been asked to design a rough "specification" for a system that will deburr a plastic box that appears in a workspace. Due to irregularities in the boxes edges I cannot use simple position control and must use force control.

I have so far decided on;

Using an IR sensor to detect the box has appeared in the workspace.

Use an Epson 2 axis robot to move around the work piece

Use an ATI 6 axis force sensor to maintain a constant force against the edge of the box as the deburrer/robot moves around it.

Is there a simple means of detecting the end of each side of the box ?
A 0N force value would indicate reaching the edge of a box but it could also mean a breakage in the box which was also specified. How can I distinguish between the two ?

Also does my work so far sound sensible ?

Thanks for any help

答: If your force sensor is sliding along the inside of the box, the end of each side will be felt by the change in the wall's orientation. If you are feeling along the outside of the box, when the 'finger' loses contact, have the finger sweep a circle. If its a hole in the box, then picking the right radius circle will re-establish contact with the box wall. If its a corner, then contact will be re established at an angle - typically +/- 90 degrees from the course the finger was following before it lost contact. I presume the deburrer is operating in concert with the contact sensor, but if the box is secured against movement, and time is not an issue, the box edge could be mapped before a deburring pass initiated. Also, the touch sensor may be able to detect the irregularity of the burr, not only to signal end of deburr, but being able to modify the deburring technique to match the burr's heaviness.</p>

ContentLicense: CC BY-SA 3.0

Title: Deburring Robot (Plastic Box)


问:
How come LIDAR is not commonly used for indoor navigation?
I'm reading this survey on the state-of-the-art techniques for indoor positioning and navigation. I noticed that LIDAR isn't mentioned at all in the paper. Is LIDAR not meant to be a common method for indoor navigation? I believe I've seen some industrial LIDAR robots some time ago though.</p>

答:
The referenced paper appears to be talking mainly about "mobile devices" (i.e. phones), not mobile robots.  I believe there are simply physical limitations to using something like LIDAR on a phone.  When holding a small device in your hand and up against your head, most of the device is covered, so optical technologies won't work well.  That is why the majority of techniques the paper investigates are radio technologies.  (Radio waves can travel around and through human bodies and walls as opposed to line of sight optical sensors like LIDAR).

I'd contend that LIDAR for indoor mobile robots is used extensively.  Robots that use 2D LIDAR for indoor SLAM can be found throughout the literature.  Including some notable books like Probabilistic Robotics.  For 2D LIDAR to be most effective, it needs to be held at a consistent height above the ground.  Something that comes naturally to wheeled indoor robots.

The costs of 2D LIDAR have greatly been reduced over the years.  Now even commodity vacuuming robots use it.

 -->  -->

However, I will also mention that in recent years cheap 3D sensors like the Kinect and its derivatives have shifted robotics (and SLAM research) to 3D.


问:
Performing Image alignment using pyramid levels with semi dense depth
To gain some confidence, I want to implement the camera tracking (optimization problem) discussed in Semi Dense Visual Odometry for a monocular cameraJ Engel, J Strum, D Cremers

$$E(\xi) = \underset{i}\Sigma\frac{\alpha(r_i(\xi))}{\sigma_{d_i}^2}(r_i(\xi))$$
$$r_i(\xi) = (I_2(w(x_i, d_i, \xi)) - I_1(x_i))$$

Using Gauss-Newton method, as discussed in the same paper, (local optima) $\xi$ between two monocular images can be found. Here is how I think the process goes:

Given

Start with initial guess $\xi_0$ (~ 0), Images $I_1, I_2$, Depth for some points in image $I_1$ is given

Steps

Start at lowest level (most coarse) $L_n$ pyramid image (same as shrinked image?) and corresponding depth map (for points in shrinked image?)

Gauss Newton iterations with some library (I plan to use python for ease).

Setup the residual calculation function that takes input $I_2$, $I_1$, {$x_i$}, {$d_i$} and {$\xi$} and produces $r_i$. The Jacobian involved will be calculated numerically.

I can skip $\alpha(.)$ and $\sigma_{d_i}^2$ for now. $E(\xi) = \underset{i}\Sigma ~r_i^2$

At the end I expect to get the result $\xi_L$

Use the solution $\xi_L$ as initial guess and repeat for the next pyramid level (n-1)

Questions:

Am I missing some step in above process ? Please let me know.

Is there a library function in openCV that take an image (and its depth image) as input and give in output the requested pyramid level (for a choosen n) image as output (depth image will also need to be shrinked)?

PS: can someone with higher reputation add the tag "Image-alignment" to this question?

答:
I'm going to try to answer this question but please don't flame me if I got something wrong. Those were two heavy papers and I didn't have as much time as I wish to go through them.

The pyramids are the same as shrank image indeed. Image pyramids are images with lower resolution. As a general concept, by reducing the resolution and representing a different amount of details, the tracking algorithm can focus on different types of feature and become more generic. See pyrUp/Down in OpenCV.

It is a little hard to answer because it is not clear what is the granularity of your question.

I feel like the general steps of the algorithm are there but if I have the time later, I'll go through it again later. However, Gaussian-Newton optimization are rarely plug and play for me, so I would be cautious there in there of the time needed to have it running.

I'm wondering if, since you'll be ignoring $\alpha$ and $\sigma^2_{d_{i}}$ You're not implementing the method of Steinbrücker et al. in Real-Time Visual Odometry from Dense RGB-D Images (full disclaimer I didn't have time to read this one in details just skimmed it).


问:
Pole placement gains tuning
given my control system

I have found the region of the complex space that satisfies my specifications, determining poles position in 0.5 +- 0.2i.

Now I want to find the gains that fix the desider pole (with matlab), but I have not understand well how to do it: anyone can suggest me an example on how to do that, with or without matlab?
Thanks

Edit: in the first image the sum blocks are +-, not ++

答:
I assume that you'd aim to place the poles in $-0.5 \pm 0.2 \cdot i$ for stability reasons.

In the s-domain, the transfer function is:
$$
\frac{\Phi_c}{\Phi}=\frac{K_p}{s^2+K_ds+K_p}.
$$

Computing the closed-loop poles, hence the roots of the characteristics polynomial $s^2+K_ds+K_p$, gives you:
$$
\begin{array}{cc}
K_d=1 \\
K_p=1.16/4
\end{array}.
$$

Title: Pole placement gains tuning


问:
Is two cameras equivalent to Stereo camera setup?
I have two webcams, which are mounted close together. I plan to use them to find out the true depth of certain pixels of images. Suppose I use a standard multi camera calibration setup and find out the relative orientation of one with respect to the other camera, can it perform as well as a stereo camera setup for depth estimation? What are the challenges typically? How accurate must the calibration be?</p>

答:
Yes you can use two camera the same as using single stereo camera for depth perception.

Step on calibration camera for two camera and stereo camera is same.


问:
How can I interface my CMOS camera module to an Arduino?
I am totally new to the camera interface and usage in an Embedded project, and would like to use a CMOS vision sensor like this.This project further will be used to power a small robot with on-board video processing power using processors like ARM 9.

I do have a limitation that until now I have worked only on 8-bit micro-controllers like the atmega 8, 16, 32 and on the Arduino platform. I think that for better processing we can use Arduino Due.

With the data sheet for the CMOS camera above, we can build its breakout board. But what next? I haven't I found any useful resources while searching. All I need to do is to capture a small video and store it in a SD card.

I have seen these links but they haven't proved to be very useful as they don't provide me the required form factor. I am looking to interface this module to a customized board.

So what so I need to understand about what commands they accept for their proper functioning like starting to take video and posting them out on a output pin.

If we get a video on a output pin, to which pin should I take that output to on my controller, i.e. on UART or I2C or SPI?

答:
"All I need to do".... Famous last words. This is a very complicated project to attempt for multiple reasons. I'll try to break down these challenges. For documentation, the datasheet has all the information that you need, but there is probably not any code available that is ready to use. Sparkfun has recently introduced a 'degree of difficulty' rating for parts, and from what I can discern just using the camera is beyond your current skill level. This doesn't mean you can't do the project, but you will be learning a lot along the way :)

To break this project down, you have a few challenges. First, you have a I2C control interface, and a parallel data output. There are a few other pins, such as the various power supplies required and the CLK, Hsync, and Vsync pins. The I/O connections aren't too complicated, but there are two different power supply domains (1.5V and 2.8V that you need in addition to your Arduino supply.

Once you have the circuit connected electrically, then you need to implement the camera control codes. This will allow you to at least set the resolution and FPS on the camera, and probably control when the camera captures images.

Then you need to transfer the image data from the camera to your microcontroller. This is done as parallel data transferred one byte at a time, and the entire sensor is row/column scanned to output the image as raw data. This means that you need at least as much RAM as the resolution of the image you are receiving. Also, the minimum transfer rate listed in the datasheet is basically 12 MBytes / sec, which is probably difficult to implement with a regular Arduino. The RAM required per frame ranges from 7MByte for full resolution, down to
25kByte for the subQCIF resolution.

Once you have an image in memory, then you need to encode each frame into some video format because even at the lowest bitrate you will be recording 370kByte/sec as a raw data. Video encoding is probably very difficult to do on an Arduino (or without a video encoding library and/or core). Encoding will require additional RAM on the device, and will vary depending on the codec you use.

Once you have encoded the video into some format, you will need to transfer it to the SD card. Again, video takes a lot of bandwidth, and it is unlikely that an Arduino will be able to interface with a SD card in a way that will provide enough bandwidth for transferring video in real-time. (AFAIK, most Arduinos access SD cards through the SPI interface - this will be very slow compared to what you need).

All in all, there are a lot of challenges to recording video from a raw sensor. They aren't insurmountable, but they are significant.


答: The challenges you are going to face is more how to mount the cameras and find the relative positions between them (also the rotation). You can find a lot of designs for mounts for the cameras, also 3D printers' designs. The calibration is pretty similar to the one for one camera chess pattern etc. There are also a lot of tutorials explaining how you should proceed. Have fun!</p>

Title: Is two cameras equivalent to Stereo camera setup?

Body: I have two webcams, which are mounted close together. I plan to use them to find out the true depth of certain pixels of images. Suppose I use a standard multi camera calibration setup and find out the relative orientation of one with respect to the other camera, can it perform as well as a stereo camera setup for depth estimation? What are the challenges typically? How accurate must the calibration be?</p>


问:
Compensator design
I got a plant $G(s)=\left(0.13s+1\right)/s^2$ to design a compensator which provides below demands:

Settling time : max 2s

Overshoot : max %35

Gain margin : min 10 dB

Phase margin : min 30 deg

Controller effort (r to u) : max 0.9

Bandwith : min 10 rad/s

The best architecture so far was the one below but I couldn't reach the demands.

assigning $C1=0.03\cdot\left(\left(s+80\right)\left(s+10\right)\right)/\left(\left(s+0.12\right)\left(s+1\right)\right)$, $C2=17.5\text{m}$ and $H=1$ results as below:

Can anyone explain or guide a design approach on how to handle $\left(s+a\right)/s^2$ type plants when designing compensators or mention some tips/shortcuts for architecture selection? How do we select the order of the controller?

答:
Consider the traditional control diagram below.

If you set $C=(2\zeta\omega_ns+\omega_n^2)/(0.13s+1)$, then you'll get the following closed-loop system transfer function:
$$
T=\frac{GC}{1+GC}=\frac{2\zeta\omega_ns+\omega_n^2}{s^2+2\zeta\omega_ns+\omega_n^2}.
$$

This can be achieved through zero-pole cancelation, which is doable since $G$ has a zero in LHP.

Finally, you can easily attain your design requirements with $\omega_n \approx 10\,\text{rad/s}$ and e.g. $\zeta=\sqrt{2}/2$.

The requirement on the maximum controller effort cannot be attained with a pure LTI controller though. You may thus consider LTV and/or nonlinear approaches to this end for controlling a double integrator (for example relying on optimal control).

Title: Compensator design


答:
As reported for example in https://robotics.stackexchange.com/a/21571/6941, a minimum-jerk trajectory in one dimension is coded with respect to time $t$ as:
$$
x(t) = x_i + (x_f-x_i) \cdot \left( 10\left(\frac{t}{t_f}\right)^3 -15\left(\frac{t}{t_f}\right)^4 +6\left(\frac{t}{t_f}\right)^5\right),
$$
where $t_f$ is the final time ($2\, \text{s}$ in your case), $t \in \left[0, t_f\right]$, and $x_i$ and $x_f$ are the initial and final position, respectively.

You can easily extend this to the two-dimensional case.

Title: Generate a Trajectory from GPS coordinates

Body:
How would I generate a trajectory (e.g. minimum snap/jerk/acceleration) for a quad rotor between GPS coordinates? In all the examples that I have seen, they assume that the x,y positions are in meters relative to a starting point (0,0). Is it as simple as calculating the distance of a straight line between the 2 points and dividing that up into segments to create a continuous path?

By the way I'm ignoring the z/altitude value as that value will be a constant value throughout in my case.

A sample trajectory for reference that I have seen when applying boundary conditions to a quin-tic polynomial to generate velocity and acceleration polynomials.

```<code>time,   x,                  y
0.0,    0.0,                0.0
0.1,    0.00350070021007,   0.00350070021007
0.2,    0.0105021006302,    0.0105021006302
0.3,    0.0210042012604,    0.0210042012604
0.4,    0.0350070021007,    0.0350070021007
0.5,    0.0525105031511,    0.0525105031511
0.6,    0.0735147044115,    0.0735147044115
0.7,    0.098019605882,     0.098019605882
0.8,    0.126025207563,     0.126025207563
0.9,    0.157531509453,     0.157531509453
1.0,    0.231046213865,     0.231046213865
1.1,    0.273054616385,     0.273054616385
1.2,    0.318563719116,     0.318563719116
1.3,    0.367573522057,     0.367573522057
1.4,    0.420084025208,     0.420084025208
1.5,    0.47609522857,      0.47609522857
1.6,    0.535607132141,     0.535607132141
1.7,    0.598619735922,     0.598619735922
1.8,    0.665133039913,     0.665133039913
1.9,    0.735147044115,     0.735147044115
2.0,    0.808661748526,     0.808661748526
</code>```


问:
How do i use the Nicolas ziegel approach if my system never becomes unstable?
How do i use the Nicolas Ziegel approach when the root locus plot of my system never becomes marginally stable , for any gain (unless it is negative).. ??

How do i estimate my ultimate gain value????

答:
We have two basic Ziegler-Nichols tuning rules: one method is used with the frequency response and one method is characterized by the use of the open-loop step response of the system. You ought to use the latter then, which sticks around the identification of two main parameters $a$ and $\tau$ that are the intercepts of the steepest tangent of the step response with the coordinate axes (see the figure).

Once $a$ and $\tau$ are identified, the method proposes the following heuristic estimates for the PID gains:

References

"Feedback Systems", K. J. Astrom, R. M. Murray.


问:
Making a tiny robot by using a remote brain
I'd like to build a robot as small as possible and with as few "delicate" parts as possible (the bots will be bashing into each other).

I was wondering if it was possible to use a small chip that could receive bluetooth/IR/wifi commands to move the motors, and in turn, send back feedback based on sensors such as an accelerometer (to detect impact).

I can probably achieve something like this with the PiCy

however this is slightly bigger than I'd like (due to the size of the Pi) and I'm not sure how long the Pi would last taking continuous impacts.

I'd therefore like to try to offset the brain (the Pi) to the side of the arena and just use a small chip to receive move commands, and send back data from the accelerometer.

Do you have any recommendations for such a chip? Wifi would be my choice but if it impacts the size I could try BT

Edit: After further research it seems an Arduino nano with a WiFi RedBack shield might do the job along with something like this for the motors: http://www.gravitech.us/2mwfecoadfor.html

答:
There are two approaches to build the robots you describe.

The first, as you suggest, is to decouple the processing power from the rest of the robot which holds the sensors and actuators. To do that you need some communication between the processing unit (PC/RPi/Other microcontroller) and your robot. A low-cost solution for this is to use cheap Bluetooth modules (search ebay for 'Serial Bluetooth Module', they should't cost more than $5). On the robot side you will need a microcontroller as well since you need to receive the data from the Bluetooth, process it and convert it to control signals for the motors. Additionally, the same microcontroller will be responsible for reading the sensors and transmitting the data back to the remote processing unit.

The second approach is to have a single processing unit which is located on the robot. The same controller will read the sensors, provide the intelligence and control the motors. Because the robot you describe it simple, this controller could be implemented on simple microcontroller. You can create your own controller (using PIC/AVR/ARM) or you can use a ready solution like an Arduino, BasicStamp etc. Optionally you can have Bluetooth connection with a PC for telemetry (observing the sensors values and/or manually controlling the robot).

For your project, the second approach seems more appealing. It will cost much less and robots will react faster since the processing is done directly on the robot. Also since the first approach requires a processing unit on the robot as well it seems like an overkill to use a second unit for processing. On the other hand, the first approach allows you to develop your robot controller in a higher level system (PC/RPi) which depending on your experience, may be a more comfortable environment.


答: Extending the previous answer which describes how to compute a minimum-jerk trajectory given a consistent distance coordinate system. A simple way to do this is to treat the first coordinate as your origin then convert each other GPS point to meter distances from your first coordinate using one of the latitude and longitude equations here</p>


问:
PID Control: Is adding a delay before the next loop a good idea?
I am implementing PID control in c++ to make a differential drive robot turn an accurate number of degrees, but I am having many issues.

Exiting control loop early due to fast loop runtime

If the robot measures its error to be less than .5 degrees, it exits the control loop and consider the turn "finished" (the .5 is a random value that I might change at some point). It appears that the control loop is running so quickly that the robot can turn at a very high speed, turn past the setpoint, and exit the loop/cut motor powers, because it was at the setpoint for a short instant. I know that this is the entire purpose of PID control, to accurately reach the setpoint without overshooting, but this problem is making it very difficult to tune the PID constants. For example, I try to find a value of kp such that there is steady oscillation, but there is never any oscillation because the robot thinks it has "finished" once it passes the setpoint. To fix this, I have implemented a system where the robot has to be at the setpoint for a certain period of time before exiting, and this has been effective, allowing oscillation to occur, but the issue of exiting the loop early seems like an unusual problem and my solution may be incorrect.

D term has no effect due to fast runtime

Once I had the robot oscillating in a controlled manner using only P, I tried to add D to prevent overshoot. However, this was having no effect for the majority of the time, because the control loop is running so quickly that 19 loops out of 20, the rate of change of error is 0: the robot did not move or did not move enough for it to be measured in that time. I printed the change in error and the derivative term each loop to confirm this and I could see that these would both be 0 for around 20 loop cycles before taking a reasonable value and then back to 0 for another 20 cycles. Like I said, I think that this is because the loop cycles are so quick that the robot literally hasn't moved enough for any sort of noticeable change in error. This was a big problem because it meant that the D term had essentially no effect on robot movement because it was almost always 0. To fix this problem, I tried using the last non-zero value of the derivative in place of any 0 values, but this didn't work well, and the robot would oscillate randomly if the last derivative didn't represent the current rate of change of error.

Note: I am also using a small feedforward for the static coefficient of friction, and I call this feedforward "f"

Should I add a delay?

I realized that I think the source of both of these issues is the loop running very very quickly, so something I thought of was adding a wait statement at the end of the loop. However, it seems like an overall bad solution to intentionally slow down a loop. Is this a good idea?

```<code>turnHeading(double finalAngle, double kp, double ki, double kd, double f){
    std::clock_t timer;
    timer = std::clock();

    double pastTime = 0;
    double currentTime = ((std::clock() - timer) / (double)CLOCKS_PER_SEC);

    const double initialHeading = getHeading();
    finalAngle = angleWrapDeg(finalAngle);

    const double initialAngleDiff = initialHeading - finalAngle;
    double error = angleDiff(getHeading(), finalAngle);
    double pastError = error;

    double firstTimeAtSetpoint = 0;
    double timeAtSetPoint = 0;
    bool atSetpoint = false;

    double integral = 0;
    double derivative = 0;
    double lastNonZeroD = 0;

    while (timeAtSetPoint < .05)
    {
        updatePos(encoderL.read(), encoderR.read());
        error = angleDiff(getHeading(), finalAngle);

        currentTime = ((std::clock() - timer) / (double)CLOCKS_PER_SEC);
        double dt = currentTime - pastTime;

        double proportional = error / fabs(initialAngleDiff);
        integral += dt * ((error + pastError) / 2.0);
        double derivative = (error - pastError) / dt;

        //FAILED METHOD OF USING LAST NON-0 VALUE OF DERIVATIVE
        // if(epsilonEquals(derivative, 0))
        // {
        //     derivative = lastNonZeroD;
        // }
        // else
        // {
        //     lastNonZeroD = derivative;
        // }

        double power = kp * proportional + ki * integral + kd * derivative;

        if (power > 0)
        {
            setMotorPowers(-power - f, power + f);
        }
        else
        {
            setMotorPowers(-power + f, power - f);
        }

        if (fabs(error) < 2)
        {
            if (!atSetpoint)
            {
                atSetpoint = true;
                firstTimeAtSetpoint = currentTime;
            }
            else //at setpoint
            {
                timeAtSetPoint = currentTime - firstTimeAtSetpoint;
            }
        }
        else //no longer at setpoint
        {
            atSetpoint = false;
            timeAtSetPoint = 0;
        }
        pastTime = currentTime;
        pastError = error;
    }
    setMotorPowers(0, 0);
}

turnHeading(90, .37, 0, .00004, .12);
</code>```

答:
Don't disengage your controller.

The purpose of a controller is not only to steer your system to the desired setpoint according to a predetermined dynamical response but also to counteract potential external factors that may impede this task. Think of a disturbance that will drive the system far from the setpoint once it has been reached. Thus, the controller shall be always operational (unless you need to change the task itself and as a result change the controller too).

To this end, you would certainly need to add up the integral part, which is responsible for attaining a null steady-state error in presence of unmodeled quantities and external disturbances.

This is quite a related resource: https://robotics.stackexchange.com/a/19198/6941.

Leave out the derivative.

95% of PID controllers in the industries are PI controllers (see "Feedback Systems" Astrom, Murray) as the D part can play a significant role only with slow processes (like those concerned with temperature and tank level regulation). This is definitely not your case. Somehow related resources about the difficulties of the derivative terms are:

https://robotics.stackexchange.com/a/21556/6941.

https://robotics.stackexchange.com/a/21555/6941.

Once I had the robot oscillating in a controlled manner using only P, I tried to add D to prevent overshoot.

Well, it seems that you are following the prescriptions of Ziegler-Nichols to tune your controller. There are tables you need to stick to that give you estimates for the gains. However, these are heuristic and it's likely that won't work in your case.

Simply drop the D part and focus on the PI controller. There is also another Z-N variant that does not rely on purposely generated oscillations: https://robotics.stackexchange.com/a/21616/6941.

Never ever add up delays to the system.

Delays are bad guys to deal with in a control loop, and the worst beasts engineers have to fight against (watch this ) as they reduce significantly the phase margin pushing the overall system toward instability.

If you deem that your loop is too fast, then apply input-shaping to the setpoint (with for example minimum-jerk trajectory) to smooth out the sharp step onset. The closed-loop system will react more gracefully. Another possibility is that your P gain is too high: just detune the controller then.

In this respect, if you insert the integral term I, then you will need to reason about the sample time $T_s$ as well.


答:
It would be much better to determine a fixed sample rate for your controller.  A really rough rule of thumb is that whatever the settling time you need out of the loop once it is operating in the linear regime, your sampling interval should be between 10 times and 100 times less than the settling time.  Put another way, the sample rate should be 10 to 100 times faster than the desired loop bandwidth.

As a small added bonus, this means you can calculate dt outside the loop

By preference, the sample rate should be dictated by hardware, e.g. by a hardware timer, and even better the sampling of the position should be done by hardware, triggered off of a timer.  This significantly eases the real-time constraints on the software.

If you're using a reasonable sample rate and you're mostly not registering changes in your encoder, then your encoder doesn't have enough steps.

I'm going to disagree with @Ugo_Pattachini, in that if the loop involves a motor and your controller is clean enough, some differential action can be beneficial.  But there's a good chance that it needs to be bandlimited (i.e., you need a lead-lag controller), and if you're doing seat-of-the-pants PID tuning there's a good chance you don't have the tools to set the bandlimiting correctly.

However, if you can't enforce very tight timing on sampling the encoder, don't even try to use derivative control.  Irregular sampling times plus some velocity on your motor will make for extra noise, and derivative controllers tend to amplify noise.  If you can't arrange for a clean signal to control on, derivative control won't be suitable.

Title: PID Control: Is adding a delay before the next loop a good idea?

Body:
I am implementing PID control in c++ to make a differential drive robot turn an accurate number of degrees, but I am having many issues.

Exiting control loop early due to fast loop runtime

If the robot measures its error to be less than .5 degrees, it exits the control loop and consider the turn "finished" (the .5 is a random value that I might change at some point). It appears that the control loop is running so quickly that the robot can turn at a very high speed, turn past the setpoint, and exit the loop/cut motor powers, because it was at the setpoint for a short instant. I know that this is the entire purpose of PID control, to accurately reach the setpoint without overshooting, but this problem is making it very difficult to tune the PID constants. For example, I try to find a value of kp such that there is steady oscillation, but there is never any oscillation because the robot thinks it has "finished" once it passes the setpoint. To fix this, I have implemented a system where the robot has to be at the setpoint for a certain period of time before exiting, and this has been effective, allowing oscillation to occur, but the issue of exiting the loop early seems like an unusual problem and my solution may be incorrect.

D term has no effect due to fast runtime

Once I had the robot oscillating in a controlled manner using only P, I tried to add D to prevent overshoot. However, this was having no effect for the majority of the time, because the control loop is running so quickly that 19 loops out of 20, the rate of change of error is 0: the robot did not move or did not move enough for it to be measured in that time. I printed the change in error and the derivative term each loop to confirm this and I could see that these would both be 0 for around 20 loop cycles before taking a reasonable value and then back to 0 for another 20 cycles. Like I said, I think that this is because the loop cycles are so quick that the robot literally hasn't moved enough for any sort of noticeable change in error. This was a big problem because it meant that the D term had essentially no effect on robot movement because it was almost always 0. To fix this problem, I tried using the last non-zero value of the derivative in place of any 0 values, but this didn't work well, and the robot would oscillate randomly if the last derivative didn't represent the current rate of change of error.

Note: I am also using a small feedforward for the static coefficient of friction, and I call this feedforward "f"

Should I add a delay?

I realized that I think the source of both of these issues is the loop running very very quickly, so something I thought of was adding a wait statement at the end of the loop. However, it seems like an overall bad solution to intentionally slow down a loop. Is this a good idea?

```<code>turnHeading(double finalAngle, double kp, double ki, double kd, double f){
    std::clock_t timer;
    timer = std::clock();

    double pastTime = 0;
    double currentTime = ((std::clock() - timer) / (double)CLOCKS_PER_SEC);

    const double initialHeading = getHeading();
    finalAngle = angleWrapDeg(finalAngle);

    const double initialAngleDiff = initialHeading - finalAngle;
    double error = angleDiff(getHeading(), finalAngle);
    double pastError = error;

    double firstTimeAtSetpoint = 0;
    double timeAtSetPoint = 0;
    bool atSetpoint = false;

    double integral = 0;
    double derivative = 0;
    double lastNonZeroD = 0;

    while (timeAtSetPoint < .05)
    {
        updatePos(encoderL.read(), encoderR.read());
        error = angleDiff(getHeading(), finalAngle);

        currentTime = ((std::clock() - timer) / (double)CLOCKS_PER_SEC);
        double dt = currentTime - pastTime;

        double proportional = error / fabs(initialAngleDiff);
        integral += dt * ((error + pastError) / 2.0);
        double derivative = (error - pastError) / dt;

        //FAILED METHOD OF USING LAST NON-0 VALUE OF DERIVATIVE
        // if(epsilonEquals(derivative, 0))
        // {
        //     derivative = lastNonZeroD;
        // }
        // else
        // {
        //     lastNonZeroD = derivative;
        // }

        double power = kp * proportional + ki * integral + kd * derivative;

        if (power > 0)
        {
            setMotorPowers(-power - f, power + f);
        }
        else
        {
            setMotorPowers(-power + f, power - f);
        }

        if (fabs(error) < 2)
        {
            if (!atSetpoint)
            {
                atSetpoint = true;
                firstTimeAtSetpoint = currentTime;
            }
            else //at setpoint
            {
                timeAtSetPoint = currentTime - firstTimeAtSetpoint;
            }
        }
        else //no longer at setpoint
        {
            atSetpoint = false;
            timeAtSetPoint = 0;
        }
        pastTime = currentTime;
        pastError = error;
    }
    setMotorPowers(0, 0);
}

turnHeading(90, .37, 0, .00004, .12);
</code>```


问:
How to handle motor stall zones in differential drive point-forward go to goal algorithm?
I am implementing the Go To Goal algorithm for a differential drive robot as described here and in this video.  The issue I have is that there is a large dead zone in pwm values where the motors are stalled.  I have calibration data for each motor that measures the stall pwm and the minimum speed that the motor can turn just above stall.  I also have calibration data for the maximum speed.  I'm using optical encoders to measure the rotational speed of the wheels.  So my issue is that the point-forward algorithm controls both linear velocity and angular velocity and it is calculating wheel speeds that cannot be achieved by the robot; they are in the stall zone.  How does one handle that issue?  It seems like just upping velocities by the minimum velocity does not work because then the turning angle is too shallow to reach the goal.</p>

答: For a similar problem (TT motors can't start the bot rolling on a carpet) I have been toying with the idea of setting up PID control for the angular velocity.  If it stays stuck, the integral term will start upping the power.  Once it suddenly breaks loose, the differential term will throttle it back.  That's the idea, anyway -- someday I'll actually try it.  Tuning might be a challenge, especially since the minuscule bit of control theory I have is quite rusty by now.</p>


问:
Stationary/inertial reference frame
In Modern Robotics by Kevin Lynch, there is a term "stationary" frame, but this is never defined. Googling shows that this is synonymous with inertial frame.

Apparently inertial frame means rigidly attaching an accelerometer to a frame would show that the frame has 0 acceleration.

However, in Modern Robotics, it says body frames, which are attached to moving objects, are also inertial frames. How is this possible? If the body frame is attached to a baseball bat, and our robot swings the bat, won't the frame undergo acceleration?

答:
The frames are considered inertial because we are not considering "dynamics" (read: acceleration). Essentially, as far as my experience goes with MR, all the math around frames in the book considers that you are momentarily frozen in time, "viewing" that state of the frame at that instantaneous time. Because of this it is considered stationary and therefore inertial.

I am no expert on the matter so I'd love to hear feedback on my answer!

From Chapter 3 Page 59 of MR:

All  frames  in  this  book  are  stationary,  inertial,  frames.When we refer to a body frame{b}, we mean a motionless frame that is instantaneously coincident with a frame that is fixed to a (possibly moving) body. This is important to keep in mind, since you may have had a dynamics course that used non-inertial moving frames attached to rotating bodies. Do not confuse these with the stationary, inertial, body frames of this book.

Title: Stationary/inertial reference frame


问:
Move ATRV robot to specific distance using ROS
Is there a node or package that can send commands to /cmd_vel to move ATRV-Jr like 2 meters forward or turn it 90 degree to right/left? I don't want to tell the robot to move with specified speed. For example when I use this command rostopic pub /cmd_vel geometry_msgs/Twist '[1.0,0.0,0.0]' '[0.0,0.0,0.0]' the robot starts moving forward until I send another command or send break command.

答:
I've found this usefull:

```<code>#!/usr/bin/env python
import roslib; roslib.load_manifest('robot_mover')
import rospy

from geometry_msgs.msg import Twist

def mover():
    pub = rospy.Publisher('cmd_vel', Twist)
    rospy.init_node('robot_mover')

    twist = Twist()
    twist.linear.x = 0.1; # move forward at 0.1 m/s

    rospy.loginfo("Moving the robot forward.")
    pub.publish(twist)
    rospy.sleep(1)

    rospy.loginfo("Moving the robot backward.")
    twist.linear.x = -0.1; # move backward at 0.1 m/s
    pub.publish(twist)
    rospy.sleep(1);

    rospy.loginfo("Turning the robot left.");
    twist = Twist();
    twist.angular.z = 0.5
    pub.publish(twist)
    rospy.sleep(1);

    rospy.loginfo("Turning the robot right.");
    twist.angular.z = -0.5
    pub.publish(twist)
    rospy.sleep(1);

    rospy.loginfo("Stopping!")
    twist = Twist()
    pub.publish(twist)

    rospy.loginfo("Node exiting.");

if __name__ == '__main__':
    try:
        mover()
    except rospy.ROSInterruptException: pass
</code>```

Source: http://pharos.ece.utexas.edu/wiki/index.php/Writing_A_Simple_Node_that_Moves_the_iRobot_Create_Robot

Body:
I've found this usefull:

#!/usr/bin/env python
import roslib; roslib.load_manifest('robot_mover')
import rospy

from geometry_msgs.msg import Twist

def mover():
    pub = rospy.Publisher('cmd_vel', Twist)
    rospy.init_node('robot_mover')

    twist = Twist()
    twist.linear.x = 0.1; # move forward at 0.1 m/s

    rospy.loginfo("Moving the robot forward.")
    pub.publish(twist)
    rospy.sleep(1)

    rospy.loginfo("Moving the robot backward.")
    twist.linear.x = -0.1; # move backward at 0.1 m/s
    pub.publish(twist)
    rospy.sleep(1);

    rospy.loginfo("Turning the robot left.");
    twist = Twist();
    twist.angular.z = 0.5
    pub.publish(twist)
    rospy.sleep(1);

    rospy.loginfo("Turning the robot right.");
    twist.angular.z = -0.5
    pub.publish(twist)
    rospy.sleep(1);

    rospy.loginfo("Stopping!")
    twist = Twist()
    pub.publish(twist)

    rospy.loginfo("Node exiting.");

if __name__ == '__main__':
    try:
        mover()
    except rospy.ROSInterruptException: pass

Source: http://pharos.ece.utexas.edu/wiki/index.php/Writing_A_Simple_Node_that_Moves_the_iRobot_Create_Robot


问:
What can cause yaw rotation on a multirotor when yaw control is disabled?
Let's assume that I assembled a multicopter (quadcopter, hexacopter or octocopter) and let's say that I disable yaw control on it while roll and pitch controllers are enabled.

Now let's assume that I require it to hover in a specific xyz point.

What could cause the multicopter to indefinitely yaw?

My answers are:

imbalance between the RPMs provided by the motors (e.g., I ask the motors a specific RPM values X (to hover) and some of them provide (consistently) X+delta).

motors not all aligned among each other and therefore able to exert a thrust perfectly aligned with gravity (correct?)

broken propellers

Is there something else that does not come to my mind?

I am asking since my octorotor, with the yaw controller enabled, tries to compensate all the time an almost constant yaw rate if I ask it to maintain a certain yaw angle. Therefore, I am thinking about a structural problem.

答:
A disturbance yaw rate of $-0.1, \text{deg/s}$ seems way low. Are sure that in steady-state there won't be any cause external to your copter (very low airflow?) justifying it?

Imbalance between the RPMs provided by the motors (max current not reached) ❌

The open-loop response of different motors will certainly vary because of the variability of the building components. Thus, if commanded with the exact same input voltage, different motors will respond with slightly different speeds.

However, closed-loop control is purposely designed and implemented to overcome this type of imbalance. So, nope; this is unlikely to be the problem if your controllers are up to the task.

This reasoning is valid if all the process controllers+motors do work in their "linear" range so that there's no saturation.

Imbalance between the RPMs provided by the motors (max current reached by one or more controllers) ❌

Differently, if you realize that one or more controllers provide the maximum allowed current, then the corresponding motors are clearly not able to deliver the requested speed and you may be in the situation you reported.

It is however unlikely that you had to deliver maximum current to a motor and this won't cause trouble to pitch and roll as well.

Variability of speed sensors ❌

Variability of the components in the speed sensors may impede the control. The outer loop, which is closed over IMU feedback, should adapt for such a difference in speed setpoints. Anyway, the inner speed control loop will experience a constant thrust that it will be required to compensate for.

It is unlikely that sensor variability affects only the yaw though.

Motors not all aligned among each other ✅

This is the most likely cause, yep. It is concerned with a structural configuration of your propellers and can possibly generate a nonnull yaw rate.

Broken propellers ❌

I tend to rule out this as you would have realized it visually, instead, plus it would have affected the pitch and roll as well.


问:
Trouble aligning/calibrating camera with laser scanner
I have a robot which has 2 multi-spectral cameras and 1 laser scanner attached. In the end I would like to have the images from the cameras aligned with the scanner so that I can have spectral information added to the scanner's point cloud. However I am having some troubles with the final alignment and am struggling to find a way to identify the location of the error. I was thus wondering if any of you know of any datasets or online exercises that deal with this problem where the correct outputs are given? ION this way I could test my approach on the dataset and see where my errors stem from.</p>

答:
Within ros there is a lidar_camera_calibration package that should take care of this for you! Their github page has a detailed readme. If you aren't using ros, you can probably take a look at the core functions and compare it with your work.

Autoware foundation has also released their own autoware_camera_lidar_calibrator package which is more recent.


问:
Sprockets for steering
I'm planning to drive the steering of a AWD rover using stepper motors. Is it usually a good idea to use sprockets and chains for that? Would the precision typically be too low for steering? The sprockets would spin along the direction of gravity - would that pose a problem as the chains would always sit on the same face of the sprockets?

Any advice appreciated.

答:
Is there any special requirement for a very precise steering?

Do you heavily rely on dead reckoning and your sensors are before the chain?

If not, you can add a tensioner for the chain and it should be fine for steering.

Title: Sprockets for steering


问:
Compute how well a laser scan matches or overlaps with its environment given a map of the environment and location of the robot is known
If I knew the exact location of my robot and have an accurate map (for eg. an occupancy grid map) of the environment beforehand, how can I compute a measure of how well the laser scan data agree with the given map ?</p>

答:
You should look into localization algorithms. A good source is the book Probabilistic Robotics - W. Burgard, D. Fox and S. Thrun.

If you just want to compute somehow how well it agrees you could try to compute the Root Square Mean Error of the closest point of your measurement to the point in the occupied square in the grid describing the map, given an accurate robot position and map description.


答:
You might find that the rPI boards are more durable than you expected.  There isn't much mass to them, so a small amount of rubber or foam padding (to reduce rattling around) should be sufficient to protect them -- provided that your robots aren't bashing together with enough force to crack the plastic casing around them.

Offloading the processing onto a remote (and likely more powerful) system will give you a few advantages, like the ones you've noted -- less weight, less to break, less battery required to move the thing around.

The downsides will be the bandwidth limitations, and the latency.  Once you introduce the delay of wireless transmissions, you go from a hardware-based loop that can handle in the ballpark of thousands of iterations per second to a networking-based loop that can handle only dozens of iterations per second.

For best results, your design should do as much control processing as possible on the local hardware, and use the remote connection for higher-level planning decisions that only will need to be received a few times per second.

Title: Making a tiny robot by using a remote brain

Body:
I'd like to build a robot as small as possible and with as few "delicate" parts as possible (the bots will be bashing into each other).

I was wondering if it was possible to use a small chip that could receive bluetooth/IR/wifi commands to move the motors, and in turn, send back feedback based on sensors such as an accelerometer (to detect impact).

I can probably achieve something like this with the PiCy

however this is slightly bigger than I'd like (due to the size of the Pi) and I'm not sure how long the Pi would last taking continuous impacts.

I'd therefore like to try to offset the brain (the Pi) to the side of the arena and just use a small chip to receive move commands, and send back data from the accelerometer.

Do you have any recommendations for such a chip? Wifi would be my choice but if it impacts the size I could try BT

Edit: After further research it seems an Arduino nano with a WiFi RedBack shield might do the job along with something like this for the motors: http://www.gravitech.us/2mwfecoadfor.html


问:
Encoder based speed control for Rover 5
I am trying to get precise control over the speed of rover 5 based robot. It has four PWM controlled motors and 4 Optical Quadrature Encoders. I am using 4-channel motor controller with rover 5 chassis. I am using arduino Nano for control. I am able to read encoder INT output and change PWM based on pulse width to control speed. But, as a result, I am getting heavy oscillations in the control output. That makes, the robot to move in steps, as PWM is changing constantly. I need an algorithm which can minimize this ringing and have a smooth moving robot. Here is my arduino code snippet.

```<code>void setup() {
    Serial.begin(9600);
    init_motors();
    init_encoders();
    req_speed[0] = 20;
    req_speed[1] = 20;
    req_speed[2] = 20;
    req_speed[3] = 20;
}

void loop() {
  update_encoders();
  update_motors();
}

void update_motors() {
  int i, err;
  unsigned long req_width;
  if(micros() - mtime > 2999) {
    mtime = micros();

    for(i=0; i<4; i++) {
      digitalWrite(pins_dir[i], req_speed[i]>0);
      if(mtime - change_time[i] > 50000ul && req_speed[i] != 0) {
        cur_pwm[i] += 5;
      }
      if(req_speed[i] > 0)
        cur_err[i] = req_speed[i]*10  - cur_speed[i];
      else
        cur_err[i] = (-req_speed[i]*10)  - cur_speed[i];
      if(cur_err[i] > 0 && cur_pwm[i] < 255) {
        cur_pwm[i]++;
      } else if(cur_err[i] < 0 && cur_pwm[i] > 0) {
        cur_pwm[i]--;
      }
      analogWrite(pins_pwm[i], cur_pwm[i]);
    }
  }
}

void update_encoders() {
  int i;
  unsigned long w;
  enc_new = PINC & B00001111;
  unsigned long etime = micros();
  for (i=0; i<4; i++) {
    if((enc_old & (1 << i)) < (enc_new & (1 << i)))
    {
      w = (unsigned long)(((etime - change_time[i])));
      pulse_width[i] = (w + pulse_width_h1[i] + pulse_width_h2[i])/3;
      pulse_width_h2[i] = pulse_width_h1[i];
      pulse_width_h1[i] = pulse_width[i];
      change_time[i]=etime;
      pulse_count[i]++;
      cur_speed[i] = (3200000ul / pulse_width[i]);
    }
  }
  enc_old=enc_new;
}
</code>```

Here req_speed is between -100 to 100, where sign indicates direction. Please consider all undefined variables as globals. I experimentally measured that, when motor is running at full speed, the pulse width is around 3200us.

Encoders' INT outputs (XOR of A and B) are connected to A0 thru A3. Motor PWM is connected to D3, D5, D6, D9. Please let me suggest any improvements to this code and advice me about what am I missing here.

答: The update_motors() method looks like it implements a constant step controller, basically increasing pwm if too slow, decreasing pwm if too fast.  What I also see is the calculated error involves multiplying the set point req_speed by 10, which exagerates the error, which can definitely cause oscillations.  Also there is no tolerance value 'close to zero' for the error, so it will always oscillate.  Finally, I don't see any feed forward logic; estimating the initial PWM when the setpoint changes from zero can make a big different in how fast the controller converges on the setpoint.  My project also uses a constant step controller for speed control and implements feed-forward; it works pretty well.  You will still need lateral control in order to do a good job of holding a line, as any initial speed differential between the wheels can create an angular offset that will not be corrected by simple speed control.  See that project's go-to-goal behavior for an example.

Title: Encoder based speed control for Rover 5


问:
Forward and Revers Kinematics For Modified Hanging Plotter
I'm building a modified version of the standard hanging plotter (v-plotter). The basic idea is that you have two cables hanging from stepper motors which form a triangle supporting the pen at the tip.

My design the strings anchored at points $C$ and $D$ which causes the behavior to be somewhat different that the normal plotter, especially when operating close to the motors.

I was able to work out the forward kinematics fairly easily, but the inverse kinematics are turning out to be a real headache. You can see my attempt at a standard geometry solution on math.stackexchange here.

Is there anything specific to calculating kinematics for robotics which could help me?

I'm not interested in modifying the hardware to make the math easier. I'm also not interested in discussing the center of gravity of the pen, cable weight...etc. I want to calculate the kinematics for this as an ideal system.

Any and all advice is appreciated.

Thank you.

答: The kinematics model which Keith Selbo contributed (and OP Bar Smith posted) is great. I've implemented it in Java for use in the g-code generator for a hanging plotter that I'm building. I haven't totally tuned it, but it already provides better results than treating the system as a simple triangle and using Pythagorean theorem.</p>


问:
How to make an "invisible line following robot"?
I would like to build a robot which follows a virtual path (Not a visible path like a 'black line on a white surface', etc).

I'm just enthusiastic by seeing some sci-fi videos which show robots carry goods and materials in a crowded place. And they really don't follow a physical line. They sense obstacles, depth, etc.

I would like to build one such robot which follows a specific (virtual)  path from point A to B.

I have tried a couple of things:

Using a magnetic "Hall effect" sensor on the robot and wire carrying current (beneath the table). The problem here was that the vicinity of the hall effect sensor is so small (< 2cms) that it is very difficult to judge whether robot is on the line or off the line. Even using series of magnets couldn't solve this issue, as my table is 1 inch thick. So this idea flopped :P

Using an ultraviolet paint (on a line) and using UV leds on the robot as sensors. This will give more Zig-Zag motion for the robot. And due to potential threats of using UV light source, even this idea flopped :P

I finally thought of having a camera on top and using image processing algorithms to see whether robot is on the line or diverging.

Is there any better solution than this? Really looking for some creative and simple solutions. :)

答:
I've made a small robot that follows a virtual path drawn on a smartphone under an NSF funded research grant.

The way you would make a robot follow a virtual path is to use the Pure Pursuit path following algorithm along with dead reckoning.

I developed the following C++ Arduino libraries for virtual robot path following:

Dead reckoning library - Dead reckoning for differential drive robots using encoders. The key limitation with this library is that only encoders are used to determine position.

PreMo (Precise mover library) - Contains the implementation for pure pursuit for path following. Designed for easy implementation for students and hobbyists.

These libraries can be modified to work on other platforms than the Arduino.

About pure pursuit algorithm

Dead reckoning library

Precise movement library


问:
PID control brushed motors via PWM using Encoder Clicks at SetPoints/Measurements
I've read numerous posts (1 , 2, 3 ) about using PID to control motors. All examples I've seen deal with the control signal being in the same units as the measurement signal. For example, use PID to set PWM values and measure PWM values as feedback or read stepper motor values in encoder clicks and then set new motor values also in clicks.

What I'm not understanding is how does one use PWM as the control when the measurements are in Encoder Clicks as would be common on a DC brush motor with encoder. How does the output of the PID taking Clicks as input, outputs and setpoint get translated to an appropriate 0 to 255 PWM signal (Assuming 8-bit PWM)?

It seems like there's a fundamental disconnect between the encoder clicks which can be though of as velocity (change of distance over time) vs PWM control signal which is an amount of power provided to the motor.

My naive guess would be to:

Determine the MAX encoder clicks per second at a given PWM value of 255 emperically.

Determine the MIN encoder value for the PWM value right before the motor stops moving under load. (For example my Pololu motors need at least 60 PWM on my motor controller to actually turn, below that value they just 'whine'.)

Linearly map the encoder readings from the MIN and MAX to an appropriate MIN and MAX PWM reading?

```<code>// Using the Arduino PID library
encoderLow = 60;   // determined empirically
encoderHigh = 8400;// determined empirically
PWMLow = 60; // determined empirically
PWMHigh = 255;  // PWM as which we reach encoderHigh

Input = reading_from_encoder();  // clicks per second
Setpoint = 1000; // also in clicks
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
translated_pwm = map(Output, encoderLow, encoderHigh, PWMLow, PWMHigh)
drive_motor(translated_pwm); // control signal to motor as PWM value.
</code>```

Where Input (the feedback from the encoders), Setpoint, and Output are in clicks. Output is the control signal from the Arduino PID library

Questions:

Is this the normal approach?

My map() function assumes a linear relationship between encoder values and PWM values. I doubt that's true. Is the PID going to compensate for the nonlinearities?

What is the correct way to do this?

答:
Output of a PID controller is a some kind of force ratio that will be applied to your motor. And the input of your PID is the error of what you are trying to control (velocity, position, torque etc.) so the input and the output dont have to be in same unit. it depends on what  you are controlling with your pwm module.

Let's say you are trying to control your motor speed. first you have to calculate the difference between your target speed and current speed. Then you will send this error to your pid function. The output of your pid function is your DUTY CYCLE. Lets say your pwm resolution is 8 bits. So your code will look like this:

```<code>float error=TargetSpeed-CurrentSpeed;

int duty=CalculatePID(error);

if(duty>0)
 SetDirectionPinHigh();
else if(duty<0)
{
  SetDirectionPinLow();
  duty=-duty;
}
analogWrite(MotorPin,duty);
</code>```

....

```<code>    int CalculatePID(float error)
    {
        TotalError+=error;  /// TotalError is used for integral term and is the sum of all previous errors
        /// it is useful to limit this value (anti-wind up)
        int duty= kp*error+ki*TotalError+kd*(error-PreviousError);
        PreviousError=error;
        /// Check the duty value if it is between 0 and 255
        if(duty>255)
          duty = 255;
        else if(duty<-255)
          duty = -255;
    return duty;
    }
</code>```

I hope this example helps. Dont get confused with input and output units of pid. it is a closed loop control so it will adjust the right force by itself eventually. The key here is to tune pid parameters correctly.

Body:
Output of a PID controller is a some kind of force ratio that will be applied to your motor. And the input of your PID is the error of what you are trying to control (velocity, position, torque etc.) so the input and the output dont have to be in same unit. it depends on what  you are controlling with your pwm module.

Let's say you are trying to control your motor speed. first you have to calculate the difference between your target speed and current speed. Then you will send this error to your pid function. The output of your pid function is your DUTY CYCLE. Lets say your pwm resolution is 8 bits. So your code will look like this:

float error=TargetSpeed-CurrentSpeed;

int duty=CalculatePID(error);

if(duty>0)
 SetDirectionPinHigh();
else if(duty<0)
{
  SetDirectionPinLow();
  duty=-duty;
}
analogWrite(MotorPin,duty);

....

    int CalculatePID(float error)
    {
        TotalError+=error;  /// TotalError is used for integral term and is the sum of all previous errors
        /// it is useful to limit this value (anti-wind up)
        int duty= kp*error+ki*TotalError+kd*(error-PreviousError);
        PreviousError=error;
        /// Check the duty value if it is between 0 and 255
        if(duty>255)
          duty = 255;
        else if(duty<-255)
          duty = -255;
    return duty;
    }

I hope this example helps. Dont get confused with input and output units of pid. it is a closed loop control so it will adjust the right force by itself eventually. The key here is to tune pid parameters correctly.


问:
Scara chess robot design for 3d printing
I have two question regarding a Chess robot.

I want to build a Scara  robot that could play chess on a 37 x 37 cm chess board, but I couldn't find any design that can cover the whole chess board and an extra space to throw dead pieces, and I have no experience in editing 3d printer files, so where I could find such designs for free?

What is the best total length for Scara robot arm to be able to cover the whole chessboard and an extra area to throw the pieces?

答:
1- Grabcad is a good source for free 3D material: https://grabcad.com/library

2- The "best" total length, depends on lots of factors. You want it to be 37x37cm, ok, but that workspace will require a conscientious analysis and design of other components as well -> Mostly the arms geometry. You can check on the design of cantilever beams and static stress calculation. If your arm is too long (more than 30, 40cm), it's better to double check these kind of things before building it.

OwnerDisplayName: Ali


答:
They use of sprockets over synchronous belts depends on the power you need to move the rover steering.

I wouldn't use sprockets + chains, mostly because moving the chains requires more power than moving the synchronous belts, so you're basically wasting power there. Of course, if you need a high power steering.

With regards to the precision, it should be fine if you have a chain tensor.

Now, with the chain always resting on the same side, that could cause more wear in the long term, but I believe the rover will end it's useful life before you worry about changing the sprocket or the chain (in a motorcycle a sprocket+chain kit can last 20-25k km / 12-15k miles).

Title: Sprockets for steering

Body:
I'm planning to drive the steering of a AWD rover using stepper motors. Is it usually a good idea to use sprockets and chains for that? Would the precision typically be too low for steering? The sprockets would spin along the direction of gravity - would that pose a problem as the chains would always sit on the same face of the sprockets?

Any advice appreciated.


问:
5 bar linkage hand exoskeleton
I have a project to design a hand exoskeleton for hand rehabilitation. The problem is that i'm thinked I only need the linkage mechanism with multiple 4 bar linkages. But because of human fingers joints and linkage supports on middle of each phalange I realised that there are 5 bar linkages and I really can't figure it out how to solve it or what equations should I use. The mechanism is driven by one actuator. Any help would be appreciated!

Here's an image for reference.

答:
With 5 bar linkages, you either need two inputs (one per each bar), or you need to couple the movement from one bar to the other (with gears for example), and then have only one input. Input meaning the rotation angle of the bars connected to the grounded link.

In case it might be useful, here are the equations of the inverse kinematics of a 5 bar linkage. Also remember that for closed chain linkages the direct kinematics is far more complicated than the inverse kinematics (unlike for open chain linkages).

In my opinion there is missing information in the paper you took as reference.

Title: 5 bar linkage hand exoskeleton


问:
How do I calculate components of an angular rate on end effector frame?
I’ve helped develop the forward kinematic chain for a two-axis gimbal. The Denavit-Hartenberg parameter table for the kinematic chain is given below.

$\theta$
$\alpha$
$r$
$d$

$90^{\circ}$
$90^{\circ}$
$0$
$0$

$180^{\circ} + θ_{1}$
$90^{\circ}$
$0$
$0$

$180^{\circ} + θ_{2}$
$180^{\circ}$
$0$
$0$

If a known angular rate was applied to a particular joint in the kinematic chain, is there a way of determining the components of that angular rate which would be observed on the end effector frame? For example, if $\theta_{1}$ is rotated at $10$ deg/sec and $\theta_{2}$ equals $270^{\circ}$, what would be the rates observed on the x, y and z axes of the end effector?

答:
You can calculate that with the Angular Jacobian ($J_\omega$) of the gimbal (see details here).

Based on your D-H, your angular Jacobian should look like:

$$ {\
  J_\omega=
  \left[ {\begin{array}{cc}
   0 & 0 \\
   -\sin(\theta_1) & \sin(\theta_1) \\
    \cos(\theta_1) & -\cos(\theta_1) \\
  \end{array} } \right]
\
}$$

So to obtain the angular speeds of the end efector ${\omega_x, \omega_y, \omega_z}$ as seen from a grounded frame, you multiply $J_\omega$ by the vector of joint angular speeds $[\dot{\theta}_1, \dot{\theta}_2]^{T}$.

I ran quick calculations, so you need to verify if the Jacobian is correct. But I hope you got the idea.


问:
How can I improve DC Motors rise time?
```<code>int16_t CalculatePID(MotorHandleTypeDef *motor)
{
    float error = motor->TargetSpeed-motor->Speed;
    /// calculate total error
    motor->PID.TotalError+=error;
    /// Check if the calculated total error value is in boundries
    if(motor->PID.TotalError>motor->PID.MaxTotalError)
        motor->PID.TotalError=motor->PID.MaxTotalError;
    else if(motor->PID.TotalError<-motor->PID.MaxTotalError)
        motor->PID.TotalError=-motor->PID.MaxTotalError;
    /// Calculate the result of PID
    float duty=(motor->PID.P*error) + (motor->PID.I*motor->PID.TotalError)+(motor->PID.D*(error-motor->PID.PreviousError));
    motor->PID.PreviousError=error;
    if(duty>1)
        duty+=motor->PWM_Offset;
    else if(duty<-1)
        duty-=motor->PWM_Offset;
    duty+=motor->PID.FeedForward*motor->TargetSpeed;

    /// Check if the Calculated Duty values are in boundries
    if(duty>motor->MaxDuty)
        duty=motor->MaxDuty;
    else if(duty<-motor->MaxDuty)
        duty=-motor->MaxDuty;
    /// Return calculated value
    motor->Duty=duty;
    return (int16_t)duty;
}
</code>```

Hi everyone.

I am trying to make an efficient dc motor speed controller and this is my PID update function. I am running my update loop in 1 kHz. The DC Motor I am using is 24 VDC 100 Watt with 6000 CPR quadrature encoder. I am using Single Dimensional Kalman Filter to calculate motor speed that is running in 2 kHz. With this method there is almost no delay and ripple in speed calculation yet I am keeping my pid frequency lower than encoder update frequency to avoid errors that can be caused by the lag. I have tuned the PID parameters using Genetic Algorithm by using 400 individuals so I am thinking that the parameters are almost at their best. I am also applying  speed feed forward control that's coefficient is 0.95.

Open loop step response of the motor has a rise time of 150 ms and the best rise time that I get with PID is 55 ms. I have posted one the output samples for lower 10 and 20 RPMs. (Dont worry about the overshoot. There is a motion planner on higher control level so it will be tolarated)

I would like to know if there is a way to lower this rise time to  around 30ms or is this the best I can get from a brushed DC motor?

答:
Besides the control code, I wonder whether the physics is worth a look:

Is there enough instantaneous torque to accelerate the rotor's moment of inertia as fast as you want?

The torque is proportional to the current.  Slow current risetime will give you slow acceleration.

dI/dt = V/L.  The motor inductance (L) limits how fast the current can increase (dI/dt).  Your 24 VDC motor might briefly tolerate a voltage (V) higher than 24 V -- if you trust your control code not to keep it high for long!

Title: How can I improve DC Motors rise time?


问:
Gazebo freezes on vm after running roscore
I'm a beginner in ROS, since the learning curve for ROS is steep i decided to use a book to learn how to use ros ([ROS Robotics Projects - Second Edition][1]). I'm currently on the third chapter. I'm learning how to create URDF files and connect ROS with Gazebo. I'm trying to test the robot base and see how it moves in gazebo but when i type the code

```<code>$ roslaunch robot_description base_gazebo_control_xacro.launch
</code>```

Gazebo opens up but never passes the loading screen and it just stays frozen throughout. I decided to check gazebo's site and i realized in the book we didn't created a world file but if that was the issue shouldn't gazebo open up at least and give an error?
I'm currently using ROS melodic on Ubuntu 18.4 running on VirtualBox
My PC specs are:
Hp Envy m4,
Intel core i7-3632QM 4 cores,
8gb RAM,
My virtualbox settings:
25gb storage,
4gb RAM,
Display | Video Memory: 128 MB,
Acceleration: 3D,
Number of CPUs: 1.
Do you think the reason my gazebo freezes is because of my laptops specs? If so do you think it'll run better if i dual boot or use windows subsystem for linux and which option do you think is better?
Thank you
[1]: https://www.packtpub.com/product/ros-robotics-projects-second-edition/9781838649326

答:
Dual booting is always a better option. It allocates all your resources for linux to use and since ros is built on top of ubuntu, you are better off dual booting. Moreover, if you are learning ros and going to be using it often, why not dual boot?

That being said, gazebo should run in your vm (given your specs). Can you launch gazebo normally (without your xacro file)? If not, do any errors show up? gazebo comes with some empty world examples. Try to see if you can load those. If you can, then your gazebo installation and runtime is probably fine and your issue stems from the xacro file you created. If gazebo throws some erros/freezes in a similar way, you probably should reinstall gazebo.


问:
How to calculate potential enegy of manipulator dynamics?
I'm trying to obtain dynamics of a 4 DOF robot. Firstly, I calculated all Transformation matrices and Jacobians. While solving Lagrangian there is two main things one is kinetic energy and the other is potential energy . The kinetic energy is simplified into D matrix and Coriolis's factor, which to find the gravitational factor in lagrangian method , we need to find the potential energy. My problem is in that potential energy which is equal to P=mgh . I don't know what does that h correspond to and how to find the value of h . Could some one help me solving this issue ?

答: We have the position of the COM of the $i_{th}$ link with respect to the $(i-1)_{th}$ frame (or joint). Also, the homogeneous transformation matrix relating the $(i-1)_{th}$ frame to the $0_{th}$ frame is known from the DH parameters. We simply multiply them in order get the transformation matrix of the $i_{th}$ link's COM w.r.t to $0_{th}$ frame. The $3rd$ element of the $4th$ column of the resultant matrix is the height of the COM from the ground.


答: In my project I did exactly what you suggested; I measured calibration data for minimum speed/pwm and maximum speed at pwm = 255.  Anything below minimum pwm is in the stall zone and yields zero velocity.  I used this calibration data to calculate a feed-forward estimated pwm for the velocity set point, assuming linear relationship between velocity and pwm above the stall zone.  The feed-forward estimate is applied when the velocity set point changes significantly. This causes the control to converge on the set point very quickly. Then I use a very simple constant-step controller (not PID) to do closed-loop control on the velocity.  The constant-step controller requires no further calibration.  The combination works very well for my simple differential drive robot and requires no calibration other than measuring min/max speed and pwm.</p>

Title: PID control brushed motors via PWM using Encoder Clicks at SetPoints/Measurements

Body:
I've read numerous posts (1 , 2, 3 ) about using PID to control motors. All examples I've seen deal with the control signal being in the same units as the measurement signal. For example, use PID to set PWM values and measure PWM values as feedback or read stepper motor values in encoder clicks and then set new motor values also in clicks.

What I'm not understanding is how does one use PWM as the control when the measurements are in Encoder Clicks as would be common on a DC brush motor with encoder. How does the output of the PID taking Clicks as input, outputs and setpoint get translated to an appropriate 0 to 255 PWM signal (Assuming 8-bit PWM)?

It seems like there's a fundamental disconnect between the encoder clicks which can be though of as velocity (change of distance over time) vs PWM control signal which is an amount of power provided to the motor.

My naive guess would be to:

Determine the MAX encoder clicks per second at a given PWM value of 255 emperically.

Determine the MIN encoder value for the PWM value right before the motor stops moving under load. (For example my Pololu motors need at least 60 PWM on my motor controller to actually turn, below that value they just 'whine'.)

Linearly map the encoder readings from the MIN and MAX to an appropriate MIN and MAX PWM reading?

```<code>// Using the Arduino PID library
encoderLow = 60;   // determined empirically
encoderHigh = 8400;// determined empirically
PWMLow = 60; // determined empirically
PWMHigh = 255;  // PWM as which we reach encoderHigh

Input = reading_from_encoder();  // clicks per second
Setpoint = 1000; // also in clicks
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
translated_pwm = map(Output, encoderLow, encoderHigh, PWMLow, PWMHigh)
drive_motor(translated_pwm); // control signal to motor as PWM value.
</code>```

Where Input (the feedback from the encoders), Setpoint, and Output are in clicks. Output is the control signal from the Arduino PID library

Questions:

Is this the normal approach?

My map() function assumes a linear relationship between encoder values and PWM values. I doubt that's true. Is the PID going to compensate for the nonlinearities?

What is the correct way to do this?


问:
wheeled vehicle forward velocity from RPM brushless data
I'm trying to hack an electric RC car with the goal to make it autonomous, as part of my PhD research.
The mounted ESC is able to send back telemetry data, including the spinning velocity (in RPM) of the brushless motor used as tracking system.

I'm wondering if it could be possible to estimate the vehicle forward velocity from this information, noting that the vehicle has three differentials and therefore negating a trivial relation between wheel velocities and motor rotations.

I'm aware that there is no way to detect slipping, but I the car will work with modest velocities and smooth accelerations, therefore an estimate of the wheel velocities should still be a significant information in e.g. a Kalman filter that fuses it with IMU data.

I've searched for anything related in literature, but nothing seems to be released on this topic.

Note: vehicle differentials are supposed to be configured as open differentials, but not sure of this.

答: This project does exactly that on an RC car.  The author is a top competitor in the DIYRobocars community; it's the blue car in this video. He uses tachometry from the brushless motor, an IMU and visual odometry for localization.  I don't know the code well enough to point you to any specific file.</p>


问:
Making a tiny robot by using a remote brain
I'd like to build a robot as small as possible and with as few "delicate" parts as possible (the bots will be bashing into each other).

I was wondering if it was possible to use a small chip that could receive bluetooth/IR/wifi commands to move the motors, and in turn, send back feedback based on sensors such as an accelerometer (to detect impact).

I can probably achieve something like this with the PiCy

however this is slightly bigger than I'd like (due to the size of the Pi) and I'm not sure how long the Pi would last taking continuous impacts.

I'd therefore like to try to offset the brain (the Pi) to the side of the arena and just use a small chip to receive move commands, and send back data from the accelerometer.

Do you have any recommendations for such a chip? Wifi would be my choice but if it impacts the size I could try BT

Edit: After further research it seems an Arduino nano with a WiFi RedBack shield might do the job along with something like this for the motors: http://www.gravitech.us/2mwfecoadfor.html

答:
I think I may have found the perfect controller for this project:

http://www.robotshop.com/en/dagu-micro-magician-robot-controller.html

The Micro Magician will allow me to control 2 simple DC motors, detect impacts and crashes with the accelerometer AND receive move commands from the IR receiver! Pretty awesome for the size.

The only piece left in the puzzle is sending back the data to the remote controller (accelerometer data). I'm not sure if I could attach an IR transmitter or maybe BT/Wifi?

Edit: looks like this could do the job! http://www.dawnrobotics.co.uk/dagu-arduino-bluetooth-module/

Now to find small motors...


问:
Where to learn ROS?
I am trying to learn ROS and so I was looking for some guide or tutorial series. I already managed to set up ROS Kinetic on a Raspberry Pi and ROS Noetic on a Ubuntu VM. I am quite experienced in Python and just need to learn ROS. Where is a good place to start. All the places I looked at were paid. I also have a basic robot setup with a L298N, 2 DC motors, and a camera.</p>

答: The official ROS tutorials are the best place to start. If you go through each of them (shouldn't take too long given your skill set), you will learn all the basics needed to start using widely available complex packages!</p>

Title: Where to learn ROS?


问:
Does the Grbl have S-curve or harmonic velocity profiles?
I'm working on a machine and the position has a high impact by the jerk and acceleration of the machine. I'm using Grbl for my machine. Does Grbl has S-curve or Harmonic velocity profiles?</p>

答:
grbl has a trapezoidal velocity profile. It has an acceleration limit (so a ramp on the velocity), but does not set a jerk limit. Jerk limiting would be probably an overkill for stepper-motors. However, grbl does use smooth stepping on for the stepper motors, this reduces the stepping frequency induced vibrations.

Source: here


问:
How can I draw a line using rotation of two circles?
I’m building a drawbot with a self imposed constraint that it’s method of motion is just two rotating disks. One holding the paper and one holding the pen. However, the math to calculate the right rotations in order to move the pen along a given line (eventually an entire vector line art image) eludes me. Can someone point me in the right direction?

I’ve attached an image of the basic idea/layout of the discs since that should make things clearer than my description. :) (note that in order to allow the Center of the pen disk to be outside the paper disk’s area, the pen disk is intentionally larger in size so it can still reach the center of the paper)

答:
Your line has a series of XY coordiantes relative to an arbitrary frame of reference, e.g. the center of the page you are drawing on, or even, the beginning of the line you are drawing.

The key is to take the XY coordinate and convert them to rotation angles for the tow rotation axes. You have to find two equations which link the two angles ($q_1, q_2$) to the XY coordinates:

$$x = f_1(q_1, q_2)$$
$$y = f_2(q_1, q_2)$$

or the other way around

$$q_1 = g_1(x, y)$$
$$q_2 = g_2(x, y)$$

Obviously the relative position of the centers of your circles to the chosen fixed reference plane will play a role here. You should start by choosing the frame of reference, project all distances to the X and Y axes and try to link everything together with geometrical relationships and get to the equations above.


问:
Stationary/inertial reference frame
In Modern Robotics by Kevin Lynch, there is a term "stationary" frame, but this is never defined. Googling shows that this is synonymous with inertial frame.

Apparently inertial frame means rigidly attaching an accelerometer to a frame would show that the frame has 0 acceleration.

However, in Modern Robotics, it says body frames, which are attached to moving objects, are also inertial frames. How is this possible? If the body frame is attached to a baseball bat, and our robot swings the bat, won't the frame undergo acceleration?

答:
Due to the way that frames are defined in the Modern Robotics book (and in this type of vector-field mechanics in general, such as those of Featherstone), both the spatial frame and the body frames are defined as stationary inertial frames. This requires a bit of a different conceptual understanding than the more traditional moving frames that have been "attached" to moving bodies in most dynamics textbooks.

As stated in the MR quote in the answer by JJB_UT, the body frames that are used to perform calculations at each instant in time are defined as the stationary inertial frames that are in the same pose (position and orientation) as the more classic moving body frames might be at that same instant. This key difference is what enables a lot of the simpler math in MR compared to other dynamics textbooks and notations.

Cheers,
Brandon

Title: Stationary/inertial reference frame


问:
Concatenate Jacobian matrices
I have a manipulator A with known Jacobian matrix and manipulator B with also known Jacobian matrix. Now I want to chain them, B will be attached at the end of A. How do I get the Jacobian of this manipulator? Can I just multiply the both knwon Jacobian matrices?</p>

答:
Unfortunately is not as straightforward as multiplying them.

The Jacobian of B is considering that the first body is fixed to the plane. You would need to add the velocity at that point, which is the end-point of the first Jacobian.

Basically, you would have an intermediate point, which needs to have the precedent velocity and with some math manipulation, you could get to the full end Jacobian. q

Title: Concatenate Jacobian matrices


答: In addition to the ROS tutorials already mentioned by Akhil Kurup, Robotis has a list of resources here. There are YT videos and a free e-book. Some of them are centered around their Turtlebot kit, but there are also general ROS info.</p>

Title: Where to learn ROS?

Body: I am trying to learn ROS and so I was looking for some guide or tutorial series. I already managed to set up ROS Kinetic on a Raspberry Pi and ROS Noetic on a Ubuntu VM. I am quite experienced in Python and just need to learn ROS. Where is a good place to start. All the places I looked at were paid. I also have a basic robot setup with a L298N, 2 DC motors, and a camera.</p>


问:
please identify this switch
can anyone identify this switch type, please? I've been looking all day at various websites. I'm just looking for a very simple touch sensor, and this seems ideal

答: It looks like a leaf switch. A search on AliExpress for "leaf switch" and sort by price gave me this</p>

Title: please identify this switch


问:
Tried to advertise a service that is already advertised in this node [/leo/controller_manager/list_controllers]
I'm trying to do a multi agent simulation using leo_rover which is open source. I'm comfortable with single system, but when I add a second robot using namespaces i get the second robot spawned in the gazebo exactly where i want, but the controllers for the two agents try to get published at the same node location. In the end neither of the controller spawns and I'm left with rovers without controllers.

This is the rover.launch file.

```<code><launch>
   <arg name="init_pose"/>
   <arg name="robot_name"/>
   <param name="robot_description" command="<span class="math-container">$(find xacro)/xacro $</span>(find leo_description)/urdf/new.urdf.xacro" />

   <!-- push robot_description to factory and spawn robot in gazebo -->
   <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model"
    args="<span class="math-container">$(arg init_pose) -unpause -urdf -model $</span>(arg robot_name) -param /robot_description" respawn="false" output="screen"/>

  <node pkg="robot_state_publisher" type="robot_state_publisher"  name="robot_state_publisher" ns="leo">
      <param name="publish_frequency" type="double" value="30.0" />
  </node>

  <include file="$(find leo_control)/launch/control.launch">
   <!-- TODO: add possible arguments for depth camera, etc.-->
  </include>

</launch>
</code>```

This is the control.launch used in the rover.launch

```<code><launch>

  <arg name="use_tf_static" default="false"/>
  <arg name="model" default="$(find leo_description)/urdf/new.urdf.xacro"/>

  <!-- Load controller configuration />-->
  <rosparam command="load" file="$(find leo_control)/config/control.yaml" />

  <node name="controller_spawner" pkg="controller_manager" type="spawner"
    respawn="false" args="leo_velocity_controller leo_joint_publisher" output="screen" ns="leo"/>

</launch>
</code>```

Below launch file tries to add 2rovers into the simulation using namespaces.

```<code><launch>
  <!-- No namespace here as we will share this description.
      Access with slash at the beginning -->
  <param name="robot_description" command="<span class="math-container">$(find xacro)/xacro $</span>(find leo_description)/urdf/new.urdf.xacro" />

  <!-- BEGIN ROBOT 1-->
  <group ns="rover1">
    <param name="tf_prefix" value="rover1_tf" />
    <include file="$(find btp)/launch/rover.launch" >
      <arg name="init_pose" value="-x 0 -y 0 -z 0" />
      <arg name="robot_name"  value="Robot1" />
    </include>
  </group>

  <!-- BEGIN ROBOT 2-->
  <group ns="rover2">
    <param name="tf_prefix" value="rover2_tf" />
    <include file="$(find btp)/launch/rover.launch" >
      <arg name="init_pose" value="-x -2 -y 0 -z 0" />
      <arg name="robot_name"  value="Robot2" />
    </include>
  </group>
</launch>
</code>```

Below multisim.launch file combines all these launches.

```<code><launch>
   <arg name="world_name" default="worlds/empty.world"/>

   <include file="<span class="math-container">$(find gazebo_ros)/launch/empty_world.launch">
     <arg name="world_name" value="$</span>(arg world_name)"/> <!-- world_name is wrt GAZEBO_RESOURCE_PATH environment variable -->
     <arg name="paused" value="false"/>
     <arg name="use_sim_time" value="true"/>
     <arg name="gui" value="true"/>
     <arg name="headless" value="false"/>
     <arg name="debug" value="true"/>
     <arg name="verbose" value="true"/>
   </include>
   <!-- start gui -->
   <!-- <node name="gazebo_gui" pkg="gazebo" type="gui" respawn="false" output="screen"/> -->

   <!-- include our robots -->
   <include file="$(find btp)/launch/multi_rover.launch"/>
</launch>
</code>```

Now the error why I launch this multisim.launch file.

```<code>[ERROR] [1611075925.200755903, 0.394000000]: Tried to advertise a service that is already advertised in this node [/leo/controller_manager/list_controllers]
[ERROR] [1611075925.200778314, 0.394000000]: Tried to advertise a service that is already advertised in this node [/leo/controller_manager/list_controller_types]
[ERROR] [1611075925.200811448, 0.394000000]: Tried to advertise a service that is already advertised in this node [/leo/controller_manager/load_controller]
[ERROR] [1611075925.200824730, 0.394000000]: Tried to advertise a service that is already advertised in this node [/leo/controller_manager/unload_controller]
[ERROR] [1611075925.200841861, 0.394000000]: Tried to advertise a service that is already advertised in this node [/leo/controller_manager/switch_controller]
[ERROR] [1611075925.200859178, 0.394000000]: Tried to advertise a service that is already advertised in this node [/leo/controller_manager/reload_controller_libraries
</code>```

答:
I have resolved the problem. It was about conflicting namespaces for the controller manager. I have removed the control.launch file and included the stuff in the rover.launch itself. then i had to include namespaces everywhere.

```<code><launch>
  <arg name="init_pose"/>
  <arg name="robot_name"/>
  <param name="robot_description" command="<span class="math-container">$(find xacro)/xacro $</span>(find leo_description)/urdf/new.urdf.xacro" />

  <!-- push robot_description to factory and spawn robot in gazebo -->
  <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" ns="/<span class="math-container">$(arg robot_name)"
        args="$</span>(arg init_pose) -unpause -urdf -model <span class="math-container">$(arg robot_name) -param /robot_description " respawn="false" output="screen"/>
  <node pkg="robot_state_publisher" type="robot_state_publisher"  name="robot_state_publisher" ns="leo">
    <param name="publish_frequency" type="double" value="30.0" />
  </node>
  <arg name="model" default="$</span>(find leo_description)/urdf/new.urdf.xacro"/>

  <!-- Load controller configuration />-->
  <rosparam command="load" file="<span class="math-container">$(find leo_control)/config/control.yaml" ns="/$</span>(arg robot_name)" />
  <node name="controller_spawner_<span class="math-container">$(arg robot_name)" pkg="controller_manager" type="spawner" ns="/$</span>(arg robot_name)"
    respawn="false" args=" leo/leo_velocity_controller leo/leo_joint_publisher --namespace=/$(arg robot_name)" output="screen"/>
</launch>
</code>```

and i had also removed the namespace from the urdf/xacro file at the bottom with the help of this answer's  first part.

Body:
I have resolved the problem. It was about conflicting namespaces for the controller manager. I have removed the control.launch file and included the stuff in the rover.launch itself. then i had to include namespaces everywhere.

<launch>
  <arg name="init_pose"/>
  <arg name="robot_name"/>
  <param name="robot_description" command="$(find xacro)/xacro $(find leo_description)/urdf/new.urdf.xacro" />

  <!-- push robot_description to factory and spawn robot in gazebo -->
  <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" ns="/$(arg robot_name)"
        args="$(arg init_pose) -unpause -urdf -model $(arg robot_name) -param /robot_description " respawn="false" output="screen"/>
  <node pkg="robot_state_publisher" type="robot_state_publisher"  name="robot_state_publisher" ns="leo">
    <param name="publish_frequency" type="double" value="30.0" />
  </node>
  <arg name="model" default="$(find leo_description)/urdf/new.urdf.xacro"/>

  <!-- Load controller configuration />-->
  <rosparam command="load" file="$(find leo_control)/config/control.yaml" ns="/$(arg robot_name)" />
  <node name="controller_spawner_$(arg robot_name)" pkg="controller_manager" type="spawner" ns="/$(arg robot_name)"
    respawn="false" args=" leo/leo_velocity_controller leo/leo_joint_publisher --namespace=/$(arg robot_name)" output="screen"/>
</launch>

and i had also removed the namespace from the urdf/xacro file at the bottom with the help of this answer's  first part.


答: If you have the two Jacobian matrices, do you also have the two positional transformation matrices?  If so, you could multiply these two matrices together, and take partial derivatives of the result to get the full Jacobian.</p>

Title: Concatenate Jacobian matrices

Body: I have a manipulator A with known Jacobian matrix and manipulator B with also known Jacobian matrix. Now I want to chain them, B will be attached at the end of A. How do I get the Jacobian of this manipulator? Can I just multiply the both knwon Jacobian matrices?</p>


问:
Quadcopter descends when rolled or pitched
I'm currently working on a quadcopter using f450 frame and YMF32 code. I was able to successfully build the quadcopter and It flies without having any vibrations or wobbles. Also, I tuned the PID setting almost two days now.

But the problem is whenever I tried to roll or pitch the quadcopter descends and need to give some trust to avoid crashing. This happens only when tried to roll or pitch. My quad is approximately 1.5kg(or more not less) weighted and 1000kv motors are used.

I can understand what's happening using physics but not sure what I should do, So what can be the problem and what can I do to solve it.

Thanks in advance!

答: What you describe is probably due to cosine losses. Namely, when you pitch or roll your thrust vector points away from the vertical direction and thus not completely compensating gravity anymore. One way to compensate for this would be to scale your thrust by dividing it by the cosine of angle of your thrust vector with the vertical direction.</p>


问:
How to keep a sensor pointed downward
I am using LIDAR to measure a robot's altitude. The robot's orientation relative to the ground is dynamic; i.e. the XY plane tilts relative to the Z axis. I would like the LIDAR to remain pointed close to perfectly downward as the robot tilts.

Some details: the tilts can be large, up to 30 degrees, but are short lived; the robot largely corrects its orientation within a few seconds.

Note, I have considered measuring the robots angle to trigonometrically derive altitude. I have also considered barometric pressure altimeters, but those do not have the reaction time I need.

Apologies if anything here was unclear, thank you.

答:
To keep your lidar pointing downwards either:

mount the LIDAR differently to staticly fix the orientation.

mount the LIDAR on a gimble to let Gravitation forces point it down.

Title: How to keep a sensor pointed downward