Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make position direct mode usable #198

Closed
PeterBowman opened this issue Dec 18, 2018 · 56 comments
Closed

Make position direct mode usable #198

PeterBowman opened this issue Dec 18, 2018 · 56 comments

Comments

@PeterBowman
Copy link
Member

PeterBowman commented Dec 18, 2018

Current (undesired/faulty) behavior:

  • Fixed. Change modes IPositionControl -> IPositionDirect -> IPositionControl and try to positionMove(): need to send this command twice, no response at first try.
  • Partially solved, obsolete. Change modes and move to a certain position after each step, IPositionControl -> IPositionDirect -> IPositionControl -> IPositionDirect.
    • We won't be able to start the PT mode since ptPointCounter is never set to zero: ref.
    • Once a buffer-full state is reached, new positions cannot be sent until the buffer is emptied (check mutex): ref.
  • Fixed. It takes ages to switch to position direct mode ("seems like a must"). Certain applications start sending targets asynchronously right away after the mode change (e.g. keyboardController), thus the first actually commanded position happens after said delay and makes the robot jump too far away.
@jgvictores
Copy link
Member

Related? "[TechnosoftIpos] Cannot change control mode some/many times #170"

@PeterBowman
Copy link
Member Author

Can't really tell unless we determine the underlying cause. Even though it's not stated explicitly in the title, #170 originated when trying to perform [torq] control after one or more mode transitions. I'd keep these two tickets along eachother since a different sequence of steps is described to reproduce their symptoms. Even if this results in a duplicate somewhere, we can point to the same problem from two distinct directions and resolve both at once.

@rsantos88
Copy link
Contributor

I've doing different tests, changing the mode in different occasions, and executing the position direct example (2ebc388) that I developed. The result has been this:

20190311_131757

Screen output:
launchManipulation -> issue-change-mode.txt.zip
examplePositionDirect -> examplePositionDirect.txt.zip
rpc commands:

teo@teo-oliver:~$ yarp rpc /teo/rightArm/rpc:i 
>>set pos 3 0
Response: [ok]
>>set pos 3 0
Response: [ok]
>>set icmd cmds (pos pos pos pos pos pos pos)
Response: [ok]
>>get icmd cmds
Response: [is] [cmds] ([pos] [pos] [pos] [pos] [pos] [pos] [pos]) [tsta] 10 1552306524.43345 [ok]
>>set pos 3 0
Response: [ok]
>>set pos 0 5
Response: [ok]
>>set pos 0 5
Response: [ok]
>>set pos 1 -5
Response: [ok]
>>set pos 1 -5
Response: [ok]
>>set pos 1 0
Response: [ok]
>>set pos 3 0
Response: [ok]

