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

Need help for fetching the info of PLEXIL Update node into OwAdapter [Release 7] #43

Closed
oceank opened this issue May 19, 2021 · 6 comments

Comments

@oceank
Copy link

oceank commented May 19, 2021

Hi, @mikedalal

Could you please give me some advices on how to retrieve information sent by a PLEXIL Update node to OwAdapter (or, OwInterface)?

I tried to fetch information (execution status) from a PLEXIL Update node and use it to decide if a re-planning is required by overriding the member function sendPlannerUpdate() of the class OwAdapter, which is inherited from the class InterfaceAdapter. But OwAdapter::sendPlannerUpdate() seems to be not called during the execution of the PLEXIL plan where I have manually inserted an Update node as follows. The Update node does exist in the compiled ple file.

    TestUpdate: {
            Update plan_name = "Exca", exec_status = true;
    }

Below is the implementation of sendPlannerUpdate() based on release 7 of ow_simulator and ow_autonomy. As seen, two pieces of debugging codes are added to check if this function is called. But I did not see the file called_sendPlannerUpdate.txt is created and neighter observed [OwAdapter:SendPlannerupdate] on the screen. I also tried to look for the ros log for autonomy node in ~/.ros/log, but did not find it.

void OwAdapter::sendPlannerUpdate(Update *update)
{
  // Debug: check if sendPlannerUpdate is called
  std::ofstream myfile;
  myfile.open ("/home/jsu/called_sendPlannerUpdate.txt");
  myfile << "Writing this to a file.\n";
  myfile.close();

  const PairValueMap& plan_status = update->getPairs();
  string plan_name;
  bool exec_status;
  plan_status["plan_name"].getValue(plan_name);
  plan_status["exec_status"].getValue(exec_status);

  debugMsg("OwAdapter:sendPlannerupdate", " from the plan (" << plan_name << ") that " << (exec_status ? "succeeded." : "failed."));

  // Debug: check if sendPlannerUpdate is called
  ROS_INFO("[OwAdapter:SendPlannerupdate]: %s: %s", plan_name, (exec_status ? "succeeded." : "failed."));

  OwInterface::instance()->updatePlexilPlanStatus(plan_name, exec_status);
}

I get stuck here. Any advice and thoughts are welcome! Thanks!

@kmdalal
Copy link
Contributor

kmdalal commented May 20, 2021

Thanks for the detailed report, @oceank. The documentation for Update node adapters is noticeably missing on the Plexil website, but your approach looks reasonable. I was able to reproduce your problem in a small example that I've shared with Chuck, the lead PLEXIL developer. I suspect there is a simple missing step, and hope to have an answer to you soon.

@oceank
Copy link
Author

oceank commented May 22, 2021

Thanks for the detailed report, @oceank. The documentation for Update node adapters is noticeably missing on the Plexil website, but your approach looks reasonable. I was able to reproduce your problem in a small example that I've shared with Chuck, the lead PLEXIL developer. I suspect there is a simple missing step, and hope to have an answer to you soon.

Thanks, Mike!

Look forward to the feedback from Chuck.

@kmdalal
Copy link
Contributor

kmdalal commented May 29, 2021

Hi @oceank, sorry for the wait, but I have a solution. As I mentioned, the PLEXIL documentation on Sourceforge is out of date and incomplete, but the needed interfacing support exists. Here's what you need to do.

  1. Don't use the virtual function sendPlannerUpdate(). Instead, define a static member function in OwAdapter with the following signature, and any function/argument names you like:
  static void myPlannerUpdate (PLEXIL::Update* update, PLEXIL::AdapterExecInterface* exec);
  1. This function, the Update node handler, must contain the line: exec->handleUpdateAck (update, true); in order to transition the Update node to finished. Your logic will determine where to place this line.
  2. In OwAdapter::initialize(), the following line is needed to register your Update handler:
g_configuration->registerPlannerUpdateHandler(OwAdapter::myPlannerUpdate);
  1. In plans/ow-config.xml, in the <Adapter AdapterType="ow_adapter"> element, add this element:
<PlannerUpdate/>

This should get you going. We will update the PLEXIL docs in time. I'm also told that the Update Node approach may be less preferable to a newer interface for writing Exec Listeners, but I am at present inexperienced with these.

@oceank
Copy link
Author

oceank commented May 29, 2021

Hi @oceank, sorry for the wait, but I have a solution. As I mentioned, the PLEXIL documentation on Sourceforge is out of date and incomplete, but the needed interfacing support exists. Here's what you need to do.

1. Don't use the virtual function sendPlannerUpdate().  Instead, define a _static_ member function in OwAdapter with the following signature, and any function/argument names you like:
  static void myPlannerUpdate (PLEXIL::Update* update, PLEXIL::AdapterExecInterface* exec);
1. This function, the Update node handler, must contain the line: `exec->handleUpdateAck (update, true);`  in order to transition the Update node to finished.  Your logic will determine where to place this line.

2. In OwAdapter::initialize(), the following line is needed to register your Update handler:
g_configuration->registerPlannerUpdateHandler(OwAdapter::myPlannerUpdate);
1. In plans/ow-config.xml, in the   `<Adapter AdapterType="ow_adapter">` element, add this element:
<PlannerUpdate/>

This should get you going. We will update the PLEXIL docs in time. I'm also told that the Update Node approach may be less preferable to a newer interface for writing Exec Listeners, but I am at present inexperienced with these.

Thanks @kmdalal! I will follow your suggestion and update here soon. For the preferred newer interface for wrting Exec Listeners, is there a document for it?

@kmdalal
Copy link
Contributor

kmdalal commented May 29, 2021

Unfortunately the section on Exec Listeners is blank, and I don't have the knowledge to write it. I suggest going with the above approach for now. Here is a brief explanation I got for it, which may not be much to go on:

"The ExecListener's implementNotifyNodeTransition() method looks for an Update node transitioning to EXECUTING. The Node* pointer passed into the method would have to be dynamic_cast to UpdateNode*; then the update can be read from the node, and the update pairs published as required."

I think the feature needs more clarification, documentation, and probably some interface enhancement to make more user-friendly. I have created a request to do this.

@oceank
Copy link
Author

oceank commented Jun 4, 2021

@kmdalal Thanks!

Your suggested approach works well! I have successfully implemented and tested re-planning on the fly. I will really appreciate it If you could send me the update when you get further information regarding ExecListener's documentation and examples.

Let's close the issue.

BTW: in case you are interested, my implementation can be found in the forked repo nasa-raspberry-si/ow_autonomy.

@oceank oceank closed this as completed Jun 4, 2021
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

No branches or pull requests

2 participants