[sdformat] 01/03: Imported Upstream version 4.1.1

Jose Luis Rivero jrivero-guest at moszumanska.debian.org
Thu Sep 15 22:35:06 UTC 2016


This is an automated email from the git hooks/post-receive script.

jrivero-guest pushed a commit to branch master
in repository sdformat.

commit e76c19072f9ae32876e08513db2897006110abfe
Author: Jose Luis Rivero <jrivero at osrfoundation.org>
Date:   Thu Sep 15 22:10:16 2016 +0000

    Imported Upstream version 4.1.1
---
 .hg_archival.txt           |  5 +++--
 .hgtags                    |  2 ++
 CMakeLists.txt             |  2 +-
 Changelog.md               | 14 +++++++++++++
 cmake/SDFUtils.cmake       | 27 ++++++++++++++++++++++++
 cmake/SearchForStuff.cmake |  2 +-
 include/sdf/Param.hh       |  9 ++++++++
 sdf/1.6/actor.sdf          | 46 ++++++++++++++++++++--------------------
 sdf/1.6/joint.sdf          | 10 +++++++++
 sdf/CMakeLists.txt         |  3 +++
 src/Console.cc             | 52 +++++++++++++++++++++++++++++++++++++---------
 src/Exception_TEST.cc      |  3 +++
 src/Param.cc               |  3 ++-
 src/Param_TEST.cc          | 26 +++++++++++++++++++----
 src/parser_urdf.cc         | 20 +++++++++++++++---
 15 files changed, 179 insertions(+), 45 deletions(-)

diff --git a/.hg_archival.txt b/.hg_archival.txt
index 281e9d2..c79e662 100644
--- a/.hg_archival.txt
+++ b/.hg_archival.txt
@@ -1,5 +1,6 @@
 repo: 17049bd77df5bd6cd56a76edba4a54afb5647740
-node: 01885813c0b9d60ff568ceca9eb09ec836795757
+node: 10551a6e8a2c03e3a6e3e81883d3191d5be4a62c
 branch: sdf4
 latesttag: sdformat4_4.1.0
-latesttagdistance: 1
+latesttagdistance: 19
+changessincelatesttag: 41
diff --git a/.hgtags b/.hgtags
index c63d578..3a4eab8 100644
--- a/.hgtags
+++ b/.hgtags
@@ -112,3 +112,5 @@ bb3fff1c17397bada85e3aad11f508c23cead6fd sdformat4_4.0.0~pre2
 0dd0fdbc39b94e9039fa98c5e816972d2584b66c sdformat4_4.0.0~pre3
 708122d23ecbe1ca98780b0621802af0c1fb8b55 sdformat4_4.0.0
 878cecf3869767f396e50ffb7cf6e6a780163894 sdformat4_4.1.0
+878cecf3869767f396e50ffb7cf6e6a780163894 sdformat4_4.1.0
+01885813c0b9d60ff568ceca9eb09ec836795757 sdformat4_4.1.0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 637cfdb..d9d3321 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -29,7 +29,7 @@ set (SDF_PROTOCOL_VERSION 1.6)
 
 set (SDF_MAJOR_VERSION 4)
 set (SDF_MINOR_VERSION 1)
-set (SDF_PATCH_VERSION 0)
+set (SDF_PATCH_VERSION 1)
 
 set (SDF_VERSION ${SDF_MAJOR_VERSION}.${SDF_MINOR_VERSION})
 set (SDF_VERSION_FULL ${SDF_MAJOR_VERSION}.${SDF_MINOR_VERSION}.${SDF_PATCH_VERSION})
diff --git a/Changelog.md b/Changelog.md
index 5d548fb..cbde7af 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,5 +1,13 @@
 ## SDFormat 4.0
 
