Weired torque senor reading

Hello folks,

We are using a torque senor (TRT-500, reaction torque sensor) to measure the torque produced from our motorized knee exoskeleton. Our motor system uses maxon motor and gearbox and is coupled with external bevel gears. We are now just testing its system response. The motor system is controlled using the current controller mode of maxon motor drive board (ESCON 50/5). We are using Teesy 3.2 as our microcontroller.

Now one task is that we are commanding the motor system to produce 2A current that is equivalent to 10Nm torque (based on our setup) at a fixed position. The reading from torque sensor is 10Nm when the microcontroller sent the instant command of 2A current to the motor system. The strangest thing is that the reading from torque sensor would be only 6Nm when the microcontroll send the command that ramps up the current to 2A in a short time (lets say in 1 second). This problem has been consistent. It happens to the other torque levels as well. We checked that the current to drive the motor is same during the instant case and ramping case.

We are bothered by this issue for a few weeks. Please let us know if you have any ideas. Thank you so much folks.

The portion of code for instant current and ramping current are as below.

if (option_motor == 'instant current') {      
      allprintln("\n\nYou selected send one current command...");
      allprint("Enter Torque (in Nm) you want to apply: ");
      while ((!Serial.available()) && (!BLE.available())) {}
      digitalWrite(onoff, LOW); analogWrite(motor, midpoint);
      float torqs = 0.0;
      update_float(torqs);
      allprintln(torqs);
      float bits_to_write = map((torqs/(0.0136*3*51*1.4)), -5.00, 5.00, 0.0, 4096.0); //##** if change from -5 to 5 change the -7,7 here   ... 1.0 value is efficiency.... dunno if we need it
      allprintln(bits_to_write);
      int bits_written = int(bits_to_write);
      if (bits_written > 4096) {
        bits_written = 4096;
      }
      else if (bits_written < 0) {
        bits_written = 0;
      }
      float volts_written = map(float(bits_to_write), 0., 4096., 0.0, 3.3);
      float current_written = map(volts_written, 0, 3.3, -5.00, 5.00);  //##** if change from -5 to 5 change the -7,7 here
      allprint(bits_written); allprint(", "); allprint(volts_written); allprint("V, "); allprint(current_written); allprintln("A");
      digitalWrite(onoff, HIGH);
      unsigned long timer_test = millis();
      analogWrite(motor, bits_written);
      while (entry != STOP) {
        if (millis() - timer_test > print_freq) {
          float current = map(float(bits_written), 0.0, 4096.0, -5.00, 5.00);
  //        allprint(x); allprint("\t");
          allprint(current);// * .0136 * 3*51); 
          allprint("\t"); allprint(read_torq(torq_pin));
          allprint("\t"); allprintln(motor_angle*motor_angle_conversion);
          timer_test = millis();
        }
        update_char(entry);  //update entry value
        //
      }
    }

    if (option_motor == 'raming current') {
      allprintln("\n\nYou selected ramp up to current command...");
      allprint("Enter Torque (in Nm) you want to apply: ");
      while ((!Serial.available()) && (!BLE.available())) {}
      digitalWrite(onoff, LOW); analogWrite(motor, midpoint);
      float torqs = 0.0;
      update_float(torqs);
      allprintln(torqs);
      float bits_to_write = map((torqs/(0.0136*3*51*1.4)), -5.00, 5.00, 0.0, 4096.0); //##** if change from -5 to 5 change the -7,7 here   ... 1.0 value is efficiency.... dunno if we need it
      int bits_written = int(bits_to_write);
      if (bits_written > 4096) {
        bits_written = 4096;
      }
      else if (bits_written < 0) {
        bits_written = 0;
      }
      float volts_written = map(bits_to_write, 0, 4096, 0.0, 3.3);
      float current_written = map(volts_written, 0, 3.3, -5.00, 5.00);  //##** if change from -5 to 5 change the -7,7 here
      allprint(bits_written); allprint(", "); allprint(volts_written); allprint("V, "); allprint(current_written); allprintln("A");
      digitalWrite(onoff, HIGH);
      unsigned long timer_test = millis();
      int x = midpoint;
      
      while (entry != STOP) {  
        [color=red]delay(1); //delayMicroseconds(75);[/color]
        analogWrite(motor, x);  
        if (x < bits_written) {
          x++;
        }
        else if (x > bits_written) {
          x--;
        }
        //for printing torq and testing
  //      allprint("\nTorq (N/m)"); allprint("\t"); allprintln("Angular Velocity (deg/s)"); 
        if (millis() - timer_test > print_freq) {
          float current = map(float(x), 0.0, 4096.0, -5.00, 5.00);
  //        allprint(x); allprint("\t");
          allprint(current);// * .0136 * 3*51); 
          allprint("\t"); allprint(read_torq(torq_pin));
          allprint("\t"); allprintln(motor_angle*motor_angle_conversion);
          timer_test = millis();
        }
        update_char(entry);  //update entry value
        //
      }
    }

