API review

Proposer: Stuart Glaser


Present at review:

  • Vijay, Wim, Gunter, Eric, Stu

Question / concerns / comments

Enter your thoughts on the API and any questions / concerns you have here. Please sign your name. Anything you want to address in the API review should be marked down here before the start of the meeting.


  • Do we need a trajectory_status message?

    • Is there any way for a smoother to confirm that its requested trajectory is being executed? It seems like the only way now is to do a deep comparison of the JointTrajectoryControllerState being published. And this deep comparison is not necessarily sufficient.

    • This could be solved by publishing a trajectory_status message at some defined rate (Maybe 10Hz?).

      Header header
      string traj_id
      time traj_start_time
      uint32 current_segment_num
      time segment_start_time
    • Note that this implies that people sending in trajectories would have to specify a traj_id, but this could be optional

  • I'd like to use this controller with the tilting laser...

    • Use Absolute Time
      I'd like to use this controller "as-is" for the tilting laser. However, in order to build point cloud snapshots, I must know exactly when I've started and ended trajectory segments. Getting this information might be tricky if the "laser-planner" and "laser-smoother" are sending commands with relative times, as opposed to absolute times.

    • Absolute Time Sucks For Stitching together trajectories
      The tilting laser will be running an infinitely long periodic trajectory that might be diverted to do a slow scan every once in a while. To divert the trajectory with a new once, I have pass in a new traj msg that diverges at some point in the future. Ideally, it would diverge 'as soon as possible', but I have to provide some buffer to account for how long it will take the interpolator & controller to receive the new traj msg.

  • How do you deal with infeasible trajectories?

    • Do you change any timing information? Or do you simply "do your best" in trying to follow it?

Meeting agenda

  • Absolute vs relative time for segments. Currently the segment has a "duration." This may be confusing, as the positions/velocities/accelerations are given for the end of the segment. This is particularly unclear for the first segment of the trajectory.

  • Place for the Trajectory message (or equivalent). Where does it go? Does it wind up in common_msgs?

To be filled out by proposer based on comments gathered during API review period

  • Trajectory status (id)
    • What is the status? Messages come in with trajectories, the status coming back is for the currently executing piece. The trajectory status changes to reflect which message the currently executing piece is from.
    • V needs to know where the laser is in its trajectory.
    • The traj is executed at an absolute time, so it is known where it's going to be at a given time.
    • How do I know that the message didn't get lost?
    • How do I know that the controller got the message in time?
    • Both these would be good as an action, but this is out of scope for now (Eric).
    • Could add an id to the traj message.
    • Messages are meant to be infinitely streaming, and actions are used for confirming that what you've asked for is actually happening.
    • Currently expect to have one node sending trajectories
    • Also assuming that the message gets through and is executed in time?
    • At the end of the day, don't care if the goal was sent, but rather that the hand got to where it should be.
    • If we really need the id, then we probably should just add an action server to the controller.
    • Result: Don't put the id in. If we need it in the long term, add an action server to the controller.
  • Absolute time:
    • Need to know when your trajectory is going to start executing
    • This system does add a connecting spline, but you need to decide how long it is.
    • Assume it takes 10ms, and that will probably work. This is performance tuning, and will always depend on many factors of communication.
  • What happens if you ask for a traj w a starting time in the past
    • Right now it causes a discontinuity. (Instead of dropping the new traj, or something equally bad).
  • Explicitly document when the first trajectory point has a non-zero duration.
  • "This interface is pretty awesome." -Vijay
  • All trajectory controllers in the system should publish the state with the same timestamp (would be great if it were synced to joint_states too).
  • Global "controllers errors" thing. Not now.
  • command message
    • "duration" or "time"
    • frame_id is there because of a standard header.
    • It's not necessarily clear that "stamp" is the start time.
    • Change "names" to "joint_names"
    • Change to JointTrajectory

    • We like the word "duration" (too much ambiguity with "time")
    • Change duration to a ros::Duration
    • "end_positions"?

  Segment segments[]
    JointDesiredStates end

string[] names
TrajectorySegment[] segments
  duration duration
  float64[] positions
  float64[] velocities

  float64[] xf, xdf, xddf
  float64[] xd_f, xd_d_f, xd_dd_f