Steps in the execution:

  1. ExamplePositionDIrect is started (IPositionControl -> IPositionDirect )
  2. We make a change to position mode by RPC of all the right arm
  3. We check that the first time we try to move different joints by RPC, it does not react (joints 0, 1 and 3). We passed the position a second time. It reacts and we move them to 0.
  4. We started the application again. It moves at 10 degrees correctly but then has made a sudden movement (I haven't had time to see it) and I've pressed the emergency button immediately.

@PeterBowman
Copy link
Member Author

Change modes IPositionControl -> IPositionDirect -> IPositionControl and try to positionMove(): need to send this command twice, no response at first try.

See iPOS driver manual, 9.1.1. Internal States.

@jgvictores
Copy link
Member

See iPOS driver manual, 9.1.1. Internal States.

Yes, that totally makes sense!

@PeterBowman
Copy link
Member Author

Change modes and move to a certain position after each step, IPositionControl -> IPositionDirect -> IPositionControl -> IPositionDirect. We won't be able to start the PT mode since ptPointCounter is never set to zero:

Done at 6dae264, seems to work now.

@rsantos88
Copy link
Contributor

I'll upload the output of launchManipulation for this issue:

Change modes IPositionControl -> IPositionDirect -> IPositionControl and try to positionMove(): need to send this command twice, no response at first try.

launchManipulation-leftArm-frontal-wrist-1503.txt.zip

@PeterBowman
Copy link
Member Author

PeterBowman commented Mar 19, 2019

launchManipulation-leftArm-frontal-wrist-1503.txt.zip

I'm really baffled that only CAN IDs 21 (left arm) and 27 (head) are responding in the CBW2 state thread, almost no other IDs are shown there (just a few PDO-related lines). Perhaps the acceptance filters are misbehaving?

By the way, I noticed that the status word (6041h) transitions from 8637h to 9237h upon issuing a positionMove() that won't move the robot, in CAN ID 21 (shoulder). According to 8.1.4. Status word in profile position mode, the set-point acknowledge bit is set (= "Trajectory generator will not accept a new set-point.") and the target reached one, reset (= "Target position not reached").

Edit: might be a coincidence (well, it is), but the following three calls issued by setPositionRaw() are interleaved with incoming CAN messages whenever this command fails:

[success] IPositionControl2RawImpl.cpp:33 positionMoveRaw(): Sent "position target". 23 7a 60 0 71 2c 0 0. canId(26) via(600).
[success] IPositionControl2RawImpl.cpp:43 positionMoveRaw(): Sent "start position". 3f 0. canId(26) via(200).
[success] IPositionControl2RawImpl.cpp:55 positionMoveRaw(): Sent "reset position". f 0. canId(26) via(200).

I mean:

[success] IControlMode2RawImpl.cpp:272 getControlModeRaw3(): [success] IPositionControl2RawImpl.cpp:55 positionMoveRaw(): Sent Motion Error Register query. 40 0 20 0 0 0 0 0. canId(21) via(600).
Sent "reset position". f 0. canId(26) via(200).

@rsantos88
Copy link
Contributor

The same test done now at 12:10 with left wrist (ID26)
oneCanBusOneWrapper-posd-2003.txt.zip

  • First: examplePositionDirect
  • Then:
>>get encs
Response: [is] encs (20.003027) [tsta] 3 1553080045.375092 [ok]
>>get icmd cmds
Response: [is] [cmds] ([posd]) [tsta] 4 1553080049.250982 [ok]
>>set icmd cmod 0 pos
Response: [ok]
>>get icmd cmds
Response: [is] [cmds] ([pos]) [tsta] 5 1553080057.332439 [ok]
>>set pos 0 0  (not working)
Response: [ok]
>>set pos 0 0  (working)
Response: [ok]

@rsantos88
Copy link
Contributor

Control word test:
oneCanBusOneWrapper-posd-2003-cw.txt.zip

@PeterBowman
Copy link
Member Author

Remarks:

  • Upon a faulty positionMove, the status word transitions from 96xxh to 86xxh (9h means that the set-point acknowledge bit is set = "Trajectory generator will not accept a new set-point.")
  • Upon a successful positionMove, the status word transitions from 86xxh to 92xxh (2h means that the target reached bit is reset = "Target position not reached", I guess the motor is still rotating).
  • The control word (6040h) transitions from 001fh to 000fh after the faulty positionMove is issued. Bit 8 means Halt:
    • 0 = "Execute positioning"
    • 1 = "Stop drive with profile acceleration"
  • According to 8.1.3. Control word in profile position mode, xfh means, most notably:
    • New point, 1 = "Assume target position (update the new motion parameters)"
    • Change set immediately, 1 = "Interrupt the actual positioning and start the next positioning. Valid only
      for linear ramp profile" (see 8.1.2. Continuous motion profile)

@PeterBowman
Copy link
Member Author

Change modes IPositionControl -> IPositionDirect -> IPositionControl and try to positionMove(): need to send this command twice, no response at first try.

Done at 2616482. The "10. Reset the set point." command has been replicated and now is sent prior to setting the target position in positionMoveRaw(). We noticed that 8.3.1. Absolute trapezoidal example assumes the user waits for the motion to complete between "8. Start the profile." and "10. Reset the set point." (see "9. Wait movement to finish.") before sending the next target, therefore our first attempt was to move said reset-related lines to the top of this function. It did work in [pos] control mode, but prevented the trajectory from executing upon switching again to [posd]. As a workaround, we reset the set point twice in positionMoveRaw().

@PeterBowman
Copy link
Member Author

PeterBowman commented Mar 29, 2019

Change modes and move to a certain position after each step

Still broken. Previous (successful) tests did not cover a full arm, rather a single joint. This time, on the second attempt (the first one is always successful, as noted above), we observe that the commanded joint rotates a bit in the beginning, then stops responding to new target points.

@rsantos88
Copy link
Contributor

Still broken. Previous (successful) tests did not cover a full arm, rather a single joint. This time, on the second attempt (the first one is always successful, as noted above), we observe that the commanded joint rotates a bit in the beginning, then stops responding to new target points.

Detected the change that produces the error in the example.
At a low level it would be necessary to see what is failing.
If we change pos->positionMove(JOINT, 10) for pos->positionMove(v.data()), the example runs correctly.

@rsantos88
Copy link
Contributor

Test summary:

  • In the example, we initialize all the joints in POSITION mode and we change also all the joints to POSITION DIRECT
  • movement orders following this order: (1) Position -> (2) PositionDirect:
    (1) positionMove(JOINT, 10) (2) setPosition(JOINT, encValue) ✔️
    (1) positionMove(JOINT, 10) (2) setPosition(jointPosition.data())
    (1) positionMove(jointPosition.data()) (2) setPosition(JOINT, encValue)) ✔️
    (1) positionMove(jointPosition.data()) (2) setPositions(jointPosition.data()) ✔️

@rsantos88
Copy link
Contributor

rsantos88 commented Apr 9, 2019

Last test, prints current pending reads in CBW2: (updated to OneCanBusOneWrapper)
OneCanBusOneWrapper-0904-2.txt.zip

@PeterBowman
Copy link
Member Author

PeterBowman commented Apr 9, 2019

We've learned that the ptBuffer semaphore is the root of all evil. The device simply stops accepting new PT-mode target points since program execution is stuck at this ptBuffer.wait() instruction, which in turn causes YARP to complain about a growing queue of (unprocessed) messages. We believe that this semaphore might not be properly released on the first run of examplePositionDirect (relevant lines). Also, note that nothing prevents us from calling post() more than once per wait() call, that is, the internal counter of the semaphore may exceed the value 1. In the log file previously attached, it's worth noting that the "pt buffer full" message is not symmetric to "pt buffer empty" (just 3 occurrences of the latter on the second run) and relates to IDs 24/25/26, mostly.

This is highly undesirable and leads to undefined behavior, to say the least. I would rethink the whole buffer full/empty handling mechanism. See roboticslab-uc3m/teo-bimanipulation#3 (comment).

@jgvictores
Copy link
Member

Attaching the oldest code I've found: locomotion.zip (from private repo which has some interesting stuff)

@PeterBowman
Copy link
Member Author

PeterBowman commented Apr 10, 2019

Regarding

if( (message.getData()[1]==0xFF)&&(message.getData()[2]==0x01)&&(message.getData()[4]==0x20) )
{
ptBuffer.wait();
CD_WARNING("pt buffer full! canId: %d.\n",canId);
return true;
}
else if( (message.getData()[1]==0xFF)&&(message.getData()[2]==0x01)&&(message.getData()[4]==0x00) )
{
ptBuffer.post();
CD_WARNING("pt buffer empty. canId: %d.\n",canId);
return true;
}

and 9.2.3. Object 2072h: Interpolated position mode status:

Remark: when a status bit changes from this object, an emergency message with the code
0xFF01 will be generated. This emergency message will have mapped object 2072h data onto
bytes 3 and 4.