Doc1.pdf (158 KB)

I am very unfamiliar with all of that, but my laymens idea is that your torque sensor outputs the first torque it senses, and then stops checking for new values.

I could be way off, but maybe you'll be inspired and get an idea on how to fix the issue haha

33chen:
The strangest thing is that the reading from torque sensor would be only 6Nm when the microcontroll send the command that ramps up the current to 2A in a short time (lets say in 1 second).

I'm sorry, but your description of events makes no sense.

With everything clamped solid, what torque do you read for what motor current ?

When the system is free to move, the torque is dependent on the rate of change of position and the mass of the elements.

Please try to describe the problem you are having a bit more accurately.

Yours,
TonyWilk

Thank you all for your reply. Sorry for the confusion, TonyWilk. Yes I have the things clamp solid. The torque sensor reads 10Nm at 2A currentt. The torque sensor reading is fine when I instantly command motor at 2A level. The reading is off about 40 percent if I ramp up the current of motor to 2A level in less than 1 second. The torque level should be same or similar right? The strange thing, however, is that the torque reading under the ramping current is much less. Hope it makes sense. Thanks.

Remember your physics! The torque need to begin to move an object(inertia + resistance) is always greater than the torque needed to overcome the resistance of a moving object. Your readings seem normal.

Paul

33chen:
Thank you all for your reply. Sorry for the confusion, TonyWilk. Yes I have the things clamp solid. The torque sensor reads 10Nm at 2A currentt. The torque sensor reading is fine when I instantly command motor at 2A level. The reading is off about 40 percent if I ramp up the current of motor to 2A level in less than 1 second. The torque level should be same or similar right? The strange thing, however, is that the torque reading under the ramping current is much less. Hope it makes sense. Thanks.

So... if you just turn the motor on at 2A you get 10Nm indicated.

If you ramp up the current over 1second, 2 seconds, 10 seconds, it only gets to 4Nm or 6Nm indicated ?

In both of these cases the motor is then stalled, consuming 2A of current.

There may be a couple of things going on

I'd guess there is some amount of backlash in the system so the motor 'jerks' when power is applied and then stalls. Ramping up the current will probably let the motor stall at a lower torque.

For example, taking it to extremes; if you ran the motor and the mechanics hit some 'end stop', the torque at that instant may be very large (and the stalled motor may then hold everything 'in tension').

Exactly where a motor stalls will affect it's 'stalled torque' - depending on exactly where the 'poles' in the motor are aligned.

You may get a better determination of maximum torque from the motor by letting it run and slowly applying more and more force until it stalls while measuring the torque.

Yours,
TonyWilk

Thank you so much for your input, Paul and TonyWilk. They are inspirational.

Paul, apparently I don't understand the physics very well. But the structure is clamp fixed. The only motion that could be introduced and actually is visible, is that the tiny movement from the planetary maxon gearbox which is connected to maxon motor. As you know, there is a tiny free play in this type of gear. So do you think this free play would cause us to see different torque reading between instant loading and ramping loading? Is that right?

TonyWilk, I actually ramp up the current less than 1 second, maybe in the magnitude of a few hundred millseconds. And the torque reading is getting close to what I see in the instant loading (lets say 10Nm which is 2A current) as I make this ramp loading happen occur faster and faster.

