Skip to content

Conversation

@miikee
Copy link
Contributor

@miikee miikee commented Jul 24, 2025

Untested Driver

This adds:

  • ArmBackend base class
  • PreciseFlexBackend
  • TCP(IOBase) class
  • Arm front end class

Docs haven't been updated yet.
There's a warning included in the PreciseFlexBackend docstring that it's untested.

@rickwierenga rickwierenga marked this pull request as draft July 24, 2025 14:35
@rickwierenga rickwierenga force-pushed the main branch 5 times, most recently from 49a6770 to 159fd78 Compare August 29, 2025 21:51
@rickwierenga rickwierenga force-pushed the main branch 2 times, most recently from bffeb24 to a1d61b7 Compare September 23, 2025 01:22
…unndant method, chenge default ip address, change test_get_base assertion to tuple, add sleep to test_set_power
…lidation

- Updated get_signal to correctly parse response and return signal value.
- Modified get_location_z_clearance to return z_world as a boolean.
- Enhanced set_location_z_clearance to convert z_world to an integer for command.
- Improved get_location_config and set_location_config to handle bit mask configurations with validation checks.
…refactor speed handling and location management
rickwierenga and others added 12 commits November 18, 2025 16:07
- Add has_rail: bool = False parameter to __init__ for both backends
- Override move_j() to conditionally include/exclude rail joint in moveJ command
- Override set_joint_angles() to conditionally include/exclude rail in locAngles command
- Fix convert_to_joint_space() to properly map all 6 wherej output values

The moveJ command format differs based on rail configuration:
- WITHOUT rail: moveJ {profile} {base} {shoulder} {elbow} {wrist} {gripper}
- WITH rail: moveJ {profile} {rail} {base} {shoulder} {elbow} {wrist} {gripper}

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- move_to(list) now directly creates PreciseFlexJointCoords from canonical 6-element list
- Previously called convert_to_joint_space() which was designed for wherej output parsing
- Input list format: [rail, base, shoulder, elbow, wrist, gripper]
- For has_rail=False robots, rail is expected to be 0.0 at position 0

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Fix elbow orientation int<->enum mapping (1=RIGHT, 2=LEFT per GPL spec)
- Add GPL_Single flag (0x1000) to restrict wrist to ±180° range
- Fix rotation.y typo to rotation.roll in set_location_xyz
- Fix attach() call to pass robot index parameter

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@rickwierenga
Copy link
Member

rickwierenga commented Dec 5, 2025

  • removed where and get_location because get_joint_position and get_cartesian_position and get_location_angles and get_location_xyz can do all of that. I didnt see the point in having more complicated methods

@rickwierenga
Copy link
Member

also in PLR we now always have joints lists be in the format [rail, base, shoulder, elbow, wrist, gripper] so we can reason about lists irrespective of robot state. this makes the code much simpler. it also simplifies cases where users add a rails after already having code for a particular robot / share code between robots with/without rails. obviously, the firmware strings still follow the pf convention of ignoring the rails when not installed...

@rickwierenga
Copy link
Member

rickwierenga commented Dec 6, 2025

when gripping a plate using pick_plate, I get this:

  An axis has been commanded to accelerate too quickly or move too fast and does not have the power to perform the operation.  If necessary, this can be confirmed by datalogging the "Compensator output torque" (DataID 12304) and the "Position tracking error" (DataID 12320) for the axis in question.  If this is the source of the envelope error, the position error will increase significantly when the motor torque saturates at its maximum value for several tens of milliseconds.
  The axis has gone unstable due to a hardware failure or some other error.  This can be confirmed by listening for an audible noise or by datalogging the "Velocity tracking error" (DataID 12321) for the axis in question and looking for high frequency oscillations.
  An axis may have crashed into an obstacle and is unable to move to the specified position.
  The "Software envelope error limit" (DataID 10302) may be set to too small of a value. - 

the reason is probably that it tries to close too far, as the gripper closes all the way when I run it without a plate. strangely, _set_grip_close_pos does not make a difference (it does change the position for the closer_gripper command)