Shouldn't the "pt buffer empty" check for value 80h, instead? That is, when bit 15 is set: "Buffer is empty – there is no point in the buffer."

Edit: this actually might explain why we keep seeing "pt buffer empty" messages next to a "pt buffer full", which makes little sense (the buffer shouldn never deplete so fast). Also, I believe the PT examples in the iPOS manual are wrong regarding the buffer low warning, note that we never enable bit 7 in 2074h (section 9.2.5), the example neither. This would imply that: 1. perhaps buffer low's default is 00h; 2. the MSB in 2072h is almost always zero (does it make sense, shouldn't that produce constant buffer-empty messages?).

@PeterBowman
Copy link
Member Author

PeterBowman commented Apr 10, 2019

Attaching the oldest code I've found: locomotion.zip (from private repo which has some interesting stuff)

This code set buffer-low signaling value to 4, buffer-empty was never checked against. There was an attempt to change the default buffer size (full) to 10792 (2A28h), which was ultimately commented out.

Considering that the buffer-empty state might not be currently reached in normal PT-mode operation (see previous comment), we don't know whether intermitent depletion of the buffer could entail undesirable effects (@jgvictores).

@rsantos88
Copy link
Contributor

Test with oneCanBusOneWrapper, prints the current changes of branch https:/roboticslab-uc3m/yarp-devices/tree/verbose-posd with the position direct example.
File: OneCanBusOneWrapper-1004.txt.zip

@PeterBowman
Copy link
Member Author

PeterBowman commented Apr 10, 2019

Shouldn't the "pt buffer empty" check look for value 80h, instead? That is, bit 15 set: "Buffer is empty – there is no point in the buffer."

Well, I can confirm the buffer is definitely not empty until the very end of the motion sequence. The buffer-low bit is set, too, in this case. After the last setPosition() call, and around 6-7 cycles later, a single buffer-low message is issued, then buffer-empty steps in. Also, on the second (failed) run, the semaphore gets stuck right after signalling a buffer-full state.

PeterBowman added a commit to roboticslab-uc3m/kinematics-dynamics that referenced this issue May 21, 2019
@PeterBowman
Copy link
Member Author

Even if the reference speed is updated while in external reference position mode, its new values are ignored by the drive upon trying to reach the next targets. Also, this mode is sometimes unresponsive upon pos->posd->pos->posd, not so often when running the examplePositionDirect app.

Considering to switch back to PT mode for online trajectories, leaving PVT aside for offline stuff.

@PeterBowman
Copy link
Member Author

PeterBowman commented May 23, 2019

Considering to switch back to PT mode for online trajectories, leaving PVT aside for offline stuff.

Implemented and tested. I'm working on this along with #208 since this solution uses the IRemoteVariables YARP interface to pass a ptModeMs parameter over the network: <0 means "not in position direct mode" (default), 0 means "use external reference position mode", >0 means "use PT interpolation mode with this period (in milliseconds)".

I noticed that device routing in the ControlBoardWrapper layer is kinda messy regarding how IRemoteVariables methods are interpreting incoming/outgoing bottles, see source code. For instance, we'd need to build a two-element bottle if we ever want to send a remote variable to the head part, one element per CanBusControlboard instance. This won't affect both arms and legs since there is a one-to-one mapping (controlboardwrapper2-to-CanBusControlboard), but we are still forced to wrap any data sent in an additional bottle (e.g. (50) instead of just 50 for ptModeMs).

In addition, this behavior introduces an assymetry in that said bottle would need to be constructed in a slightly different manner in case the CanBusControlboard device is not attached to a network wrapper.

@PeterBowman
Copy link
Member Author

PeterBowman commented May 25, 2019

Recent tests showed that online trajectories performed in the new position direct mode, (re)implemented as PT interpolation, suddenly stop roughly at the 150th-200th commanded target. The drives had turned unresponsive after that point: no lines received in the CAN read stream (interpretMessage) despite reporting apparently successful status queries. A close inspection in EasyMotion did not reveal much - I could only learn that all four position trigger bits in object 1002h (Manufacturer Status Register) had been toggled to zero. This behavior was observed in all drives accounting for the right arm (firmware F508D) except id 19 (firmware F508F).