This is where how we create the ramping by using the delay(). It happens very fast though.

      while (entry != STOP) {  
        [color=red]delay(1); //delayMicroseconds(75);[/color]
        analogWrite(motor, x);  
        if (x < bits_written) {
          x++;
        }
        else if (x > bits_written) {
          x--;
        }

This code comes from this part of code for ramping current

 if (option_motor == 'raming current') {
      allprintln("\n\nYou selected ramp up to current command...");
      allprint("Enter Torque (in Nm) you want to apply: ");
      while ((!Serial.available()) && (!BLE.available())) {}
      digitalWrite(onoff, LOW); analogWrite(motor, midpoint);
      float torqs = 0.0;
      update_float(torqs);
      allprintln(torqs);
      float bits_to_write = map((torqs/(0.0136*3*51*1.4)), -5.00, 5.00, 0.0, 4096.0); //##** if change from -5 to 5 change the -7,7 here   ... 1.0 value is efficiency.... dunno if we need it
      int bits_written = int(bits_to_write);
      if (bits_written > 4096) {
        bits_written = 4096;
      }
      else if (bits_written < 0) {
        bits_written = 0;
      }
      float volts_written = map(bits_to_write, 0, 4096, 0.0, 3.3);
      float current_written = map(volts_written, 0, 3.3, -5.00, 5.00);  //##** if change from -5 to 5 change the -7,7 here
      allprint(bits_written); allprint(", "); allprint(volts_written); allprint("V, "); allprint(current_written); allprintln("A");
      digitalWrite(onoff, HIGH);
      unsigned long timer_test = millis();
      int x = midpoint;
      
      while (entry != STOP) {  
        [color=red]delay(1); //delayMicroseconds(75);[/color]
        analogWrite(motor, x);  
        if (x < bits_written) {
          x++;
        }
        else if (x > bits_written) {
          x--;
        }
        //for printing torq and testing
  //      allprint("\nTorq (N/m)"); allprint("\t"); allprintln("Angular Velocity (deg/s)"); 
        if (millis() - timer_test > print_freq) {
          float current = map(float(x), 0.0, 4096.0, -5.00, 5.00);
  //        allprint(x); allprint("\t");
          allprint(current);// * .0136 * 3*51); 
          allprint("\t"); allprint(read_torq(torq_pin));
          allprint("\t"); allprintln(motor_angle*motor_angle_conversion);
          timer_test = millis();
        }
        update_char(entry);  //update entry value
        //
      }
    }

Hey TonyWilk,

One more question: as you suggest, it would be better to determine the max torque by slowly ramping up to the expected torque level. Then how should I do a step response test for torque output? Should I not get everything fixed? Thank you.

Ji

33chen:
Thank you so much for your input, Paul and TonyWilk. They are inspirational.

Paul, apparently I don't understand the physics very well. But the structure is clamp fixed. The only motion that could be introduced and actually is visible, is that the tiny movement from the planetary maxon gearbox which is connected to maxon motor. As you know, there is a tiny free play in this type of gear. So do you think this free play would cause us to see different torque reading between instant loading and ramping loading? Is that right?

My point was torque is the power required to (1) overcome inertia and (2) overcome the inherent resistance in any mechanism.

The inertia part is changing the speed of the object, from 0 to some number, or increasing the speed, or stopping the object. All involve torque.

The resistance part is fairly constant, until wind resistance come into play.

Paul

Thank you Paul very much for the reply. I wish I can always learn the physics this way.

By the way, I just did some test. I let the lever (which is used to cramp fixed and connected to torque sensor) free but push against wall. Then I do the instant loading. This would give me 10Nm torque reading (at 2A) (when it is against wall).

What I did Next is interesting to obersrve: When the system is loading the instand torque, I started pulling back the lever UNTIL it makes the external gear movea tooth and then let it against the wall again. The torque reading becomes 6N. It is very interesting. So TonyWilk, does this make sense?

And also when I do the ramp loading (which only gives me the 6N torque reading), I can see the gear also moves about a tooth. Our external gear system has some backlash ( it is not harmonic drive, you know).

So do you think the instant loading (which puts the whole system tensed up right away) would introduce higher torque because there is no any gear movement?

Thanks again.

My guess is that it has something to do with friction holding the "impact" level of torque after the application of the "instant" current. That is, friction prevents it from backing off.

Hi,
Been away for the weekend (our late xmas get-together with family, so I have a slight sore head :slight_smile: )

I'm not entirely sure what reason you are taking torque measurements.

What is useful to you is a bit dependant on your mechanical setup.

With, say, a simple stepper motor it may be useful to know:

a) the maximum driving torque
While driving the motor, slowly increase the load (with a clutch, weight on an arm or whatever) until the motor just stalls. From this you could estimate e.g. the force you could apply along a given lever.
b) the holding 'torque'
Drive the motor to hold position and increase torque until the motor slips.
c) starting torque
From a standstill, what loading can the motor overcome to reliably start moving... this is complicated by backlash in gears and so on.

