void BSWalkTo::update()
{
#ifndef TARGET_TOOL
  DECLARE_DEBUG_DRAWING("module:BH2011BehaviorControl:BSWalkTo:Field", "drawingOnField");
  MODIFY("module:BH2011BehaviorControl:BSWalkTo:parameters", p);
#endif
}
void GameDataProvider::update(OwnTeamInfo& ownTeamInfo)
{
  if(!ownTeamInfoSet)
  {
    (RoboCup::TeamInfo&) ownTeamInfo = gameControlData.teams[0];
    ownTeamInfo.teamNumber = Global::getSettings().teamNumber;
    ownTeamInfoSet = true;
  }

  bool received = false;
  if(theFrameInfo.getTimeSince(gameControlTimeStamp) < 500)
  {
    for(int i = 0; i < 2; ++i)
      if(Global::getSettings().teamNumber == (int)gameControlData.teams[i].teamNumber)
      {
        (RoboCup::TeamInfo&) ownTeamInfo = gameControlData.teams[i];
        received = true;
        break;
      }

  }
  if(!received && &theBehaviorControlOutput && Global::getSettings().teamNumber == (int)theBehaviorControlOutput.ownTeamInfo.teamNumber)
  {
    ownTeamInfo = theBehaviorControlOutput.ownTeamInfo;
    memset(ownTeamInfo.players, 0, sizeof(ownTeamInfo.players));
  }

  MODIFY("representation:OwnTeamInfo", ownTeamInfo);
  EXECUTE_ONLY_IN_DEBUG(theFieldDimensions.drawPolygons(ownTeamInfo.teamColor););
void SideConfidenceProvider::update(SideConfidence& sideConfidence)
{
  MODIFY("parameters:SideConfidenceProvider", parameters);
  updateBallConfidences();
  updateSideConfidenceFromOthers(sideConfidence);
  updateSideConfidenceFromOwn(sideConfidence);
  handleAloneAndConfused(sideConfidence);
  updateConfidenceState(sideConfidence);
  
  // Setting some timings
  lastFrameTime = theFrameInfo.time;
  // Setting the time when not in own penalty area
  if(!(theRobotPose.translation.x < theFieldDimensions.xPosOwnPenaltyArea && abs(theRobotPose.translation.y) < theFieldDimensions.yPosLeftPenaltyArea))
    timeWhenEnteredOwnPenaltyArea = theFrameInfo.time;
  // Setting the distance walked when not having a bad validity
  if(theRobotPose.validity > parameters.halfPercentage)
    lastDistanceWalkedAtHighValidity = theOdometer.distanceWalked;
  // Setting the time when the robot has a good stand 
  if((theFallDownState.state != theFallDownState.upright && 
     theFallDownState.state != theFallDownState.undefined && 
     theFallDownState.state != theFallDownState.staggering) && (theFrameInfo.getTimeSince(timeOfLastFall) > 8000)
     && !robotHasFallen)
  {
    timeOfLastFall = theFrameInfo.time;
    robotHasFallen = true;
  }
  // Setting the time when the robot not has arm contact
  if(!theArmContactModel.contactLeft && !theArmContactModel.contactRight)
    lastTimeWithoutArmContact = theFrameInfo.time;
}
Exemple #4
0
void FieldModel::draw()
{
  DECLARE_DEBUG_DRAWING("module:SelfLocator:fieldModel", "drawingOnField"); // Draws the closest points tables
  int index = 0;
  MODIFY("module:SelfLocator:fieldModel", index);
  COMPLEX_DRAWING("module:SelfLocator:fieldModel", 
    if(index < 4)
      linePointsTables[index >> 1][index & 1].draw(); 
    else if(index < 8)
Exemple #5
0
ts::uint32 mainrect_c::gm_handler( gmsg<ISOGM_APPRISE> & )
{
    if (g_app->F_MODAL_ENTER_PASSWORD) return 0;

    if (getprops().is_collapsed())
        MODIFY(*this).decollapse();
    if (getroot()) getroot()->set_system_focus(true);
    return 0;
}
void TeamMarkerPerceptor::update(TeamMarkerSpots& teamMarkerSpots)
{
  DECLARE_DEBUG_DRAWING("module:TeamMarkerPerceptor:grid", "drawingOnImage");
  DECLARE_DEBUG_DRAWING("module:TeamMarkerPerceptor:polygon", "drawingOnImage");
  DECLARE_DEBUG_DRAWING("module:TeamMarkerPerceptor:rejected", "drawingOnImage");
  DECLARE_DEBUG_DRAWING("module:TeamMarkerPerceptor:ellipse", "drawingOnImage");
  DECLARE_DEBUG_DRAWING("module:TeamMarkerPerceptor:bb", "drawingOnImage");
  MODIFY("parameters:TeamMarkerPerceptor", params);

  teamMarkerSpots.teamMarkers.clear();
  extractTeamMarkers(teamMarkerSpots);
}
void FieldModel::draw()
{
  DECLARE_DEBUG_DRAWING("module:SelfLocator:fieldModel", "drawingOnField"); // Draws the closest points tables
#ifndef RELEASE
  int index = 0;
#endif
  MODIFY("module:SelfLocator:fieldModel", index);
  COMPLEX_DRAWING("module:SelfLocator:fieldModel",
  {
    if(index < 4)
      linePointsTables[index >> 1][index & 1].draw();
    else if(index < 8)
      tCornersTables[index - 4].draw();
    else
      lCornersTables[index - 8].draw();
  });
Exemple #8
0
ts::uint32 mainrect_c::gm_handler(gmsg<GM_HEARTBEAT> &)
{
    // check monitor

    if (0 != (checktick & 1) && !getprops().is_maximized())
    {
        ts::irect cmrect = ts::wnd_get_max_size(rrect);
        if (cmrect != mrect || getprops().screenrect() != rrect)
        {
            ts::ivec2 newc = rrect.center() - mrect.center() + cmrect.center();
            ts::irect newr = ts::irect::from_center_and_size(newc, rrect.size());
            newr.movein(cmrect);
            MODIFY(*this).pos(newr.lt).size(newr.size());
        }
    }
    ++checktick;

    return 0;
}
Exemple #9
0
void USControl::update(USRequest& usRequest)
{
  MODIFY("parameters:USControl", parameters);
  

  if(commandSent)
  {
    usRequest.sendMode = -1;
    if (SystemCall::getTimeSince(lastSendTime) >= parameters.timeBetweenSendAndReceive)
    {
      usRequest.receiveMode = parameters.modes[currentMode];
      commandSent = false;
    }
    // wait a while more
  }
  else
  {
    usRequest.receiveMode = -1; //-1 = do not read anything

    //If a command has been sent last frame: check if we should send one this frame
    if(SystemCall::getTimeSince(lastSendTime) >= parameters.sendInterval)
    {
      if(SystemCall::getTimeSince(lastSwitchTime) >= parameters.switchInterval)
      {
        currentMode = (currentMode + 1) % parameters.modes.size();
        lastSwitchTime = SystemCall::getCurrentSystemTime();
      }
      usRequest.sendMode = parameters.modes[currentMode];
      lastSendTime = SystemCall::getCurrentSystemTime();
      commandSent = true;
    }
    else
    {
      usRequest.sendMode = -1; //do not send anything
    }

  }



}
Exemple #10
0
bool gui_filterbar_c::do_contact_check(RID, GUIPARAM p)
{
    for (int n = ts::tmax(1, contacts().count() / 10 ); contact_index < contacts().count() && n > 0; --n)
    {
        contact_c &c = contacts().get(contact_index++);
        if (c.is_rootcontact())
        {
            contact_root_c *cr = ts::ptr_cast<contact_root_c *>(&c);

            if (cr->is_full_search_result())
            {
                cr->full_search_result(false);
                if (cr->gui_item) cr->gui_item->update_text();
            }

            if (cr->gui_item)
            {
                MODIFY(*cr->gui_item).visible(check_one(cr));
            }
        }
    }

    if (contact_index < contacts().count())
    {
        if (active)
        {
            gui_contactlist_c &cl = HOLD(getparent()).as<gui_contactlist_c>();
            cl.scroll_to_child(active, false);
        }
        DEFERRED_UNIQUE_CALL(0, DELEGATE(this, do_contact_check), 0);
    }
    else
    {
        apply_full_text_search_result();
    }

    return true;
}
Exemple #11
0
void gui_filterbar_c::apply_full_text_search_result()
{
    for (found_item_s &itm : found_stuff.items)
        if (contact_root_c *c = contacts().rfind(itm.historian))
        {
            c->full_search_result(true);
            if (c->gui_item)
            {
                c->gui_item->update_text();
                MODIFY(*c->gui_item).show();
            }
        }

    if (active)
    {
        gui_contactlist_c &cl = HOLD(getparent()).as<gui_contactlist_c>();
        cl.scroll_to_child(active, false);
    }

    gmsg<ISOGM_REFRESH_SEARCH_RESULT>().send();


}
void ShipGoalsDlg::update_item(int item, int multi)
{
	char *docker, *dockee, *subsys;
	int mode;
	char buf[512], save[80];
	waypoint_list *wp_list;

	if (item >= MAX_AI_GOALS)
		return;

	if (!multi || m_priority[item] >= 0)
		goalp[item].priority = m_priority[item];

	if (m_behavior[item] < 0) {
		if (multi)
			return;
		else
			m_behavior[item] = 0;
	}

	mode = (int)m_behavior_box[item] -> GetItemData(m_behavior[item]);
	switch (mode) {
		case AI_GOAL_NONE:
		case AI_GOAL_CHASE_ANY:
		case AI_GOAL_UNDOCK:
		case AI_GOAL_KEEP_SAFE_DISTANCE:
		case AI_GOAL_PLAY_DEAD:
		case AI_GOAL_PLAY_DEAD_PERSISTENT:
		case AI_GOAL_WARP:
			// these goals do not have a target in the dialog box, so let's set the goal and return immediately
			// so that we don't run afoul of the "doesn't have a valid target" code at the bottom of the function
			MODIFY(goalp[item].ai_mode, mode);
			return;

		case AI_GOAL_WAYPOINTS:
		case AI_GOAL_WAYPOINTS_ONCE:
		case AI_GOAL_DISABLE_SHIP:
		case AI_GOAL_DISARM_SHIP:
		case AI_GOAL_IGNORE:
		case AI_GOAL_IGNORE_NEW:
		case AI_GOAL_EVADE_SHIP:
		case AI_GOAL_STAY_NEAR_SHIP:
		case AI_GOAL_STAY_STILL:
		case AI_GOAL_CHASE_SHIP_CLASS:
			break;

		case AI_GOAL_DESTROY_SUBSYSTEM:
			subsys = NULL;
			if (!multi || (m_data[item] && (m_subsys[item] >= 0)))
				subsys = (char *) m_subsys_box[item]->GetItemDataPtr(m_subsys[item]);
				//MODIFY(goalp[item].ai_submode, m_subsys[item] + 1);

			if (!subsys) {
				sprintf(buf, "Order #%d doesn't have valid subsystem name.  Order will be removed", item + 1);
				MessageBox(buf, "Notice");
				MODIFY(goalp[item].ai_mode, AI_GOAL_NONE);
				return;

			} else {
				if (!goalp[item].docker.name || (goalp[item].docker.name && !stricmp(goalp[item].docker.name, subsys)))
					set_modified();

				goalp[item].docker.name = subsys;
			}

			break;

		case AI_GOAL_CHASE | AI_GOAL_CHASE_WING:
			switch (m_data[item] & TYPE_MASK) {
				case TYPE_SHIP:
				case TYPE_PLAYER:
					mode = AI_GOAL_CHASE;
					break;

				case TYPE_WING:
					mode = AI_GOAL_CHASE_WING;
					break;
			}

			break;

		case AI_GOAL_DOCK:
			docker = NULL;
			if (!multi || (m_data[item] && (m_subsys[item] >= 0)))
				docker = (char *) m_subsys_box[item] -> GetItemDataPtr(m_subsys[item]);

			dockee = NULL;
			if (!multi || (m_data[item] && (m_dock2[item] >= 0)))
				dockee = (char *) m_dock2_box[item] -> GetItemDataPtr(m_dock2[item]);

			if (docker == (char *) SIZE_T_MAX)
				docker = NULL;
			if (dockee == (char *) SIZE_T_MAX)
				dockee = NULL;

			if (!docker || !dockee) {
				sprintf(buf, "Order #%d doesn't have valid docking points.  Order will be removed", item + 1);
				MessageBox(buf, "Notice");
				MODIFY(goalp[item].ai_mode, AI_GOAL_NONE);
				return;

			} else {
				if (!goalp[item].docker.name)
					set_modified();
				else if (!stricmp(goalp[item].docker.name, docker))
					set_modified();

				if (!goalp[item].dockee.name)
					set_modified();
				else if (!stricmp(goalp[item].dockee.name, dockee))
					set_modified();

				goalp[item].docker.name = docker;
				goalp[item].dockee.name = dockee;
			}

			break;

		case AI_GOAL_GUARD | AI_GOAL_GUARD_WING:
			switch (m_data[item] & TYPE_MASK) {
				case TYPE_SHIP:
				case TYPE_PLAYER:
					mode = AI_GOAL_GUARD;
					break;

				case TYPE_WING:
					mode = AI_GOAL_GUARD_WING;
					break;
			}

			break;

		default:
			Warning(LOCATION, "Unknown AI_GOAL type 0x%x", mode);
			MODIFY(goalp[item].ai_mode, AI_GOAL_NONE);
			return;
	}

	MODIFY(goalp[item].ai_mode, mode);

	*save = 0;
	if (goalp[item].target_name)
		strcpy_s(save, goalp[item].target_name);

	switch (m_data[item] & TYPE_MASK) {
		int not_used;

		case TYPE_SHIP:
		case TYPE_PLAYER:
			goalp[item].target_name = ai_get_goal_target_name(Ships[m_data[item] & DATA_MASK].ship_name, &not_used);
			break;

		case TYPE_WING:
			goalp[item].target_name = ai_get_goal_target_name(Wings[m_data[item] & DATA_MASK].name, &not_used);
			break;

		case TYPE_PATH:
			wp_list = find_waypoint_list_at_index(m_data[item] & DATA_MASK);
			Assert(wp_list != NULL);
			goalp[item].target_name = ai_get_goal_target_name(wp_list->get_name(), &not_used);
			break;

		case TYPE_WAYPOINT:
			goalp[item].target_name = ai_get_goal_target_name(object_name(m_data[item] & DATA_MASK), &not_used);
			break;

		case TYPE_SHIP_CLASS:
			goalp[item].target_name = ai_get_goal_target_name(Ship_info[m_data[item] & DATA_MASK].name, &not_used);
			break;

		case 0:
		case -1:
		case (-1 & TYPE_MASK):
			if (multi)
				return;

			sprintf(buf, "Order #%d doesn't have a valid target.  Order will be removed", item + 1);
			MessageBox(buf, "Notice");
			MODIFY(goalp[item].ai_mode, AI_GOAL_NONE);
			return;

		default:
			Error(LOCATION, "Unhandled TYPE_X #define %d in ship goals dialog box", m_data[item] & TYPE_MASK);
	}

	if (stricmp(save, goalp[item].target_name))
		set_modified();
}
void GroundContactDetector::update(GroundContactState& groundContactState)
{
  DECLARE_PLOT("module:GroundContactDetector:angleNoiseX");
  DECLARE_PLOT("module:GroundContactDetector:angleNoiseY");
  DECLARE_PLOT("module:GroundContactDetector:accNoiseX");
  DECLARE_PLOT("module:GroundContactDetector:accNoiseY");
  DECLARE_PLOT("module:GroundContactDetector:accNoiseZ");
  DECLARE_PLOT("module:GroundContactDetector:gyroNoiseX");
  DECLARE_PLOT("module:GroundContactDetector:gyroNoiseY");

  MODIFY("module:GroundContactDetector:contact", contact);

  if(theMotionInfo.motion == MotionRequest::getUp) //hack to avoid long pause after get up 
  {
    contact = true;
    useAngle = false;
    groundContactState.contact = contact;
    contactStartTime = theFrameInfo.time;
  }

  bool ignoreSensors = (theMotionInfo.motion != MotionRequest::walk && theMotionInfo.motion != MotionRequest::stand &&
                        theMotionInfo.motion != MotionRequest::specialAction && theMotionInfo.motion != MotionRequest::getUp) ||
                       (theMotionRequest.motion != MotionRequest::walk && theMotionRequest.motion != MotionRequest::stand &&
                        theMotionRequest.motion != MotionRequest::specialAction && theMotionRequest.motion != MotionRequest::getUp) ||
                       (theMotionInfo.motion == MotionRequest::walk && theMotionInfo.walkRequest.kickType != WalkRequest::none) ||
                       (theMotionRequest.motion == MotionRequest::walk && theMotionRequest.walkRequest.kickType != WalkRequest::none);
  if(!ignoreSensors)
  {
    if(contact)
    {
      calibratedAccZValues.add(theSensorData.data[SensorData::accZ]);

      Vector3<> angleDiff = ((const RotationMatrix&)(theTorsoMatrix.rotation * expectedRotationInv)).getAngleAxis();
      angleNoises.add(Vector2<>(sqr(angleDiff.x), sqr(angleDiff.y)));
      Vector2<> angleNoise = angleNoises.getAverage();
      PLOT("module:GroundContactDetector:angleNoiseX", angleNoise.x);
      PLOT("module:GroundContactDetector:angleNoiseY", angleNoise.y);

      if(!useAngle && angleNoises.isFull() && angleNoise.x < contactAngleActivationNoise && angleNoise.y < contactAngleActivationNoise)
        useAngle = true;

      if((useAngle && (angleNoise.x > contactMaxAngleNoise || angleNoise.y > contactMaxAngleNoise)) ||
         (calibratedAccZValues.isFull() && calibratedAccZValues.getAverage() > contactMaxAccZ))
      {
        /*
        if((useAngle && (angleNoise.x > p.contactMaxAngleNoise || angleNoise.y > p.contactMaxAngleNoise)))
          OUTPUT_ERROR("lost ground contact via angle");
        if((calibratedAccZValues.isFull() && calibratedAccZValues.getAverage() > p.contactMaxAccZ))
          OUTPUT_ERROR("lost ground contact via acc");
        */

        contact = false;
        accNoises.clear();
        gyroNoises.clear();
        accValues.clear();
        gyroValues.clear();
        angleNoises.clear();
        if(SystemCall::getMode() == SystemCall::physicalRobot && contactStartTime != 0)
          SystemCall::playSound("high.wav");
      }
    }
    else
    {
      const Vector3<> accAverage = accValues.getAverage();
      const Vector2<> gyroAverage = gyroValues.getAverage();
      const Vector2<> gyro = Vector2<>(theSensorData.data[SensorData::gyroX], theSensorData.data[SensorData::gyroY]);
      const Vector3<> acc = Vector3<>(theSensorData.data[SensorData::accX], theSensorData.data[SensorData::accY], theSensorData.data[SensorData::accZ]);
      accValues.add(acc);
      gyroValues.add(gyro);
      if(accValues.isFull())
      {
        accNoises.add(Vector3<>(sqr(acc.x - accAverage.x), sqr(acc.y - accAverage.y), sqr(acc.z - accAverage.z)));
        gyroNoises.add(Vector2<>(sqr(gyro.x - gyroAverage.x), sqr(gyro.y - gyroAverage.y)));
      }
      Vector3<> accNoise = accNoises.getAverage();
      Vector2<> gyroNoise = gyroNoises.getAverage();
      PLOT("module:GroundContactDetector:accNoiseX", accNoise.x);
      PLOT("module:GroundContactDetector:accNoiseY", accNoise.y);
      PLOT("module:GroundContactDetector:accNoiseZ", accNoise.z);
      PLOT("module:GroundContactDetector:gyroNoiseX", gyroNoise.x);
      PLOT("module:GroundContactDetector:gyroNoiseY", gyroNoise.y);

      if(accNoises.isFull() &&
         accAverage.z < -5.f && std::abs(accAverage.x) < 5.f && std::abs(accAverage.y) < 5.f &&
         accNoise.x < noContactMinAccNoise && accNoise.y < noContactMinAccNoise && accNoise.z < noContactMinAccNoise &&
         gyroNoise.x < noContactMinGyroNoise && gyroNoise.y < noContactMinGyroNoise)
      {
        contact = true;
        useAngle = false;
        contactStartTime = theFrameInfo.time;
        angleNoises.clear();
        calibratedAccZValues.clear();
      }
    }
  }

  groundContactState.contact = contact;

  expectedRotationInv = theRobotModel.limbs[MassCalibration::footLeft].translation.z > theRobotModel.limbs[MassCalibration::footRight].translation.z ? theRobotModel.limbs[MassCalibration::footLeft].rotation : theRobotModel.limbs[MassCalibration::footRight].rotation;
}
void asteroid_editor::update_init()
{
	int num_asteroids, idx, cur_choice;

	UpdateData(TRUE);
	if (last_field >= 0) {
		// store into temp asteroid field
		num_asteroids = a_field[last_field].num_initial_asteroids;
		a_field[last_field].num_initial_asteroids = m_enable_asteroids ? m_density : 0;
		if (a_field[last_field].num_initial_asteroids < 0)
			a_field[last_field].num_initial_asteroids = 0;

		if (a_field[last_field].num_initial_asteroids > MAX_ASTEROIDS)
			a_field[last_field].num_initial_asteroids = MAX_ASTEROIDS;

		if (num_asteroids != a_field[last_field].num_initial_asteroids)
			set_modified();

		vector	vel_vec = {1.0f, 0.0f, 0.0f};
		vm_vec_scale(&vel_vec, (float) m_avg_speed);

		MODIFY(a_field[last_field].vel.x, vel_vec.x);
		MODIFY(a_field[last_field].vel.y, vel_vec.y);
		MODIFY(a_field[last_field].vel.z, vel_vec.z);

		MODIFY(a_field[last_field].min_bound.x, (float) atof(m_min_x));
		MODIFY(a_field[last_field].min_bound.y, (float) atof(m_min_y));
		MODIFY(a_field[last_field].min_bound.z, (float) atof(m_min_z));
		MODIFY(a_field[last_field].max_bound.x, (float) atof(m_max_x));
		MODIFY(a_field[last_field].max_bound.y, (float) atof(m_max_y));
		MODIFY(a_field[last_field].max_bound.z, (float) atof(m_max_z));

		// type of field
		MODIFY(a_field[last_field].field_type, m_field_type);
		MODIFY(a_field[last_field].debris_genre, m_debris_genre);
		if ( (m_field_type == FT_PASSIVE) && (m_debris_genre == DG_SHIP) ) {
			// we should have ship debris
			for (idx=0; idx<3; idx++) {
				// loop over combo boxes, store the item data of the cur selection, -1 in no cur selection
				int cur_sel = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->GetCurSel();
				if (cur_sel != CB_ERR) {
					cur_choice = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->GetItemData(cur_sel);
				} else {
					cur_choice = -1;
				}
				MODIFY(a_field[cur_field].field_debris_type[idx], cur_choice);
			}
		}

		if ( m_debris_genre == DG_ASTEROID ) {
			if ( ((CButton *)GetDlgItem(IDC_SUBTYPE1))->GetCheck() == 1) {
				cur_choice = 1;
			} else {
				cur_choice = -1;
			}
			MODIFY(a_field[cur_field].field_debris_type[0], cur_choice);


			if ( ((CButton *)GetDlgItem(IDC_SUBTYPE2))->GetCheck() == 1) {
				cur_choice = 1;
			} else {
				cur_choice = -1;
			}
			MODIFY(a_field[cur_field].field_debris_type[1], cur_choice);


			if ( ((CButton *)GetDlgItem(IDC_SUBTYPE3))->GetCheck() == 1) {
				cur_choice = 1;
			} else {
				cur_choice = -1;
			}
			MODIFY(a_field[cur_field].field_debris_type[2], cur_choice);
		}

		MODIFY(a_field[last_field].has_inner_bound, m_enable_inner_bounds);

		MODIFY(a_field[last_field].inner_min_bound.x, (float) atof(m_box_min_x));
		MODIFY(a_field[last_field].inner_min_bound.y, (float) atof(m_box_min_y));
		MODIFY(a_field[last_field].inner_min_bound.z, (float) atof(m_box_min_z));
		MODIFY(a_field[last_field].inner_max_bound.x, (float) atof(m_box_max_x));
		MODIFY(a_field[last_field].inner_max_bound.y, (float) atof(m_box_max_y));
		MODIFY(a_field[last_field].inner_max_bound.z, (float) atof(m_box_max_z));
	}

	Assert(cur_field >= 0);
	// get from temp asteroid field into class
	m_enable_asteroids = a_field[cur_field].num_initial_asteroids ? TRUE : FALSE;
	m_enable_inner_bounds = a_field[cur_field].has_inner_bound ? TRUE : FALSE;
	m_density = a_field[cur_field].num_initial_asteroids;
	if (!m_enable_asteroids)
		m_density = 10;

	// set field type
	m_field_type = a_field[cur_field].field_type;
	m_debris_genre = a_field[cur_field].debris_genre;
//	m_debris_species = a_field[cur_field].debris_species;

	m_avg_speed = (int) vm_vec_mag(&a_field[cur_field].vel);
	m_min_x.Format("%.1f", a_field[cur_field].min_bound.x);
	m_min_y.Format("%.1f", a_field[cur_field].min_bound.y);
	m_min_z.Format("%.1f", a_field[cur_field].min_bound.z);
	m_max_x.Format("%.1f", a_field[cur_field].max_bound.x);
	m_max_y.Format("%.1f", a_field[cur_field].max_bound.y);
	m_max_z.Format("%.1f", a_field[cur_field].max_bound.z);

	m_box_min_x.Format("%.1f", a_field[cur_field].inner_min_bound.x);
	m_box_min_y.Format("%.1f", a_field[cur_field].inner_min_bound.y);
	m_box_min_z.Format("%.1f", a_field[cur_field].inner_min_bound.z);
	m_box_max_x.Format("%.1f", a_field[cur_field].inner_max_bound.x);
	m_box_max_y.Format("%.1f", a_field[cur_field].inner_max_bound.y);
	m_box_max_z.Format("%.1f", a_field[cur_field].inner_max_bound.z);

	// set up combo boxes
	int box_index;
	int num_field_debris_info = MAX_DEBRIS_TYPES + 1;

	for (idx=0; idx<num_field_debris_info; idx++) {
		box_index = ((CComboBox*)GetDlgItem(IDC_SHIP_DEBRIS1))->AddString(Field_debris_info[idx].name);
		((CComboBox*)GetDlgItem(IDC_SHIP_DEBRIS1))->SetItemData(box_index, Field_debris_info[idx].index);

		box_index = ((CComboBox*)GetDlgItem(IDC_SHIP_DEBRIS2))->AddString(Field_debris_info[idx].name);
		((CComboBox*)GetDlgItem(IDC_SHIP_DEBRIS2))->SetItemData(box_index, Field_debris_info[idx].index);

		box_index = ((CComboBox*)GetDlgItem(IDC_SHIP_DEBRIS3))->AddString(Field_debris_info[idx].name);
		((CComboBox*)GetDlgItem(IDC_SHIP_DEBRIS3))->SetItemData(box_index, Field_debris_info[idx].index);
	}

	// now delete asteroid data
	// search by string Field_debris_info[1-3].name

	for (idx=0; idx<3; idx++) {
		box_index = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->FindStringExact(0, Field_debris_info[1].name);	// "Asteroid Small"
		if (box_index > 0) {
			((CComboBox*)GetDlgItem(Dlg_id[idx]))->DeleteString(box_index);
		}

		box_index = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->FindStringExact(0, Field_debris_info[2].name);	// "Asteroid Medium"
		if (box_index > 0) {
			((CComboBox*)GetDlgItem(Dlg_id[idx]))->DeleteString(box_index);
		}

		box_index = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->FindStringExact(0, Field_debris_info[3].name);	// "Asteroid Big"
		if (box_index > 0) {
			((CComboBox*)GetDlgItem(Dlg_id[idx]))->DeleteString(box_index);
		}
	}

	// set active debris type for each combo box
	int box_count, cur_box_data;
	for (idx=0;idx<3; idx++) {
		// Only set selection if not "None"
		if (a_field[cur_field].field_debris_type[idx] != -1) {
			box_count = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->GetCount();
			for (box_index=0; box_index<box_count; box_index++) {
				cur_box_data = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->GetItemData(box_index);
				if (cur_box_data == a_field[cur_field].field_debris_type[idx]) {
					// set cur sel
					((CComboBox*)GetDlgItem(Dlg_id[idx]))->SetCurSel(box_index);
					break;
				}
			}
		}
	}

	// set up asteroid subtype checkboxes
	((CButton*)GetDlgItem(IDC_SUBTYPE1))->SetCheck(a_field[cur_field].field_debris_type[0] == 1);
	((CButton*)GetDlgItem(IDC_SUBTYPE2))->SetCheck(a_field[cur_field].field_debris_type[1] == 1);
	((CButton*)GetDlgItem(IDC_SUBTYPE3))->SetCheck(a_field[cur_field].field_debris_type[2] == 1);


	UpdateData(FALSE);
	OnEnableAsteroids();

	last_field = cur_field;
}
void GroundContactDetector::update(GroundContactState& groundContactState)
{
  MODIFY("module:GroundContactDetector:parameters", p);
  PLOT("module:GroundContactDetector:groundContact", groundContactState.contact ? 0.75 : 0.25);

#ifdef TARGET_ROBOT
  if(p.forceContact)
#endif
  {
    groundContactState.contact = true;
    //groundContactState.contactSafe = true;
    return;
  }

  // states
  ContactState stateFsrLeft = checkFsr(true);
  ContactState stateFsrRight = checkFsr(false);
  ContactState stateLoad = checkLoad();
  // contact plots
  PLOT("module:GroundContactDetector:contactLoad", stateLoad.contact ? 0.75 : 0.25);
  PLOT("module:GroundContactDetector:contactFsrLeft", stateFsrLeft.contact ? 0.75 : 0.25);
  PLOT("module:GroundContactDetector:contactFsrRight", stateFsrRight.contact ? 0.75 : 0.25);
  // confidence plots
  PLOT("module:GroundContactDetector:confidenceLoad", stateLoad.confidence);
  PLOT("module:GroundContactDetector:confidenceFsrLeft", stateFsrLeft.confidence);
  PLOT("module:GroundContactDetector:confidenceFsrRight", stateFsrRight.confidence);

  float confidenceContact = 0.f;
  float confidenceNoContact = 0.f;
  if(stateFsrLeft.contact) confidenceContact += stateFsrLeft.confidence;
  else confidenceNoContact += stateFsrLeft.confidence;
  if(stateFsrRight.contact) confidenceContact += stateFsrRight.confidence;
  else confidenceNoContact += stateFsrRight.confidence;
  if(stateLoad.contact) confidenceContact += stateLoad.confidence;
  else confidenceNoContact += stateLoad.confidence;

  confidenceContactBuffer.add(confidenceContact);
  confidenceNoContactBuffer.add(confidenceNoContact);
  if(confidenceContactBuffer.getSum() >= BUFFER_SIZE * p.contactThreshold)
    contact = true;
  else if(confidenceNoContactBuffer.getSum() >= BUFFER_SIZE * p.noContactThreshold)
    contact = false;

  groundContactState.contact = contact || theMotionRequest.motion == MotionRequest::specialAction || theMotionInfo.motion == MotionRequest::specialAction;
  PLOT("module:GroundContactDetector:contactThreshold", BUFFER_SIZE * p.contactThreshold);
  PLOT("module:GroundContactDetector:noContactThreshold", BUFFER_SIZE * p.noContactThreshold);
  PLOT("module:GroundContactDetector:confidenceContact", confidenceContactBuffer.getSum());
  PLOT("module:GroundContactDetector:confidenceNoContact", confidenceNoContactBuffer.getSum());

  if((contact && !lastContact) || (contact && contactStartTime == 0))
    contactStartTime = theFrameInfo.time;
  //groundContactState.contactSafe = contact && theFrameInfo.getTimeSince(contactStartTime) >= p.safeContactTime;
  if(!contact && lastContact)
  {
#ifndef TARGET_SIM
    if(contactStartTime != 0 && theMotionInfo.motion == MotionRequest::walk)
      SoundPlayer::play("high.wav");
#endif
  }

  lastContact = contact;
}
void initial_status::change_subsys()
{
	int z, cargo_index, enable = FALSE, enable_cargo_name = FALSE;
	int ship_has_scannable_subsystems;
	ship_subsys *ptr;

	// Goober5000
	ship_has_scannable_subsystems = Ship_info[Ships[m_ship].ship_info_index].is_huge_ship();
	if (Ships[m_ship].flags[Ship::Ship_Flags::Toggle_subsystem_scanning])
		ship_has_scannable_subsystems = !ship_has_scannable_subsystems;

	if (cur_subsys != LB_ERR) {
		ptr = GET_FIRST(&Ships[m_ship].subsys_list);
		while (cur_subsys--) {
			Assert(ptr != END_OF_LIST(&Ships[m_ship].subsys_list));
			ptr = GET_NEXT(ptr);
		}

		MODIFY(ptr -> current_hits, 100.0f - (float) m_damage);

		// update cargo name
		if (strlen(m_cargo_name) > 0) { //-V805
			cargo_index = string_lookup(m_cargo_name, Cargo_names, Num_cargo);
			if (cargo_index == -1) {
				if (Num_cargo < MAX_CARGO);
				cargo_index = Num_cargo++;
				strcpy(Cargo_names[cargo_index], m_cargo_name);
				ptr->subsys_cargo_name = cargo_index;
			} else {
				ptr->subsys_cargo_name = cargo_index;
			}
		} else {
			ptr->subsys_cargo_name = 0;
		}
		set_modified();
	}

	cur_subsys = z = ((CListBox *) GetDlgItem(IDC_SUBSYS)) -> GetCurSel();
	if (z == LB_ERR) {
		m_damage = 100;

	} else {
		ptr = GET_FIRST(&Ships[m_ship].subsys_list);
		while (z--) {
			Assert(ptr != END_OF_LIST(&Ships[m_ship].subsys_list));
			ptr = GET_NEXT(ptr);
		}

		m_damage = 100 - (int) ptr -> current_hits;
		if ( ship_has_scannable_subsystems ) {
			enable_cargo_name = TRUE;
			if (ptr->subsys_cargo_name > 0) {
				m_cargo_name = Cargo_names[ptr->subsys_cargo_name];
			} else {
				m_cargo_name = _T("");
			}
		} else {
			m_cargo_name = _T("");
		}
		enable = TRUE;
	}

	GetDlgItem(IDC_DAMAGE) -> EnableWindow(enable);
	GetDlgItem(IDC_DAMAGE_SPIN) -> EnableWindow(enable);
	GetDlgItem(IDC_CARGO_NAME)->EnableWindow(enable && enable_cargo_name);
}
void ParticleFilterBallLocator::execute()
{
  getBallModel().reset();

  
  // update by motion model
  motionUpdate(theSampleSet, true);
  

  if(getBallPercept().ballWasSeen)
  {
    if(theSampleSet.size() > 0)
    {
      // 
      updateByBallPercept(theSampleSet);

      // 
      resampleGT07(theSampleSet, false);
    }//end if

    // replace a random particle
    if(perceptBuffer.isFull())
    {
      if(theSampleSet.size() < 20)
      {
        theSampleSet.push_back(generateNewSample());
      }
      else
      {
        int k = Math::random(theSampleSet.size());
        theSampleSet[k] = generateNewSample();
      }
    }
  }//end if


  // calculate the model
  if(!theSampleSet.empty())
  {
    Vector2<double> mean;
    Vector2<double> meanSpeed;
    double numberOfMovingSamples = 0;
    for (unsigned int i = 0; i < theSampleSet.size(); i++)
    { 
      mean += theSampleSet[i].position;

      if(theSampleSet[i].moving)
      {
        meanSpeed += theSampleSet[i].speed;
        numberOfMovingSamples++;
      }      

    }//end for

    double meanSpeedAbs = meanSpeed.abs();
    MODIFY("ParticleFilterBallLocator:meanSpeadAbs", meanSpeedAbs);
    MODIFY("ParticleFilterBallLocator:numberOfMovingSamples", numberOfMovingSamples);


    mean /= theSampleSet.size();
    if(numberOfMovingSamples > 1)
      meanSpeed /= numberOfMovingSamples;



    // set the ball model
    if(getBallPercept().ballWasSeen)
      getBallModel().setFrameInfoWhenBallWasSeen(getFrameInfo());

    getBallModel().position = mean;
    //TODO change 13.03
    //getBallModel().speed = Vector2<double>();
    getBallModel().speed = meanSpeed*100;
    getBallModel().valid = true;

    updatePreviewModel();
  }//end if
  

  DEBUG_REQUEST("ParticleFilterBallLocator:draw_ball_on_field", drawBallModel(getBallModel()); );
void GroundContactDetector::update(GroundContactState& groundContactState)
{
  DECLARE_PLOT("module:GroundContactDetector:angleNoiseX");
  DECLARE_PLOT("module:GroundContactDetector:angleNoiseY");
  DECLARE_PLOT("module:GroundContactDetector:accNoiseX");
  DECLARE_PLOT("module:GroundContactDetector:accNoiseY");
  DECLARE_PLOT("module:GroundContactDetector:accNoiseZ");
  DECLARE_PLOT("module:GroundContactDetector:gyroNoiseX");
  DECLARE_PLOT("module:GroundContactDetector:gyroNoiseY");

  MODIFY("module:GroundContactDetector:contact", contact);

  if(theMotionInfo.motion == MotionRequest::getUp) //hack to avoid long pause after get up
  {
    contact = true;
    useAngle = false;
    groundContactState.contact = contact;
    contactStartTime = theFrameInfo.time;
  }

  bool ignoreSensors = (theMotionInfo.motion != MotionRequest::walk && theMotionInfo.motion != MotionRequest::stand &&
                        theMotionInfo.motion != MotionRequest::specialAction && theMotionInfo.motion != MotionRequest::getUp) ||
                       (theMotionRequest.motion != MotionRequest::walk && theMotionRequest.motion != MotionRequest::stand &&
                        theMotionRequest.motion != MotionRequest::specialAction && theMotionRequest.motion != MotionRequest::getUp) ||
                       (theMotionInfo.motion == MotionRequest::walk && theMotionInfo.walkRequest.kickType != WalkRequest::none) ||
                       (theMotionRequest.motion == MotionRequest::walk && theMotionRequest.walkRequest.kickType != WalkRequest::none) ||
                       (theMotionInfo.motion == MotionRequest::specialAction && theMotionInfo.specialActionRequest.specialAction != SpecialActionRequest::standHigh) ||
                       (theMotionRequest.motion == MotionRequest::specialAction && theMotionRequest.specialActionRequest.specialAction != SpecialActionRequest::standHigh);
  if(!ignoreSensors)
  {
    if(contact)
    {
      calibratedAccZValues.push_front(theInertialData.acc.z());

      Vector3f angleDiff = (theTorsoMatrix.rotation * expectedRotationInv).getPackedAngleAxis();
      angleNoises.push_front(Vector2f(sqr(angleDiff.x()), sqr(angleDiff.y())));
      Vector2f angleNoise = angleNoises.average();
      PLOT("module:GroundContactDetector:angleNoiseX", angleNoise.x());
      PLOT("module:GroundContactDetector:angleNoiseY", angleNoise.y());

      if(!useAngle && angleNoises.full() && angleNoise.x() < contactAngleActivationNoise && angleNoise.y() < contactAngleActivationNoise)
        useAngle = true;

      if((useAngle && (angleNoise.x() > contactMaxAngleNoise || angleNoise.y() > contactMaxAngleNoise)) ||
         (calibratedAccZValues.full() && calibratedAccZValues.average() > contactMaxAccZ))
      {
        /*
        if((useAngle && (angleNoise.x > p.contactMaxAngleNoise || angleNoise.y > p.contactMaxAngleNoise)))
          OUTPUT_ERROR("lost ground contact via angle");
        if((calibratedAccZValues.isFull() && calibratedAccZValues.getAverage() > p.contactMaxAccZ))
          OUTPUT_ERROR("lost ground contact via acc");
        */

        contact = false;
        accNoises.clear();
        gyroNoises.clear();
        accValues.clear();
        gyroValues.clear();
        angleNoises.clear();
        if(SystemCall::getMode() == SystemCall::physicalRobot && contactStartTime != 0)
          SystemCall::playSound("high.wav");
      }
    }
    else
    {
      const Vector3f accAverage = accValues.average();
      const Vector2f gyroAverage = gyroValues.average();
      const Vector2f gyro = theInertialData.gyro.head<2>().cast<float>();
      const Vector3f acc = theInertialData.acc.cast<float>();
      accValues.push_front(acc);
      gyroValues.push_front(gyro);
      if(accValues.full())
      {
        accNoises.push_front((acc - accAverage).array().square());
        gyroNoises.push_front((gyro - gyroAverage).array().square());
      }
      Vector3f accNoise = accNoises.average();
      Vector2f gyroNoise = gyroNoises.average();
      PLOT("module:GroundContactDetector:accNoiseX", accNoise.x());
      PLOT("module:GroundContactDetector:accNoiseY", accNoise.y());
      PLOT("module:GroundContactDetector:accNoiseZ", accNoise.z());
      PLOT("module:GroundContactDetector:gyroNoiseX", gyroNoise.x());
      PLOT("module:GroundContactDetector:gyroNoiseY", gyroNoise.y());

      if(accNoises.full() &&
         std::abs(accAverage.z() - Constants::g_1000) < 5.f && std::abs(accAverage.x()) < 5.f && std::abs(accAverage.y()) < 5.f &&
         accNoise.x() < noContactMinAccNoise && accNoise.y() < noContactMinAccNoise && accNoise.z() < noContactMinAccNoise &&
         gyroNoise.x() < noContactMinGyroNoise && gyroNoise.y() < noContactMinGyroNoise)
      {
        contact = true;
        useAngle = false;
        contactStartTime = theFrameInfo.time;
        angleNoises.clear();
        calibratedAccZValues.clear();
      }
    }
  }

  groundContactState.contact = contact;

  expectedRotationInv = theRobotModel.limbs[Limbs::footLeft].translation.z() > theRobotModel.limbs[Limbs::footRight].translation.z() ? theRobotModel.limbs[Limbs::footLeft].rotation : theRobotModel.limbs[Limbs::footRight].rotation;
}
void ArmContactModelProvider::update(ArmContactModel& model)
{
  MODIFY("module:ArmContactModelProvider:parameters", p);
  DECLARE_PLOT("module:ArmContactModelProvider:errorLeftX");
  DECLARE_PLOT("module:ArmContactModelProvider:errorRightX");
  DECLARE_PLOT("module:ArmContactModelProvider:errorLeftY");
  DECLARE_PLOT("module:ArmContactModelProvider:errorRightY");
  DECLARE_PLOT("module:ArmContactModelProvider:errorDurationLeft");
  DECLARE_PLOT("module:ArmContactModelProvider:errorDurationRight");
  DECLARE_PLOT("module:ArmContactModelProvider:errorYThreshold");
  DECLARE_PLOT("module:ArmContactModelProvider:errorXThreshold");
  DECLARE_PLOT("module:ArmContactModelProvider:contactLeft");
  DECLARE_PLOT("module:ArmContactModelProvider:contactRight");

  DECLARE_DEBUG_DRAWING("module:ArmContactModelProvider:armContact", "drawingOnField");

  CIRCLE("module:ArmContactModelProvider:armContact", 0, 0, 200, 30, Drawings::ps_solid, ColorClasses::blue, Drawings::ps_null, ColorClasses::blue);
  CIRCLE("module:ArmContactModelProvider:armContact", 0, 0, 400, 30, Drawings::ps_solid, ColorClasses::blue, Drawings::ps_null, ColorClasses::blue);
  CIRCLE("module:ArmContactModelProvider:armContact", 0, 0, 600, 30, Drawings::ps_solid, ColorClasses::blue, Drawings::ps_null, ColorClasses::blue);
  CIRCLE("module:ArmContactModelProvider:armContact", 0, 0, 800, 30, Drawings::ps_solid, ColorClasses::blue, Drawings::ps_null, ColorClasses::blue);
  CIRCLE("module:ArmContactModelProvider:armContact", 0, 0, 1000, 30, Drawings::ps_solid, ColorClasses::blue, Drawings::ps_null, ColorClasses::blue);
  CIRCLE("module:ArmContactModelProvider:armContact", 0, 0, 1200, 30, Drawings::ps_solid, ColorClasses::blue, Drawings::ps_null, ColorClasses::blue);


  /* Buffer arm angles */
  struct ArmAngles angles;
  angles.leftX = theJointRequest.angles[JointData::LShoulderPitch];
  angles.leftY = theJointRequest.angles[JointData::LShoulderRoll];
  angles.rightX = theJointRequest.angles[JointData::RShoulderPitch];
  angles.rightY = theJointRequest.angles[JointData::RShoulderRoll];
  angleBuffer.add(angles);
  
  /* Reset in case of a fall or penalty */
  if(theFallDownState.state == FallDownState::onGround || theRobotInfo.penalty != PENALTY_NONE)
  {
    leftErrorBuffer.init();
    rightErrorBuffer.init();
  }

  Pose2D odometryOffset = theOdometryData - lastOdometry;
  lastOdometry = theOdometryData;
  
  const Vector3<>& leftHandPos3D = theRobotModel.limbs[MassCalibration::foreArmLeft].translation;
  Vector2<> leftHandPos(leftHandPos3D.x, leftHandPos3D.y);
  Vector2<> leftHandSpeed = (odometryOffset + Pose2D(leftHandPos) - Pose2D(lastLeftHandPos)).translation / theFrameInfo.cycleTime;
  float leftFactor = std::max(0.f, 1.f - leftHandSpeed.abs() / p.speedBasedErrorReduction);
  lastLeftHandPos = leftHandPos;

  const Vector3<>& rightHandPos3D = theRobotModel.limbs[MassCalibration::foreArmRight].translation;
  Vector2<> rightHandPos(rightHandPos3D.x, rightHandPos3D.y);
  Vector2<> rightHandSpeed = (odometryOffset + Pose2D(rightHandPos) - Pose2D(lastRightHandPos)).translation / theFrameInfo.cycleTime;
  float rightFactor = std::max(0.f, 1.f - rightHandSpeed.abs() / p.speedBasedErrorReduction);
  lastRightHandPos = rightHandPos;
  
  /* Check for arm contact */
  // motion types to take into account: stand, walk (if the robot is upright)
  if((theMotionInfo.motion == MotionInfo::stand || theMotionInfo.motion == MotionInfo::walk) &&
     (theFallDownState.state == FallDownState::upright || theFallDownState.state == FallDownState::staggering) &&
     (theGameInfo.state == STATE_PLAYING || theGameInfo.state == STATE_READY) &&
     (theRobotInfo.penalty == PENALTY_NONE)) // TICKET 897: ArmContact only if robot is not penalized
  {
    checkArm(LEFT, leftFactor);
    checkArm(RIGHT, rightFactor);

    //left and right are projections of the 3 dimensional shoulder-joint vector
    //onto the x-y plane.
    Vector2f left = leftErrorBuffer.getAverageFloat();
    Vector2f right = rightErrorBuffer.getAverageFloat();

    
    //Determine if we are being pushed or not
    bool leftX  = fabs(left.x) > fromDegrees(p.errorXThreshold);
    bool leftY  = fabs(left.y) > fromDegrees(p.errorYThreshold);
    bool rightX = fabs(right.x)> fromDegrees(p.errorXThreshold);
    bool rightY = fabs(right.y)> fromDegrees(p.errorYThreshold);

    // update the model
    model.contactLeft  = leftX || leftY;
    model.contactRight = rightX || rightY;

    // The duration of the contact is counted upwards as long as the error
    //remains. Otherwise it is reseted to 0.
    model.durationLeft  = model.contactLeft  ? model.durationLeft + 1 : 0;
    model.durationRight = model.contactRight ? model.durationRight + 1 : 0;

    model.contactLeft &= model.durationLeft < p.malfunctionThreshold;
    model.contactRight &= model.durationRight < p.malfunctionThreshold;


    if(model.contactLeft)
    {
      model.timeOfLastContactLeft = theFrameInfo.time;
    }
    if(model.contactRight)
    {
      model.timeOfLastContactRight = theFrameInfo.time;
    }
    
    model.pushDirectionLeft = getDirection(LEFT, leftX, leftY, left);
    model.pushDirectionRight = getDirection(RIGHT, rightX, rightY, right);

    model.lastPushDirectionLeft = model.pushDirectionLeft != ArmContactModel::NONE ? model.pushDirectionLeft : model.lastPushDirectionLeft;
    model.lastPushDirectionRight = model.pushDirectionRight != ArmContactModel::NONE ? model.pushDirectionRight : model.lastPushDirectionRight;

    PLOT("module:ArmContactModelProvider:errorLeftX",         toDegrees(left.x));
    PLOT("module:ArmContactModelProvider:errorRightX",        toDegrees(right.x));
    PLOT("module:ArmContactModelProvider:errorLeftY",         toDegrees(left.y));
    PLOT("module:ArmContactModelProvider:errorRightY",        toDegrees(right.y));
    PLOT("module:ArmContactModelProvider:errorDurationLeft",  model.durationLeft);
    PLOT("module:ArmContactModelProvider:errorDurationRight", model.durationRight);
    PLOT("module:ArmContactModelProvider:errorYThreshold",    toDegrees(p.errorYThreshold));
    PLOT("module:ArmContactModelProvider:errorXThreshold",    toDegrees(p.errorXThreshold));
    PLOT("module:ArmContactModelProvider:contactLeft",        model.contactLeft ? 10.0 : 0.0);
    PLOT("module:ArmContactModelProvider:contactRight",       model.contactRight ? 10.0 : 0.0);

    ARROW("module:ArmContactModelProvider:armContact", 0, 0, -(toDegrees(left.y) * SCALE), toDegrees(left.x) * SCALE, 20, Drawings::ps_solid, ColorClasses::green);
    ARROW("module:ArmContactModelProvider:armContact", 0, 0, toDegrees(right.y) * SCALE, toDegrees(right.x) * SCALE, 20, Drawings::ps_solid, ColorClasses::red);

    COMPLEX_DRAWING("module:ArmContactModelProvider:armContact",
    {
      DRAWTEXT("module:ArmContactModelProvider:armContact", -2300, 1300, 20, ColorClasses::black, "LEFT");
      DRAWTEXT("module:ArmContactModelProvider:armContact", -2300, 1100, 20, ColorClasses::black, "ErrorX: " << toDegrees(left.x));
      DRAWTEXT("module:ArmContactModelProvider:armContact", -2300, 900, 20, ColorClasses::black,  "ErrorY: " << toDegrees(left.y));
      DRAWTEXT("module:ArmContactModelProvider:armContact", -2300, 500, 20, ColorClasses::black,  ArmContactModel::getName(model.pushDirectionLeft));
      DRAWTEXT("module:ArmContactModelProvider:armContact", -2300, 300, 20, ColorClasses::black,  "Time: " << model.timeOfLastContactLeft);

      DRAWTEXT("module:ArmContactModelProvider:armContact", 1300, 1300, 20, ColorClasses::black, "RIGHT");
      DRAWTEXT("module:ArmContactModelProvider:armContact", 1300, 1100, 20, ColorClasses::black, "ErrorX: " << toDegrees(right.x));
      DRAWTEXT("module:ArmContactModelProvider:armContact", 1300, 900, 20, ColorClasses::black,  "ErrorY: " << toDegrees(right.y));
      DRAWTEXT("module:ArmContactModelProvider:armContact", 1300, 500, 20, ColorClasses::black,  ArmContactModel::getName(model.pushDirectionRight));
      DRAWTEXT("module:ArmContactModelProvider:armContact", 1300, 300, 20, ColorClasses::black,  "Time: " << model.timeOfLastContactRight);

      if (model.contactLeft)
      {
        CROSS("module:ArmContactModelProvider:armContact", -2000, 0, 100, 20, Drawings::ps_solid, ColorClasses::red);
      }
      if (model.contactRight)
      {
        CROSS("module:ArmContactModelProvider:armContact", 2000, 0, 100, 20, Drawings::ps_solid, ColorClasses::red);
      }
  });
void ExpGroundContactDetector::update(GroundContactState& groundContactState)
{
  MODIFY("module:ExpGroundContactDetector:parameters", p);

  DECLARE_PLOT("module:ExpGroundContactDetector:angleNoiseX");
  DECLARE_PLOT("module:ExpGroundContactDetector:angleNoiseY");
  DECLARE_PLOT("module:ExpGroundContactDetector:accNoiseX");
  DECLARE_PLOT("module:ExpGroundContactDetector:accNoiseY");
  DECLARE_PLOT("module:ExpGroundContactDetector:accNoiseZ");
  DECLARE_PLOT("module:ExpGroundContactDetector:gyroNoiseX");
  DECLARE_PLOT("module:ExpGroundContactDetector:gyroNoiseY");

  MODIFY("module:ExpGroundContactDetector:contact", contact);
  bool ignoreSensors = (theMotionInfo.motion != MotionRequest::walk && theMotionInfo.motion != MotionRequest::stand) ||
                       (theMotionRequest.motion != MotionRequest::walk && theMotionRequest.motion != MotionRequest::stand) ||
                       (theMotionInfo.motion == MotionRequest::walk && theMotionInfo.walkRequest.kickType != WalkRequest::none);
  if(!ignoreSensors)
  {
    if(contact)
    {
      if(theInertiaSensorData.acc.z != InertiaSensorData::off)
        calibratedAccZValues.add(theInertiaSensorData.acc.z);

      Vector3<> angleDiff = ((const RotationMatrix&)(theTorsoMatrix.rotation * expectedRotationInv)).getAngleAxis();
      angleNoises.add(Vector2<>(sqr(angleDiff.x), sqr(angleDiff.y)));
      Vector2<> angleNoise = angleNoises.getAverage();
      PLOT("module:ExpGroundContactDetector:angleNoiseX", angleNoise.x);
      PLOT("module:ExpGroundContactDetector:angleNoiseY", angleNoise.y);

      if(!useAngle && angleNoises.isFull() && angleNoise.x < p.contactAngleActivationNoise && angleNoise.y < p.contactAngleActivationNoise)
        useAngle = true;

      if((useAngle && (angleNoise.x > p.contactMaxAngleNoise || angleNoise.y > p.contactMaxAngleNoise)) ||
        (calibratedAccZValues.isFull() && calibratedAccZValues.getAverage() > p.contactMaxAccZ))
      {
        /*
        if((useAngle && (angleNoise.x > p.contactMaxAngleNoise || angleNoise.y > p.contactMaxAngleNoise)))
          OUTPUT_ERROR("lost ground contact via angle");
        if((calibratedAccZValues.isFull() && calibratedAccZValues.getAverage() > p.contactMaxAccZ))
          OUTPUT_ERROR("lost ground contact via acc");
        */

        contact = false;
        accNoises.clear();
        gyroNoises.clear();
        accValues.clear();
        gyroValues.clear();
        angleNoises.clear();
#ifndef TARGET_SIM
        if(contactStartTime != 0)
          SoundPlayer::play("high.wav");
#endif
      }
    }
    else
    {
      Vector3<> accAverage = accValues.getAverage();
      Vector2<> gyroAverage = gyroValues.getAverage();
      if(theInspectedInertiaSensorData.acc.x != InertiaSensorData::off)
      {
        accValues.add(theInspectedInertiaSensorData.acc);
        gyroValues.add(theInspectedInertiaSensorData.gyro);
        if(accValues.isFull())
        {
          accNoises.add(Vector3<>(sqr(theInspectedInertiaSensorData.acc.x - accAverage.x), sqr(theInspectedInertiaSensorData.acc.y - accAverage.y), sqr(theInspectedInertiaSensorData.acc.z - accAverage.z)));
          gyroNoises.add(Vector2<>(sqr(theInspectedInertiaSensorData.gyro.x - gyroAverage.x), sqr(theInspectedInertiaSensorData.gyro.y - gyroAverage.y)));
        }
      }
      Vector3<> accNoise = accNoises.getAverage();
      Vector2<> gyroNoise = gyroNoises.getAverage();
      PLOT("module:ExpGroundContactDetector:accNoiseX", accNoise.x);
      PLOT("module:ExpGroundContactDetector:accNoiseY", accNoise.y);
      PLOT("module:ExpGroundContactDetector:accNoiseZ", accNoise.z);
      PLOT("module:ExpGroundContactDetector:gyroNoiseX", gyroNoise.x);
      PLOT("module:ExpGroundContactDetector:gyroNoiseY", gyroNoise.y);

      if(accNoises.isFull() &&
        accAverage.z < -5.f && std::abs(accAverage.x) < 5.f && std::abs(accAverage.y) < 5.f &&
        accNoise.x < p.noContactMinAccXNoise && accNoise.y < p.noContactMinAccYNoise && accNoise.z < p.noContactMinAccZNoise &&
        gyroNoise.x < p.noContactMinGyroNoise && gyroNoise.y < p.noContactMinGyroNoise)
      {
        contact = true;
        useAngle = false;
        contactStartTime = theFrameInfo.time;
        angleNoises.clear();
        calibratedAccZValues.clear();
      }
    }
  }

  groundContactState.contact = contact;
  
  expectedRotationInv = theRobotModel.limbs[MassCalibration::footLeft].translation.z > theRobotModel.limbs[MassCalibration::footRight].translation.z ? theRobotModel.limbs[MassCalibration::footLeft].rotation : theRobotModel.limbs[MassCalibration::footRight].rotation;
}
void initial_status::OnOK()
{
	char buf[256];
	int vflag = 0, sflag = 0, hflag = 0;
	object *objp;

	if (GetDlgItem(IDC_VELOCITY)->GetWindowText(buf, 255))
		vflag = 1;
	if (GetDlgItem(IDC_SHIELDS)->GetWindowText(buf, 255))
		sflag = 1;
	if (GetDlgItem(IDC_HULL)->GetWindowText(buf, 255))
		hflag = 1;

	UpdateData(TRUE);

	change_subsys();

	if (m_multi_edit) {
		objp = GET_FIRST(&obj_used_list);
		while (objp != END_OF_LIST(&obj_used_list)) {
			if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->flags & OF_MARKED)) {
				if (vflag)
					MODIFY(objp->phys_info.speed, (float) m_velocity);

				if (sflag)
					MODIFY(objp->shield_quadrant[0], (float) m_shields);

				if (hflag)
					MODIFY(objp->hull_strength, (float) m_hull);

				if (m_has_shields == 1)
					objp->flags &= ~OF_NO_SHIELDS;
				else if (!m_has_shields)
					objp->flags |= OF_NO_SHIELDS;
				
				if (m_force_shields == 1) {
					Ships[get_ship_from_obj(objp)].flags2 |= SF2_FORCE_SHIELDS_ON;
				}
				else if (!m_force_shields) {
					Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_FORCE_SHIELDS_ON;
				}
				
				if (m_ship_locked == 1)
					Ships[get_ship_from_obj(objp)].flags2 |= SF2_SHIP_LOCKED;
				else if (!m_ship_locked)
					Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_SHIP_LOCKED;
				
				if (m_weapons_locked == 1)
					Ships[get_ship_from_obj(objp)].flags2 |= SF2_WEAPONS_LOCKED;
				else if (!m_weapons_locked)
					Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_WEAPONS_LOCKED;

				if (m_primaries_locked == 1) {
					Ships[get_ship_from_obj(objp)].flags2 |= SF2_PRIMARIES_LOCKED;
				}
				else if (!m_primaries_locked) {
					Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_PRIMARIES_LOCKED;
				}

				if (m_secondaries_locked == 1) {
					Ships[get_ship_from_obj(objp)].flags2 |= SF2_SECONDARIES_LOCKED;
				}
				else if (!m_secondaries_locked)	{
					Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_SECONDARIES_LOCKED;
				}

				if (m_turrets_locked == 1) {
					Ships[get_ship_from_obj(objp)].flags2 |= SF2_LOCK_ALL_TURRETS_INITIALLY;
				}
				else if (!m_turrets_locked) {
					Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_LOCK_ALL_TURRETS_INITIALLY;
				}
				
				if (m_afterburner_locked == 1) {
					Ships[get_ship_from_obj(objp)].flags2 |= SF2_AFTERBURNER_LOCKED;
				}
				else if (!m_afterburner_locked)	{
					Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_AFTERBURNER_LOCKED;
				}
			}

			objp = GET_NEXT(objp);
		}

	} else {
		MODIFY(Objects[cur_object_index].phys_info.speed, (float) m_velocity);
		MODIFY(Objects[cur_object_index].shield_quadrant[0], (float) m_shields);
		MODIFY(Objects[cur_object_index].hull_strength, (float) m_hull);
		if (m_has_shields)
			Objects[cur_object_index].flags &= ~OF_NO_SHIELDS;
		else
			Objects[cur_object_index].flags |= OF_NO_SHIELDS;

		if (m_force_shields == 1)
			Ships[m_ship].flags2 |= SF2_FORCE_SHIELDS_ON;
		else if (!m_force_shields)
			Ships[m_ship].flags2 &= ~SF2_FORCE_SHIELDS_ON;		

		if (m_ship_locked == 1)
			Ships[m_ship].flags2 |= SF2_SHIP_LOCKED;
		else if (!m_ship_locked)
			Ships[m_ship].flags2 &= ~SF2_SHIP_LOCKED;		

		if (m_weapons_locked == 1)
			Ships[m_ship].flags2 |= SF2_WEAPONS_LOCKED;
		else if (!m_weapons_locked)
			Ships[m_ship].flags2 &= ~SF2_WEAPONS_LOCKED;				

		if (m_primaries_locked == 1)
			Ships[m_ship].flags2 |= SF2_PRIMARIES_LOCKED;
		else if (!m_primaries_locked)
			Ships[m_ship].flags2 &= ~SF2_PRIMARIES_LOCKED;		

		if (m_secondaries_locked == 1)
			Ships[m_ship].flags2 |= SF2_SECONDARIES_LOCKED;
		else if (!m_secondaries_locked)
			Ships[m_ship].flags2 &= ~SF2_SECONDARIES_LOCKED;		

		if (m_turrets_locked == 1)
			Ships[m_ship].flags2 |= SF2_LOCK_ALL_TURRETS_INITIALLY;
		else if (!m_turrets_locked)
			Ships[m_ship].flags2 &= ~SF2_LOCK_ALL_TURRETS_INITIALLY;		

		if (m_afterburner_locked == 1)
			Ships[m_ship].flags2 |= SF2_AFTERBURNER_LOCKED;
		else if (!m_afterburner_locked)
			Ships[m_ship].flags2 &= ~SF2_AFTERBURNER_LOCKED;
	}

	if (m_team_color_setting.IsWindowEnabled() && m_team_color_setting.GetCurSel() > 0)
		Ships[m_ship].team_name = Team_Names[m_team_color_setting.GetCurSel() - 1];
	else
		Ships[m_ship].team_name = "none";

	update_docking_info();

	CDialog::OnOK();
}
void briefing_editor_dlg::update_data(int update)
{
	char buf[MAX_LABEL_LEN], buf2[MAX_ICON_TEXT_LEN], buf3[MAX_BRIEF_LEN];
	int i, j, l, lines, count, enable = TRUE, valid = 0, invalid = 0;
	object *objp;
	brief_stage *ptr = NULL;

	if (update)
		UpdateData(TRUE);

	// save off current data before we update over it with new briefing stage/team stuff
	Briefing = save_briefing;

	Mission_music[SCORE_BRIEFING] = m_briefing_music - 1;
	strcpy(The_mission.substitute_briefing_music_name, m_substitute_briefing_music);
	if (m_last_stage >= 0) {
		ptr = &Briefing->stages[m_last_stage];
		deconvert_multiline_string(buf3, m_text, MAX_BRIEF_LEN);
		if (stricmp(ptr->new_text, buf3))
			set_modified();

		strcpy(ptr->new_text, buf3);
		MODIFY(ptr->camera_time, atoi(m_time));
		string_copy(ptr->voice, m_voice, MAX_FILENAME_LEN, 1);
		i = ptr->flags;
		if (m_cut_prev)
			i |= BS_BACKWARD_CUT;
		else
			i &= ~BS_BACKWARD_CUT;

		if (m_cut_next)
			i |= BS_FORWARD_CUT;
		else
			i &= ~BS_FORWARD_CUT;

		MODIFY(ptr->flags, i);
		ptr->formula = m_tree.save_tree();
		switch (m_lines.GetCheck()) {
			case 1:
				// add lines between every pair of 2 marked icons if there isn't one already.
				for (i=0; i<ptr->num_icons - 1; i++)
					for (j=i+1; j<ptr->num_icons; j++) {
						if ( icon_marked[i] && icon_marked[j] ) {
							for (l=0; l<ptr->num_lines; l++)
								if ( ((ptr->lines[l].start_icon == i) && (ptr->lines[l].end_icon == j)) || ((ptr->lines[l].start_icon == j) && (ptr->lines[l].end_icon == i)) )
									break;

							if ((l == ptr->num_lines) && (l < MAX_BRIEF_STAGE_LINES)) {
								ptr->lines[l].start_icon = i;
								ptr->lines[l].end_icon = j;
								ptr->num_lines++;
							}
						}
					}

				break;

			case 0:
				// remove all existing lines between any 2 marked icons
				i = ptr->num_lines;
				while (i--)
					if ( icon_marked[ptr->lines[i].start_icon] && icon_marked[ptr->lines[i].end_icon] ) {
						ptr->num_lines--;
						for (l=i; l<ptr->num_lines; l++)
							ptr->lines[l] = ptr->lines[l + 1];
					}

				break;
		}

		if (m_last_icon >= 0) {
			valid = (m_id != ptr->icons[m_last_icon].id);
			if (m_id >= 0) {
				if (valid && !m_change_local) {
					for (i=m_last_stage+1; i<Briefing->num_stages; i++) {
						if (find_icon(m_id, i) >= 0) {
							char msg[1024];

							valid = 0;
							sprintf(msg, "Icon ID #%d is already used in a later stage.  You can only\n"
								"change to that ID locally.  Icon ID has been reset back to %d", m_id, ptr->icons[m_last_icon].id);

							m_id = ptr->icons[m_last_icon].id;
							MessageBox(msg);
							break;
						}
					}
				}

				for (i=0; i<ptr->num_icons; i++)
					if ((i != m_last_icon) && (ptr->icons[i].id == m_id)) {
						char msg[1024];

						sprintf(msg, "Icon ID #%d is already used in this stage.  Icon ID has been reset back to %d",
							m_id, ptr->icons[m_last_icon].id);

						m_id = ptr->icons[m_last_icon].id;
						MessageBox(msg);
						break;
					}

				if (valid && !m_change_local) {
					set_modified();
					reset_icon_loop(m_last_stage);
					while (get_next_icon(ptr->icons[m_last_icon].id))
						iconp->id = m_id;
				}
			}

			ptr->icons[m_last_icon].id = m_id;
			string_copy(buf, m_icon_label, MAX_LABEL_LEN);
			if (stricmp(ptr->icons[m_last_icon].label, buf) && !m_change_local) {
				set_modified();
				reset_icon_loop(m_last_stage);
				while (get_next_icon(m_id))
					strcpy(iconp->label, buf);
			}

			strcpy(ptr->icons[m_last_icon].label, buf);
			if ( m_hilight )
				ptr->icons[m_last_icon].flags |= BI_HIGHLIGHT;
			else
				ptr->icons[m_last_icon].flags &= ~BI_HIGHLIGHT;

			if (m_flipicon)
				ptr->icons[m_last_icon].flags |= BI_MIRROR_ICON;
			else
				ptr->icons[m_last_icon].flags &= ~BI_MIRROR_ICON;

			if ((ptr->icons[m_last_icon].type != m_icon_image) && !m_change_local) {
				set_modified();
				reset_icon_loop(m_last_stage);
				while (get_next_icon(m_id))
					iconp->type = m_icon_image;
			}

			ptr->icons[m_last_icon].type = m_icon_image;
			if ((ptr->icons[m_last_icon].team != m_icon_team) && !m_change_local) {
				set_modified();
				reset_icon_loop(m_last_stage);
				while (get_next_icon(m_id))
					iconp->team = m_icon_team;
			}

			ptr->icons[m_last_icon].team = m_icon_team;
			if ((ptr->icons[m_last_icon].ship_class != m_ship_type) && !m_change_local) {
				set_modified();
				reset_icon_loop(m_last_stage);
				while (get_next_icon(m_id))
					iconp->ship_class = m_ship_type;
			}

			MODIFY(ptr->icons[m_last_icon].ship_class, m_ship_type);
			deconvert_multiline_string(buf2, m_icon_text, MAX_ICON_TEXT_LEN);
/*
			if (stricmp(ptr->icons[m_last_icon].text, buf2) && !m_change_local) {
				set_modified();
				reset_icon_loop(m_last_stage);
				while (get_next_icon(m_id))
					strcpy(iconp->text, buf2);
			}

			strcpy(ptr->icons[m_last_icon].text, buf2);
*/
		}
	}

	if (!::IsWindow(m_hWnd))
		return;

	// set briefing pointer to correct team
	Briefing = &Briefings[m_current_briefing];

	if ((m_cur_stage >= 0) && (m_cur_stage < Briefing->num_stages)) {
		ptr = &Briefing->stages[m_cur_stage];
		m_stage_title.Format("Stage %d of %d", m_cur_stage + 1, Briefing->num_stages);
		m_text = convert_multiline_string(ptr->new_text);
		m_time.Format("%d", ptr->camera_time);
		m_voice = ptr->voice;
		m_cut_prev = (ptr->flags & BS_BACKWARD_CUT) ? 1 : 0;
		m_cut_next = (ptr->flags & BS_FORWARD_CUT) ? 1 : 0;
		m_tree.load_tree(ptr->formula);

	} else {
		m_stage_title = _T("No stages");
		m_text = _T("");
		m_time = _T("");
		m_voice = _T("");
		m_cut_prev = m_cut_next = 0;
		m_tree.clear_tree();
		enable = FALSE;
		m_cur_stage = -1;
	}

	if (m_cur_stage == Briefing->num_stages - 1)
		GetDlgItem(IDC_NEXT) -> EnableWindow(FALSE);
	else
		GetDlgItem(IDC_NEXT) -> EnableWindow(enable);

	if (m_cur_stage)
		GetDlgItem(IDC_PREV) -> EnableWindow(enable);
	else
		GetDlgItem(IDC_PREV) -> EnableWindow(FALSE);

	if (Briefing->num_stages >= MAX_BRIEF_STAGES)
		GetDlgItem(IDC_ADD_STAGE) -> EnableWindow(FALSE);
	else
		GetDlgItem(IDC_ADD_STAGE) -> EnableWindow(TRUE);

	if (Briefing->num_stages) {
		GetDlgItem(IDC_DELETE_STAGE) -> EnableWindow(enable);
		GetDlgItem(IDC_INSERT_STAGE) -> EnableWindow(enable);
	} else {
		GetDlgItem(IDC_DELETE_STAGE) -> EnableWindow(FALSE);
		GetDlgItem(IDC_INSERT_STAGE) -> EnableWindow(FALSE);
	}

	GetDlgItem(IDC_TIME) -> EnableWindow(enable);
	GetDlgItem(IDC_VOICE) -> EnableWindow(enable);
	GetDlgItem(IDC_BROWSE) -> EnableWindow(enable);
	GetDlgItem(IDC_TEXT) -> EnableWindow(enable);
	GetDlgItem(IDC_SAVE_VIEW) -> EnableWindow(enable);
	GetDlgItem(IDC_GOTO_VIEW) -> EnableWindow(enable);
	GetDlgItem(IDC_CUT_PREV) -> EnableWindow(enable);
	GetDlgItem(IDC_CUT_NEXT) -> EnableWindow(enable);
	GetDlgItem(IDC_TREE) -> EnableWindow(enable);
	GetDlgItem(IDC_PLAY) -> EnableWindow(enable);

	if ((m_cur_stage >= 0) && (m_cur_icon >= 0) && (m_cur_icon < ptr->num_icons)) {
		m_hilight = (ptr->icons[m_cur_icon].flags & BI_HIGHLIGHT)?1:0;
		m_flipicon = (ptr->icons[m_cur_icon].flags & BI_MIRROR_ICON)?1:0;
		m_icon_image = ptr->icons[m_cur_icon].type;
		m_icon_team = ptr->icons[m_cur_icon].team;
		m_icon_label = ptr->icons[m_cur_icon].label;
		m_ship_type = ptr->icons[m_cur_icon].ship_class;
//		m_icon_text = convert_multiline_string(ptr->icons[m_cur_icon].text);
		m_id = ptr->icons[m_cur_icon].id;
		enable = TRUE;

	} else {
		m_flipicon = FALSE;
		m_hilight = FALSE;
		m_icon_image = -1;
		m_icon_team = -1;
		m_ship_type = -1;
		m_icon_label = _T("");
		m_cur_icon = -1;
		m_id = 0;
		enable = FALSE;
	}

	GetDlgItem(IDC_ICON_TEXT) -> EnableWindow(enable);
	GetDlgItem(IDC_ICON_LABEL) -> EnableWindow(enable);
	GetDlgItem(IDC_ICON_IMAGE) -> EnableWindow(enable);
	GetDlgItem(IDC_SHIP_TYPE) -> EnableWindow(enable);
	GetDlgItem(IDC_HILIGHT) -> EnableWindow(enable);
	GetDlgItem(IDC_FLIP_ICON) -> EnableWindow(enable);
	GetDlgItem(IDC_LOCAL) -> EnableWindow(enable);
	GetDlgItem(IDC_TEAM) -> EnableWindow(enable);
	GetDlgItem(IDC_ID) -> EnableWindow(enable);
	GetDlgItem(IDC_DELETE_ICON) -> EnableWindow(enable);

	valid = invalid = 0;
	objp = GET_FIRST(&obj_used_list);
	while (objp != END_OF_LIST(&obj_used_list)) {
		if (objp->flags & OF_MARKED) {
			if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START) || (objp->type == OBJ_WAYPOINT) || (objp->type == OBJ_JUMP_NODE))
				valid = 1;
			else
				invalid = 1;
		}

		objp = GET_NEXT(objp);
	}

	if (m_cur_stage >= 0)
		ptr = &Briefing->stages[m_cur_stage];

	if (valid && !invalid && (m_cur_stage >= 0) && (ptr->num_icons < MAX_STAGE_ICONS))
		GetDlgItem(IDC_MAKE_ICON) -> EnableWindow(TRUE);
	else
		GetDlgItem(IDC_MAKE_ICON) -> EnableWindow(FALSE);

	if (m_cur_stage >= 0)
		for (i=0; i<ptr->num_icons; i++)
			icon_marked[i] = 0;

	valid = invalid = 0;
	objp = GET_FIRST(&obj_used_list);
	while (objp != END_OF_LIST(&obj_used_list)) {
		if (objp->flags & OF_MARKED) {
			if (objp->type == OBJ_POINT) {
				valid++;
				icon_marked[objp->instance] = 1;

			} else
				invalid++;
		}

		objp = GET_NEXT(objp);
	}

	if (valid && !invalid && (m_cur_stage >= 0))
		GetDlgItem(IDC_PROPAGATE_ICONS) -> EnableWindow(TRUE);
	else
		GetDlgItem(IDC_PROPAGATE_ICONS) -> EnableWindow(FALSE);

	count = 0;
	lines = 1;  // default lines checkbox to checked
	
	if (m_cur_stage >= 0) {
		for (i=0; i<ptr->num_lines; i++)
			line_marked[i] = 0;

		// go through and locate all lines between marked icons
		for (i=0; i<ptr->num_icons - 1; i++)
			for (j=i+1; j<ptr->num_icons; j++) {
				if ( icon_marked[i] && icon_marked[j] ) {
					for (l=0; l<ptr->num_lines; l++)
						if ( ((ptr->lines[l].start_icon == i) && (ptr->lines[l].end_icon == j)) || ((ptr->lines[l].start_icon == j) && (ptr->lines[l].end_icon == i)) ) {
							line_marked[l] = 1;
							count++;  // track number of marked lines (lines between 2 icons that are both marked)
							break;
						}

					// at least 1 line missing between 2 marked icons, so use mixed state
					if (l == ptr->num_lines)
						lines = 2;
				}
			}
	}

	// not even 1 line between any 2 marked icons?  Set checkbox to unchecked.
	if (!count)
		lines = 0;

	i = 0;
	if (m_cur_stage >= 0){
		i = calc_num_lines_for_icons(valid) + ptr->num_lines - count;
	}

	if ((valid > 1) && !invalid && (m_cur_stage >= 0) && (i <= MAX_BRIEF_STAGE_LINES))
		GetDlgItem(IDC_LINES) -> EnableWindow(TRUE);
	else
		GetDlgItem(IDC_LINES) -> EnableWindow(FALSE);

	m_lines.SetCheck(lines);

	UpdateData(FALSE);
	if ((m_last_stage != m_cur_stage) || (Briefing != save_briefing)) {
		if (m_last_stage >= 0) {
			for (i=0; i<save_briefing->stages[m_last_stage].num_icons; i++) {
				// save positions of all icons, in case they have moved
				save_briefing->stages[m_last_stage].icons[i].pos = Objects[icon_obj[i]].pos;
				// release objects being used by last stage
				obj_delete(icon_obj[i]);
			}
		}

		if (m_cur_stage >= 0) {
			for (i=0; i<ptr->num_icons; i++) {
				// create an object for each icon for display/manipulation purposes
				icon_obj[i] = obj_create(OBJ_POINT, -1, i, NULL, &ptr->icons[i].pos, 0.0f, OF_RENDERS);
			}

			obj_merge_created_list();
		}

		m_last_stage = m_cur_stage;
	}

	m_last_icon = m_cur_icon;
	Update_window = 1;
	save_briefing = Briefing;
}
void SpecialActions::update(SpecialActionsOutput& specialActionsOutput)
{
  if(!motionNetData.nodeArray)
  {
    specialActionsOutput.angles.fill(0);
    specialActionsOutput.stiffnessData.stiffnesses.fill(0);
    return;
  }

  float speedFactor = 1.0f;
  MODIFY("parameters:SpecialActions:speedFactor", speedFactor);
  if(theMotionSelection.specialActionMode != MotionSelection::deactive)
  {
    specialActionsOutput.isLeavingPossible = true;
    if(dataRepetitionCounter <= 0)
    {
      if(!wasActive)
      {
        //entered from external motion
        currentNode = 0;
        for(int i = 0; i < Joints::numOfJoints; ++i)
          lastRequest.angles[i] = theJointAngles.angles[i];
        lastSpecialAction = SpecialActionRequest::numOfSpecialActionIDs;
      }

      // this is need when a special actions gets executed directly after another without
      // switching to a different motion for interpolating the stiffness
      if(wasEndOfSpecialAction)
      {
        specialActionsOutput.stiffnessData.resetToDefault();
        if(!mirror)
          lastStiffnessRequest = currentStiffnessRequest;
        else
          lastStiffnessRequest.mirror(currentStiffnessRequest);
        currentStiffnessRequest.resetToDefault();
      }
      wasEndOfSpecialAction = false;
      // search next data, leave on transition to external motion
      if(!getNextData(theMotionSelection.specialActionRequest, specialActionsOutput))
      {
        wasActive = true;
        wasEndOfSpecialAction = true;
        specialActionsOutput.odometryOffset = Pose2f();
        return;
      }
    }
    else
    {
      dataRepetitionCounter -= int(theFrameInfo.cycleTime * 1000 * speedFactor);
      stiffnessInterpolationCounter -= int(theFrameInfo.cycleTime * 1000 * speedFactor);
    }

    //set current joint values
    calculateJointRequest(specialActionsOutput);

    //odometry update
    if(currentInfo.type == SpecialActionInfo::homogeneous || currentInfo.type == SpecialActionInfo::once)
      if(mirror)
        specialActionsOutput.odometryOffset = Pose2f(-currentInfo.odometryOffset.rotation, currentInfo.odometryOffset.translation.x(), -currentInfo.odometryOffset.translation.y());
      else
        specialActionsOutput.odometryOffset = currentInfo.odometryOffset;
    else
      specialActionsOutput.odometryOffset = Pose2f();
    if(currentInfo.type == SpecialActionInfo::once)
      currentInfo.type = SpecialActionInfo::none;

    //store value if current data line finished
    if(dataRepetitionCounter <= 0)
    {
      if(!mirror)
        lastRequest = currentRequest;
      else
        lastRequest.mirror(currentRequest);
    }
    specialActionsOutput.isLeavingPossible = false;
    if(deShakeMode)
      for(int i = Joints::lShoulderPitch; i <= Joints::rElbowRoll; ++i)
        if(randomFloat() < 0.25)
          specialActionsOutput.angles[i] = JointAngles::off;
  }
  wasActive = theMotionSelection.specialActionMode != MotionSelection::deactive;
}
Exemple #24
0
/*virtual*/ bool gui_filterbar_c::sq_evt(system_query_e qp, RID rid, evt_data_s &data)
{
    switch(qp)
    {
    case SQ_RECT_CHANGED:
        {
            ts::irect cla = get_client_area();
            fake_margin.x = 5;
            fake_margin.y = 0;
            if (prf().get_options().is(UIOPT_TAGFILETR_BAR))
            {
                if (!textrect.get_text().is_empty())
                {
                    ts::ivec2 sz = textrect.calc_text_size(cla.width() - 10, custom_tag_parser_delegate());
                    sz.y += 3;
                    textrect.set_size(sz);
                }
            }
            if (edit)
            {
                MODIFY(*edit).pos(cla.lt).size(cla.width(), filtereditheight);
                fake_margin.y += filtereditheight;

            }
            if (option1)
            {
                int omy = option1->get_min_size().y;
                MODIFY( *option1 ).pos( cla.lt + ts::ivec2(0,filtereditheight) ).size( cla.width(), omy );
                fake_margin.y += omy;
            }
        }
        return true;
    case SQ_MOUSE_LUP:
        if (overlink == clicklink && clicklink >= 0)
            do_tag_click(clicklink);
        clicklink = -1;
        break;
    case SQ_MOUSE_LDOWN:
        if (overlink >= 0)
            clicklink = overlink;
        break;
    case SQ_MOUSE_RUP:
        if (overlink == rclicklink && rclicklink >= 0)
            do_tag_rclick(rclicklink);
        rclicklink = -1;
        break;
    case SQ_MOUSE_RDOWN:
        if (overlink >= 0)
            rclicklink = overlink;
        break;
    case SQ_DRAW:
        if (rid == getrid())
        {
            if (prf().get_options().is(UIOPT_TAGFILETR_BAR))
            {
                ts::irect ca = get_client_area();
                draw_data_s &dd = getengine().begin_draw();

                dd.offset += ca.lt; dd.offset.x += 5;
                dd.size = ca.size();
                dd.size.x -= 10;

                if (edit)
                    dd.offset.y += edit->getprops().size().y;
                if (option1)
                    dd.offset.y += option1->get_min_size().y;

                text_draw_params_s tdp;
                tdp.rectupdate = updaterect;
                draw(dd, tdp);
                getengine().end_draw();

            }

            return gui_control_c::sq_evt(qp,rid,data);

        }
        break;
    }

    return __super::sq_evt(qp,rid,data);
}
void ObstacleCombinator::update(ObstacleModel& obstacleModel)
{
  MODIFY("parameters:ObstacleCombinator", parameters);

  // Perform grid cell clustering and add clusters as obstacles:
  memset(clusterAssignment, 0, USObstacleGrid::GRID_SIZE * sizeof(int));
  obstacleModel.obstacles.clear();
  currentCluster.init();
  int currentClusterIndex(1);
  for(int y = 1; y < USObstacleGrid::GRID_LENGTH - 1; ++y)
  {
    for(int x = 1; x < USObstacleGrid::GRID_LENGTH - 1; ++x)
    {
      const int currentCellIndex = y * USObstacleGrid::GRID_LENGTH + x;
      const USObstacleGrid::Cell& c = theUSObstacleGrid.cells[currentCellIndex];
      if(clusterAssignment[currentCellIndex] == 0 && c.state >= theUSObstacleGrid.cellOccupiedThreshold)
      {
        clusterAssignment[currentCellIndex] = currentClusterIndex;
        // iterative implementation of floodfill algorithm
        cellStack.push(Vector2<int>(x, y));
        while(!cellStack.empty())
        {
          int x = cellStack.top().x;
          int y = cellStack.top().y;
          cellStack.pop();
          currentCluster.cells.push_back(Vector2<int>(x, y));
          if(x == 0 || y == 0 || x == USObstacleGrid::GRID_LENGTH - 1 || y == USObstacleGrid::GRID_LENGTH - 1) //ignore border
            continue;
          // Test all eight neighbors (also stupid check for center cell)
          for(int y2 = y - 1; y2 <= y + 1; ++y2)
          {
            for(int x2 = x - 1; x2 <= x + 1; ++x2)
            {
              const int neighborCellIndex = y2 * USObstacleGrid::GRID_LENGTH + x2;
              const USObstacleGrid::Cell& cn = theUSObstacleGrid.cells[neighborCellIndex];
              if(clusterAssignment[neighborCellIndex] == 0 &&
                 ((cn.state >= theUSObstacleGrid.cellOccupiedThreshold && !parameters.clusterNonMaxThresholdCells) ||
                  (cn.state > 0 && parameters.clusterNonMaxThresholdCells)))
              {
                clusterAssignment[neighborCellIndex] = currentClusterIndex;
                cellStack.push(Vector2<int>(x2, y2));
              }
            }
          }
        }
        ++currentClusterIndex;
        if(currentCluster.cells.size() >= (unsigned int)(parameters.minClusterSize))
          generateObstacleFromCurrentCluster(obstacleModel.obstacles);
        currentCluster.init();
      }
    }
  }

  // Robot dimensions:
  const float robotHeight = 580;
  const float robotWidth  = 300; // Guessed value
  const float robotDepth  = 150; // Guessed value
  const int   robotSize   = 9;   // Guessed value

  // Add robot obstacles:
  for(RobotsModel::RCIt robot = theRobotsModel.robots.begin(); robot != theRobotsModel.robots.end(); robot++)
  {
    float robotDistance = robot->relPosOnField.abs();
    if((!robot->standing && parameters.considerLyingRobots) && (robotDistance < parameters.maxRobotDistance))
    {
      Vector2<> widthOffset(robotHeight / 2.0f, 0.0f);
      Vector2<> robotCenter(robot->relPosOnField);
      Vector2<> closestRobotPoint(robotCenter);
      closestRobotPoint.normalize(robotCenter.abs() - robotWidth / 2.0f); // Assume that robot lies crosswise
      Vector2<> leftCorner(widthOffset);
      leftCorner.rotateLeft();
      leftCorner += robotCenter;
      Vector2<> rightCorner(widthOffset);
      rightCorner.rotateRight();
      rightCorner += robotCenter;
      obstacleModel.obstacles.push_back(ObstacleModel::Obstacle(leftCorner, rightCorner, robotCenter, closestRobotPoint,
                                        robotSize, robot->covariance, ObstacleModel::Obstacle::ROBOT));
    }
    else if((robot->standing && parameters.considerStandingRobots) && (robotDistance < parameters.maxRobotDistance))
    {
      Vector2<> widthOffset(robotWidth / 2.0f, 0.0f);
      Vector2<> robotCenter(robot->relPosOnField);
      Vector2<> closestRobotPoint(robotCenter);
      closestRobotPoint.normalize(robotCenter.abs() - robotWidth / 2.0f);
      Vector2<> leftCorner(widthOffset);
      leftCorner.rotateLeft();
      leftCorner += robotCenter;
      Vector2<> rightCorner(widthOffset);
      rightCorner.rotateRight();
      rightCorner += robotCenter;
      obstacleModel.obstacles.push_back(ObstacleModel::Obstacle(leftCorner, rightCorner, robotCenter, closestRobotPoint,
                                        robotSize, robot->covariance, ObstacleModel::Obstacle::ROBOT));
    }
  }

  // Add arm obstacles:
  Vector2<> robotCenter(0.0f, robotWidth / 2.0f + robotDepth / 2.0f);
  float robotDistance = robotCenter.abs();
  if(parameters.considerArmCollisions
     && (theArmContactModel.contactLeft || theArmContactModel.contactRight)
     && (robotDistance < parameters.maxRobotDistance))
  {
    // Assume chest to arm contact
    Vector2<> widthOffset(0.0f, robotWidth / 2.0f);
    Vector2<> closestRobotPoint(0.0f, robotWidth / 2.0f);
    Vector2<> leftCorner(widthOffset);
    leftCorner.rotateRight();
    leftCorner += robotCenter;
    Vector2<> rightCorner(widthOffset);
    rightCorner.rotateLeft();
    rightCorner += robotCenter;
    Matrix2x2<> covariance(robotWidth / 2.0f, 0.0f, 0.0f, robotWidth / 2.0f);
    if(theArmContactModel.contactLeft)
      obstacleModel.obstacles.push_back(ObstacleModel::Obstacle(leftCorner, rightCorner, robotCenter, closestRobotPoint,
                                        robotSize, covariance, ObstacleModel::Obstacle::ARM));
    if(theArmContactModel.contactRight)
      obstacleModel.obstacles.push_back(ObstacleModel::Obstacle(-leftCorner, -rightCorner, -robotCenter, -closestRobotPoint,
                                        robotSize, covariance, ObstacleModel::Obstacle::ARM));
  }

  TEAM_OUTPUT(idTeamMateObstacleModel, bin, obstacleModel);
}
void FieldBoundary::draw() const
{
  DECLARE_DEBUG_DRAWING("representation:FieldBoundary:BoundarySpots", "drawingOnImage");
  for(const Vector2<int>& p : boundarySpots)
  {
    DOT("representation:FieldBoundary:BoundarySpots", p.x, p.y, ColorRGBA::blue, ColorRGBA::blue);
  }

  DECLARE_DEBUG_DRAWING("representation:FieldBoundary:ConvexBoundary", "drawingOnImage");
  const Vector2<int>* previ = nullptr;
  for(const Vector2<int>& p : convexBoundary)
  {
    DOT_AS_VECTOR("representation:FieldBoundary:ConvexBoundary", p, ColorRGBA::red, ColorRGBA::red);
    if(previ != nullptr)
    {
      LINE("representation:FieldBoundary:ConvexBoundary", p.x, p.y, previ->x, previ->y, 1, Drawings::ps_solid, ColorRGBA::red);
    }
    previ = &p;
  }

  int selected = -1;
  MODIFY("representation:FieldBoundary:SelectedCandidate", selected);

  DECLARE_DEBUG_DRAWING("representation:FieldBoundary:BoundaryCandidates", "drawingOnImage");
  int num = (int) convexBoundaryCandidates.size();
  float step = 255.0f / (num - 1);
  int pos = 0;
  for(const InImage& tmpBoundary : convexBoundaryCandidates)
  {
    previ = nullptr;
    unsigned char colorMod = static_cast<unsigned char>(step * pos);
    ColorRGBA col = ColorRGBA(colorMod, colorMod, 255 - colorMod);
    if(pos == selected || selected < 0 || selected >= num)
    {
      for(const Vector2<int>& p : tmpBoundary)
      {
        DOT_AS_VECTOR("representation:FieldBoundary:BoundaryCandidates", p, col, col);
        if(previ != nullptr)
        {
          LINE("representation:FieldBoundary:BoundaryCandidates", p.x, p.y, previ->x, previ->y, 1, Drawings::ps_solid, col);
        }
        previ = &p;
      }
    }
    pos++;
  }

  DECLARE_DEBUG_DRAWING("representation:FieldBoundary:Image", "drawingOnImage");
  previ = nullptr;
  for(const Vector2<int>& p : boundaryInImage)
  {
    DOT_AS_VECTOR("representation:FieldBoundary:Image", p, ColorRGBA::orange, ColorRGBA::orange);
    if(previ != nullptr)
    {
      LINE("representation:FieldBoundary:Image", p.x, p.y, previ->x, previ->y, 1, Drawings::ps_solid, ColorRGBA::orange);
    }
    previ = &p;
  }

  DECLARE_DEBUG_DRAWING("representation:FieldBoundary:Field", "drawingOnField");
  const Vector2<float>* prevf = nullptr;
  for(const Vector2<float>& p : boundaryOnField)
  {
    DOT("representation:FieldBoundary:Field", p.x, p.y, ColorRGBA::black, ColorRGBA::black);
    if(prevf != nullptr)
    {
      LINE("representation:FieldBoundary:Field", p.x, p.y, prevf->x, prevf->y, 20, Drawings::ps_solid, ColorRGBA::black);
    }
    prevf = &p;
  }

  DECLARE_DEBUG_DRAWING("representation:FieldBoundary:HighestPoint", "drawingOnImage");
  LINE("representation:FieldBoundary:HighestPoint", highestPoint.x, highestPoint.y, highestPoint.x + 20, highestPoint.y, 2, Drawings::ps_solid, ColorRGBA::black);
  LINE("representation:FieldBoundary:HighestPoint", highestPoint.x, highestPoint.y, highestPoint.x, highestPoint.y + 20, 2, Drawings::ps_solid, ColorRGBA::black);
}
// update parts of wing that can't fail.  This is useful if for when you need to change
// something in a wing that this updates elsewhere in Fred.  Normally when auto-update
// kicks in, the changes you make will be wiped out by the auto=update, so instead you
// would call this function to update the wing, make your changes, and then call the
// initialize_data_safe() function to show your changes in the dialog
void wing_editor::update_data_safe()
{
	char buf[512];
	int i, d, hotkey = -1;

	nprintf(("Fred routing", "Wing dialog save safe\n"));
	if (!GetSafeHwnd())
		return;

	UpdateData(TRUE);
	UpdateData(TRUE);

	if (cur_wing < 0)
		return;

	if (m_threshold >= Wings[cur_wing].wave_count) {
		m_threshold = Wings[cur_wing].wave_count - 1;
		if (!bypass_errors)
			sprintf(buf, "Wave threshold is set too high.  Value has been lowered to %d", (int) m_threshold);

		MessageBox(buf);
	}

	if (m_threshold + Wings[cur_wing].wave_count > MAX_SHIPS_PER_WING) {
		m_threshold = MAX_SHIPS_PER_WING - Wings[cur_wing].wave_count;
		if (!bypass_errors)
			sprintf(buf, "Wave threshold is set too high.  Value has been lowered to %d", (int) m_threshold);

		MessageBox(buf);
	}

	if (m_waves < 1) {
		m_waves = 1;
		if (!bypass_errors)
			sprintf(buf, "Number of waves illegal.  Has been set to 1.", (int) m_waves);

		MessageBox(buf);
	}

	MODIFY(Wings[cur_wing].special_ship, m_special_ship);
	MODIFY(Wings[cur_wing].num_waves, m_waves);
	MODIFY(Wings[cur_wing].threshold, m_threshold);
	MODIFY(Wings[cur_wing].arrival_location, m_arrival_location);
	MODIFY(Wings[cur_wing].departure_location, m_departure_location);
	MODIFY(Wings[cur_wing].arrival_delay, m_arrival_delay);
	if (m_arrival_delay_min > m_arrival_delay_max) {
		if (!bypass_errors)
			sprintf(buf, "Arrival delay minimum greater than maximum.  Value lowered to %d", m_arrival_delay_max);

		MessageBox(buf);
		m_arrival_delay_min = m_arrival_delay_max;
	}

	MODIFY(Wings[cur_wing].wave_delay_min, m_arrival_delay_min);
	MODIFY(Wings[cur_wing].wave_delay_max, m_arrival_delay_max);
	MODIFY(Wings[cur_wing].arrival_distance, m_arrival_dist);
	if (m_arrival_target >= 0) {
		i = ((CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET)) -> GetItemData(m_arrival_target);
		MODIFY(Wings[cur_wing].arrival_anchor, i);

		// when arriving near or in front of a ship, be sure that we are far enough away from it!!!
		if (((m_arrival_location != ARRIVE_AT_LOCATION) && (m_arrival_location != ARRIVE_FROM_DOCK_BAY)) && (i >= 0) && (i < SPECIAL_ARRIVAL_ANCHORS_OFFSET)) {
			d = int(min(500, 2.0f * Objects[Ships[i].objnum].radius));
			if ((Wings[cur_wing].arrival_distance < d) && (Wings[cur_wing].arrival_distance > -d)) {
				if (!bypass_errors)
					sprintf(buf, "Ship must arrive at least %d meters away from target.\n"
						"Value has been reset to this.  Use with caution!\r\n"
						"Reccomended distance is %d meters.\r\n", d, (int)(2.0f * Objects[Ships[i].objnum].radius) );

				MessageBox(buf);
				if (Wings[cur_wing].arrival_distance < 0)
					Wings[cur_wing].arrival_distance = -d;
				else
					Wings[cur_wing].arrival_distance = d;

				m_arrival_dist = Wings[cur_wing].arrival_distance;
			}
		}
	}

	i = ((CComboBox*)GetDlgItem(IDC_DEPARTURE_TARGET))->GetItemData(m_departure_target);
	
	if (m_departure_location == DEPART_AT_DOCK_BAY) 
		MODIFY(Wings[cur_wing].departure_anchor,  i);
	else
		MODIFY(Wings[cur_wing].jump_anchor, m_departure_target);

	MODIFY(Wings[cur_wing].departure_delay, m_departure_delay);
	hotkey = m_hotkey - 1;
	MODIFY(Wings[cur_wing].hotkey, hotkey);
	if ( m_ignore_count ) {
		if ( !(Wings[cur_wing].flags & WF_IGNORE_COUNT) )
			set_modified();
		Wings[cur_wing].flags |= WF_IGNORE_COUNT;

	} else {
		if ( Wings[cur_wing].flags & WF_IGNORE_COUNT )
			set_modified();
		Wings[cur_wing].flags &= ~WF_IGNORE_COUNT;
	}

	if ( m_no_arrival_music ) {
		if ( !(Wings[cur_wing].flags & WF_NO_ARRIVAL_MUSIC) )
			set_modified();
		Wings[cur_wing].flags |= WF_NO_ARRIVAL_MUSIC;

	} else {
		if ( Wings[cur_wing].flags & WF_NO_ARRIVAL_MUSIC )
			set_modified();
		Wings[cur_wing].flags &= ~WF_NO_ARRIVAL_MUSIC;
	}

	// check the no message flag
	if ( m_no_arrival_message ) {
		if ( !(Wings[cur_wing].flags & WF_NO_ARRIVAL_MESSAGE) )
			set_modified();
		Wings[cur_wing].flags |= WF_NO_ARRIVAL_MESSAGE;

	} else {
		if ( Wings[cur_wing].flags & WF_NO_ARRIVAL_MESSAGE )
			set_modified();
		Wings[cur_wing].flags &= ~WF_NO_ARRIVAL_MESSAGE;
	}

	// set the no warp effect for wings flag
	if ( m_no_arrival_warp ) {
		if ( !(Wings[cur_wing].flags & WF_NO_ARRIVAL_WARP) )
			set_modified();
		Wings[cur_wing].flags |= WF_NO_ARRIVAL_WARP;
	} else {
		if ( Wings[cur_wing].flags & WF_NO_ARRIVAL_WARP )
			set_modified();
		Wings[cur_wing].flags &= ~WF_NO_ARRIVAL_WARP;
	}
	// set the no warp effect for wings flag
	if ( m_no_departure_warp ) {
		if ( !(Wings[cur_wing].flags & WF_NO_DEPARTURE_WARP) )
			set_modified();
		Wings[cur_wing].flags |= WF_NO_DEPARTURE_WARP;
	} else {
		if ( Wings[cur_wing].flags & WF_NO_DEPARTURE_WARP )
			set_modified();
		Wings[cur_wing].flags &= ~WF_NO_DEPARTURE_WARP;
	}

	if ( m_no_dynamic ) {
		if ( !(Wings[cur_wing].flags & WF_NO_DYNAMIC) )
			set_modified();
		Wings[cur_wing].flags |= WF_NO_DYNAMIC;
	} else {
		if ( Wings[cur_wing].flags & WF_NO_DYNAMIC )
			set_modified();
		Wings[cur_wing].flags &= ~WF_NO_DYNAMIC;
	}

	if (Wings[cur_wing].arrival_cue >= 0)
		free_sexp2(Wings[cur_wing].arrival_cue);
	Wings[cur_wing].arrival_cue = m_arrival_tree.save_tree();

	if (Wings[cur_wing].departure_cue >= 0)
		free_sexp2(Wings[cur_wing].departure_cue);
	Wings[cur_wing].departure_cue = m_departure_tree.save_tree();

	// copy squad stuff
	if(stricmp(m_wing_squad_filename, Wings[cur_wing].wing_squad_filename))
	{
		string_copy(Wings[cur_wing].wing_squad_filename, m_wing_squad_filename, MAX_FILENAME_LEN);
		set_modified();
	}

	if (modified)
		set_modified();
}
void FootContactModelProvider::update(FootContactModel& model)
{
  MODIFY("module:FootContactModelProvider:parameters", p);

  // Check, if any bumper is pressed
  bool leftFootLeft = checkContact(KeyStates::leftFootLeft, leftFootLeftDuration);
  bool leftFootRight = checkContact(KeyStates::leftFootRight, leftFootRightDuration);
  bool rightFootLeft = checkContact(KeyStates::rightFootLeft, rightFootLeftDuration);
  bool rightFootRight = checkContact(KeyStates::rightFootRight, rightFootRightDuration);

  // Update statistics
  if (leftFootLeft || leftFootRight)
  {
    contactBufferLeft.add(1);
    contactDurationLeft++;
  }
  else
  {
    contactBufferLeft.add(0);
    contactDurationLeft = 0;
  }
  if (rightFootLeft || rightFootRight)
  {
    contactBufferRight.add(1);
    contactDurationRight++;
  }
  else
  {
    contactBufferRight.add(0);
    contactDurationRight = 0;
  }

  // Generate model
  if ((theMotionInfo.motion == MotionInfo::stand || theMotionInfo.motion == MotionInfo::walk) &&
      (theGameInfo.state == STATE_READY || theGameInfo.state == STATE_SET || theGameInfo.state == STATE_PLAYING) && //The bumper is used for configuration in initial
      (theFallDownState.state == FallDownState::upright))
  {
    if(contactBufferLeft.getSum() > p.contactThreshold)
    {
      model.contactLeft = true;
      model.contactDurationLeft = contactDurationLeft;
      model.lastContactLeft = theFrameInfo.time;
    }
    else
    {
      model.contactLeft = false;
      model.contactDurationLeft = 0;
    }
    if(contactBufferRight.getSum() > p.contactThreshold)
    {
      model.contactRight = true;
      model.contactDurationRight = contactDurationRight;
      model.lastContactRight = theFrameInfo.time;
    }
    else
    {
      model.contactRight = false;
      model.contactDurationRight = 0;
    }
  }
  else
  {
    model.contactLeft = false;
    model.contactRight = false;
    model.contactDurationLeft = 0;
    model.contactDurationRight = 0;
  }

  // Debugging stuff:

  if(p.debug && theFrameInfo.getTimeSince(lastSoundTime) > (int)p.soundDelay &&
    (model.contactLeft || model.contactRight))
  {
    lastSoundTime = theFrameInfo.time;
    SoundPlayer::play("doh.wav");
  }


  DECLARE_PLOT("module:FootContactModelProvider:sumLeft");
  DECLARE_PLOT("module:FootContactModelProvider:durationLeft");
  DECLARE_PLOT("module:FootContactModelProvider:contactLeft");
  DECLARE_PLOT("module:FootContactModelProvider:sumRight");
  DECLARE_PLOT("module:FootContactModelProvider:durationRight");
  DECLARE_PLOT("module:FootContactModelProvider:contactRight");
  DECLARE_PLOT("module:FootContactModelProvider:leftFootLeft");
  DECLARE_PLOT("module:FootContactModelProvider:leftFootRight");
  DECLARE_PLOT("module:FootContactModelProvider:rightFootLeft");
  DECLARE_PLOT("module:FootContactModelProvider:rightFootRight");
  PLOT("module:FootContactModelProvider:sumLeft", contactBufferLeft.getSum());
  PLOT("module:FootContactModelProvider:durationLeft", contactDurationLeft);
  PLOT("module:FootContactModelProvider:sumRight", contactBufferRight.getSum());
  PLOT("module:FootContactModelProvider:durationRight", contactDurationRight);
  PLOT("module:FootContactModelProvider:contactLeft", model.contactLeft ? 10 : 0);
  PLOT("module:FootContactModelProvider:contactRight", model.contactRight ? 10 : 0);
  PLOT("module:FootContactModelProvider:leftFootLeft", leftFootLeft ? 10 : 0);
  PLOT("module:FootContactModelProvider:leftFootRight", leftFootRight ? 10 : 0);
  PLOT("module:FootContactModelProvider:rightFootLeft", rightFootLeft ? 10 : 0);
  PLOT("module:FootContactModelProvider:rightFootRight", rightFootRight ? 10 : 0);
}
void KickEngineData::ModifyData(const KickRequest& br, JointRequest& kickEngineOutput, std::vector<KickEngineParameters>& params)
{
  auto& p = params.back();
  MODIFY("module:KickEngine:newKickMotion", p);
  strcpy(p.name, "newKick");

  MODIFY("module:KickEngine:px", gyroP.x());
  MODIFY("module:KickEngine:dx", gyroD.x());
  MODIFY("module:KickEngine:ix", gyroI.x());
  MODIFY("module:KickEngine:py", gyroP.y());
  MODIFY("module:KickEngine:dy", gyroD.y());
  MODIFY("module:KickEngine:iy", gyroI.y());

  MODIFY("module:KickEngine:formMode", formMode);
  MODIFY("module:KickEngine:lFootTraOff", limbOff[Phase::leftFootTra]);
  MODIFY("module:KickEngine:rFootTraOff", limbOff[Phase::rightFootTra]);
  MODIFY("module:KickEngine:lFootRotOff", limbOff[Phase::leftFootRot]);
  MODIFY("module:KickEngine:rFootRotOff", limbOff[Phase::rightFootRot]);
  MODIFY("module:KickEngine:lHandTraOff", limbOff[Phase::leftArmTra]);
  MODIFY("module:KickEngine:rHandTraOff", limbOff[Phase::rightArmTra]);
  MODIFY("module:KickEngine:lHandRotOff", limbOff[Phase::leftHandRot]);
  MODIFY("module:KickEngine:rHandRotOff", limbOff[Phase::rightHandRot]);

  //Plot com stabilizing
  PLOT("module:KickEngine:comy", robotModel.centerOfMass.y());
  PLOT("module:KickEngine:diffy", actualDiff.y());
  PLOT("module:KickEngine:refy", ref.y());

  PLOT("module:KickEngine:comx", robotModel.centerOfMass.x());
  PLOT("module:KickEngine:diffx", actualDiff.x());
  PLOT("module:KickEngine:refx", ref.x());

  PLOT("module:KickEngine:lastdiffy", toDegrees(lastBody.y()));
  PLOT("module:KickEngine:bodyErrory", toDegrees(bodyError.y()));

  for(int i = 0; i < Phase::numOfLimbs; i++)
  {
    const int stiffness = limbOff[i] ? 0 : 100;

    switch(static_cast<Phase::Limb>(i))
    {
      case Phase::leftFootTra:
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lHipRoll] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lHipPitch] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lKneePitch] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lAnklePitch] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lAnkleRoll] = stiffness;
        break;
      case Phase::rightFootTra:
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rHipRoll] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rHipPitch] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rKneePitch] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rAnklePitch] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rAnkleRoll] = stiffness;
        break;
      case Phase::leftFootRot:
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lAnklePitch] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lAnkleRoll] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rHipYawPitch] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lHipYawPitch] = stiffness;
        break;
      case Phase::rightFootRot:
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rAnklePitch] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rAnkleRoll] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rHipYawPitch] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lHipYawPitch] = stiffness;
        break;
      case Phase::leftArmTra:
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lShoulderPitch] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lShoulderRoll] = stiffness;
        break;
      case Phase::rightArmTra:
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rShoulderPitch] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rShoulderRoll] = stiffness;
        break;
      case Phase::leftHandRot:
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lElbowRoll] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lElbowYaw] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lWristYaw] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::lHand] = stiffness;
        break;
      case Phase::rightHandRot:
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rElbowRoll] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rElbowYaw] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rWristYaw] = stiffness;
        kickEngineOutput.stiffnessData.stiffnesses[Joints::rHand] = stiffness;
        break;
    }
  }
}
void initial_status::OnOK()
{
	char buf[256];
	int vflag = 0, sflag = 0, hflag = 0;
	object *objp;

	if (GetDlgItem(IDC_VELOCITY)->GetWindowText(buf, 255))
		vflag = 1;
	if (GetDlgItem(IDC_SHIELDS)->GetWindowText(buf, 255))
		sflag = 1;
	if (GetDlgItem(IDC_HULL)->GetWindowText(buf, 255))
		hflag = 1;

	UpdateData(TRUE);

	change_subsys();

	if (m_multi_edit) {
		objp = GET_FIRST(&obj_used_list);
		while (objp != END_OF_LIST(&obj_used_list)) {
			if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->flags[Object::Object_Flags::Marked])) {
				if (vflag)
					MODIFY(objp->phys_info.speed, (float) m_velocity);

				if (sflag)
					MODIFY(objp->shield_quadrant[0], (float) m_shields);

				if (hflag)
					MODIFY(objp->hull_strength, (float) m_hull);

				objp->flags.set(Object::Object_Flags::No_shields, m_has_shields == 0);

                auto shipp = &Ships[get_ship_from_obj(objp)];
				
                shipp->flags.set(Ship::Ship_Flags::Force_shields_on, m_force_shields == 1);
                shipp->flags.set(Ship::Ship_Flags::Ship_locked, m_ship_locked == 1);
                shipp->flags.set(Ship::Ship_Flags::Weapons_locked, m_weapons_locked == 1);
                shipp->flags.set(Ship::Ship_Flags::Primaries_locked, m_primaries_locked == 1);
                shipp->flags.set(Ship::Ship_Flags::Secondaries_locked, m_secondaries_locked == 1);
                shipp->flags.set(Ship::Ship_Flags::Lock_all_turrets_initially, m_turrets_locked == 1);
                shipp->flags.set(Ship::Ship_Flags::Afterburner_locked, m_afterburner_locked == 1);
			}

			objp = GET_NEXT(objp);
		}

	} else {
		MODIFY(Objects[cur_object_index].phys_info.speed, (float) m_velocity);
		MODIFY(Objects[cur_object_index].shield_quadrant[0], (float) m_shields);
		MODIFY(Objects[cur_object_index].hull_strength, (float) m_hull);

		Objects[cur_object_index].flags.set(Object::Object_Flags::No_shields, m_has_shields != 0);

        Ships[m_ship].flags.set(Ship::Ship_Flags::Force_shields_on, m_force_shields == 1);
        Ships[m_ship].flags.set(Ship::Ship_Flags::Ship_locked, m_ship_locked == 1);
        Ships[m_ship].flags.set(Ship::Ship_Flags::Weapons_locked, m_weapons_locked == 1);
        Ships[m_ship].flags.set(Ship::Ship_Flags::Primaries_locked, m_primaries_locked == 1);
        Ships[m_ship].flags.set(Ship::Ship_Flags::Secondaries_locked, m_secondaries_locked == 1);
        Ships[m_ship].flags.set(Ship::Ship_Flags::Lock_all_turrets_initially, m_turrets_locked == 1);
        Ships[m_ship].flags.set(Ship::Ship_Flags::Afterburner_locked, m_afterburner_locked == 1);
	}

	if (m_team_color_setting.IsWindowEnabled() && m_team_color_setting.GetCurSel() > 0)
		Ships[m_ship].team_name = Team_Names[m_team_color_setting.GetCurSel() - 1];
	else
		Ships[m_ship].team_name = "none";

	update_docking_info();

	CDialog::OnOK();
}