Header header
string[] joint_names
JointTrajectorySegment[] segments
  duration duration
  JointTrajectoryPoint[] end
    float64[] positions
    float64[] velocities
    float64[] accelerations
  • Currently in robot_mechanism_controllers, but should go elsewhere
    • Should be more general than pr2 (though pr2_common might be ok)
    • Package name? trajectory_msgs (so it's easy to propagate it up the stacks).
  • State message
    • joint_names
    • Can we use the JointTrajectoryPoint?

      • desired, measured, and error (leave acc blank in some cases)
  • query service
    • joint_names
    • JointTrajectoryPoint!!!!! yata!!!


  • Won't be adding ID's to the trajectory nor reporting on which trajectory segment we are currently following. This information may be useful for outside nodes to track progress on a trajectory, but we will postpone these features to a later version of the controller.
  • We will continue to use absolute times for the trajectory start time. The controller will add a connecting spline between the last point and the new trajectory's first point, but the sender of the trajectory must determine the duration of the connecting spline.
  • [ ] It's difficult for the user to determine what happens when the first segment has a non-zero duration. Document that explicitly.
  • It would be great if all trajectory controllers published their state messages at the same times.
  • command message
    • [ ] Put into trajectory_msgs
    • [ ] Use JointTrajectoryPoint all over the place (state message, query service).

    • [ ] Create the message with the following structure:

Header header
string[] joint_names
JointTrajectorySegment[] segments
  duration duration
  JointTrajectoryPoint[] end
    float64[] positions
    float64[] velocities
    float64[] accelerations


  • I have some concerns about this structure - it is way too different from the way the current set of trajectory controllers and messages operate
    • trajectories consist of a set of waypoints, spline trajectories consist of a set of segments. If we specify something as a segment, it implicitly implies that we know what will happen during that segment but all we know is what is specified for the waypoints
    • The manipulation_msgs implementation of trajectory is this

Waypoint.msg - used to specify a single waypoint

  •  float64[] positions
     float64[] velocities
     float64[] accelerations
     float64 time

WaypointTraj.msg - used to specify a path

  • # A complete trajectory specified as a set of waypoints.  Since each waypoint
    # contains the pos/vel/acc for many joints (or other dimensions), the names array
    # is used to specify joint names
    string[] joint_names
    Waypoint[] points
    • Could we move back to this message (I am fine with changing the names of individual fields/messages and having absolute times with a field name timestamp).

    • In summary, here are the differences between the Waypoint message and the message we settled on in the last trajectory meeting:

      • The boundary conditions have a "time" instead of a "duration"
      • The positions/velocities/accelerations fields are not inside a "-Point" structure.
      • I think they differ on what the timestamp in the header means.
  • The planners currently need the following information from the controller
    • Information on when a trajectory is done
    • Information on the expected trajectory the controller will follow - essentially a query service with a trajectory id to which the controller responds with a trajectory message
    • Either the planner needs the order in which the joints being controlled are arranged or the controller must be able to deal with requests where this order might change.
      • The controller will reorder the trajectory according to the order of "joint_names"

    • The controller/action should be able to (sensibly) deal with 1 waypoint or a set of waypoints with the same timestamp.
      • The controller treats them all as occurring at the same time t. Before t, it will interpolate using the first waypoint, and after t it will interpolate using the last waypoint.

    • Timeout behavior/safe behavior - if the node that sent you the request went down, stop
  • When a new trajectory is sent in, there should be minimal abrupt jumps in behavior.
    • The current policy is that if the user asks for an abrubt jump then the controller will perform an abrubt jump.

  • Default behavior should not be linear, people expect to be able to send a single point to this controller and have it do something sensible (essentially make sure there is some kind of velocity saturation by default).

Notes 2009-10-22

  • Discussing absolute vs relative timestamps within trajectory.
    • Duration requires summing
    • Absolute time is harder to shift (requires iterating)
  • We have a time independent "path" vs a time specific "trajectory"
    • Do we want to have a single data type which is large and has all data that then gets filled in at each stage or do we want to have two data types which enforces filling in the timestamp at the intermediate stage.
  • Need separate logic for paths and trajectories anyways, so having separate messages/callbacks also makes sense.
  • Path should just be positions
  • What is a "point"? Just position, or (pos,vel,acc)?
  • What is (pos,vel,acc) called?
  • Time vs duration
    • Times can be switched around, but durations can be negative
    • Planners are currently returning a "suggested" time
    • Why are the planners dealing with time? They're not modeling it. If the planners came out with paths, there would have to be something in between that would convert it to time. It was decided that it would be easiest for the planners to come up with the suggested parameterization and to deal with it later on.
      • If you're not reasoning about time, it seems like you shouldn't be commanding a time.
      • Chomp does, but then shouldn't chomp spit out a trajectory and all the others should spit out a path?
    • Should still put trajectories through the traj generator. Why? (Sachin)
      • Sanity check has to be done in the controller (times in order, etc)
      • There are plenty of reasons, but in the end it's optional. Could just connect a dynamic planner's trajectory outputs to the controller.
  • Controller shouldn't do "crazy" things:
    • Crazy: shouldn't be able to give the controller a discontinuity or an unachievable path.
    • No, the controller should follow what you ask it to do
    • No, the controller should adjust if you ask it to do something it can't do.
    • No, the controller needs to know everything about the environment in order to know if the trajectory is followable.
    • Pretty decided that the controller should make a best-effort attempt to do whatever you ask, but not determine if
  • "duration" vs "time"?
    • recorded trajectories need to be "re-adjusted" if we use absolute times.
    • three possibilities: absolute time, time since start, time since previous point
  • Definitely need a different message for cartesian trajectories. Call this JointTrajectory?

  • Could use it for the base. But we could consider the base to be virtual joints
  • Path must become JointPath (we already have a path of poses)

  Header header
  string[] joint_names
  JointTrajectoryPoint[] points
    float64[] positions
    float64[] velocities
    float64[] accelerations
    duration time_from_start

Header header
string[] joint_names
JointTrajectoryPoint desired
JointTrajectoryPoint actual

  string[] joint_names
  JointPathPoint[] points
    float64[] positions    
  • timestamp in header?
  • naming
  • Things to name:
    • (pos,vel,acc) (joints or cartesian?)
    • (pos,vel,acc,t)
  • Will write an action to report on whether the trajectory succeeds or fails.
  • The first action will not allow queueing
  • controller must spit out what it's current trajectory is. "What is the next 10 seconds of trajectory"
  • invalid trajectories should be refused (timestamps out of order), but "unsafe" is not defined.
  • The commanding node should never send a trajectory that's longer than it's okay for the controller to follow to the end.

Package status change mark change manifest)

  • /!\ Action items that need to be taken.

  • {X} Major issues that need to be resolved

Wiki: robot_mechanism_controllers/Reviews/2009-10-16_Traj_API_Review (last edited 2009-10-22 19:26:54 by TullyFoote)