Example #1
0
int wam_main(int argc, char** argv, ProductManager& pm,
		systems::Wam<DOF>& wam) {
	BARRETT_UNITS_TEMPLATE_TYPEDEFS(DOF);

	std::string filename(argv[1]);

	printf("\nMoving to start configuration \n");

	jp_type jp(0.0);
	jp[1] = -1.967;
	jp[3] = 2.5;
	jp[5] = -0.5;
	wam.moveTo(jp);

	printf("Opening hands\n");

	// Open hands.
	barrett::Hand& hand = *pm.getHand();
	hand.initialize();

	// wam.idle();

	Teach<DOF> teach(wam, pm, filename);

	teach.init();

	printf("\nPress [Enter] to start teaching.\n");
	waitForEnter();
	teach.record();
	//boost::thread t(&Teach<DOF>::display, &teach);

	printf("Press [Enter] to stop teaching.\n");
	waitForEnter();
	teach.createSpline();

	// Move to start and close hands.
	wam.moveTo(jp);
	hand.close();
	hand.idle();

	wam.idle();

	pm.getSafetyModule()->waitForMode(SafetyModule::IDLE);

	return 0;
}
Example #2
0
int wam_main(int argc, char** argv, ProductManager& pm,
        systems::Wam<DOF>& wam) {
    BARRETT_UNITS_TEMPLATE_TYPEDEFS(DOF);

    std::string filename(argv[1]);

    Teach<DOF> teach(wam, pm, filename);

    teach.init();

    printf("\nPress [Enter] to start teaching.\n");
    waitForEnter();
    teach.record();
    //boost::thread t(&Teach<DOF>::display, &teach);

    printf("Press [Enter] to stop teaching.\n");
    waitForEnter();
    teach.createSpline();

    pm.getSafetyModule()->waitForMode(SafetyModule::IDLE);

    return 0;
}
Example #3
0
int wam_main(int argc, char** argv, ProductManager& pm, systems::Wam<DOF>& wam){
	BARRETT_UNITS_TEMPLATE_TYPEDEFS(DOF);

	double dW,dL,bF;
	if(argc == 3){
		dL = atof(argv[2]);
		dL = dL*0.0254;
		dW = atof(argv[1]);
	}
	else if(argc == 2){
		dW = atof(argv[1]);
		dL = 0.762;
	}else{
		dW = 30.0;
		dL = 0.762;
	}

	bF = (dW / dL)*1.35581795;
	// Lets prevent the torque fault by limiting acceleration?
	//pm.safetyModule->setVelocityLimit(2.0);

	// Lets instantiate the system calls
	systems::ExposedOutput<cp_type> homePos;
	systems::Summer<cp_type> posErr("+-");
	systems::Gain<cp_type, double, cf_type> gain(bF);
	systems::ToolForceToJointTorques<DOF> tf2jt;

	connect(homePos.output, posErr.getInput(0));
	connect(wam.toolPosition.output, posErr.getInput(1));

	connect(posErr.output, gain.input);

	connect(wam.kinematicsBase.kinOutput, tf2jt.kinInput);
	connect(gain.output, tf2jt.input);

	homePos.setValueUndefined();
	connect(tf2jt.output, wam.input);

	wam.gravityCompensate();
	/*
	std::string line;
	bool active = true,set=false;
	while(active){
		std::getline(std::cin, line);
		switch (line[0]) {
			case 'x':
			case 'q':
				active = false;
				break;
			default:
				if (line.size() != 0) {
					if(set){
						homePos.setValue(wam.getToolPosition());
					}else{
						homePos.setValueUndefined();
					}
					set = !set;
				}
				break;
		}
	}*/

	while(pm.getSafetyModule()->getMode() == SafetyModule::ACTIVE){
		waitForEnter();
		homePos.setValue(wam.getToolPosition());
		printf(">>> Bow Position Locked.");

		waitForEnter();
		homePos.setValueUndefined();
		printf(">>> Bow Position Unlocked.");
	}

	wam.idle();
//	wam.moveHome();
	pm.getSafetyModule()->waitForMode(SafetyModule::IDLE);
	return 0;
}
int wam_main(int argc, char** argv, ProductManager& pm, systems::Wam<DOF>& wam) {
	BARRETT_UNITS_TEMPLATE_TYPEDEFS(DOF);
	typedef boost::tuple<double, jp_type> jp_sample_type;

	char tmpFile[] = "/tmp/btXXXXXX";
	if (mkstemp(tmpFile) == -1) {
		printf("ERROR: Couldn't create temporary file!\n");
		return 1;
	}

	const double T_s = pm.getExecutionManager()->getPeriod();


	wam.gravityCompensate();

	systems::Ramp time(pm.getExecutionManager());

	systems::TupleGrouper<double, jp_type> jpLogTg;

	// Record at 1/10th of the loop rate
	systems::PeriodicDataLogger<jp_sample_type> jpLogger(pm.getExecutionManager(),
			new barrett::log::RealTimeWriter<jp_sample_type>(tmpFile, 10*T_s), 10);


	printf("Press [Enter] to start teaching.\n");
	waitForEnter();
	{
		// Make sure the Systems are connected on the same execution cycle
		// that the time is started. Otherwise we might record a bunch of
		// samples all having t=0; this is bad because the Spline requires time
		// to be monotonic.
		BARRETT_SCOPED_LOCK(pm.getExecutionManager()->getMutex());

		connect(time.output, jpLogTg.template getInput<0>());
		connect(wam.jpOutput, jpLogTg.template getInput<1>());
		connect(jpLogTg.output, jpLogger.input);
		time.start();
	}

	printf("Press [Enter] to stop teaching.\n");
	waitForEnter();
	jpLogger.closeLog();
	disconnect(jpLogger.input);


	// Build spline between recorded points
	log::Reader<jp_sample_type> lr(tmpFile);
	std::vector<jp_sample_type> vec;
	for (size_t i = 0; i < lr.numRecords(); ++i) {
		vec.push_back(lr.getRecord());
	}
	math::Spline<jp_type> spline(vec);

	printf("Press [Enter] to play back the recorded trajectory.\n");
	waitForEnter();

	// First, move to the starting position
	wam.moveTo(spline.eval(spline.initialS()));

	// Then play back the recorded motion
	time.stop();
	time.setOutput(spline.initialS());

	systems::Callback<double, jp_type> trajectory(boost::ref(spline));
	connect(time.output, trajectory.input);
	wam.trackReferenceSignal(trajectory.output);

	time.start();

	while (trajectory.input.getValue() < spline.finalS()) {
		usleep(100000);
	}


	printf("Press [Enter] to idle the WAM.\n");
	waitForEnter();
	wam.idle();


	std::remove(tmpFile);
	pm.getSafetyModule()->waitForMode(SafetyModule::IDLE);

	return 0;
}
int wam_main(int argc, char** argv, ProductManager& pm,
		systems::Wam<DOF>& wam) {
	BARRETT_UNITS_TEMPLATE_TYPEDEFS(DOF);

//
	typedef boost::tuple<double, jp_type, jv_type, ja_type, jt_type, jt_type> tuple_type;
	typedef systems::TupleGrouper<double, jp_type, jv_type, ja_type, jt_type,
			jt_type> tg_type;
	tg_type tg;

	char tmpFile[] = "btXXXXXX";
	if (mkstemp(tmpFile) == -1) {
		printf("ERROR: Couldn't create temporary file!\n");
		return 1;
	}

	double Frequency;
	double Amplitude;

	double omega1;
	double offset;

	if (argc == 2) {
		Frequency = 0.1;
		Amplitude = 0.525;
		offset = 0;
	}
	if (argc == 3) {
		Amplitude = 0.525;
		offset = 0;
	}
	if (argc == 4) {
		offset = 0;
	}

	else {
		Frequency = boost::lexical_cast<double>(argv[2]);
		Amplitude = boost::lexical_cast<double>(argv[3]);
		offset = boost::lexical_cast<double>(argv[4]);
	}





	const double JT_AMPLITUDE = Amplitude;
	const double FREQUENCY = Frequency;
	const double OFFSET = offset;

	omega1 = 120;

	wam.gravityCompensate();

	const double TRANSITION_DURATION = 0.5; // seconds

	jp_type startpos(0.0);
	startpos[3] = +3.14;
	startpos[1] = offset;

	systems::Ramp time(pm.getExecutionManager(), 1.0);
	printf("Press [Enter] to turn on torque control to go to zero position");
	wam.moveTo(startpos);

	printf("Press [Enter] to turn on torque control to joint 2.");
	waitForEnter();

	// Joint acc calculator
	systems::FirstOrderFilter<jv_type> filter;
	wam.jvFilter.setLowPass(jv_type(omega1));
	filter.setHighPass(jp_type(omega1), jp_type(omega1));
	pm.getExecutionManager()->startManaging(filter);
	systems::Gain<jv_type, double, ja_type> changeUnits1(1.0);
	systems::connect(wam.jvOutput, filter.input);
	systems::connect(filter.output, changeUnits1.input);

	//
	const size_t PERIOD_MULTIPLIER = 1;
	systems::PeriodicDataLogger<tuple_type> logger(pm.getExecutionManager(),
			new log::RealTimeWriter<tuple_type>(tmpFile,
					PERIOD_MULTIPLIER * pm.getExecutionManager()->getPeriod()),
			PERIOD_MULTIPLIER);
	//

	J2control<DOF> jtc(startpos, JT_AMPLITUDE, FREQUENCY, OFFSET);
	systems::connect(tg.output, logger.input);
	systems::connect(time.output, jtc.input);
	systems::connect(time.output, tg.template getInput<0>());
	systems::connect(wam.jpOutput, tg.template getInput<1>());
	systems::connect(wam.jvOutput, tg.template getInput<2>());
	systems::connect(changeUnits1.output, tg.template getInput<3>());
	systems::connect(wam.supervisoryController.output,
			tg.template getInput<4>());
	systems::connect(wam.gravity.output, tg.template getInput<5>());

	wam.trackReferenceSignal(jtc.output);
	time.smoothStart(TRANSITION_DURATION);

	printf("Press [Enter] to stop.");
	waitForEnter();
	logger.closeLog();
	time.smoothStop(TRANSITION_DURATION);
	wam.idle();

	// Wait for the user to press Shift-idle
	pm.getSafetyModule()->waitForMode(SafetyModule::IDLE);
	log::Reader<boost::tuple<tuple_type> > lr(tmpFile);
	lr.exportCSV(argv[1]);
	printf("Output written to %s.\n", argv[1]);
	std::remove(tmpFile);
	return 0;
}
int wam_main(int argc, char** argv, ProductManager& pm,
		systems::Wam<DOF>& wam) {
	BARRETT_UNITS_TEMPLATE_TYPEDEFS(DOF);

	Eigen::MatrixXd Lamda;

	Eigen::MatrixXd Coeff;
	Eigen::VectorXd Delta;
	Eigen::VectorXd Amp;
	Eigen::VectorXd Freq;
	Eigen::VectorXd StartPos;
	Eigen::VectorXd dist_K_tmp;
	Eigen::VectorXd state_intg;
	Eigen::VectorXd A_tmp;


	Sam::initEigenMat<double>(Lamda, Sam::readFile<double>("lamda.txt"));
	Sam::initEigenMat<double>(Coeff, Sam::readFile<double>("coeff.txt"));
	Sam::initEigenVec<double>(Delta, Sam::readFile<double>("delta.txt"));
	Sam::initEigenVec<double>(Amp, Sam::readFile<double>("amp.txt"));
	Sam::initEigenVec<double>(Freq, Sam::readFile<double>("freq.txt"));
	Sam::initEigenVec<double>(StartPos, Sam::readFile<double>("start.txt"));
	Sam::initEigenVec<double>(dist_K_tmp, Sam::readFile<double>("dist_K.txt"));
	Sam::initEigenVec<double>(state_intg, Sam::readFile<double>("integrator_state.txt"));
	Sam::initEigenVec<double>(A_tmp, Sam::readFile<double>("A.txt"));



	std::cout << "Lamda is" << Lamda << "\n" << "Coeff is" << Coeff << "\n"
			<< "Delta is" << Delta << "\n" << std::endl;
	typedef boost::tuple<double, jp_type, jv_type, jp_type, jv_type, jt_type,
			jt_type, double, jp_type> tuple_type;
	typedef systems::TupleGrouper<double, jp_type, jv_type, jp_type, jv_type,
			jt_type, jt_type, double, jp_type> tg_type;
	tg_type tg;
	char tmpFile[] = "btXXXXXX";
	if (mkstemp(tmpFile) == -1) {
		printf("ERROR: Couldn't create temporary file!\n");
		return 1;
	}
	const double TRANSITION_DURATION = 0.5;
//	double amplitude1, omega1;
	const Eigen::Matrix4d lamda = Lamda;

	const Eigen::Matrix4d coeff = Coeff;
	const Eigen::Vector4d delta = Delta;
	jp_type startpos(0.0);

	startpos[0] = StartPos[0];
	startpos[1] = StartPos[1];
	startpos[2] = StartPos[2];
	startpos[3] = StartPos[3];

	const Eigen::Vector4d JP_AMPLITUDE = Amp;
	const Eigen::Vector4d OMEGA = Freq;
	Eigen::Vector4d tmp_velocity;
	tmp_velocity[0] = Amp[0]*Freq[0];
	tmp_velocity[1] = Amp[1]*Freq[1];
	tmp_velocity[2] = Amp[2]*Freq[2];
	tmp_velocity[3] = Amp[3]*Freq[3];
	bool status = true;
	const double dist_K =  dist_K_tmp[0];
	const int state = state_intg[0];
	const Eigen::Vector4d initial_velocity = tmp_velocity;

	const float A = A_tmp[0];

	J_ref<DOF> joint_ref(JP_AMPLITUDE, OMEGA, startpos);
	Slidingmode_Controller<DOF> slide(status, lamda, coeff, delta);
	Dynamics<DOF> nilu_dynamics;
	disturbance_observer<DOF> nilu_disturbance(dist_K,state, initial_velocity,A);
	Dummy<DOF> nilu_dummy;

	wam.gravityCompensate();
	printf("Press [Enter] to turn on torque control to go to zero position");
	waitForEnter();

	wam.moveTo(startpos);
	printf("Press [Enter] to turn on torque control to joint 2.");
	waitForEnter();
	printf("Error 1 \n");

	systems::Ramp time(pm.getExecutionManager(), 1.0);
	const size_t PERIOD_MULTIPLIER = 1;
	systems::PeriodicDataLogger<tuple_type> logger(pm.getExecutionManager(),
			new log::RealTimeWriter<tuple_type>(tmpFile,
					PERIOD_MULTIPLIER * pm.getExecutionManager()->getPeriod()),
			PERIOD_MULTIPLIER);
	printf("Error 2 \n");

	systems::connect(tg.output, logger.input);
	systems::connect(time.output, joint_ref.timef);
	systems::connect(wam.jpOutput, slide.feedbackjpInput);
	systems::connect(wam.jvOutput, slide.feedbackjvInput);
	systems::connect(wam.jpOutput, nilu_dynamics.jpInputDynamics);
	systems::connect(wam.jvOutput, nilu_dynamics.jvInputDynamics);
	systems::connect(nilu_dynamics.MassMAtrixOutput, slide.M);
	systems::connect(nilu_dynamics.CVectorOutput, slide.C);
	systems::connect(joint_ref.referencejpTrack, slide.referencejpInput);
	systems::connect(joint_ref.referencejvTrack, slide.referencejvInput);
	systems::connect(joint_ref.referencejaTrack, slide.referencejaInput);

	systems::connect(time.output, nilu_disturbance.time);
	systems::connect(nilu_dynamics.MassMAtrixOutput, nilu_disturbance.M);
	systems::connect(nilu_dynamics.CVectorOutput, nilu_disturbance.C);
	systems::connect(wam.jpOutput, nilu_disturbance.inputactual_pos);
	systems::connect(wam.jvOutput, nilu_disturbance.inputactual_vel);
	systems::connect(slide.controlOutput, nilu_disturbance.SMC);

	systems::connect(slide.controlOutput, nilu_dummy.ControllerInput);
	systems::connect(nilu_disturbance.disturbance_torque_etimate,
			nilu_dummy.CompensatorInput);

	wam.trackReferenceSignal(nilu_dummy.Total_torque);
	printf("Error 3 \n");

	systems::connect(time.output, tg.template getInput<0>());
	systems::connect(joint_ref.referencejpTrack, tg.template getInput<1>());
	systems::connect(joint_ref.referencejvTrack, tg.template getInput<2>());
	systems::connect(wam.jpOutput, tg.template getInput<3>());
	systems::connect(wam.jvOutput, tg.template getInput<4>());
	systems::connect(nilu_disturbance.disturbance_torque_etimate,
			tg.template getInput<5>());
	systems::connect(slide.controlOutput, tg.template getInput<6>());
	systems::connect(nilu_disturbance.Test, tg.template getInput<7>());
	systems::connect(nilu_disturbance.InverseTest, tg.template getInput<8>());



	printf("Error 4 \n");

	time.smoothStart(TRANSITION_DURATION);
	printf("Press [Enter] to stop.");
	waitForEnter();
	logger.closeLog();
	time.smoothStop(TRANSITION_DURATION);
	wam.idle();
	printf("Error 5 \n");

	pm.getSafetyModule()->waitForMode(SafetyModule::IDLE);
	log::Reader<boost::tuple<tuple_type> > lr(tmpFile);
	lr.exportCSV(argv[1]);
	printf("Error 6 \n");

	printf("Output written to %s.\n", argv[1]);
	std::remove(tmpFile);

	return 0;
}
int wam_main(int argc, char** argv, ProductManager& pm,
		systems::Wam<DOF>& wam) {
	BARRETT_UNITS_TEMPLATE_TYPEDEFS(DOF);


	Eigen::MatrixXd Coeff;
	Eigen::VectorXd Delta;
	Eigen::VectorXd Amp;
	Eigen::VectorXd Freq;
	Eigen::VectorXd StartPos;
	Eigen::MatrixXd A;
	Eigen::MatrixXd B;
	Eigen::VectorXd P;
	Eigen::VectorXd Q;

	Sam::initEigenMat<double>(A, Sam::readFile<double>("A.txt"));
	Sam::initEigenMat<double>(B, Sam::readFile<double>("B.txt"));
	Sam::initEigenVec<double>(P, Sam::readFile<double>("P.txt"));
	Sam::initEigenVec<double>(Q, Sam::readFile<double>("Q.txt"));

	Sam::initEigenMat<double>(Coeff, Sam::readFile<double>("coeff.txt"));
	Sam::initEigenVec<double>(Delta, Sam::readFile<double>("delta.txt"));
	Sam::initEigenVec<double>(Amp, Sam::readFile<double>("amp.txt"));
	Sam::initEigenVec<double>(Freq, Sam::readFile<double>("freq.txt"));
	Sam::initEigenVec<double>(StartPos, Sam::readFile<double>("start.txt"));

	typedef boost::tuple<double, jp_type, jv_type, jp_type, jv_type, jt_type> tuple_type;
	typedef systems::TupleGrouper<double, jp_type, jv_type, jp_type, jv_type,
			jt_type> tg_type;
	tg_type tg;
	char tmpFile[] = "btXXXXXX";
	if (mkstemp(tmpFile) == -1) {
		printf("ERROR: Couldn't create temporary file!\n");
		return 1;
	}
	const double TRANSITION_DURATION = 0.5;
	double amplitude1, omega1;
	const Eigen::Matrix4d coeff = Coeff;
	const Eigen::Vector4d delta = Delta;
	jp_type startpos(0.0);


	startpos[0] = StartPos[0];
	startpos[1] = StartPos[1];
	startpos[2] = StartPos[2];
	startpos[3] = StartPos[3];

	const Eigen::Vector4d JP_AMPLITUDE = Amp;
	const Eigen::Vector4d OMEGA = Freq;
	bool status = true;
	const Eigen::Matrix4d A1 = A;
	const Eigen::Matrix4d B1 = B;
	const float P1 = P[0];
	const float Q1 = Q[0];

	J_ref<DOF> joint_ref(JP_AMPLITUDE, OMEGA, startpos);
	SMC_higher_order<DOF> slide(status, coeff, delta , A1, B1,P1, Q1 );
	Dynamics<DOF> nilu_dynamics;

	wam.gravityCompensate();
	printf("Press [Enter] to turn on torque control to go to zero position");
	waitForEnter();

	wam.moveTo(startpos);
	printf("Press [Enter] to turn on torque control to joint 2.");
	waitForEnter();
	printf("Error 1 \n");

	systems::Ramp time(pm.getExecutionManager(), 1.0);
	const size_t PERIOD_MULTIPLIER = 1;
	systems::PeriodicDataLogger<tuple_type> logger(pm.getExecutionManager(),
			new log::RealTimeWriter<tuple_type>(tmpFile,
					PERIOD_MULTIPLIER * pm.getExecutionManager()->getPeriod()),
			PERIOD_MULTIPLIER);
	printf("Error 2 \n");

	systems::connect(tg.output, logger.input);
	systems::connect(time.output, joint_ref.timef);
	systems::connect(wam.jpOutput, slide.feedbackjpInput);
	systems::connect(wam.jvOutput, slide.feedbackjvInput);
	systems::connect(wam.jpOutput, nilu_dynamics.jpInputDynamics);
	systems::connect(wam.jvOutput, nilu_dynamics.jvInputDynamics);
	systems::connect(nilu_dynamics.MassMAtrixOutput, slide.M);
	systems::connect(nilu_dynamics.CVectorOutput, slide.C);
	systems::connect(joint_ref.referencejpTrack, slide.referencejpInput);
	systems::connect(joint_ref.referencejvTrack, slide.referencejvInput);
	systems::connect(joint_ref.referencejaTrack, slide.referencejaInput);

	wam.trackReferenceSignal(slide.controlOutput);
	printf("Error 3 \n");

	systems::connect(time.output, tg.template getInput<0>());
	systems::connect(joint_ref.referencejpTrack, tg.template getInput<1>());
	systems::connect(joint_ref.referencejvTrack, tg.template getInput<2>());
	systems::connect(wam.jpOutput, tg.template getInput<3>());
	systems::connect(wam.jvOutput, tg.template getInput<4>());
	systems::connect(slide.controlOutput, tg.template getInput<5>());
	printf("Error 4 \n");

	time.smoothStart(TRANSITION_DURATION);
	printf("Press [Enter] to stop.");
	waitForEnter();
	logger.closeLog();
	time.smoothStop(TRANSITION_DURATION);
	wam.idle();
	printf("Error 5 \n");

	pm.getSafetyModule()->waitForMode(SafetyModule::IDLE);
	log::Reader<boost::tuple<tuple_type> > lr(tmpFile);
	lr.exportCSV(argv[1]);
	printf("Error 6 \n");

	printf("Output written to %s.\n", argv[1]);
	std::remove(tmpFile);

	return 0;
}
void displayEntryPoint(Hand* hand) {
	
	typedef Hand::jp_type hjp_t;
	double O = 0.0;
        double C = 2.4;
	double C1= 1.2;
        double SC = M_PI;
        hjp_t open(O);
        hjp_t closed(C);
	hjp_t closed1(C1);
        closed[3] = SC;
	closed1[3]= SC;

        double OR = -0.75;
        double CR = 0.75;
        Hand::jv_type opening(OR);
        Hand::jv_type closing(CR);
	Hand::jt_type oopen(-1.00);
	Hand::jt_type cclose(1.00);
	Hand::jt_type cclose1(0.50);



	if (hand != NULL) {
		printf("Press [Enter] to initialize the Hand. (Make sure it has room!)");
		waitForEnter();	
		hand->initialize();
	} else {
		printf("WARNING: No Hand found!\n");
	}

	assertPosition(hand, open);
        hand->close();
        assertPosition(hand, closed);
        hand->open();
        assertPosition(hand, open);
        hand->close(Hand::SPREAD);

/*
	{
                // Original interface preserved? Should move all 4 motors.
                hand->trapezoidalMove(closed);
                assertPosition(hand, closed);
                hand->trapezoidalMove(open, false);
                hand->waitUntilDoneMoving();
                assertPosition(hand, open);

                // New interface
                hand->trapezoidalMove(closed1, Hand::SPREAD);
                assertPosition(hand, hjp_t(O,O,O,SC));std::cout<<"111"<<std::endl;
                hand->trapezoidalMove(closed1, Hand::F1);
                assertPosition(hand, hjp_t(C1,O,O,SC));std::cout<<"222"<<std::endl;
                hand->trapezoidalMove(closed1, Hand::F2);
                assertPosition(hand, hjp_t(C1,C1,O,SC));std::cout<<"333"<<std::endl;
                hand->trapezoidalMove(closed1, Hand::F3);
                assertPosition(hand, closed1);std::cout<<"444"<<std::endl;
                hand->trapezoidalMove(open, Hand::GRASP);
                assertPosition(hand, hjp_t(O,O,O,SC));std::cout<<"555"<<std::endl;
                hand->trapezoidalMove(open, Hand::SPREAD);
                assertPosition(hand, open);std::cout<<"666"<<std::endl;
                hand->trapezoidalMove(closed1, Hand::F3 | Hand::SPREAD);
                assertPosition(hand, hjp_t(O,O,C1,SC));std::cout<<"777"<<std::endl;
                hand->trapezoidalMove(open, Hand::WHOLE_HAND);
                assertPosition(hand, open);
        }

	{
                double t = 0.0;

                // Original interface preserved? Should move all 4 motors.
                hand->velocityMove(closing);
                btsleep(1);
                t = 1.0;
                assertPosition(hand, hjp_t(CR*t), 0.2);

                // New interface
                hand->velocityMove(opening, Hand::GRASP);
                btsleep(1);
                t = 2.0;
                assertPosition(hand, hjp_t(O,O,O,CR*t), 0.4);
                hand->velocityMove(opening, Hand::WHOLE_HAND);
                hand->waitUntilDoneMoving();
                assertPosition(hand, open);
        }

*/


	Hand::jp_type currentPos(0.0);
	Hand::jp_type nextPos(M_PI);
	nextPos[3] = 0;


	printf("\n");
	printf("Commands:\n");
	printf("  t    Start teaching a new trajectory\n");
	printf("  p    Play back recorded trajectory\n");
	printf("  l    Loop recorded trajectory\n");
	printf("  s    Stop teaching, stop playing\n");
	printf("  At any time, press [Enter] to open or close the Hand.\n");
	printf("\n");

	std::string line;
	while (true) {
		printf(">> ");
		std::getline(std::cin, line);

		if (line.size() == 0) {
			if (hand != NULL) {
				hand->trapezoidalMove(nextPos, false);
				std::swap(currentPos, nextPos);
			}
		} else {
			switch (line[0]) {
			case 'c':
				hand->setTorqueMode();
				hand->setTorqueCommand(cclose);
				tpState = TEACHING;
				break;
			case 'l':
				hand->setTorqueMode();
                                hand->setTorqueCommand(cclose1);

				//loop = true;
				break;
			case 'o':
				hand->open();
				tpState = PLAYING;
				break;
			case 's':
				loop = false;
				if (tpState == TEACHING) {
					tpState = WAIT_FOR_PLAY;
				} else if (tpState == PLAYING  ||  tpState == DONE_PLAYING) {
					tpState = IDLE;
				}
				break;
			default:
				break;
			}
		}
	}
}