+### SDFormat 4.2.0 (2016-08-19)
+
+1. Added documentation and animation to `<actor>` element.
+    * [Pull request 280](https://bitbucket.org/osrf/sdformat/pull-request/280)
+
+1. Added tag to specify initial joint position
+    * [Pull request 279](https://bitbucket.org/osrf/sdformat/pull-request/279)
+
 ### SDFormat 4.1.0 (2016-04-01)
 
 1. Added SDF conversion functions to parser including sdf::convertFile and sdf::convertString.
@@ -34,6 +42,12 @@
 
 ## SDFormat 3.0
 
+### SDFormat 3.X.X (201X-XX-XX)
+
+1. Improve precision of floating point parameters
+     * [Pull request 273](https://bitbucket.org/osrf/sdformat/pull-requests/273)
+     * [Pull request 276](https://bitbucket.org/osrf/sdformat/pull-requests/276)
+
 ### SDFormat 3.7.0 (2015-11-20)
 
 1. Add spring pass through for sdf3
diff --git a/cmake/SDFUtils.cmake b/cmake/SDFUtils.cmake
index 71b40e1..ec5e879 100644
--- a/cmake/SDFUtils.cmake
+++ b/cmake/SDFUtils.cmake
@@ -160,6 +160,33 @@ macro (sdf_build_tests)
         ${IGNITION-MATH_LIBRARIES}
         ${Boost_LIBRARIES}
       )
+
+      # Copy in sdformat library
+      add_custom_command(TARGET ${BINARY_NAME}
+        COMMAND ${CMAKE_COMMAND} -E copy_if_different
+        "${CMAKE_BINARY_DIR}/src/sdformat.dll"
+        $<TARGET_FILE_DIR:${BINARY_NAME}> VERBATIM)
+
+      # Copy in ignition-math library
+      add_custom_command(TARGET ${BINARY_NAME}
+        COMMAND ${CMAKE_COMMAND} -E copy_if_different
+        "${IGNITION-MATH_LIBRARY_DIRS}/${IGNITION-MATH_LIBRARIES}.dll"
+        $<TARGET_FILE_DIR:${BINARY_NAME}> VERBATIM)
+  
+      # Copy in boost libraries
+      foreach(lib ${Boost_LIBRARIES})
+        if (EXISTS ${lib})
+          add_custom_command(TARGET ${BINARY_NAME}
+            COMMAND ${CMAKE_COMMAND} -E copy_if_different "${lib}"
+            $<TARGET_FILE_DIR:${BINARY_NAME}> VERBATIM)
+  
+          string(REPLACE ".lib" ".dll" dll ${lib})
+          add_custom_command(TARGET ${BINARY_NAME}
+            COMMAND ${CMAKE_COMMAND} -E copy_if_different "${dll}"
+            $<TARGET_FILE_DIR:${BINARY_NAME}> VERBATIM)
+  
+        endif()
+      endforeach()
     endif()
 
     add_test(${BINARY_NAME} ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
diff --git a/cmake/SearchForStuff.cmake b/cmake/SearchForStuff.cmake
index f9895a2..d19225e 100644
--- a/cmake/SearchForStuff.cmake
+++ b/cmake/SearchForStuff.cmake
@@ -130,8 +130,8 @@ endmacro()
 
 ########################################
 # Find ignition math
+set(IGNITION-MATH_REQUIRED_MAJOR_VERSION 2)
 if (NOT DEFINED IGNITION-MATH_LIBRARY_DIRS AND NOT DEFINED IGNITION-MATH_INCLUDE_DIRS AND NOT DEFINED IGNITION-MATH_LIBRARIES)
-  set(IGNITION-MATH_REQUIRED_MAJOR_VERSION 2)
   find_package(ignition-math${IGNITION-MATH_REQUIRED_MAJOR_VERSION} QUIET)
   if (NOT ignition-math${IGNITION-MATH_REQUIRED_MAJOR_VERSION}_FOUND)
     message(STATUS "Looking for ignition-math${IGNITION-MATH_REQUIRED_MAJOR_VERSION}-config.cmake - not found")
diff --git a/include/sdf/Param.hh b/include/sdf/Param.hh
index 7cf15d5..215d43b 100644
--- a/include/sdf/Param.hh
+++ b/include/sdf/Param.hh
@@ -23,6 +23,7 @@
   #include <boost/lexical_cast.hpp>
   #include <boost/any.hpp>
   #include <boost/variant.hpp>
+  #include <boost/version.hpp>
 #endif
 
 #include <memory>
@@ -288,6 +289,14 @@ namespace sdf
         else
           _value = boost::lexical_cast<T>("0");
       }
+      else if (typeid(T) == this->dataPtr->value.type())
+      {
+#if BOOST_VERSION < 105800
+         _value = boost::get<T>(this->dataPtr->value);
+#else
+         _value = boost::relaxed_get<T>(this->dataPtr->value);
+#endif
+      }
       else
       {
         _value = boost::lexical_cast<T>(this->dataPtr->value);
diff --git a/sdf/1.6/actor.sdf b/sdf/1.6/actor.sdf
index bb1fa41..7ed3460 100644
--- a/sdf/1.6/actor.sdf
+++ b/sdf/1.6/actor.sdf
@@ -1,80 +1,80 @@
 <!-- Actor -->
 <element name="actor" required="*">
-  <description></description>
+  <description>A special kind of model which can have a scripted motion. This includes both global waypoint type animations and skeleton animations.</description>
 
   <attribute name="name" type="string" default="__default__" required="1">
-    <description></description>
+    <description>A unique name for the actor.</description>
   </attribute>
 
   <element name="static" type="bool" default="true" required="0">
-    <description>Actors should be static, in terms of physics simulation.</description>
+    <description>(DEPRECATION WARNING: This is deprecated in 1.6 and removed in 1.7. Actors should be static, so this is always true.</description>
   </element>
 
   <include filename="frame.sdf" required="*"/>
   <include filename="pose.sdf" required="0"/>
 
-  <element name="skin" required="1">
-    <description></description>
+  <element name="skin" required="0">
+    <description>Skin file which defines a visual and the underlying skeleton which moves it.</description>
 
     <element name="filename" type="string" default="__default__" required="1">
-      <description></description>
+      <description>Path to skin file, accepted formats: COLLADA, BVH.</description>
     </element>
 
     <element name="scale" type="double" default="1.0" required="0">
-      <description></description>
+      <description>Scale the skin's size.</description>
     </element>
   </element> <!-- End Skin -->
 
-  <element name="animation" required="+">
-    <description></description>
+  <element name="animation" required="*">
+    <description>Animation file defines an animation for the skeleton in the skin. The skeleton must be compatible with the skin skeleton.</description>
 
     <attribute name="name" type="string" default="__default__" required="1">
-      <description></description>
+      <description>Unique name for animation.</description>
     </attribute>
 
     <element name="filename" type="string" default="__default__" required="1">
-      <description></description>
+      <description>Path to animation file. Accepted formats: COLLADA, BVH.</description>
     </element>
     <element name="scale" type="double" default="1.0" required="0">
-      <description></description>
+      <description>Scale for the animation skeleton.</description>
     </element>
     <element name="interpolate_x" type="bool" default="false" required="0">
-      <description></description>
+      <description>Set to true so the animation is interpolated on X.</description>
     </element>
   </element> <!-- End Animation -->
 
   <element name="script" required="1">
-    <description></description>
+    <description>Adds scripted trajectories to the actor.</description>
 
     <element name="loop" type="bool" default="true" required="0">
-      <description></description>
+      <description>Set this to true for the script to be repeated in a loop. For a fluid continuous motion, make sure the last waypoint matches the first one.</description>
     </element>
 
     <element name="delay_start" type="double" default="0.0" required="0">
-      <description></description>
+      <description>This is the time to wait before starting the script. If running in a loop, this time will be waited before starting each cycle.</description>
     </element>
 
     <element name="auto_start" type="bool" default="true" required="0">
-      <description></description>
+      <description>Set to true if the animation should start as soon as the simulation starts playing. It is useful to set this to false if the animation should only start playing only when triggered by a plugin, for example.</description>
     </element>
 
     <element name="trajectory" required="*">
-      <description></description>
+      <description>The trajectory contains a series of keyframes to be followed.</description>
       <attribute name="id" type="int" default="0" required="1">
-        <description></description>
+        <description>Unique id for a trajectory.</description>
       </attribute>
 
       <attribute name="type" type="string" default="__default__" required="1">
-        <description></description>
+        <description>If it matches the type of an animation, they will be played at the same time.</description>
       </attribute>
 
       <element name="waypoint" required="*">
-        <description></description>
+        <description>Each point in the trajectory.</description>
         <element name="time" type="double" default="0.0" required="1">
-          <description></description>
+          <description>The time in seconds, counted from the beginning of the script, when the pose should be reached.</description>
         </element>
         <element name="pose" type="pose" default="0 0 0 0 0 0" required="1">
-          <description></description>
+          <description>The pose which should be reached at the given time.</description>
         </element>
       </element> <!-- End Waypoint -->
     </element> <!-- End Action -->
diff --git a/sdf/1.6/joint.sdf b/sdf/1.6/joint.sdf
index abc9750..75e3e63 100644
--- a/sdf/1.6/joint.sdf
+++ b/sdf/1.6/joint.sdf
@@ -44,6 +44,11 @@
       Parameters related to the axis of rotation for revolute joints,
       the axis of translation for prismatic joints.
     </description>
+    <element name="initial_position" type="double" default="0" required="0">
+      <description>
+        Default joint position for this joint axis.
+      </description>
+    </element>
     <element name="xyz" type="vector3" default="0 0 1" required="1">
       <description>
         Represents the x,y,z components of the axis unit vector. The axis is
@@ -103,6 +108,11 @@
     <description>
       Parameters related to the second axis of rotation for revolute2 joints and universal joints.
     </description>
+    <element name="initial_position" type="double" default="0" required="0">
+      <description>
+        Default joint position for this joint axis.
+      </description>
+    </element>
     <element name="xyz" type="vector3" default="0 0 1" required="1">
       <description>
         Represents the x,y,z components of the axis unit vector. The axis is
diff --git a/sdf/CMakeLists.txt b/sdf/CMakeLists.txt
index 19a8b6a..61342e2 100644
--- a/sdf/CMakeLists.txt
+++ b/sdf/CMakeLists.txt
@@ -4,3 +4,6 @@ add_subdirectory(1.3)
 add_subdirectory(1.4)
 add_subdirectory(1.5)
 add_subdirectory(1.6)
+
+add_custom_target(schema)
+add_dependencies(schema schema1_6)
diff --git a/src/Console.cc b/src/Console.cc
index 1576b89..f654744 100644
--- a/src/Console.cc
+++ b/src/Console.cc
@@ -39,6 +39,16 @@ using namespace sdf;
 static std::shared_ptr<Console> myself;
 static std::mutex g_instance_mutex;
 
+/// \todo Output disabled for windows, to allow tests to pass. We should
+/// disable output just for tests on windows.
+#ifndef _WIN32
+static bool g_quiet = false;
+#else
+static bool g_quiet = true;
+#endif
+
+static Console::ConsoleStream g_NullStream(NULL);
+
 //////////////////////////////////////////////////
 Console::Console()
   : dataPtr(new ConsolePrivate)
@@ -53,7 +63,8 @@ Console::Console()
 #endif
     if (!home)
     {
-      sdfwarn << "No HOME defined in the environment. Will not log.";
+      std::cerr << "No HOME defined in the environment. Will not log."
+                << std::endl;
       return;
     }
     boost::filesystem::path logFile(home);
@@ -66,14 +77,16 @@ Console::Console()
     }
     else if (!boost::filesystem::is_directory(logDir))
     {
-      sdfwarn << logDir << " exists but is not a directory.  Will not log.";
+      std::cerr << logDir << " exists but is not a directory.  Will not log."
+                << std::endl;
       return;
     }
     this->dataPtr->logFileStream.open(logFile.string().c_str(), std::ios::out);
   }
   catch(const boost::filesystem::filesystem_error& e)
   {
-    sdfwarn << "Exception while setting up logging: " << e.what();
+    std::cerr << "Exception while setting up logging: " << e.what()
+              << std::endl;
     return;
   }
 }
@@ -94,8 +107,9 @@ ConsolePtr Console::Instance()
 }
 
 //////////////////////////////////////////////////
-void Console::SetQuiet(bool)
+void Console::SetQuiet(bool _quiet)
 {
+  g_quiet = _quiet;
 }
 
 //////////////////////////////////////////////////
@@ -103,8 +117,15 @@ Console::ConsoleStream &Console::ColorMsg(const std::string &lbl,
                                           const std::string &file,
                                           unsigned int line, int color)
 {
-  this->dataPtr->msgStream.Prefix(lbl, file, line, color);
-  return this->dataPtr->msgStream;
+  if (!g_quiet)
+  {
+    this->dataPtr->msgStream.Prefix(lbl, file, line, color);
+    return this->dataPtr->msgStream;
+  }
+  else
+  {
+    return g_NullStream;
+  }
 }
 
 //////////////////////////////////////////////////
@@ -118,16 +139,28 @@ Console::ConsoleStream &Console::Log(const std::string &lbl,
 
 //////////////////////////////////////////////////
 void Console::ConsoleStream::Prefix(const std::string &_lbl,
-                          const std::string &_file,
-                          unsigned int _line, int _color)
+    const std::string &_file,
+    unsigned int _line,
+    // This is here to prevent a compilation warning about an unused variable.
+#ifndef _WIN32
+    int _color
+#else
+    int /*_color*/
+#endif
+)
 {
   size_t index = _file.find_last_of("/") + 1;
 
   if (this->stream)
   {
+#ifndef _WIN32
     *this->stream << "\033[1;" << _color << "m" << _lbl << " [" <<
-      _file.substr(index , _file.size() - index)<< ":" << _line <<
+      _file.substr(index , _file.size() - index) << ":" << _line <<
       "]\033[0m ";
+#else
+    *this->stream << _lbl << " [" <<
+      _file.substr(index , _file.size() - index) << ":" << _line << "] ";
+#endif
   }
 
   if (Console::Instance()->dataPtr->logFileStream.is_open())
@@ -136,4 +169,3 @@ void Console::ConsoleStream::Prefix(const std::string &_lbl,
       _file.substr(index , _file.size() - index)<< ":" << _line << "] ";
   }
 }
-
diff --git a/src/Exception_TEST.cc b/src/Exception_TEST.cc
index bf13d17..d5ba58f 100644
--- a/src/Exception_TEST.cc
+++ b/src/Exception_TEST.cc
@@ -22,8 +22,11 @@
 /// Test exception throwing
 TEST(Exception, Throwing)
 {
+  // This test fails on Windows
+#ifndef _MSC_VER
   EXPECT_ANY_THROW(sdfthrow("throw message"));
   EXPECT_THROW(sdfthrow("throw message"), sdf::Exception);
+#endif
 }
 
 /////////////////////////////////////////////////
diff --git a/src/Param.cc b/src/Param.cc
index 1c3ac52..1a21d76 100644
--- a/src/Param.cc
+++ b/src/Param.cc
@@ -25,7 +25,8 @@ using namespace sdf;
 class string_set : public boost::static_visitor<>
 {
   public: explicit string_set(const std::string &_value)
-          {this->value = _value;}
+    : value(_value)
+          {}
 
   public: template <typename T>
           void operator()(T & _operand) const
diff --git a/src/Param_TEST.cc b/src/Param_TEST.cc
index 37dd914..5f86e26 100644
--- a/src/Param_TEST.cc
+++ b/src/Param_TEST.cc
@@ -17,6 +17,7 @@
 
 #include <gtest/gtest.h>
 #include <boost/version.hpp>
+#include <ignition/math/Angle.hh>
 #include "sdf/Param.hh"
 
 bool check_double(std::string num)
@@ -142,6 +143,9 @@ TEST(Param, HexUInt)
 /// Test setting and reading hex and non-hex float values.
 TEST(Param, HexFloat)
 {
+// Microsoft does not parse hex values properly.
+// https://bitbucket.org/osrf/sdformat/issues/114
+#ifndef _MSC_VER
   sdf::Param floatParam("key", "float", "0", false, "description");
   float value;
   EXPECT_TRUE(floatParam.Get<float>(value));
@@ -162,6 +166,7 @@ TEST(Param, HexFloat)
   EXPECT_FALSE(floatParam.SetFromString("1.0e100"));
   EXPECT_TRUE(floatParam.Get<float>(value));
   EXPECT_FLOAT_EQ(value, 0.123f);
+#endif
 }
 
 ////////////////////////////////////////////////////
@@ -173,6 +178,9 @@ TEST(Param, HexDouble)
   EXPECT_TRUE(doubleParam.Get<double>(value));
   EXPECT_DOUBLE_EQ(value, 0.0);
 
+// Microsoft does not parse hex values properly.
+// https://bitbucket.org/osrf/sdformat/issues/114
+#ifndef _MSC_VER
   EXPECT_TRUE(doubleParam.SetFromString("0x01"));
   EXPECT_TRUE(doubleParam.Get<double>(value));
   EXPECT_DOUBLE_EQ(value, 1.0);
@@ -180,14 +188,14 @@ TEST(Param, HexDouble)
   EXPECT_TRUE(doubleParam.SetFromString("0X2A"));
   EXPECT_TRUE(doubleParam.Get<double>(value));
   EXPECT_DOUBLE_EQ(value, 42.0);
-
-  EXPECT_TRUE(doubleParam.SetFromString("0.123"));
+#endif
+  EXPECT_TRUE(doubleParam.SetFromString("0.123456789"));
   EXPECT_TRUE(doubleParam.Get<double>(value));
-  EXPECT_DOUBLE_EQ(value, 0.123);
+  EXPECT_DOUBLE_EQ(value, 0.123456789);
 
   EXPECT_FALSE(doubleParam.SetFromString("1.0e1000"));
   EXPECT_TRUE(doubleParam.Get<double>(value));
-  EXPECT_DOUBLE_EQ(value, 0.123);
+  EXPECT_DOUBLE_EQ(value, 0.123456789);
 }
 
 ////////////////////////////////////////////////////
@@ -205,6 +213,16 @@ TEST(Param, uint64t)
   EXPECT_EQ(value, UINT64_MAX);
 }
 