Everything worked like a charm after I commented out the bits that set the PT buffer length to its maximum value as detailed in #198 (comment). This buffer has never been modified in that way before, even if we thought it was modified by us to store 15 points by the following lines:

//-- 10. Interpolated position buffer length. Set the buffer length to 12. The maximum length is 15.
//uint8_t buffLength[]={0x2B,0x74,0x20,0x00,0x00,0x0C,0x00,0x00}; //-- 12
uint8_t buffLength[]= {0x2B,0x74,0x20,0x00,0x00,0x0F,0x00,0x00}; //-- 15
if ( ! send(0x600,8,buffLength) )
return false;

This has been fixed in a recent revision of the iPOS CAN user manual: should have read object 2073h (Interpolated position buffer length) instead of 2074h (Interpolated position buffer configuration).

@PeterBowman PeterBowman changed the title Improvements in IPositionDirect Make position direct mode usable May 26, 2019
@rsantos88
Copy link
Contributor

Reminder:
When I do pos->posd->pos->posd, it doesn't change to PT mode and the launchManipulation shows:

[debug] IRemoteVariablesImpl.cpp:50 setRemoteVariable(): ptModeMs
[debug] IRemoteVariablesRawImpl.cpp:37 setRemoteVariableRaw(): ptModeMs
[warning] IRemoteVariablesRawImpl.cpp:45 setRemoteVariableRaw(): Illegal state, unable to change variable when currently used.
[warning] IRemoteVariablesImpl.cpp:58 setRemoteVariable(): Unable to set remote variable on node 0.

@PeterBowman
Copy link
Member Author

Could you upload the latest code? I don't see the changes we had to introduce in this method. There is a possibility the CAN network has nothing to do here, perhaps a state variable is not being correctly cleared on the iPOS-YARP device side, or some tweaks need to be made in your app.

@rsantos88
Copy link
Contributor

rsantos88 commented May 28, 2019

Could you upload the latest code? I don't see the changes we had to introduce in this method. There is a possibility the CAN network has nothing to do here, perhaps a state variable is not being correctly cleared on the iPOS-YARP device side, or some tweaks need to be made in your app.

roboticslab-uc3m/teo-bimanipulation@bc0a8e1

@PeterBowman
Copy link
Member Author

Please run your applicacion twice, make sure this error happens on the second run, and paste here the complete logs of launchManipulation.

@rsantos88
Copy link
Contributor

rsantos88 commented May 30, 2019

Here you have the output information of launchManipulation:
launchManipulation-pvt-test-3005.txt.zip

And the output of my app: output.txt.

@PeterBowman
Copy link
Member Author

Identified at #211 (comment). Suggested workaround: edit launchManipulation.ini, remove head joints.

@PeterBowman
Copy link
Member Author

PeterBowman commented Jul 20, 2019

Just tried another implementation which does not need to care about synchronizing send rates on remote client and CAN master. Each TechnosoftIpos node starts a separate thread given a fixed period (50 ms). By the way, I'm giving another try to PVT submode, therefore the internal buffer (shrinked to hold a single target) must never deplete. ASBJ (as suggested by @jgvictores), the thread mimicks a LIFO stack in that only the last received target is forwarded to the buffer via CAN. In other words, high-frequency (<50 ms) trajectories get downsampled, whereas the last commanded target is placed in the buffer if no new point was received within 50 ms.