Any sort of 'shock loading' e.g. running into a 'hard stop' or having the motor 'jerk' to takeup gear backlash can give all sorts of readings - mainly depending on how much metal was moving and then how suddenly it stops.

Yours,
TonyWilk

Thank you for your ideas TonyWilk. It helped a lot Hope you had a great holiday. Thank you for the comment, DaveEvans and Paul

Based on what you guys mentioned, could I understand the reason instant current causes the system to have a higher torque than the ramping current, is because of the backlush and stiction. But for the ramping current, the stiction should exist there as well. Sorry for making it more confused. It just is hard to internalize.

Thank you guys again.

Consider two cases:

  1. A suddenly applied weight to a lightly-damped spring
  2. A very gradually applied weight, of the same magnitude, to the same spring.

Case 1 maximum deflection will be two times the Case 2 deflection. After a number of oscillations, the Case 1 deflection will, eventually, decrease to the Case 2 deflection.

Your torque sensor has a stiff spring in it (76,000 in-lb/rad), and the measured torque is proportional to the deflection of that "spring."

Hypothesis: The ramping up of torque is similar to Case 2. The sudden application of torque is similar to Case 1. You don't see the oscillations because they are very small and fast. Friction in the system may prevent the sensor deflection (and hence torque) from decreasing back all the way down to the Case 2 deflection.

If you sampled the torque at a high rate and plotted torque vs time, you may be able to see this effect. Even if I'm wrong, I'd suggest doing that (high speed sampling and plotting), since graphing data can sometimes help you figure out what's going on.

Thanks a lot for giving that analogy, DaveEvans. I will try to graph the torque reading with high sampling rate and see if this effect occurs in a short time.

This device we are building aims to providing the torque assistance to human knee during the stance phase of each walking cycle. As you may know, the time the stance phase lasts is very short (less than 0.5 second). We plan to do the instant loading of torque to make sure the expected level of torque can be instantly provided to the human knee. But as you mentioned, this instant loading introduced the oscillation of torque since the torque sensor is essentially highly stiff spring. And the method of raming up would have the system delay some time to reach the expected level of torque.

We are now characterizing the torque loading of device through a simple step response test. In this test, the frames which is attached to the human leg are fixed. We have the system input the instant current command (the current controller) and measure the output torque based on the torque sensor reading. Is this step response method using instant loading decent enough to characterize the torque loading of device, given that we only want to use the sensors we have now?

Thanks again.

33chen:
Is this step response method using instant loading decent enough to characterize the torque loading of device, given that we only want to use the sensors we have now?

Sorry, I have no idea.

It would be interesting to see the results of your fast sampling and also photographs of your test mechanism.

Hey DaveEvans and all folks,

Sorry to update late. We are collecting our torque data at 100Hz. We feel that it is about how fast we can go with our Teensy 3.2 microcontroller and the code that has thousands of lines. (Maybe 200Hz is our limit. Not sure.) Attached pictures have my testing mechanism for step response. First picture shows the solidworks model of the mechanism and the second picture shows how we fix the mechanism for step response. This is the typical way used in the step response test (you can see this link to get an idea of step response as well. https://www-cs.stanford.edu/group/manips/publications/pdfs/Vischer_1990.pdf)

Please let me know if you have any other questions. Thanks alot, DaveEvans.

Ji

picture_1.jpg

picture_2.jpg

My hypothesis is that your instant-on test causes the red behavior and that the slower ramping up causes the blue behavior:

Capture.JPG

Capture.JPG

That makes quite sense, DaveEvans. So if I command the system is ramping up to 10Nm, the output torque only reaches at 6Nm based on the torque reading. However when I put the free weight at the end of my lower leg attachment (to creat the overhung moment of 10Nm) to balance the output torque from motor system, the torque reading will stay at the 10Nm. Why does this happen?

I don't know.

What torque do you expect the motor deliver at 2 amps? If the gearbox is frictionless, what torque would you expect to measure at the output?

With your hanging weight test, you're forcing the gearbox to rotate the other direction (if I understand what you're doing); maybe that affects friction in the system. Just a WAG from a non-ME.

Have you plotted torque vs time for your instant-on and ramp-up tests? If you have, please post them. For faster sampling, why don't you delete the 1000s of lines of code and write a simple test program.