two questions:

  • how to make it pick up a plate using pick_plate?
  • how to recover from this error? hp 1 and attach 1 don't work.

@rickwierenga
Copy link
Member

rickwierenga commented Dec 6, 2025

re my second question:

I get the following error when attempting any command after the crash:

PreciseFlexError -1009: No robot attached. A function or method was executed that required that a robot be ATTACHED.  ...

when I attach, I get this:

PreciseFlexError: PreciseFlexError -1007: Robot not ready to be attached. An Auto Execution task or a GPL project has attempted to gain control of a robot by executing a Robot.Attach method or similar function, but the specified robot is not in a state where it can be attached. If this was generated by a GPL project, it might indicate: That the system is configured to execute DIOMotion blocks instead of a GPL motion program (DataID 200) or "Auto start auto execute mode" (DataID 202) is not set to TRUE. If so, please check the Setup>Startup Configuration web page to verify the current setup. - 

I have to power cycle by physically powering off and on the robot.

@rickwierenga
Copy link
Member

how to make it pick up a plate using pick_plate?

turns out, it pulls information not from the _set_grip_close_pos but from grasp_data (set_grasp_data and get_grasp_data). pushing a nice api in a bit.

@miikee
Copy link
Contributor Author

miikee commented Dec 6, 2025

I havent run into this error with the pick plate before. But it maybe that the speed in your profile is too fast. So that may need to be lowered in the speed profile because some joints may not be able to keep up.

The other part is I add in a setting to keep the wrist between +/- 180° to prevent some wild spinning of the wrist. It's a bitwise setting called GPL_Single flag (0x1000) in commit a332ab5

I think this including this would be useful because the wrist can get a little wild sometimes... but it may be the cause of this problem. I'd check the profile setting first though. I think the pick always just runs on profile 1.

@rickwierenga
Copy link
Member

I think the reason is our end effector has prongs, which makes the default width different than yours. It is my first time using pick_plate.

@miikee
Copy link
Contributor Author

miikee commented Dec 6, 2025

If setup(), which has the hp 1 and attach 1 isn't working, it may have gotten hung up with the GPL code running on the system.

Go to the web application, I think its 192.168.0.1. Then select admin button and then click the top option in the side panel... I think it maybe be pendant or operator or similar. And in there I think you need to stop the GPL program that's loaded then need to load it again. I think there's a stop button and then you need to load it again. (You can also do this from Brooks' GDS app, if you have that)

I dont have my laptop or the bot right now... so this is from memory. And a bad memory too.

@rickwierenga rickwierenga force-pushed the dev-precise-flex-pf400 branch from c1cc8af to e6c6593 Compare December 6, 2025 06:24
@rickwierenga
Copy link
Member

we are mostly ready I think!

I just wrote a small tutorial showing how to do the basic things

one thing still to discuss:

  • there are many duplicitous methods, such as pick_plate and its lower level function grasp_plate, and place_plate and release_plate. I think we should consider removing the lower level methods because I am not sure who would use those, and it makes the api ambiguous. do I use place_plate or release_plate? if there's a reason to keep them, maybe make them private? they are not used by PLR, and probably won't be by users.

I will do the resource modeling (ie picking up resources instead of "pick up from coordinate") in a future PR.

@miikee
Copy link
Contributor Author

miikee commented Dec 6, 2025

The only reason I can think of for keeping those functions is to have all endpoints of the TCS API exposed in python in case there is a difference and a user is specifically looking for one of them. But I think its probably just better to remove them in favor of a non-ambiguous API.

Brooks' TCS GPL code is open source if a user wants to explore things more. There's a few things not exposed through the TCS interface. An example is the Kinematic Solve function for cartesian <-> joint conversions. It exists on the robot, but isn't exposed through the TCS program that ships with the robot.

This is where Brooks' has a lot of their software - Guidance Development Studio (GDS), TCP Command Server (TCS), etc:
https://www.brooks.com/support/brooks-preciseflex-support/ - But they require you to reach out to get a password for access: support_preciseflex@brooks.com

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants