{"action":"created","comment":{"url":"https://api.github.com/repos/AutoRally/autorally/pulls/comments/72464780","id":72464780,"diff_hunk":"@@ -0,0 +1,583 @@\n+/*\n+* Software License Agreement (BSD License)\n+* Copyright (c) 2016, Georgia Institute of Technology\n+* All rights reserved.\n+*\n+* Redistribution and use in source and binary forms, with or without\n+* modification, are permitted provided that the following conditions are met:\n+*\n+* 1. Redistributions of source code must retain the above copyright notice, this\n+* list of conditions and the following disclaimer.\n+* 2. Redistributions in binary form must reproduce the above copyright notice,\n+* this list of conditions and the following disclaimer in the documentation\n+* and/or other materials provided with the distribution.\n+*\n+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n+* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE\n+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+*/\n+/**********************************************\n+ * @file AutoRallyChassis.cpp\n+ * @author Brian Goldfain <bgoldfai@gmail.com>\n+ * @date July 10, 2016\n+ * @copyright 2016 Georgia Institute of Technology\n+ * @brief Interface for an AutoRally chassis\n+ *\n+ * @details Implementation of the AutoRallyChassis class that controls and receives state information from an AutoRally\n+ *          chassis\n+ ***********************************************/\n+\n+#include <boost/algorithm/string/split.hpp>\n+#include <boost/algorithm/string.hpp>\n+\n+#include <pluginlib/class_list_macros.h>\n+\n+#include \"AutoRallyChassis.h\"\n+\n+PLUGINLIB_DECLARE_CLASS(autorally_core, AutoRallyChassis, autorally_core::AutoRallyChassis, nodelet::Nodelet)\n+\n+namespace autorally_core\n+{\n+\n+AutoRallyChassis::~AutoRallyChassis()\n+{\n+  chassisControlTimer_.stop();\n+}\n+\n+void AutoRallyChassis::onInit()\n+{\n+  ros::NodeHandle nh = getNodeHandle();\n+  ros::NodeHandle nhPvt = getPrivateNodeHandle();\n+  std::string port;\n+  if(!nh.getParam(getName()+\"/port\", port))\n+  {\n+    NODELET_ERROR(\"AutoRallyChassis: could not get chassis interface port\");\n+  }\n+\n+  loadChassisConfig();\n+  loadChassisCommandPriorities();\n+  serialPort_.init(nh, getName(), \"\", \"AutoRallyChassis\", port, true);\n+  \n+  double commandRate = 0.0;\n+  double chassisCommandMaxAge = 0.0;\n+  double runstopMaxAge = 0.0;\n+\n+  if(!nhPvt.getParam(\"commandRate\", commandRate) ||\n+     !nhPvt.getParam(\"commandMaxAge\", chassisCommandMaxAge) ||\n+     !nhPvt.getParam(\"runstopMaxAge\", runstopMaxAge))\n+  {\n+    NODELET_ERROR_STREAM(getName() << \" could not get all startup params\");\n+  }\n+  chassisCommandMaxAge_ = ros::Duration(chassisCommandMaxAge);\n+  runstopMaxAge_ = ros::Duration(runstopMaxAge);\n+\n+  chassisStatePub_ = nh.advertise<autorally_msgs::chassisState>\n+                     (\"chassisState\", 1);\n+  wheelSpeedsPub_ = nh.advertise<autorally_msgs::wheelSpeeds>\n+                     (\"wheelSpeeds\", 1);\n+  chassisCommandPub_ = nh.advertise<autorally_msgs::chassisCommand>\n+                     (\"RC/chassisCommand\", 1);\n+\n+  for (auto& mapIt : chassisCommands_)\n+  {\n+    std::string topic = mapIt.first+\"/chassisCommand\";\n+    ros::Subscriber sub = nh.subscribe(topic, 1,\n+                                       &AutoRallyChassis::chassisCommandCallback, this);\n+    chassisCommandSub_[mapIt.first] = sub;\n+  }\n+  runstopSub_ = nh.subscribe(\"/runstop\", 5, &AutoRallyChassis::runstopCallback, this);  \n+  \n+  //callback for serial data from chassis\n+  serialPort_.registerDataCallback(boost::bind(&AutoRallyChassis::chassisFeedbackCallback, this));\n+\n+  chassisControlTimer_ = nh.createTimer(ros::Rate(commandRate),\n+                      &AutoRallyChassis::setChassisActuators, this);\n+}\n+\n+//subscribe to a one topic for every chassis commander listed in the chassis commander priorities file\n+void AutoRallyChassis::chassisCommandCallback(\n+                     const autorally_msgs::chassisCommandConstPtr& msg)\n+{\n+  std::map<std::string, autorally_msgs::chassisCommand>::iterator mapIt;\n+  if((mapIt = chassisCommands_.find(msg->sender)) == chassisCommands_.end())\n+  {\n+    NODELET_ERROR_STREAM(\"AutoRallyChassis: Unknown controller \" <<\n+                         msg->sender <<\n+                         \" attempting to control chassis, please add entry \" <<\n+                         \" to chassisCommandPriorities.yaml\");\n+  } else\n+  {\n+    mapIt->second = *msg;\n+  }\n+}\n+\n+void AutoRallyChassis::chassisFeedbackCallback()\n+{\n+  //Any variables accessed in here and in other places in the code need to be mutex'd as this fires in a different\n+  //thread than the main thread. This is also a pretyt long callback, and ROS can shutdown underneath us, so check\n+  //if ROS system is still running any time anything ROS is used\n+\n+  serialPort_.lock();\n+  size_t startPosition = serialPort_.m_data.find_first_of('#');\n+  size_t endPosition = serialPort_.m_data.find_first_of('\\n', startPosition);\n+  serialPort_.unlock();\n+  std::string data = \"\";\n+\n+  //retrieve and process all available messages from the chassis\n+  while(endPosition != std::string::npos)\n+  {\n+    //make sure we have start and end position\n+    serialPort_.lock();\n+    if(startPosition !=  std::string::npos && endPosition != std::string::npos)\n+    {\n+      //frame data if not framed\n+      if(startPosition != 0)\n+      {\n+        serialPort_.m_data.erase(0, startPosition);\n+      }\n+\n+      startPosition = 0;\n+      endPosition = serialPort_.m_data.find_first_of('\\n', startPosition);\n+\n+      //cut out and erase message from queue\n+      data = serialPort_.m_data.substr(0, endPosition);\n+      serialPort_.m_data.erase(0, endPosition);\n+\n+    } else if(startPosition != std::string::npos)\n+    {\n+      serialPort_.m_data.erase(0, startPosition);\n+    }\n+    serialPort_.unlock();\n+\n+    //process a complete messsage from the chassis\n+    if(!data.empty())\n+    {\n+      processChassisMessage(data.substr(1,1), data.substr(2, endPosition-2));\n+    }\n+\n+    //make sure we are framed\n+    serialPort_.lock();\n+    startPosition = serialPort_.m_data.find_first_of('#');\n+    endPosition = serialPort_.m_data.find_first_of('\\n', startPosition);\n+    serialPort_.unlock();\n+  }\n+}\n+\n+void AutoRallyChassis::processChassisMessage(std::string msgType, std::string msg)\n+{\n+  switch(msgType[0])\n+  {\n+    //wheel speeds data as comma separated doubles, units in m/s\n+    case 'w':\n+    {\n+      std::vector<std::string> data;\n+      boost::split(data, msg, boost::is_any_of(\",\"));\n+      if(data.size() == 4)\n+      {\n+        autorally_msgs::wheelSpeedsPtr wheelSpeeds(new autorally_msgs::wheelSpeeds);\n+        try\n+        {\n+          wheelSpeeds->lfSpeed = std::stod(data[0]);\n+          wheelSpeeds->rfSpeed = std::stod(data[1]);\n+          wheelSpeeds->lbSpeed = std::stod(data[2]);\n+          wheelSpeeds->rbSpeed = std::stod(data[3]);\n+          if(wheelSpeedsPub_ && !ros::isShuttingDown())\n+          {\n+            wheelSpeeds->header.stamp = ros::Time::now();\n+            wheelSpeedsPub_.publish(wheelSpeeds);\n+          }\n+          serialPort_.tick(\"wheelSpeeds data\");\n+        } catch (std::exception& e )\n+        {\n+          serialPort_.diag_warn(\"Converting wheel speeds data failed\");\n+        }\n+      } else\n+      {\n+        serialPort_.diag_warn(\"Processing wheel speeds data failed\");\n+      }\n+      break;\n+    }\n+    \n+    //Actuator controls from RC input, as comma separated us pulse width, currentl frontBrake is not controlled by RC\n+    case 'r':\n+    {\n+      std::vector<std::string> data;\n+      boost::split(data, msg, boost::is_any_of(\",\"));\n+      if(data.size() == 4)\n+      {\n+        autorally_msgs::chassisCommandPtr chassisCommand(new autorally_msgs::chassisCommand);\n+        try\n+        {\n+          //std::cout << std::stoi(data[0]) << \" \" << std::stoi(data[1]) << std::endl;\n+          chassisCommand->steering = actuatorUsToCmd(std::stoi(data[0]), \"steering\");\n+          chassisCommand->throttle = actuatorUsToCmd(std::stoi(data[1]), \"throttle\");\n+          chassisCommand->frontBrake = -5.0;\n+          chassisCommand->sender = \"RC\";\n+          //this line is in here for compatibility with the old servoInterface\n+          chassisCommand->header.frame_id = \"RC\";\n+          \n+          rcMutex_.lock();\n+          mostRecentRcSteering_ = chassisCommand->steering;\n+          mostRecentRcThrottle_ = chassisCommand->throttle;\n+          mostRecentRcFrontBrake_ = chassisCommand->frontBrake;\n+          rcMutex_.unlock();\n+          \n+          if(chassisCommandPub_ && !ros::isShuttingDown())\n+          {\n+            chassisCommand->header.stamp = ros::Time::now();\n+            chassisCommandPub_.publish(chassisCommand);\n+          }\n+\n+          chassisStateMutex_.lock();\n+          if(std::stoi(data[2]) > 1500)\n+          {\n+            autonomousEnabled_ = true;\n+          } else\n+          {\n+            autonomousEnabled_ = false;\n+          }\n+          throttleRelayEnabled_ = std::stoi(data[3]); //this value can be 0 or 1\n+          chassisStateMutex_.unlock();\n+\n+          serialPort_.tick(\"RC data\");\n+        } catch(std::exception& e)\n+        {\n+          serialPort_.diag_warn(\"Converting wheel speeds data failed\");","path":"autorally_core/src/autorally_chassis/AutoRallyChassis.cpp","position":252,"original_position":252,"commit_id":"946bd2e3e5825777a32c20d1ec9d3205765af90a","original_commit_id":"946bd2e3e5825777a32c20d1ec9d3205765af90a","user":{"login":"pdrews","id":506166,"avatar_url":"https://avatars.githubusercontent.com/u/506166?v=3","gravatar_id":"","url":"https://api.github.com/users/pdrews","html_url":"https://github.com/pdrews","followers_url":"https://api.github.com/users/pdrews/followers","following_url":"https://api.github.com/users/pdrews/following{/other_user}","gists_url":"https://api.github.com/users/pdrews/gists{/gist_id}","starred_url":"https://api.github.com/users/pdrews/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pdrews/subscriptions","organizations_url":"https://api.github.com/users/pdrews/orgs","repos_url":"https://api.github.com/users/pdrews/repos","events_url":"https://api.github.com/users/pdrews/events{/privacy}","received_events_url":"https://api.github.com/users/pdrews/received_events","type":"User","site_admin":false},"body":"Except, I think this method locks the port, we would need to find a workaround if we keep it locked in the above function.","created_at":"2016-07-27T15:41:51Z","updated_at":"2016-07-27T15:41:51Z","html_url":"https://github.com/AutoRally/autorally/pull/24#discussion_r72464780","pull_request_url":"https://api.github.com/repos/AutoRally/autorally/pulls/24","_links":{"self":{"href":"https://api.github.com/repos/AutoRally/autorally/pulls/comments/72464780"},"html":{"href":"https://github.com/AutoRally/autorally/pull/24#discussion_r72464780"},"pull_request":{"href":"https://api.github.com/repos/AutoRally/autorally/pulls/24"}}},"pull_request":{"url":"https://api.github.com/repos/AutoRally/autorally/pulls/24","id":78900574,"html_url":"https://github.com/AutoRally/autorally/pull/24","diff_url":"https://github.com/AutoRally/autorally/pull/24.diff","patch_url":"https://github.com/AutoRally/autorally/pull/24.patch","issue_url":"https://api.github.com/repos/AutoRally/autorally/issues/24","number":24,"state":"open","locked":false,"title":"New chassis controller","user":{"login":"bgoldfai","id":1173259,"avatar_url":"https://avatars.githubusercontent.com/u/1173259?v=3","gravatar_id":"","url":"https://api.github.com/users/bgoldfai","html_url":"https://github.com/bgoldfai","followers_url":"https://api.github.com/users/bgoldfai/followers","following_url":"https://api.github.com/users/bgoldfai/following{/other_user}","gists_url":"https://api.github.com/users/bgoldfai/gists{/gist_id}","starred_url":"https://api.github.com/users/bgoldfai/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bgoldfai/subscriptions","organizations_url":"https://api.github.com/users/bgoldfai/orgs","repos_url":"https://api.github.com/users/bgoldfai/repos","events_url":"https://api.github.com/users/bgoldfai/events{/privacy}","received_events_url":"https://api.github.com/users/bgoldfai/received_events","type":"User","site_admin":false},"body":"This pull request includes the new autorally chassis interface messages, the new autorally_chassis interface, and updates to all existing programs to use the new messaging interface.\r\n\r\nThis closes #23 \r\n","created_at":"2016-07-26T18:24:12Z","updated_at":"2016-07-27T15:41:51Z","closed_at":null,"merged_at":null,"merge_commit_sha":"fff58cd87b59c7cb66f4260502197324161b8c29","assignee":{"login":"pdrews","id":506166,"avatar_url":"https://avatars.githubusercontent.com/u/506166?v=3","gravatar_id":"","url":"https://api.github.com/users/pdrews","html_url":"https://github.com/pdrews","followers_url":"https://api.github.com/users/pdrews/followers","following_url":"https://api.github.com/users/pdrews/following{/other_user}","gists_url":"https://api.github.com/users/pdrews/gists{/gist_id}","starred_url":"https://api.github.com/users/pdrews/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pdrews/subscriptions","organizations_url":"https://api.github.com/users/pdrews/orgs","repos_url":"https://api.github.com/users/pdrews/repos","events_url":"https://api.github.com/users/pdrews/events{/privacy}","received_events_url":"https://api.github.com/users/pdrews/received_events","type":"User","site_admin":false},"assignees":[{"login":"pdrews","id":506166,"avatar_url":"https://avatars.githubusercontent.com/u/506166?v=3","gravatar_id":"","url":"https://api.github.com/users/pdrews","html_url":"https://github.com/pdrews","followers_url":"https://api.github.com/users/pdrews/followers","following_url":"https://api.github.com/users/pdrews/following{/other_user}","gists_url":"https://api.github.com/users/pdrews/gists{/gist_id}","starred_url":"https://api.github.com/users/pdrews/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pdrews/subscriptions","organizations_url":"https://api.github.com/users/pdrews/orgs","repos_url":"https://api.github.com/users/pdrews/repos","events_url":"https://api.github.com/users/pdrews/events{/privacy}","received_events_url":"https://api.github.com/users/pdrews/received_events","type":"User","site_admin":false},{"login":"bgoldfai","id":1173259,"avatar_url":"https://avatars.githubusercontent.com/u/1173259?v=3","gravatar_id":"","url":"https://api.github.com/users/bgoldfai","html_url":"https://github.com/bgoldfai","followers_url":"https://api.github.com/users/bgoldfai/followers","following_url":"https://api.github.com/users/bgoldfai/following{/other_user}","gists_url":"https://api.github.com/users/bgoldfai/gists{/gist_id}","starred_url":"https://api.github.com/users/bgoldfai/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bgoldfai/subscriptions","organizations_url":"https://api.github.com/users/bgoldfai/orgs","repos_url":"https://api.github.com/users/bgoldfai/repos","events_url":"https://api.github.com/users/bgoldfai/events{/privacy}","received_events_url":"https://api.github.com/users/bgoldfai/received_events","type":"User","site_admin":false},{"login":"barulicm","id":1761749,"avatar_url":"https://avatars.githubusercontent.com/u/1761749?v=3","gravatar_id":"","url":"https://api.github.com/users/barulicm","html_url":"https://github.com/barulicm","followers_url":"https://api.github.com/users/barulicm/followers","following_url":"https://api.github.com/users/barulicm/following{/other_user}","gists_url":"https://api.github.com/users/barulicm/gists{/gist_id}","starred_url":"https://api.github.com/users/barulicm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/barulicm/subscriptions","organizations_url":"https://api.github.com/users/barulicm/orgs","repos_url":"https://api.github.com/users/barulicm/repos","events_url":"https://api.github.com/users/barulicm/events{/privacy}","received_events_url":"https://api.github.com/users/barulicm/received_events","type":"User","site_admin":false},{"login":"gradyrw","id":1912106,"avatar_url":"https://avatars.githubusercontent.com/u/1912106?v=3","gravatar_id":"","url":"https://api.github.com/users/gradyrw","html_url":"https://github.com/gradyrw","followers_url":"https://api.github.com/users/gradyrw/followers","following_url":"https://api.github.com/users/gradyrw/following{/other_user}","gists_url":"https://api.github.com/users/gradyrw/gists{/gist_id}","starred_url":"https://api.github.com/users/gradyrw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gradyrw/subscriptions","organizations_url":"https://api.github.com/users/gradyrw/orgs","repos_url":"https://api.github.com/users/gradyrw/repos","events_url":"https://api.github.com/users/gradyrw/events{/privacy}","received_events_url":"https://api.github.com/users/gradyrw/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/AutoRally/autorally/milestones/1","html_url":"https://github.com/AutoRally/autorally/milestones/0.2.0%20Release","labels_url":"https://api.github.com/repos/AutoRally/autorally/milestones/1/labels","id":1816277,"number":1,"title":"0.2.0 Release","description":"","creator":{"login":"bgoldfai","id":1173259,"avatar_url":"https://avatars.githubusercontent.com/u/1173259?v=3","gravatar_id":"","url":"https://api.github.com/users/bgoldfai","html_url":"https://github.com/bgoldfai","followers_url":"https://api.github.com/users/bgoldfai/followers","following_url":"https://api.github.com/users/bgoldfai/following{/other_user}","gists_url":"https://api.github.com/users/bgoldfai/gists{/gist_id}","starred_url":"https://api.github.com/users/bgoldfai/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bgoldfai/subscriptions","organizations_url":"https://api.github.com/users/bgoldfai/orgs","repos_url":"https://api.github.com/users/bgoldfai/repos","events_url":"https://api.github.com/users/bgoldfai/events{/privacy}","received_events_url":"https://api.github.com/users/bgoldfai/received_events","type":"User","site_admin":false},"open_issues":13,"closed_issues":0,"state":"open","created_at":"2016-06-08T17:48:39Z","updated_at":"2016-07-26T18:24:12Z","due_on":"2016-06-24T04:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/AutoRally/autorally/pulls/24/commits","review_comments_url":"https://api.github.com/repos/AutoRally/autorally/pulls/24/comments","review_comment_url":"https://api.github.com/repos/AutoRally/autorally/pulls/comments{/number}","comments_url":"https://api.github.com/repos/AutoRally/autorally/issues/24/comments","statuses_url":"https://api.github.com/repos/AutoRally/autorally/statuses/946bd2e3e5825777a32c20d1ec9d3205765af90a","head":{"label":"AutoRally:chassisController","ref":"chassisController","sha":"946bd2e3e5825777a32c20d1ec9d3205765af90a","user":{"login":"AutoRally","id":16822115,"avatar_url":"https://avatars.githubusercontent.com/u/16822115?v=3","gravatar_id":"","url":"https://api.github.com/users/AutoRally","html_url":"https://github.com/AutoRally","followers_url":"https://api.github.com/users/AutoRally/followers","following_url":"https://api.github.com/users/AutoRally/following{/other_user}","gists_url":"https://api.github.com/users/AutoRally/gists{/gist_id}","starred_url":"https://api.github.com/users/AutoRally/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AutoRally/subscriptions","organizations_url":"https://api.github.com/users/AutoRally/orgs","repos_url":"https://api.github.com/users/AutoRally/repos","events_url":"https://api.github.com/users/AutoRally/events{/privacy}","received_events_url":"https://api.github.com/users/AutoRally/received_events","type":"Organization","site_admin":false},"repo":{"id":56652382,"name":"autorally","full_name":"AutoRally/autorally","owner":{"login":"AutoRally","id":16822115,"avatar_url":"https://avatars.githubusercontent.com/u/16822115?v=3","gravatar_id":"","url":"https://api.github.com/users/AutoRally","html_url":"https://github.com/AutoRally","followers_url":"https://api.github.com/users/AutoRally/followers","following_url":"https://api.github.com/users/AutoRally/following{/other_user}","gists_url":"https://api.github.com/users/AutoRally/gists{/gist_id}","starred_url":"https://api.github.com/users/AutoRally/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AutoRally/subscriptions","organizations_url":"https://api.github.com/users/AutoRally/orgs","repos_url":"https://api.github.com/users/AutoRally/repos","events_url":"https://api.github.com/users/AutoRally/events{/privacy}","received_events_url":"https://api.github.com/users/AutoRally/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/AutoRally/autorally","description":"","fork":false,"url":"https://api.github.com/repos/AutoRally/autorally","forks_url":"https://api.github.com/repos/AutoRally/autorally/forks","keys_url":"https://api.github.com/repos/AutoRally/autorally/keys{/key_id}","collaborators_url":"https://api.github.com/repos/AutoRally/autorally/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/AutoRally/autorally/teams","hooks_url":"https://api.github.com/repos/AutoRally/autorally/hooks","issue_events_url":"https://api.github.com/repos/AutoRally/autorally/issues/events{/number}","events_url":"https://api.github.com/repos/AutoRally/autorally/events","assignees_url":"https://api.github.com/repos/AutoRally/autorally/assignees{/user}","branches_url":"https://api.github.com/repos/AutoRally/autorally/branches{/branch}","tags_url":"https://api.github.com/repos/AutoRally/autorally/tags","blobs_url":"https://api.github.com/repos/AutoRally/autorally/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/AutoRally/autorally/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/AutoRally/autorally/git/refs{/sha}","trees_url":"https://api.github.com/repos/AutoRally/autorally/git/trees{/sha}","statuses_url":"https://api.github.com/repos/AutoRally/autorally/statuses/{sha}","languages_url":"https://api.github.com/repos/AutoRally/autorally/languages","stargazers_url":"https://api.github.com/repos/AutoRally/autorally/stargazers","contributors_url":"https://api.github.com/repos/AutoRally/autorally/contributors","subscribers_url":"https://api.github.com/repos/AutoRally/autorally/subscribers","subscription_url":"https://api.github.com/repos/AutoRally/autorally/subscription","commits_url":"https://api.github.com/repos/AutoRally/autorally/commits{/sha}","git_commits_url":"https://api.github.com/repos/AutoRally/autorally/git/commits{/sha}","comments_url":"https://api.github.com/repos/AutoRally/autorally/comments{/number}","issue_comment_url":"https://api.github.com/repos/AutoRally/autorally/issues/comments{/number}","contents_url":"https://api.github.com/repos/AutoRally/autorally/contents/{+path}","compare_url":"https://api.github.com/repos/AutoRally/autorally/compare/{base}...{head}","merges_url":"https://api.github.com/repos/AutoRally/autorally/merges","archive_url":"https://api.github.com/repos/AutoRally/autorally/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/AutoRally/autorally/downloads","issues_url":"https://api.github.com/repos/AutoRally/autorally/issues{/number}","pulls_url":"https://api.github.com/repos/AutoRally/autorally/pulls{/number}","milestones_url":"https://api.github.com/repos/AutoRally/autorally/milestones{/number}","notifications_url":"https://api.github.com/repos/AutoRally/autorally/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/AutoRally/autorally/labels{/name}","releases_url":"https://api.github.com/repos/AutoRally/autorally/releases{/id}","deployments_url":"https://api.github.com/repos/AutoRally/autorally/deployments","created_at":"2016-04-20T03:30:14Z","updated_at":"2016-07-25T02:09:32Z","pushed_at":"2016-07-27T15:11:49Z","git_url":"git://github.com/AutoRally/autorally.git","ssh_url":"git@github.com:AutoRally/autorally.git","clone_url":"https://github.com/AutoRally/autorally.git","svn_url":"https://github.com/AutoRally/autorally","homepage":null,"size":1179,"stargazers_count":207,"watchers_count":207,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":25,"mirror_url":null,"open_issues_count":22,"forks":25,"open_issues":22,"watchers":207,"default_branch":"master"}},"base":{"label":"AutoRally:devel","ref":"devel","sha":"170d89048a02b14a90d0fbea47095fc163f25c99","user":{"login":"AutoRally","id":16822115,"avatar_url":"https://avatars.githubusercontent.com/u/16822115?v=3","gravatar_id":"","url":"https://api.github.com/users/AutoRally","html_url":"https://github.com/AutoRally","followers_url":"https://api.github.com/users/AutoRally/followers","following_url":"https://api.github.com/users/AutoRally/following{/other_user}","gists_url":"https://api.github.com/users/AutoRally/gists{/gist_id}","starred_url":"https://api.github.com/users/AutoRally/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AutoRally/subscriptions","organizations_url":"https://api.github.com/users/AutoRally/orgs","repos_url":"https://api.github.com/users/AutoRally/repos","events_url":"https://api.github.com/users/AutoRally/events{/privacy}","received_events_url":"https://api.github.com/users/AutoRally/received_events","type":"Organization","site_admin":false},"repo":{"id":56652382,"name":"autorally","full_name":"AutoRally/autorally","owner":{"login":"AutoRally","id":16822115,"avatar_url":"https://avatars.githubusercontent.com/u/16822115?v=3","gravatar_id":"","url":"https://api.github.com/users/AutoRally","html_url":"https://github.com/AutoRally","followers_url":"https://api.github.com/users/AutoRally/followers","following_url":"https://api.github.com/users/AutoRally/following{/other_user}","gists_url":"https://api.github.com/users/AutoRally/gists{/gist_id}","starred_url":"https://api.github.com/users/AutoRally/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AutoRally/subscriptions","organizations_url":"https://api.github.com/users/AutoRally/orgs","repos_url":"https://api.github.com/users/AutoRally/repos","events_url":"https://api.github.com/users/AutoRally/events{/privacy}","received_events_url":"https://api.github.com/users/AutoRally/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/AutoRally/autorally","description":"","fork":false,"url":"https://api.github.com/repos/AutoRally/autorally","forks_url":"https://api.github.com/repos/AutoRally/autorally/forks","keys_url":"https://api.github.com/repos/AutoRally/autorally/keys{/key_id}","collaborators_url":"https://api.github.com/repos/AutoRally/autorally/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/AutoRally/autorally/teams","hooks_url":"https://api.github.com/repos/AutoRally/autorally/hooks","issue_events_url":"https://api.github.com/repos/AutoRally/autorally/issues/events{/number}","events_url":"https://api.github.com/repos/AutoRally/autorally/events","assignees_url":"https://api.github.com/repos/AutoRally/autorally/assignees{/user}","branches_url":"https://api.github.com/repos/AutoRally/autorally/branches{/branch}","tags_url":"https://api.github.com/repos/AutoRally/autorally/tags","blobs_url":"https://api.github.com/repos/AutoRally/autorally/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/AutoRally/autorally/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/AutoRally/autorally/git/refs{/sha}","trees_url":"https://api.github.com/repos/AutoRally/autorally/git/trees{/sha}","statuses_url":"https://api.github.com/repos/AutoRally/autorally/statuses/{sha}","languages_url":"https://api.github.com/repos/AutoRally/autorally/languages","stargazers_url":"https://api.github.com/repos/AutoRally/autorally/stargazers","contributors_url":"https://api.github.com/repos/AutoRally/autorally/contributors","subscribers_url":"https://api.github.com/repos/AutoRally/autorally/subscribers","subscription_url":"https://api.github.com/repos/AutoRally/autorally/subscription","commits_url":"https://api.github.com/repos/AutoRally/autorally/commits{/sha}","git_commits_url":"https://api.github.com/repos/AutoRally/autorally/git/commits{/sha}","comments_url":"https://api.github.com/repos/AutoRally/autorally/comments{/number}","issue_comment_url":"https://api.github.com/repos/AutoRally/autorally/issues/comments{/number}","contents_url":"https://api.github.com/repos/AutoRally/autorally/contents/{+path}","compare_url":"https://api.github.com/repos/AutoRally/autorally/compare/{base}...{head}","merges_url":"https://api.github.com/repos/AutoRally/autorally/merges","archive_url":"https://api.github.com/repos/AutoRally/autorally/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/AutoRally/autorally/downloads","issues_url":"https://api.github.com/repos/AutoRally/autorally/issues{/number}","pulls_url":"https://api.github.com/repos/AutoRally/autorally/pulls{/number}","milestones_url":"https://api.github.com/repos/AutoRally/autorally/milestones{/number}","notifications_url":"https://api.github.com/repos/AutoRally/autorally/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/AutoRally/autorally/labels{/name}","releases_url":"https://api.github.com/repos/AutoRally/autorally/releases{/id}","deployments_url":"https://api.github.com/repos/AutoRally/autorally/deployments","created_at":"2016-04-20T03:30:14Z","updated_at":"2016-07-25T02:09:32Z","pushed_at":"2016-07-27T15:11:49Z","git_url":"git://github.com/AutoRally/autorally.git","ssh_url":"git@github.com:AutoRally/autorally.git","clone_url":"https://github.com/AutoRally/autorally.git","svn_url":"https://github.com/AutoRally/autorally","homepage":null,"size":1179,"stargazers_count":207,"watchers_count":207,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":25,"mirror_url":null,"open_issues_count":22,"forks":25,"open_issues":22,"watchers":207,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/AutoRally/autorally/pulls/24"},"html":{"href":"https://github.com/AutoRally/autorally/pull/24"},"issue":{"href":"https://api.github.com/repos/AutoRally/autorally/issues/24"},"comments":{"href":"https://api.github.com/repos/AutoRally/autorally/issues/24/comments"},"review_comments":{"href":"https://api.github.com/repos/AutoRally/autorally/pulls/24/comments"},"review_comment":{"href":"https://api.github.com/repos/AutoRally/autorally/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/AutoRally/autorally/pulls/24/commits"},"statuses":{"href":"https://api.github.com/repos/AutoRally/autorally/statuses/946bd2e3e5825777a32c20d1ec9d3205765af90a"}}}}
{"actor":{"display_login":"pdrews"}}