Checklist:

  • Make sure PVT is the right choice. PT might perform better and safer (it's OK to reach buffer empty state).

  • Forgot to run examplePositionDirect on different rates. Test <50 ms and >50 ms.

  • iPOS drives will generate an EMCY message every time a point is received because of the single-element-size buffer. I guess this point is never replaced by successively arriving targets unless it's consumed by the PVT interpolator, thus making room for more points. Let's check that. Also make sure that points are actually discarded in that case.

  • PVT target processing sequence behaves like so: point is stored, therefore buffer is bull; point is consumed and buffer low state is signalized; a new point arrives and fills the buffer, thus it never depletes. Current implementation on posd mode change starts PVT thread prior to starting drive's PVT mode. Inverting this sequence turns the posd commands unresponsive, need to check why:

    pvtThread->setInitialPose(ref);
    pvtThread->updateTarget(ref);
    pvtThread->step();
    pvtThread->step();
    if (!pvtThread->start())
    {
    CD_ERROR("Unable to start PVT thread.\n");
    return false;
    }
    yarp::os::Time::delay(PVT_MODE_MS * 0.001 / 2);
    uint8_t startPT[]= {0x1F,0x00};
    if( ! send(0x200,2,startPT) )
    {
    CD_ERROR("Could not send \"startPT\". %s\n", msgToStr(0x200,2,startPT).c_str() );
    return false;
    }
    CD_SUCCESS("Sent \"startPT\". %s\n", msgToStr(0x200,2,startPT).c_str() );

  • I observed a rather poor behavior while commanding the robot in an online manner (spnav). Reminds me of external reference position mode, which was unable to cope with distinct per-joint trajectory durations (same speed on all joints). This time, it's a bit worse since joints appear to move in a non-synchronized manner. My hunch is that PVT threads must send points simultaneously. Preferably, a single thread started on the CanBusControlboatd level would take care of this.

@PeterBowman
Copy link
Member Author

PeterBowman commented Jul 22, 2019

Follow-ups to my previous post:

Make sure PVT is the right choice. PT might perform better and safer (it's OK to reach buffer empty state).

By now, PT is far better (i.e. produces a smooth movement) than PVT. Even more, smaller periods favor PT submode, whereas PVT is prone to induce oscillations.

Forgot to run examplePositionDirect on different rates. Test <50 ms and >50 ms.

OK with smaller rates, loses smoothness at higher values (as expected).

iPOS drives will generate an EMCY message every time a point is received because of the single-element-size buffer. I guess this point is never replaced by successively arriving targets unless it's consumed by the PVT interpolator, thus making room for more points. Let's check that. Also make sure that points are actually discarded in that case.

If the PT/PVT buffer is full, new points are always dismissed.

Current implementation on posd mode change starts PVT thread prior to starting drive's PVT mode. Inverting this sequence turns the posd commands unresponsive.

Can't reproduce.

Preferably, a single thread started on the CanBusControlboatd level would take care of this.

Implemented, see first point: I like PT far more than PVT in this regard.

@PeterBowman
Copy link
Member Author

So, no CSP mode in CiA DSP 402 v3.0. We'd probably need to perform a firmware update on our drives in order to use this mode.

Updated ID 9 (left leg) to F508M (latest one in F508 series) and checked supported drive operation modes thanks to 1aef421. Still no CSP mode available, although I had to check other manufacturer's description pertaining to this CAN object since the iPOS user manual does not cover CSP at all in 6502h.

[info] ICanBusSharerImpl.cpp:1084 interpretMessage(): Got "Supported drive modes" from driver. 43 2 65 0 65 0 1f 0. canId(9) via(580).
[info] ICanBusSharerImpl.cpp:1088 interpretMessage(): 	*profiled position (pp)
[info] ICanBusSharerImpl.cpp:1096 interpretMessage(): 	*profiled velocity (pv)
[info] ICanBusSharerImpl.cpp:1104 interpretMessage(): 	*homing (hm)
[info] ICanBusSharerImpl.cpp:1108 interpretMessage(): 	*interpolated position (ip)
[info] ICanBusSharerImpl.cpp:1124 interpretMessage(): 	*electronic camming position (manufacturer specific)
[info] ICanBusSharerImpl.cpp:1128 interpretMessage(): 	*electronic gearing position (manufacturer specific)
[info] ICanBusSharerImpl.cpp:1132 interpretMessage(): 	*external reference position (manufacturer specific)
[info] ICanBusSharerImpl.cpp:1136 interpretMessage(): 	*external reference speed (manufacturer specific)
[info] ICanBusSharerImpl.cpp:1140 interpretMessage(): 	*external reference torque (manufacturer specific)

@PeterBowman
Copy link
Member Author

Change mode, set first PT point, don't send start signal:

[debug] LinearInterpolationBuffer.cpp:165 configureMessage(): Sending p -0.009668 t 50 (ic 0).
[info] ICanBusSharerImpl.cpp:433 interpretMessage(): Interpolated position mode status. canId: 20.
[info] ICanBusSharerImpl.cpp:437 interpretMessage(): 	* buffer is not empty.
[info] ICanBusSharerImpl.cpp:458 interpretMessage(): 	* buffer is not low.
[info] ICanBusSharerImpl.cpp:471 interpretMessage(): 	* buffer is full.
[info] ICanBusSharerImpl.cpp:476 interpretMessage(): 	* no integrity counter error.

Once (iff) start signal is sent, the buffer is being processed by the linear interpolator:

[success] TechnosoftIpos.cpp:97 sendLinearInterpolationStart(): Sent "startPT". 1f 0. canId(20) via(200).
[...]
[info] ICanBusSharerImpl.cpp:433 interpretMessage(): Interpolated position mode status. canId: 20.
[info] ICanBusSharerImpl.cpp:437 interpretMessage(): 	* buffer is not empty.
[info] ICanBusSharerImpl.cpp:462 interpretMessage(): 	* buffer is low.
[info] ICanBusSharerImpl.cpp:467 interpretMessage(): 	* buffer is not full.
[info] ICanBusSharerImpl.cpp:476 interpretMessage(): 	* no integrity counter error.

Shortly thereafter:

[info] ICanBusSharerImpl.cpp:433 interpretMessage(): Interpolated position mode status. canId: 20.
[info] ICanBusSharerImpl.cpp:441 interpretMessage(): 	* buffer is empty.
[info] ICanBusSharerImpl.cpp:462 interpretMessage(): 	* buffer is low.
[info] ICanBusSharerImpl.cpp:467 interpretMessage(): 	* buffer is not full.
[info] ICanBusSharerImpl.cpp:476 interpretMessage(): 	* no integrity counter error.

Conclusion: buffer empty state is triggered when there are no more points in the buffer AND the last point has been already processed. If the buffer low signal is configured for buffer size zero, it is sent to the CAN master a bit earlier, that is, when that last point is being consumed (thus producing motion).

@PeterBowman
Copy link
Member Author

The position direct control mode has been rewritten (again), this time it should be final. See #220 for implementation details. To sum up, we tried four different setups:

old PT mode

  • was filling the internal iPOS buffer with seven points, using T=50 milliseconds
  • unsuitable for online trajectories because of the massive delay (7*50=350 ms)
  • suffered from several bugs, see intro comment at this very issue
  • Make position direct mode usable #198 (comment)

external reference position mode

  • aimed for execution of online trajectories (no buffer involved)
  • kinda jerky since zero-velocity states are almost always reached between successive points
  • joint coordination cannot be achieved, every motor reaches its final target at a different instant
  • we are unable to change the reference speed unless leaving and entering this mode again
  • Make position direct mode usable #198 (comment)

PT mode with synchronized client-master period

PT/PVT modes with downsampling

Learn more at #220.

@PeterBowman
Copy link
Member Author

Regarding CSP mode... Just discovered object 208Eh, Auxiliary Settings Register:

  • Bit 8 = 0: Set interpolation mode compatible with PT and PVT (legacy)
  • Bit 8 = 1: Set interpolation mode (when 6060=7) as described in the CiA402 standard

Default is 1, but this object does not exist in earlier versions of the iPOS user manual.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants