diff --git a/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.cpp b/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.cpp
index 10a1a704006d1460b13681264b37ae2c07a4fa65..9b34a3829edade24e82e936d0cc261c3d3b1c6b7 100644
--- a/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.cpp
+++ b/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.cpp
@@ -8,6 +8,7 @@
 #include <VirtualRobot/Obstacle.h>
 #include <VirtualRobot/Nodes/RobotNodePrismatic.h>
 #include <VirtualRobot/Nodes/RobotNodeFixed.h>
+#include <VirtualRobot/RobotNodeSet.h>
 #include <VirtualRobot/Nodes/RobotNodeRevolute.h>
 #include <VirtualRobot/Nodes/ForceTorqueSensor.h>
 
@@ -1409,6 +1410,40 @@ Eigen::Matrix4f BulletRobot::getComGlobal( VirtualRobot::RobotNodePtr rn )
     return bo->getComGlobal();
 }
 
+Eigen::Vector3f BulletRobot::getComGlobal( VirtualRobot::RobotNodeSetPtr set)
+{
+	Eigen::Vector3f com = Eigen::Vector3f::Zero();
+	float totalMass = 0.0;
+	for (int i = 0; i < set->getSize(); i++)
+	{
+		VirtualRobot::RobotNodePtr node = (*set)[i];
+		BulletObjectPtr bo = boost::dynamic_pointer_cast<BulletObject>(getDynamicsRobotNode(node));
+		Eigen::Matrix4f pose = bo->getComGlobal();
+		com += node->getMass() * pose.block(0, 3, 3, 1);
+		totalMass += node->getMass();
+	}
+
+	com *= 1.0f/totalMass;
+	return com;
+}
+
+Eigen::Vector3f BulletRobot::getComGlobalVelocity( VirtualRobot::RobotNodeSetPtr set)
+{
+	Eigen::Vector3f com = Eigen::Vector3f::Zero();
+	float totalMass = 0.0;
+	for (int i = 0; i < set->getSize(); i++)
+	{
+		VirtualRobot::RobotNodePtr node = (*set)[i];
+		BulletObjectPtr bo = boost::dynamic_pointer_cast<BulletObject>(getDynamicsRobotNode(node));
+		Eigen::Vector3f vel = bo->getLinearVelocity();
+		com += node->getMass() * vel;
+		totalMass += node->getMass();
+	}
+
+	com *= 1.0f/totalMass;
+	return com;
+}
+
 void BulletRobot::setPoseNonActuatedRobotNodes()
 {
     VR_ASSERT(robot);
diff --git a/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.h b/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.h
index 6afa26948d50b7705a2c3bafb85f14a613e43dbc..6b6fc81f5c1075a60d805c2a85ee0409f547ab9b 100644
--- a/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.h
+++ b/SimDynamics/DynamicsEngine/BulletEngine/BulletRobot.h
@@ -128,6 +128,8 @@ public:
         Returns the CoM pose, which is reported by bullet
     */
     virtual Eigen::Matrix4f getComGlobal(VirtualRobot::RobotNodePtr rn);
+	Eigen::Vector3f getComGlobal( VirtualRobot::RobotNodeSetPtr set);
+	Eigen::Vector3f getComGlobalVelocity( VirtualRobot::RobotNodeSetPtr set);
 
 	// experimental...
 	virtual void ensureKinematicConstraints();
diff --git a/SimDynamics/DynamicsEngine/BulletEngine/BulletRobotLogger.cpp b/SimDynamics/DynamicsEngine/BulletEngine/BulletRobotLogger.cpp
index 2ab94b21cb7a2cb19ff5e07cec7b6ed83b2f6786..c14edeef31617d77489a49aa3a5d433ec71f42b7 100644
--- a/SimDynamics/DynamicsEngine/BulletEngine/BulletRobotLogger.cpp
+++ b/SimDynamics/DynamicsEngine/BulletEngine/BulletRobotLogger.cpp
@@ -36,6 +36,9 @@ void BulletRobotLogger::writeToFile(const std::string& path)
 	output << "CoM X" << ",";
 	output << "CoM Y" << ",";
 	output << "CoM Z" << ",";
+	output << "CoMVelocity X" << ",";
+	output << "CoMVelocity Y" << ",";
+	output << "CoMVelocity Z" << ",";
 	output << std::endl;
 
 	for (int frame = 0; frame < num_frames; frame++)
@@ -52,6 +55,9 @@ void BulletRobotLogger::writeToFile(const std::string& path)
 		output << actualCoMLog[frame].x() << ",";
 		output << actualCoMLog[frame].y() << ",";
 		output << actualCoMLog[frame].z() << ",";
+		output << actualCoMVelocityLog[frame].x() << ",";
+		output << actualCoMVelocityLog[frame].y() << ",";
+		output << actualCoMVelocityLog[frame].z() << ",";
 		output << std::endl;
 	}
 }
@@ -91,6 +97,7 @@ void BulletRobotLogger::log(btScalar dt)
 	}
 
 	actualCoMLog.push_back(bodyNodes->getCoM());
+	actualCoMVelocityLog.push_back(robot->getComGlobalVelocity(bodyNodes));
 	actualVelocityLog.push_back(actualVelocity);
 	actualAngleLog.push_back(actualAngle);
 	targetAngleLog.push_back(targetAngle);
diff --git a/SimDynamics/DynamicsEngine/BulletEngine/BulletRobotLogger.h b/SimDynamics/DynamicsEngine/BulletEngine/BulletRobotLogger.h
index 7126993b977946f240c5262b83423169bd296948..c247be26af5de0a7c51108e4d6b1575062e2599c 100644
--- a/SimDynamics/DynamicsEngine/BulletEngine/BulletRobotLogger.h
+++ b/SimDynamics/DynamicsEngine/BulletEngine/BulletRobotLogger.h
@@ -42,6 +42,7 @@ private:
 	std::vector<Eigen::VectorXf> actualAngleLog;
 	std::vector<Eigen::VectorXf> actualVelocityLog;
 	std::vector<Eigen::Vector3f> actualCoMLog;
+	std::vector<Eigen::Vector3f> actualCoMVelocityLog;
 	std::vector<float> timestamps;
 	float timestamp;
 	bool running;