+////////////////////////////////////////////////////
+/// Unknown type, should fall back to lexical_cast
+TEST(Param, UnknownType)
+{
+  sdf::Param doubleParam("key", "double", "1.0", false, "description");
+  ignition::math::Angle value;
+  EXPECT_TRUE(doubleParam.Get<ignition::math::Angle>(value));
+  EXPECT_DOUBLE_EQ(value.Radian(), 1.0);
+}
+
 /////////////////////////////////////////////////
 /// Main
 int main(int argc, char **argv)
diff --git a/src/parser_urdf.cc b/src/parser_urdf.cc
index fe9bb9b..3740bda 100644
--- a/src/parser_urdf.cc
+++ b/src/parser_urdf.cc
@@ -290,8 +290,12 @@ urdf::Vector3 ParseVector3(TiXmlNode *_key, double _scale)
     {
       return ParseVector3(GetKeyValueAsString(key), _scale);
     }
+    sdferr << "key[" << _key->Value() << "] does not contain a Vector3\n";
+  }
+  else
+  {
+    sdferr << "Pointer to XML node _key is NULL\n";
   }
-  sdferr << "key[" << _key->Value() << "] does not contain a Vector3\n";
 
   return urdf::Vector3(0, 0, 0);
 }
@@ -3316,11 +3320,16 @@ void CreateCollision(TiXmlElement* _elem, ConstUrdfLinkPtr _link,
   // set its name, if lumped, add original link name
   // for meshes in an original mesh, it's likely
   // _link->name + mesh count
-  if (_oldLinkName.find(_link->name) == 0 || _oldLinkName.empty())
+  if (_oldLinkName.compare(0, _link->name.size(), _link->name) == 0 ||
+      _oldLinkName.empty())
+  {
     sdfCollision->SetAttribute("name", _oldLinkName);
+  }
   else
+  {
     sdfCollision->SetAttribute("name", _link->name
         + g_lumpPrefix + _oldLinkName);
+  }
 
   // std::cerr << "collision [" << sdfCollision->Attribute("name") << "]\n";
 
@@ -3358,11 +3367,16 @@ void CreateVisual(TiXmlElement *_elem, ConstUrdfLinkPtr _link,
   TiXmlElement *sdfVisual = new TiXmlElement("visual");
 
   // set its name
-  if (_oldLinkName.find(_link->name) == 0 || _oldLinkName.empty())
+  if (_oldLinkName.compare(0, _link->name.size(), _link->name) == 0 ||
+      _oldLinkName.empty())
+  {
     sdfVisual->SetAttribute("name", _oldLinkName);
+  }
   else
+  {
     sdfVisual->SetAttribute("name", _link->name
         + g_lumpPrefix + _oldLinkName);
+  }
 
   // add the visualisation transfrom
   double pose[6];

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/sdformat.git



More information about the debian-science-commits mailing list